diff options
Diffstat (limited to 'packages/meshbay-hub/src/meshbay_hub/static/keyderive.js')
| -rw-r--r-- | packages/meshbay-hub/src/meshbay_hub/static/keyderive.js | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/keyderive.js b/packages/meshbay-hub/src/meshbay_hub/static/keyderive.js index 6bd5896..b1770a7 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/keyderive.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/keyderive.js @@ -426,13 +426,36 @@ async function decryptBundle(bundleB64, aesKey, { userId, nodePk }) { * decrypts it and returns the keys + encrypted bundle for push to node. * Otherwise returns bundleKey so the caller can fetch from node during handshake. */ +// The token the hub gave this browser at an earlier sign-in, per account. It +// is not a credential — the passphrase is still asked — but a sign-in that +// presents it has a failure counter of its own, so a stranger who keeps +// failing on this account's name locks only browsers it has never used. +// Kept across sign-outs on purpose: forgetting it would be the lockout again. +const KNOWN_BROWSERS = 'mb_known_browsers'; + +function _knownBrowser(username) { + try { return (JSON.parse(localStorage.getItem(KNOWN_BROWSERS)) || {})[username] || null; } + catch { return null; } +} + +function _rememberBrowser(username, token) { + if (!token) return; + try { + const all = JSON.parse(localStorage.getItem(KNOWN_BROWSERS)) || {}; + all[username] = token; + localStorage.setItem(KNOWN_BROWSERS, JSON.stringify(all)); + } catch { /* storage refused: this browser stays an unknown one */ } +} + async function loginAndRecover(username, password) { const authKey = await deriveAuthKey(password, username); + const known = _knownBrowser(username); const resp = await hubCall('/v1/users/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ username, auth_key: authKey }), + body: JSON.stringify({ username, auth_key: authKey, + ...(known ? { known_browser: known } : {}) }), }); if (!resp.ok) { @@ -454,6 +477,7 @@ async function loginAndRecover(username, password) { } const data = await resp.json(); + _rememberBrowser(username, data.known_browser); const result = { accessToken: data.access_token, refreshToken: data.refresh_token, |