Skip to main content

Account recovery

About this documentation

This documentation only describes how to configure the SDK for our account recovery feature. If you want to learn about the feature and the full set of implementation requirements, see the main feature documentation:


How does account recovery work?

Recovery methods

For iOS, recovery is currently supported with the following recovery methods:

NameRecovery method
Recovery code.backupRecoveryCode
Face scan.backupServerSideFace

Recovery code

A recovery code is code that is chosen and remembered by the end-user.

  • Backup-based recovery uses a secret code (recoveryCode).
  • It is associated with the recovery method .backupRecoveryCode.
  • Recovery of this type will be deleted after recovery has been performed.
Example: Recovery method with recovery code
RecoveryMethod.backupRecoveryCode(_: String)

Face scan

Face scan data is obtained from a face scan of the end-user. This data contains the face scan and optionally, audit trail images.

  • Recovery with face scan uses face scan data (faceScanData).
  • It is associated with the recovery method .backupServerSideFace.
  • This type of recovery is kept after the recovery is performed, to avoid the need for another face scan.
Important

The recovery method .backupServerSideFace requires that the authentication method AuthMethod.serverSideFace is added to the registration, before adding recovery.

Example: Recovery method with face scan
RecoveryMethod.backupServerSideFace(faceScanData: FaceScanData)

Supported backup types

  • iCloud backup.
  • Encrypted and unencrypted computer-based backup on Mac or PC.
Want to learn more?

For additional details, see Apple's support documentation on Backup methods for iPhone, iPad and iPod touch.

Prerequisites

The end-user is required to have:

  • An Apple ID.
  • iCloud Keychain enabled on their mobile device.
    Note

    iCloud Keychain is only required for iCloud backups.

Token authorisation

When you are using our SDKs for account recovery, you need to provide a token to authorise the operation.

  • Authorisation tokens are issued by our server when performing certain SDK operations.
  • In these operations, you need to set what purpose you will use the token for.
  • The token is returned back to the app as a response.
  • This token is used to authorise the next account recovery operation after a successful activation or authentication.
What does this mean?

For example, this makes it possible to implement a flow that both registers the end-user and sets up recovery for the registration, without an additional authentication.

Operations that require a token

An authorisation token is required for the following recovery-related operations:

  • addOrUpdateRecovery
  • deleteRecovery

Operations that can yield a token

The server will issue an authorisation token for the following operations:

  • finishActivation
  • finishAuthentication
  • finishAddOrUpdateRecovery
  • finishRecovery
  • finishDeleteRecovery

Token purpose

To request the authorisation token, you must provide one of the following purposes in the finish call:

  • TokenPurpose.addOrUpdateRecovery
  • TokenPurpose.deleteRecovery
Note

The default value is TokenPurpose.none.

Configure the SDK

How to get a token

The operations addOrUpdateRecovery and deleteRecovery require an EncapToken.

  1. To request a token, you must set the tokenPurpose in one of the supported finish calls.
    • If adding or updating recovery, set TokenPurpose.addOrUpdateRecovery.
    • If deleting recovery, set TokenPurpose.deleteRecovery.
    Example: Request a token during activation
    EncapController.shared.startActivation(withCode: activationCode) { startResult in
    switch startResult {
    case .success(let activationResponse):

    // Setting tokenPurpose = .addOrUpdateRecovery
    EncapController.shared.finishActivation(withAuthMethod: .faceID, tokenPurpose: .addOrUpdateRecovery) { finishResult in
    ...
    }

    case .failure(let error):
    // Error
    }
    }
  2. The token is returned with the usual operation response. To learn how to access it, see example below:
    Example: Access a token
    EncapController.shared.finishActivation(withAuthMethod: .faceID, tokenPurpose: .addOrUpdateRecovery) { finishResult in
    switch finishResult {
    case .success(let finishActivationResponse):
    // Token will be available by accessing finishActivationResponse.encapToken
    case .failure(let error):
    // Error
    }
    })

Recovery code

The following describes how to add, perform and delete recovery using a recovery code.

Add account recovery

To add account recovery and connect it to the end-user's registration, you can perform the addOrUpdateRecovery operation.

This operation requires a valid EncapToken and EncapRecoveryParameter for the type of recovery method that should be activated.

Example: How to add account recovery with RecoveryMethod.backupRecoveryCode
EncapController.shared.startAddOrUpdateRecovery(withToken: encapToken) { startResult in
switch startResult {
case .success(let successResult):

EncapController.shared.finishAddOrUpdateRecovery(withRecoveryMethod: .backupRecoveryCode("123456")) { finishResult in
switch finishResult {
case .success(let finishAddOrUpdateRecoveryResult):
// Success
case .failure(let error):
// Error
}
}

case .failure(let error):
// Error
}
}

Perform an account recovery

To recover an end-user's registration, you can perform the startRecovery and finishRecovery operations.

This works similarly in concept to the activation process, where you must select and enable a new authentication method.

  • You can only enable one authentication method for a single recovery.
  • To add more authentication methods, you can perform the addOrUpdate operation.
Example: Perform an account recovery with RecoveryMethod.backupRecoveryCode
EncapController.shared.startRecovery { startResult in
switch startResult {
case .success(let startRecoveryResult):

EncapController.shared.finishRecovery(withRecoveryMethod: .backupRecoveryCode("123456"), authMethodToActivate: .faceID) { finishResult in

switch finishResult {
case .success(let finishRecoveryResult):
// Success
case .failure(let error):
// Error
}
}

case .failure(let error):
// Error
}
}
What is the recovery code?

The recoveryCode is a secret code that is provided by the end-user, and is only known by them.

  • The end-user chooses the recovery code, which is a parameter to the finishAddOrUpdateRecovery() operation.
  • The end-user must then provide the same recovery code as a parameter to the finishRecovery() operation.
  • The end-user's choice of authentication method to activate is also a parameter to the finishRecovery() operation.

Delete a recovery

To remove an active recovery, you can perform the deleteRecovery operation.

Example: Delete a recovery with RecoveryMethod.backupRecoveryCode
EncapController.shared.startDeleteRecovery(withToken: encapToken) { startResult in
switch startResult {
case .success(_):

EncapController.shared.finishDeleteRecovery(withRecoveryMethod: .backupRecoveryCode("")) { finishResult in

switch finishResult {
case .success(let finishDeleteRecovery):
// Success
case .failure(let error):
// Error
}
}

case .failure(let error):
// Error
}
}

Face scan

The following describes how to add, perform and delete recovery using face scan.

Add account recovery

To add account recovery and connect it to the end-user's registration, you can perform the addOrUpdateRecovery operation.

This operation requires a valid EncapToken and EncapRecoveryParameter for the type of recovery method that should be activated.

Example: How to add account recovery with RecoveryMethod.backupServerSideFace
EncapController.shared.startAddOrUpdateRecovery(withToken: encapToken) { startResult in
switch startResult {
case .success(let successResult):

EncapController.shared.finishAddOrUpdateRecovery(withRecoveryMethod: .backupServerSideFace(faceScanData: nil)) { finishResult in
switch finishResult {
case .success(let finishAddOrUpdateRecoveryResult):
// Success
case .failure(let error):
// Error
}
}

case .failure(let error):
// Error
}
}
Note
  • The RecoveryMethod.backupServerSideFace takes a faceScanData containing the face scan data of the end-user.
  • No face scan data is needed when adding recovery using the RecoveryMethod.backupServerSideFace, as the existing face scan from addOrUpdate is used.
  • The end-user needs to perform a new face scan when they perform a recovery later on.

Perform an account recovery

To recover an end-user's registration, you can perform the startRecovery and finishRecovery operations.

This works similarly in concept to the activation process, where you must select and enable a new authentication method.

  • You can only enable one authentication method for a single recovery.
  • To add more authentication methods, you can perform the addOrUpdate operation.
Example: Perform an account recovery with RecoveryMethod.backupServerSideFace
EncapController.shared.startRecovery { startResult in
switch startResult {
case .success(let startRecoveryResult):

EncapController.shared.finishRecovery(withRecoveryMethod: .backupServerSideFace(faceScanData: faceScanData), authMethodToActivate: .faceID) { finishResult in

switch finishResult {
case .success(let finishRecoveryResult):
// Success
case .failure(let error):
// Error
}
}

case .failure(let error):
// Error
}
}
What is the face scan data?
  • The <FACE_SCAN_DATA> contains a face scan of the end-user, optionally with audit trail images.
  • The end-user's choice of authentication method to activate is a parameter to the finishRecovery() operation.

Delete a recovery

To remove an active recovery, you can perform the deleteRecovery operation.

Example: Delete a recovery with RecoveryMethod.backupServerSideFace
EncapController.shared.startDeleteRecovery(withToken: encapToken) { startResult in
switch startResult {
case .success(_):

EncapController.shared.finishDeleteRecovery(withRecoveryMethod: .backupServerSideFace(faceScanData: FaceScanData)) { finishResult in

switch finishResult {
case .success(let finishDeleteRecovery):
// Success
case .failure(let error):
// Error
}
}

case .failure(let error):
// Error
}
}

Additional operations

These additional operations can help you to create app logic in scenarios where a backup or restore has occurred, so that you can show recovery instead of a normal registration.

Check if account recovery is added

To check whether account recovery is added on a device, you can use the following method:

Example: Check if recovery is activated
isRecoveryActivated

Check if device has been restored from backup

To check whether the end-user's device has been restored from backup and your app is ready to perform account recovery, you can use the following app flow:

  1. Check that isActivatedLocally is returning false.
  2. Check that isRecoveryActivated is returning true before performing an account recovery.

Identify activated recovery method

To identify what the activated recovery method is, you can use activatedRecoveryMethods.