authenticateWithEmail method

Future<Response?> authenticateWithEmail(
  1. Request request
)

Signs in an existing user identified by an email address.

Authentication consists of the following three steps:

  1. Ask the relying party server for a challenge.
  2. Ask the _authenticator to solve the challenge.
  3. Send the solution of the challenge back to the relying party server. For a successful solution the relying party server will respond with Response.

The contents of Response depend on the relying party server (the _backend), but usually it contains some user data (name, email) and some kind of token (e.g. a JWT token).

returns null if the user did cancel the authentication.

Implementation

Future<Response?> authenticateWithEmail(Request request) async {
  try {
    final initResponse = await _backend.initAuthenticate(request);
    final authenticatorResponse = await _authenticator.authenticate(
      initResponse.rpId,
      initResponse.challenge,
      initResponse.timeout,
      initResponse.userVerification,
      initResponse.allowCredentials
          ?.map(
            (e) => AllowCredentialType(
              id: e.id,
              type: e.type,
              transports: e.transports,
            ),
          )
          .toList(),
    );

    final completeRequest = AuthenticationCompleteRequest(
      id: authenticatorResponse.id,
      rawId: authenticatorResponse.rawId,
      clientDataJSON: authenticatorResponse.clientDataJSON,
      authenticatorData: authenticatorResponse.authenticatorData,
      signature: authenticatorResponse.signature,
    );
    final completeResponse =
        await _backend.completeAuthenticate(completeRequest);

    return completeResponse;
  } on NoPasskeyForDeviceException catch (e) {
    // no passkey has been created for this device
    // TODO: send a email challenge instead
    debugPrint('No passkey has been created for this device. The user must login with another method.');
    rethrow;
  } on PlatformException catch (e) {
    switch (e.code) {
      case 'cancelled':
        return null;
      case 'domainNotAssociated':
        throw DomainNotAssociatedException();
      default:
        rethrow;
    }
  }
}