bliss-cli: detect failed logins instead of caching anon sessions
The server issues a connect.sid cookie on every response, including a rejected login (which re-renders the form as 200). login() treated any returned cookie as success, so bad creds silently cached an anonymous session and the CLI stayed logged out with no warning — and since it only re-authenticates on a 401 (which the server never sends), the stale cookie was never refreshed. Trust the redirect status instead (302 = success, 2xx = rejected) and throw a clear error with the HTTP code on failure. Add a `bliss login` command that forces a fresh login past any stale cookie. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
02cdca748d
commit
e7064a7c6a
2 changed files with 23 additions and 3 deletions
|
|
@ -68,6 +68,14 @@ const commands = {
|
|||
out(c.BASE);
|
||||
}
|
||||
},
|
||||
// Force a fresh login with BLISS_USER / BLISS_PASS and report the result.
|
||||
// Unlike normal commands (which reuse a cached cookie and only re-auth on a
|
||||
// 401 the server never sends), this always hits /login, so it's the way to
|
||||
// (re)authenticate after changing creds or clearing a stale anonymous cookie.
|
||||
async login() {
|
||||
await c.login(); // throws with a clear message if the server rejects creds
|
||||
out("logged in as '" + (process.env.BLISS_USER || "?") + "' -> " + c.BASE);
|
||||
},
|
||||
// ---- reads (JSON via /plumbing) ----
|
||||
async structures() {
|
||||
out(await c.getJSON("/plumbing/structures"));
|
||||
|
|
|
|||
|
|
@ -79,10 +79,21 @@ async function login() {
|
|||
headers: { "content-type": "application/x-www-form-urlencoded" },
|
||||
body: new URLSearchParams({ username: USER, password: PASS }).toString(),
|
||||
});
|
||||
// The server issues an (anonymous) connect.sid on EVERY response — including a
|
||||
// failed login, which re-renders the form as a 200. So the presence of a
|
||||
// cookie says nothing about success. The real signal is the redirect: a good
|
||||
// login 302s to `next`/"/", a rejected one stays 2xx. Trust the status, not
|
||||
// the cookie, or we'd cache an anonymous session and silently stay logged out.
|
||||
const cookie = extractCookie(res);
|
||||
if (!cookie) {
|
||||
// A 200 back from /login means the login form re-rendered => bad creds.
|
||||
throw new Error("login failed for user '" + USER + "' (check BLISS_PASS)");
|
||||
const redirected = res.status >= 300 && res.status < 400;
|
||||
if (!redirected || !cookie) {
|
||||
throw new Error(
|
||||
"login failed for user '" +
|
||||
USER +
|
||||
"' — server rejected the credentials (HTTP " +
|
||||
res.status +
|
||||
"). Check BLISS_USER / BLISS_PASS.",
|
||||
);
|
||||
}
|
||||
saveCookie(cookie);
|
||||
return cookie;
|
||||
|
|
@ -168,6 +179,7 @@ async function getText(urlPath) {
|
|||
module.exports = {
|
||||
BASE,
|
||||
setTarget,
|
||||
login,
|
||||
request,
|
||||
getJSON,
|
||||
getText,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue