react-native-matrix-crypto
    Preparing search index...

    Function recoverIdentity

    • Restores this account's private signing keys from server-side storage.

      secret is either the passphrase createRecovery derived the key from or the recovery key it returned. One parameter serves both, so you do not have to ask your user which one they are holding.

      accountData is what you read back from your homeserver. Five events are needed and a complete recovery has all five: 'm.secret_storage.default_key', the 'm.secret_storage.key.<id>' it names, and 'm.cross_signing.master', 'm.cross_signing.self_signing' and 'm.cross_signing.user_signing'. Fetch them with GET /_matrix/client/v3/user/{userId}/account_data/{eventType}, or take them out of a /sync response's global account data, which carries all of them. Entries this call does not need are ignored, so passing more than the five is fine.

      Pass one reading of the account, not two joined together. A homeserver never serves two events of one global type, so where a duplicate can come from is a caller concatenating an older snapshot with a newer one, and the first of the two wins here. Do that across a createRecovery and the older pointer is the one followed, which reports 'recovery_key_incorrect' for the secret your user actually has: a refusal no amount of retyping resolves.

      The key description's event type is not known in advance, because it ends in the key's own id. Read 'm.secret_storage.default_key' first and its key field is that id, so fetching one event at a time takes two rounds. Taking the account data from a sync you already perform costs none.

      What this restores, and what it does not

      It restores the identity and, with it, every verification anyone else had made of this account. That is the part a second device cannot give back and the reason this call exists. It does not publish anything: the recovered device still has to publish its own device keys and be signed into the identity it has just rejoined, which is bootstrapCrossSigning republishing on a device that now holds the private keys.

      After it succeeds, getIdentityStatus reports privateKeysHeld. That is the durable answer; a 'trust_changed' signal for your own user id follows on the next receiveSyncChanges, exactly as it does when the keys arrive by gossip instead.

      Refusals, and the one distinction your error message needs

      'recovery_key_incorrect' means the secret is wrong and the stored recovery is intact. Ask again. Both halves of secret report it: a mistyped passphrase, and a recovery key with a character wrong, whatever the stored key description does or does not carry. That second case is the one worth naming, because a recovery written by another client need not describe a passphrase at all, and this refusal is what a user with a typo must be shown rather than the one below.

      'recovery_data_malformed' means no secret will ever open it. Stop asking, and set recovery up again from a device that still holds the keys. What lands here is damaged or unreadable account data, and also a recovery written for an identity this account has since replaced.

      These two are never folded together, and your product should not fold them either. Telling a user with a typo that their identity is destroyed sends them to do the one thing that destroys it; telling a user whose recovery really is unreadable that their passphrase is wrong leaves them retyping forever. The line is drawn by the MAC stored beside the key description, which is what a wrong secret fails and damaged data does not reach.

      'recovery_not_set_up' means the account data you handed over carries no complete recovery. Either this account has none, or you did not fetch all of it, or its 'm.secret_storage.default_key' has been cleared and now points at nothing. This library sees only what it was given, so it cannot tell those apart, and the list above is what to check.

      A cleared pointer belongs here and not with the two refusals above, and the difference matters to your user. PUT {} is the only way the client-server API can delete an account data event, so a cleared pointer is what a half-finished replacement leaves behind: the key description and every ciphertext are still on your homeserver, and writing the pointer back makes the same passphrase work again. Nothing has been destroyed, so do not show your user the sentence for 'recovery_data_malformed', which sends them to set recovery up again and is the one action that would destroy it.

      'account_keys_not_fetched' and 'identity_not_known' are the same pair bootstrapCrossSigning and requestSelfVerification report, and they are checked before the passphrase is even derived. Importing a private key checks it against the account's published identity, so this call needs a 'keys_query' for your own account answered first. The refusal queues that query itself, so the remedy is the ordinary loop: drain, send, report sent, call this again.

      Parameters

      Returns Promise<void>