Documentation Hub
Mobile SDK
Mobile SDK
  • Keyless SDK Documentation
  • Introduction
    • 🧩Components
    • ⚙️Integration Flows
    • 🤳Sample Apps
  • 📱Mobile SDK Guide
    • 1️⃣ Getting started
    • 2️⃣ Enrollment
    • 3️⃣ Authentication
    • 4️⃣ De-Enrollment
    • 5️⃣ Backup
    • 6️⃣ User and device management
  • 📱Mobile SDK Reference
    • UI Customization
    • Error handling
    • Liveness Settings
    • JWT signing
    • PIN authentication
    • Introduce Keyless to Users
  • 📱Mobile SDK Use Cases
    • Account recovery
    • Dynamic Linking
  • 📒Mobile SDK Changelog
    • Changelog
  • 💽Server API
    • Getting Started
    • Users
    • Devices
    • Operations
Powered by GitBook
On this page
  • User identifier
  • Device identifier
  • Keyless SDK reset
  • Lockout management

Was this helpful?

  1. Mobile SDK Guide

6️⃣ User and device management

Last updated 21 days ago

Was this helpful?

The Keyless SDK "caches" the enrolled user locally on the device.

There are some use cases where it is possible to and . The Keyless SDK will not be notified about such deletions. For this reason if you try to authenticate a user or a device that have been deleted from server API you will get an error.

Call validateUserAndDeviceActive before authenticating, to validate that both the user and the device are still active in the Keyless backend, to avoid asking the user for biometric data which will still not let them authenticate.

Keyless.validateUserAndDeviceActive(
    onCompletion = { result ->
        when (result) {
            is Keyless.KeylessResult.Success -> Log.d("KeylessSDK ", "user and device active")
            is Keyless.KeylessResult.Failure -> Log.d("KeylessSDK ", "user or device not ofund - error code ${result.error.code}")
            // error code 1131 = user is not enrolled on the device (not even locally so did not check on backend)
            // error code 534 = user not found or deactivated on backend
            // error code 535 = device not found or deactivated on backend
        }
    }
)
Keyless.validateUserDeviceActive(
            completionHandler: { error in
                if let error = error {
                    print("user or device deactivated")
                       // error code 1131 = user is not enrolled on the device (not even locally so did not check on backend)
                       // error code 534 = user not found or deactivated on backend
                       // error code 535 = device not found or deactivated on backend
                } else {
                    print("user and device active")
                }
            }
        )
try {
  await Keyless.validateUserAndDeviceActive();
  print("user and device active");
} catch (error) {
  print("user or device deactivated - error code: ${error.code}");
  // error code 1131 = user is not enrolled on the device (not even locally so did not check on backend)
  // error code 534 = user not found or deactivated on backend
  // error code 535 = device not found or deactivated on backend
}

User identifier

Retrieve the user identifier with Keyless.getUserId():

fun getUserId(): KeylessResult<String, KeylessSdkError>
func getUserId() -> Result<String, KeylessSDKError>
Future<String> getUserId() async

Device identifier

The device is identified by its public signing key. To retrieve the public signing key use Keyless.getDevicePublicSigningKey():

fun getDevicePublicSigningKey(): KeylessResult<ByteArray, KeylessSdkError>
func getDevicePublicSigningKey() -> Result<String, KeylessSDKError>
Future<String> getDevicePublicSigningKey() async

Keyless SDK reset

Resetting the Keyless SDK to a clean state deletes local data from the device, but does not de-enoll the user from the Keyless backend or deactivate the device from the Keyless backend:

fun reset(
  onCompletion: (KeylessResult<Unit, KeylessSdkError>) -> Unit
)
func reset() -> KeylessSDKError?
Future<void> reset() async

Lockout management

The getRateLimitInfo API checks whether the user is currently rate-limited and, if so, for how many seconds. This API is typically used to provide feedback to users after multiple failed authentication attempts.

Keyless.getRateLimitInfo { result ->
    when (result) {
        is Keyless.KeylessResult.Success -> {
            val rateLimitInfo = result.value
            println("User is rate limited: ${rateLimitInfo.isRateLimited} with remaining seconds: ${rateLimitInfo.remainingSeconds}")
        }
        is Keyless.KeylessResult.Failure -> {
            println("Error: ${result.error.message}")
        }
    }
}
Keyless.getRateLimitInfo(completion: { result in
        switch result {
        case .success(let success):
            print("User is rate limited: \(success.isRateLimited) with remaining seconds: \(success.remainingSeconds)")
        case .failure(let error):
            print("Error: \(error.message)")
        }
})
try {
    final rateLimitInfo = await Keyless.instance.getRateLimitInfo();
    print("User is rate limited: ${rateLimitInfo.isRateLimited} with remaining seconds: ${rateLimitInfo.remainingSeconds}");
} catch (error) {
    print("Error: $error");
}
📱
delete the user from server API
delete the device from server API