feat(backup): pass recovery phrase through RestoreManager fulfill/complete (R24-c)

This commit is contained in:
null 2026-06-30 21:24:30 -05:00
parent 209ad74532
commit 71227561e7
1 changed files with 8 additions and 3 deletions

View File

@ -76,7 +76,7 @@ class RestoreManager @Inject constructor(
): Result<BackupRestoreManager.RestoreResult> = runCatching {
val keybox = request.keybox ?: error("no keybox yet")
val privateKey = userKeyManager.loadPrivateKey() ?: error("device key missing")
val keyset = coupleKeyTransfer.unwrapCoupleKey(
val transferred = coupleKeyTransfer.unwrapCoupleKey(
keyboxB64 = keybox,
recipientPrivateKey = privateKey,
coupleId = session.coupleId,
@ -84,7 +84,8 @@ class RestoreManager @Inject constructor(
recipientUid = session.recipientUid,
nonce = request.requestNonce
)
encryptionManager.storeTransferredKeyset(session.coupleId, keyset)
// Store the key AND, if the partner included it, the couple's recovery phrase.
encryptionManager.storeTransferredKeyset(session.coupleId, transferred.keyset, transferred.recoveryPhrase)
// Consume the request so no wrapped couple key lingers server-side.
backupDataSource.deleteRestoreRequest(session.coupleId, session.recipientUid)
backupRestoreManager.restore()
@ -106,13 +107,17 @@ class RestoreManager @Inject constructor(
val expected = CoupleKeyTransfer.verificationCode(request.recipientPublicKey, request.requestNonce)
require(enteredCode.trim() == expected) { "verification code does not match" }
val coupleKeyset = encryptionManager.exportKeysetForTransfer(coupleId) ?: error("couple key missing on this device")
// Hand back the couple's recovery phrase too, if we have it, so the restored device isn't left
// without the self-recovery backstop. Null (we're phrase-less ourselves) → key-only, as before.
val recoveryPhrase = encryptionManager.recoveryPhrase(coupleId)
val keybox = coupleKeyTransfer.wrapCoupleKey(
coupleKeyset = coupleKeyset,
recipientPublicKeyB64 = request.recipientPublicKey,
coupleId = coupleId,
senderUid = uid,
recipientUid = recipientUid,
nonce = request.requestNonce
nonce = request.requestNonce,
recoveryPhrase = recoveryPhrase
)
// Make sure the partner can also pull fresh content right after unlocking the key.
runCatching { backupManager.backupNow(force = true) }