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 Android, recovery is currently supported with the following recovery methods:

NameRecovery method
Recovery codeCLOUD_BACKUP_RECOVERY_CODE
Face scanCLOUD_BACKUP_SERVER_SIDE_FACE

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 CLOUD_BACKUP_RECOVERY_CODE.
  • This type of recovery is deleted after the recovery is performed.
Example: Recovery method with recovery code
RecoveryCodeRecoveryParameter(recoveryCode)
Note

The parameter RecoveryCodeRecoveryParameter replaces the former parameter EncapRecoveryCodeParameter(CLOUD_BACKUP), providing an easier constructor.

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 CLOUD_BACKUP_SERVER_SIDE_FACE.
  • This type of recovery is kept after the recovery is performed, to avoid the need for another face scan.
Example: Recovery method with face scan
ServerSideFaceRecoveryParameter(faceScanData)
Important

The parameter ServerSideFaceRecoveryParameter requires that the end-user has set up face scan for the registration, before adding recovery.

To do this, you must use addOrUpdate(AuthenticationParameter, DeviceServerSideFaceActivationParameter).

Supported backup types

Recovery for Android is fully compliant with the Android Auto Backup feature.

Prerequisites

Account recovery generates secrets that are tied to a specific device. The secrets are stored inside the app files, which the end-user needs to back up.

To enable this, you need to ensure that:

  1. Your application declares allowBackup in its manifest files.
    android:allowBackup="true"
  2. The file 2c5f882341aa8372a6166769bd469903.xml is not excluded from the backup in the application manifest section.
    Note

    You can skip this step if the manifest does not include the attributes fullBackupContent or dataExtractionRules. For more information, see Back up and restore attributes in our Encap SDK developer documentation.

  3. The end-user enables backup in their mobile device's settings. To do this, they can either:
    • Set up a Google account and enable auto backup to Google Drive.
    • Set up a cloud backup specific to the their mobile device's manufacturer, such as Samsung Cloud.
    • Transfer data from another mobile device.
    • Perform a manual backup to the external storage.
Using Google backup

Google's auto backup is the most convenient way of backing up and restoring data. However, it runs on its own and in some cases files can be backed up with a delay reaching up to 24 hours. This makes recovery on another device impossible until that time.

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.ADD_OR_UPDATE_RECOVERY
  • TokenPurpose.DELETE_RECOVERY
Note

The default value is TokenPurpose.UNSET_PURPOSE.

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 token purpose together with the activation or authentication parameter, using the setTokenPurpose method.
    • If adding or updating recovery, you should use TokenPurpose.ADD_OR_UPDATE_RECOVERY.
    • If deleting recovery, you should use TokenPurpose.DELETE_RECOVERY.
Example: How to request a token during activation
val activationParameter = DevicePinActivationParameter(userPinCode).apply {
tokenPurpose = TokenPurpose.ADD_OR_UPDATE_RECOVERY
}
  1. The token is returned with the usual operation response. To learn how to access it, see example below:
Example: How to access a token
override fun onSuccess(result: FinishActivationResult) {
val token = result.encapToken
}

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.

  1. Call startAddOrUpdateRecovery and pass in the EncapToken you acquired from the previous step.
  2. If this is successful, then you can call finishAddOrUpdateRecovery with an RecoveryCodeRecoveryParameter.
Note
  • The RecoveryCodeRecoveryParameter takes a recoveryCode that the end-user creates.
  • The end-user needs to use this code when they perform a recovery later on.
Example: Add account recovery, with recovery code
controller.startAddOrUpdateRecovery(
encapToken = <ENCAP_TOKEN>,
appCallback = object : AsyncCallback<StartAddOrUpdateRecoveryResult> {
override fun onFailure(errorCodeException: ErrorCodeException) { ... }
override fun onSuccess(result: StartAddOrUpdateRecoveryResult) { ... }
}
)

controller.finishAddOrUpdateRecovery(
recoveryParameter = RecoveryCodeRecoveryParameter(<RECOVERY_CODE>),
appCallback = object : AsyncCallback<FinishAddOrUpdateRecoveryResult> {
override fun onFailure(errorCodeException: ErrorCodeException) { ... }
override fun onSuccess(result: FinishAddOrUpdateRecoveryResult) { ... }
}
)

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: How to perform an account recovery with recovery code, activating PIN
controller.startRecovery(
object : AsyncCallback<StartRecoveryResult> {
override fun onFailure(errorCodeException: ErrorCodeException) { ... }
override fun onSuccess(result: StartRecoveryResult) { ... }
}
)

controller.finishRecovery(
recoveryParameter = RecoveryCodeRecoveryParameter(<RECOVERY_CODE>),
activationParameter = DevicePinActivationParameter(<PIN_CODE>),
appCallback = object : AsyncStateChangedCallback<FinishRecoveryResult> {
override fun onFailure(errorCodeException: ErrorCodeException) { ... }
override fun onSuccess(result: FinishRecoveryResult) { ... }
override fun onStateChanged(state: EncapController.State) { ... }
}
)
What is the recovery code?

The <RECOVERY_CODE> 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 startDeleteRecovery and finishDeleteRecovery operations.

The <ENCAP_TOKEN> has to be requested with an authentication, and must have the token purpose set to DELETE_RECOVERY.

Example: How to delete a recovery, of type recovery code
controller.startDeleteRecovery(
encapToken = <ENCAP_TOKEN>,
appCallback = object : AsyncCallback<StartDeleteRecoveryResult> {
override fun onFailure(errorCodeException: ErrorCodeException) { ... }
override fun onSuccess(result: StartDeleteRecoveryResult) { ... }
}
)

controller.finishDeleteRecovery(
recoveryParameter = RecoveryCodeRecoveryParameter(),
appCallback = object : AsyncCallback<FinishDeleteRecoveryResult> {
override fun onFailure(errorCodeException: ErrorCodeException) { ... }
override fun onSuccess(result: FinishDeleteRecoveryResult) { ... }
}
)

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.

  1. If the registration does not have server-side face, then you add it. To do this:
    1. Call startAddOrUpdate with StartAddOrUpdateParameter(authMethod = DEVICE_SERVER_SIDE_FACE).
    2. Call finishAddOrUpdate with a valid AuthenticationParameter (typically for PIN or biometrics), and a DeviceServerSideFaceActivationParameter containing the face scan data of the end-user.
    3. Request a token with TokenPurpose.ADD_OR_UPDATE_RECOVERY.
  2. Call startAddOrUpdateRecovery and pass in the EncapToken that you acquired from the previous step.
  3. If this is successful, then you can call finishAddOrUpdateRecovery with an empty ServerSideFaceRecoveryParameter.
Note
  • The DeviceServerSideFaceActivationParameter takes a faceScanData containing the face scan data of the end-user.
  • No face scan data is needed when adding recovery using the ServerSideFaceRecoveryParameter, 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.
Example: Add account recovery, with face scan
controller.startAddOrUpdate(
startParameter = StartAddOrUpdateParameter(authMethod = DEVICE_SERVER_SIDE_FACE),
appCallback = object : AsyncCallback<StartAddOrUpdateResult> {
override fun onFailure(errorCodeException: ErrorCodeException) { ... }
override fun onSuccess(result: StartAddOrUpdateResult) { ... }
}
)

controller.finishAddOrUpdate(
authParameter = DevicePinAuthParameter(<PIN_CODE>),
activationParameter = DeviceServerSideFaceActivationParameter(FaceScanData(<FACE_SCAN_DATA>)),
appCallback = object : AsyncCallback<FinishAuthenticationResult> {
override fun onFailure(errorCodeException: ErrorCodeException) { ... }
override fun onSuccess(result: FinishAuthenticationResult) { ... }
}
)

controller.startAddOrUpdateRecovery(
encapToken = <ENCAP_TOKEN>,
appCallback = object : AsyncCallback<StartAddOrUpdateRecoveryResult> {
override fun onFailure(errorCodeException: ErrorCodeException) { ... }
override fun onSuccess(result: StartAddOrUpdateRecoveryResult) { ... }
}
)

controller.finishAddOrUpdateRecovery(
recoveryParameter = ServerSideFaceRecoveryParameter(),
appCallback = object : AsyncCallback<FinishAddOrUpdateRecoveryResult> {
override fun onFailure(errorCodeException: ErrorCodeException) { ... }
override fun onSuccess(result: FinishAddOrUpdateRecoveryResult) { ... }
}
)

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: How to perform an account recovery with face scan, activating PIN
controller.startRecovery(
appCallback = object : AsyncCallback<StartRecoveryResult> {
override fun onFailure(errorCodeException: ErrorCodeException) { ... }
override fun onSuccess(result: StartRecoveryResult) { ... }
}
)

controller.finishRecovery(
recoveryParameter = ServerSideFaceRecoveryParameter(FaceScanData(<FACE_SCAN_DATA>)),
activationParameter = DevicePinActivationParameter(<PIN_CODE>),
appCallback = object : AsyncStateChangedCallback<FinishRecoveryResult> {
override fun onFailure(errorCodeException: ErrorCodeException) { ... }
override fun onSuccess(result: FinishRecoveryResult) { ... }
override fun onStateChanged(state: EncapController.State) { ... }
}
)
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 startDeleteRecovery and finishDeleteRecovery operations.

The <ENCAP_TOKEN> has to be requested with an authentication, and must have the token purpose set to DELETE_RECOVERY.

Example: How to delete a recovery, of type face scan
controller.startDeleteRecovery(
encapToken = <ENCAP_TOKEN>,
appCallback = object : AsyncCallback<StartDeleteRecoveryResult> {
override fun onFailure(errorCodeException: ErrorCodeException) { ... }
override fun onSuccess(result: StartDeleteRecoveryResult) { ... }
}
)

controller.finishDeleteRecovery(
recoveryParameter = ServerSideFaceRecoveryParameter(),
appCallback = object : AsyncCallback<FinishDeleteRecoveryResult> {
override fun onFailure(errorCodeException: ErrorCodeException) { ... }
override fun onSuccess(result: FinishDeleteRecoveryResult) { ... }
}
)

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
controller.isRecoveryActivated
Note

In order for the method to detect account recovery, backup has to be restored on the new device first.

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 isActivated() is returning false.
  2. Check that isRecoveryActivated is returning true before performing an account recovery.
Example: Check if restoration from backup has occurred
if(!controller.isActivated() && controller.isRecoveryActivated) {
// recovery has been activated and can be used to recover registration
}