vault: pass full connect/token crypto through session/login
Vaultwarden (2025.12.0/f21a3ada) returns both classic (Key/PrivateKey/Kdf*) and v2 crypto (UserDecryptionOptions.MasterPasswordUnlock, AccountKeys) synthesized from the classic stored fields. session/login now returns the whole native connect/token response minus the transport tokens (under `connectToken`), alongside the spec's protectedUserKey/privateKey/kdf aliases, so the SDK gets whatever unlock path it uses. Temp diagnostic logs the response field NAMES (values redacted) to empirically confirm on a real login. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -83,7 +83,19 @@ vaultRouter.post('/session/login', async (ctx) => {
|
|||||||
clientId,
|
clientId,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Ciphertext to us — passed straight to the client, which decrypts on-device with the master key.
|
// TEMP diagnostic — field NAMES only (values redacted) to empirically confirm the crypto shape.
|
||||||
|
const names = (o: unknown) => (o && typeof o === 'object' ? Object.keys(o as object) : typeof o);
|
||||||
|
const udo = (d as { UserDecryptionOptions?: { MasterPasswordUnlock?: unknown } }).UserDecryptionOptions;
|
||||||
|
console.log(
|
||||||
|
`[vault] connect/token fields: ${Object.keys(d).join(',')} | UserDecryptionOptions=${JSON.stringify(names(udo))} | MasterPasswordUnlock=${JSON.stringify(names(udo?.MasterPasswordUnlock))} | AccountKeys=${JSON.stringify(names((d as { AccountKeys?: unknown }).AccountKeys))}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Everything except the transport tokens (which the platform holds) is crypto material the SDK unlocks
|
||||||
|
// on-device — ciphertext to us. Vaultwarden returns BOTH classic (Key/PrivateKey/Kdf*) and v2
|
||||||
|
// (UserDecryptionOptions.MasterPasswordUnlock, AccountKeys); pass the whole native response through
|
||||||
|
// under `connectToken` so the SDK gets whatever it uses, alongside the spec's named aliases.
|
||||||
|
const connectToken: Record<string, unknown> = { ...d };
|
||||||
|
for (const k of ['access_token', 'refresh_token', 'token_type', 'expires_in']) delete connectToken[k];
|
||||||
return ctx.json({
|
return ctx.json({
|
||||||
ok: true,
|
ok: true,
|
||||||
protectedUserKey: pick(d, 'Key') ?? null,
|
protectedUserKey: pick(d, 'Key') ?? null,
|
||||||
@@ -94,6 +106,7 @@ vaultRouter.post('/session/login', async (ctx) => {
|
|||||||
kdfMemory: pick(d, 'KdfMemory') ?? null,
|
kdfMemory: pick(d, 'KdfMemory') ?? null,
|
||||||
kdfParallelism: pick(d, 'KdfParallelism') ?? null,
|
kdfParallelism: pick(d, 'KdfParallelism') ?? null,
|
||||||
},
|
},
|
||||||
|
connectToken,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user