dashboard(matrix-accounts): shape-agnostic login error bodies
The matrix-account-login endpoint returns failures as a bare plain-text body today (hive-c0re error_response). The RFC 9457 rework moves it to application/problem+json. The submit handler previously called resp.json() on the error path, which threw on the plain-text body and collapsed every real failure to a generic 'login failed (HTTP 500)', hiding the actual reason. Read the error body shape-agnostically: parse JSON only on 2xx for the success envelope; on failure read the body once as text and, if it parses as JSON, surface problem+json 'detail' (then 'error'/'title' fallbacks), else use the raw text. This handles both the current plain-text and the future problem+json shapes with no BE/FE merge-order coupling. Header contract doc updated to match.
This commit is contained in:
parent
55229fdf5b
commit
0ec9e8b8a0
1 changed files with 40 additions and 10 deletions
|
|
@ -12,8 +12,12 @@
|
|||
// POST /api/matrix-account-login (x-www-form-urlencoded, operator-auth)
|
||||
// fields: agent, account, homeserver, mode=password|token,
|
||||
// user_id?, password?, token?
|
||||
// -> 2xx { ok: true, user_id } on success
|
||||
// -> 4xx { error: "<msg>" } on failure
|
||||
// -> 200 JSON { ok: true, user_id } on success
|
||||
// -> error body in transition: today a bare plain-text body
|
||||
// (hive-c0re's error_response), migrating to RFC 9457
|
||||
// application/problem+json { type, title, detail, … }. The error
|
||||
// path reads shape-agnostically (text first, then JSON `detail` if
|
||||
// it parses) so both shapes work regardless of BE/FE merge order.
|
||||
// The token is NEVER echoed back in any response, and this page never
|
||||
// re-renders a submitted secret.
|
||||
//
|
||||
|
|
@ -198,17 +202,43 @@ async function submitLogin(e) {
|
|||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||||
body: new URLSearchParams(fd),
|
||||
});
|
||||
let body = {};
|
||||
try { body = await resp.json(); } catch { /* tolerate non-JSON error pages */ }
|
||||
|
||||
if (resp.ok && body.ok) {
|
||||
out.className = 'ma-result ok';
|
||||
out.textContent = '✓ logged in as ' + (body.user_id || '(unknown)') + ' — token stored.';
|
||||
clearSecrets(formEl);
|
||||
loadAccounts(agent);
|
||||
if (resp.ok) {
|
||||
// Success is 200 + JSON { ok, user_id }.
|
||||
let body = {};
|
||||
try { body = await resp.json(); } catch { /* tolerate odd 2xx body */ }
|
||||
if (body.ok) {
|
||||
out.className = 'ma-result ok';
|
||||
out.textContent = '✓ logged in as ' + (body.user_id || '(unknown)') + ' — token stored.';
|
||||
clearSecrets(formEl);
|
||||
loadAccounts(agent);
|
||||
} else {
|
||||
out.className = 'ma-result err';
|
||||
out.textContent = '✗ login failed (unexpected response).';
|
||||
clearSecrets(formEl);
|
||||
}
|
||||
} else {
|
||||
// The BE error-body shape is in transition: today hive-c0re's
|
||||
// error_response sends a bare plain-text body (e.g. "matrix-account-
|
||||
// login: password mode needs user_id + password"); the RFC 9457 rework
|
||||
// moves it to application/problem+json ({ type, title, detail, … }).
|
||||
// Read shape-agnostically so the FE handles both with no merge-order
|
||||
// coupling: pull the body once as text, and if it parses as JSON
|
||||
// surface `detail` (problem+json) → `error`/`title` fallback, else use
|
||||
// the raw text. A bare HTTP code is the last resort.
|
||||
let msg = '';
|
||||
try {
|
||||
const raw = (await resp.text()).trim();
|
||||
msg = raw;
|
||||
if (raw && (raw[0] === '{' || raw[0] === '[')) {
|
||||
try {
|
||||
const body = JSON.parse(raw);
|
||||
msg = body.detail || body.error || body.title || raw;
|
||||
} catch { /* not JSON after all — keep the raw text */ }
|
||||
}
|
||||
} catch { /* fall back to the status code below */ }
|
||||
out.className = 'ma-result err';
|
||||
out.textContent = '✗ ' + (body.error || ('login failed (HTTP ' + resp.status + ')'));
|
||||
out.textContent = '✗ ' + (msg || ('login failed (HTTP ' + resp.status + ')'));
|
||||
clearSecrets(formEl);
|
||||
}
|
||||
} catch (err) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue