getDeviceResponse method

Future<CognitoUserSession?> getDeviceResponse()

This is used to get a session using device authentication. It is called at the end of user authentication

Implementation

Future<CognitoUserSession?> getDeviceResponse() async {
  final authenticationHelper = AuthenticationHelper(_deviceGroupKey);
  final dateHelper = DateHelper();

  final authParameters = {
    'USERNAME': username,
    'DEVICE_KEY': _deviceKey,
  };
  final aValue = authenticationHelper.getLargeAValue()!;
  authParameters['SRP_A'] = aValue.toRadixString(16);
  if (_clientSecretHash != null) {
    authParameters['SECRET_HASH'] = _clientSecretHash;
  }

  final params = {
    'ChallengeName': 'DEVICE_SRP_AUTH',
    'ClientId': pool.getClientId(),
    'ChallengeResponses': authParameters,
  };

  if (getUserContextData() != null) {
    params['UserContextData'] = getUserContextData();
  }

  final data = await client!.request('RespondToAuthChallenge',
      await _analyticsMetadataParamsDecorator.call(params));
  final challengeParameters = data['ChallengeParameters'];
  final serverBValue = BigInt.parse(challengeParameters['SRP_B'], radix: 16);
  final saltString =
      authenticationHelper.toUnsignedHex(challengeParameters['SALT']);
  final salt = BigInt.parse(saltString, radix: 16);

  final hkdf = authenticationHelper.getPasswordAuthenticationKey(
      _deviceKey, _randomPassword, serverBValue, salt);

  final dateNow = dateHelper.getNowString();

  final signature = Hmac(sha256, hkdf);
  final signatureData = <int>[];
  signatureData
    ..addAll(utf8.encode(_deviceGroupKey!))
    ..addAll(utf8.encode(_deviceKey!))
    ..addAll(base64.decode(challengeParameters['SECRET_BLOCK']))
    ..addAll(utf8.encode(dateNow));
  final dig = signature.convert(signatureData);
  final signatureString = base64.encode(dig.bytes);

  final challengeResponses = {
    'USERNAME': username,
    'PASSWORD_CLAIM_SECRET_BLOCK': challengeParameters['SECRET_BLOCK'],
    'TIMESTAMP': dateNow,
    'PASSWORD_CLAIM_SIGNATURE': signatureString,
    'DEVICE_KEY': _deviceKey,
  };

  if (_clientSecretHash != null) {
    challengeResponses['SECRET_HASH'] = _clientSecretHash;
  }

  final paramsResp = {
    'ChallengeName': 'DEVICE_PASSWORD_VERIFIER',
    'ClientId': pool.getClientId(),
    'ChallengeResponses': challengeResponses,
    'Session': data['Session'],
  };

  if (getUserContextData() != null) {
    paramsResp['UserContextData'] = getUserContextData();
  }

  final dataAuthenticate = await client!.request('RespondToAuthChallenge',
      await _analyticsMetadataParamsDecorator.call(paramsResp));

  _signInUserSession =
      getCognitoUserSession(dataAuthenticate['AuthenticationResult']);
  await cacheTokens();
  return _signInUserSession;
}