authenticateBiometric method

Future<UserInfo> authenticateBiometric({
  1. required BiometricOptionsIOS ios,
  2. required BiometricOptionsAndroid android,
})

Implementation

Future<UserInfo> authenticateBiometric({
  required BiometricOptionsIOS ios,
  required BiometricOptionsAndroid android,
}) async {
  final kid = await _storage.getBiometricKeyID(name);
  if (kid == null) {
    throw Exception("biometric is not enabled");
  }

  final deviceInfo = await native.getDeviceInfo();
  final challengeResponse =
      await _apiClient.getChallenge("biometric_request");
  final now = DateTime.now().toUtc().millisecondsSinceEpoch / 1000;
  final payload = {
    "iat": now,
    "exp": now + 300,
    "challenge": challengeResponse.token,
    "action": "authenticate",
    "device_info": deviceInfo,
  };

  try {
    final jwt = await native.signWithBiometricPrivateKey(
      kid: kid,
      payload: payload,
      ios: ios,
      android: android,
    );
    final tokenResponse = await _apiClient.sendAuthenticateBiometricRequest(
      BiometricRequest(
        clientID: clientID,
        jwt: jwt,
        scope: _getAuthenticationScopes(
            preAuthenticatedURLEnabled: preAuthenticatedURLEnabled),
      ),
    );
    await _persistTokenResponse(
        tokenResponse, SessionStateChangeReason.authenticated);
    final userInfo = await _apiClient.getUserInfo();
    return userInfo;
  } on BiometricPrivateKeyNotFoundException {
    await disableBiometric();
    rethrow;
  } on OAuthException catch (e) {
    if (e.error == "invalid_grant" &&
        e.errorDescription == "InvalidCredentials") {
      await disableBiometric();
    }
    rethrow;
  }
}