From 91297944791a36f30302ef8c86dd69ebeb177671 Mon Sep 17 00:00:00 2001 From: Christophe Besson Date: Wed, 30 Sep 2026 15:06:14 +0200 Subject: feat: bundles sealed per node under the passphrase and the hub's pepper The session key is M = HKDF(Argon2(passphrase) || pepper, account id); each node's bundle key and the playlist key derive from it. Bundles are MBK3, bound to account and node; MBK1/MBK2 are refused by name, never replaced silently. Playlists move to key v2 and are re-sealed over unreadable node copies. Co-Authored-By: Claude Opus 5.5 --- packages/meshbay-hub/src/meshbay_hub/static/auth-page.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'packages/meshbay-hub/src/meshbay_hub/static/auth-page.js') diff --git a/packages/meshbay-hub/src/meshbay_hub/static/auth-page.js b/packages/meshbay-hub/src/meshbay_hub/static/auth-page.js index 09c4acf..8e67e20 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/auth-page.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/auth-page.js @@ -683,9 +683,12 @@ export function ResetPasswordPage({ onLogin }) { await _storeRecoveryKey(session.recoveryKey); setPhase('working'); const auth = loadAuth() || {}; + // The sign-in above derived the key for the new passphrase; the bundles + // are still sealed under the old one, so connect opens the recovery copy + // and they are sealed again under this key. const r = await window.MeshBayTransport.rewrapAllNodes({ hubUrl: HUB, token: auth.token, username: name, userId: auth.userId, - newPassphrase: password, recoveryKey: mnemonic, + bundleKey: session.bundleKey, recoveryKey: mnemonic, onProgress: setProgress, }); setResult(r); -- cgit v1.2.3