sendMFACode method
This is used by the user once he has an MFA code
Implementation
Future<CognitoUserSession?> sendMFACode(String confirmationCode,
[String mfaType = 'SMS_MFA']) async {
final challengeResponses = {
'USERNAME': username,
'SMS_MFA_CODE': confirmationCode,
};
if (mfaType == 'SOFTWARE_TOKEN_MFA') {
challengeResponses['SOFTWARE_TOKEN_MFA_CODE'] = confirmationCode;
}
if (mfaType == 'EMAIL_OTP') {
challengeResponses['EMAIL_OTP_CODE'] = confirmationCode;
}
if (_clientSecretHash != null) {
challengeResponses['SECRET_HASH'] = _clientSecretHash;
}
await getCachedDeviceKeyAndPassword();
if (_deviceKey != null) {
challengeResponses['DEVICE_KEY'] = _deviceKey;
}
final paramsReq = {
'ChallengeName': mfaType,
'ChallengeResponses': challengeResponses,
'ClientId': pool.getClientId(),
'Session': _session,
};
if (getUserContextData() != null) {
paramsReq['UserContextData'] = getUserContextData();
}
dynamic dataAuthenticate;
try {
dataAuthenticate = await client!.request('RespondToAuthChallenge',
await _analyticsMetadataParamsDecorator.call(paramsReq));
} on CognitoClientException catch (e) {
// When trying to use MFA with a non verified phone_number this
// missleading error will be received because Cognito expects in this case
// the GUID style user name instead of the normal user name used in every
// other request.
if (e.code == "UserNotFoundException") {
throw CognitoUserPhoneNumberVerificationNecessaryException();
} else {
rethrow;
}
}
final String? challengeName = dataAuthenticate['ChallengeName'];
if (challengeName == 'DEVICE_SRP_AUTH') {
return getDeviceResponse();
}
_signInUserSession =
getCognitoUserSession(dataAuthenticate['AuthenticationResult']);
await cacheTokens();
if (dataAuthenticate['AuthenticationResult']['NewDeviceMetadata'] == null) {
return _signInUserSession;
}
final authenticationHelper =
AuthenticationHelper(pool.getUserPoolId().split('_')[1]);
authenticationHelper.generateHashDevice(
dataAuthenticate['AuthenticationResult']['NewDeviceMetadata']
['DeviceGroupKey'],
dataAuthenticate['AuthenticationResult']['NewDeviceMetadata']
['DeviceKey']);
final deviceSecretVerifierConfig = {
'Salt': base64.encode(hex.decode(authenticationHelper.getSaltDevices()!)),
'PasswordVerifier':
base64.encode(hex.decode(authenticationHelper.getVerifierDevices()!)),
};
verifierDevices = deviceSecretVerifierConfig['PasswordVerifier'];
_deviceGroupKey = dataAuthenticate['AuthenticationResult']
['NewDeviceMetadata']['DeviceGroupKey'];
_randomPassword = authenticationHelper.getRandomPassword();
final confirmDeviceParamsReq = {
'DeviceKey': dataAuthenticate['AuthenticationResult']['NewDeviceMetadata']
['DeviceKey'],
'AccessToken': _signInUserSession!.getAccessToken().getJwtToken(),
'DeviceSecretVerifierConfig': deviceSecretVerifierConfig,
'DeviceName': deviceName,
};
final dataConfirm =
await client!.request('ConfirmDevice', confirmDeviceParamsReq);
_deviceKey = dataAuthenticate['AuthenticationResult']['NewDeviceMetadata']
['DeviceKey'];
await cacheDeviceKeyAndPassword();
if (dataConfirm['UserConfirmationNecessary'] == true) {
throw CognitoUserDeviceConfirmationNecessaryException(
signInUserSession: _signInUserSession);
}
return _signInUserSession;
}