getPasswordOrPasskey method
- AuthenticateRequestType? passkeyRequest, {
- bool? preferImmediatelyAvailableCredentials,
Shows the platform credential manager with the user's saved passwords
and, when passkeyRequest is given, their passkeys, and returns the one
the user picks.
A returned password has not been checked by anyone: sign in with it as if the user had typed it. A returned passkey assertion must be sent to the relying party server exactly like the result of authenticate.
With preferImmediatelyAvailableCredentials no sheet is shown when
nothing is saved on the device, which suits showing it unprompted. When
it is omitted, the value from passkeyRequest is used, or false when
there is no passkeyRequest. The mediation of passkeyRequest does
not apply here.
Passkeys need Android 9 (API 28) or newer. Below that only saved
passwords are offered, even when passkeyRequest is given.
Throws PasskeyAuthCancelledException when the user dismisses the sheet, CredentialNotAuthenticatedException when none of the allowed credentials could be used, NoCredentialsAvailableException when nothing is saved, and PasswordCredentialUnsupportedException on platforms other than Android.
Implementation
Future<PasswordOrPasskeyResponseType> getPasswordOrPasskey(
AuthenticateRequestType? passkeyRequest, {
bool? preferImmediatelyAvailableCredentials,
}) async {
if (debugMode && passkeyRequest != null) {
await _doctor?.check(passkeyRequest.relyingPartyId);
}
try {
await _platform.cancelCurrentAuthenticatorOperation();
if (passkeyRequest != null) {
_isValidChallenge(passkeyRequest.challenge);
if (passkeyRequest.allowCredentials != null) {
for (final credential in passkeyRequest.allowCredentials!) {
_isValidCredentialID(credential.id);
}
}
}
return await _platform.getPasswordOrPasskey(
passkeyRequest,
preferImmediatelyAvailableCredentials:
preferImmediatelyAvailableCredentials ??
passkeyRequest?.preferImmediatelyAvailableCredentials ??
false,
);
} on PlatformException catch (e, stackTrace) {
if (debugMode) {
_doctor?.recordException(e);
}
switch (e.code) {
case 'password-credential-unsupported':
throw PasswordCredentialUnsupportedException(e.message);
case 'cancelled':
throw PasskeyAuthCancelledException(e.message);
case 'android-credential-not-authenticated':
throw CredentialNotAuthenticatedException(e.message);
case 'android-no-credential':
throw NoCredentialsAvailableException();
case 'domain-not-associated':
throw DomainNotAssociatedException(e.message);
case 'android-sync-account-not-available':
throw SyncAccountNotAvailableException();
case 'android-timeout':
throw TimeoutException(e.message);
default:
if (e.code.startsWith('android-unhandled')) {
throw UnhandledAuthenticatorException(e.code, e.message, e.details);
}
Error.throwWithStackTrace(e, stackTrace);
}
}
}