startRegistration method

Future<UuidValue> startRegistration(
  1. Session session, {
  2. required String email,
  3. Transaction? transaction,
})

Starts the registration for a new user account with an email-based login associated to it.

Upon successful completion of this method, an email will have been sent to email with a verification link, which the user must open to complete the registration.

Always returns a account request ID, which can be used to complete the registration. If the email is already registered, the returned ID will not be valid.

Implementation

Future<UuidValue> startRegistration(
  final Session session, {
  required final String email,
  final Transaction? transaction,
}) async {
  return DatabaseUtil.runInTransactionOrSavepoint(
    session.db,
    transaction,
    (final transaction) => EmailIdpUtils.withReplacedServerEmailException(
      () async {
        try {
          return await utils.accountCreation.startRegistration(
            session,
            email: email,
            transaction: transaction,
          );
        } on EmailAccountRequestServerException catch (e) {
          // The details of these operation are intentionally not given to the caller, in order to not leak the existence of accounts.
          // Clients should always show something like "check your email to proceed with the account creation".
          // One might want to send a "password reset" in case of a "email already exists" exception, to help the user log in.
          switch (e) {
            case EmailAccountAlreadyRegisteredException():
              session.log(
                'Failed to start account registration for $email, reason: email already registered',
                level: LogLevel.debug,
              );
              break;
            case EmailAccountRequestAlreadyExistsException():
              session.log(
                'Failed to start account registration for $email, reason: email account request already exists',
                level: LogLevel.debug,
              );
              break;
            default:
              rethrow;
          }

          // NOTE: It is necessary to keep the version of the uuid in sync with the
          // one used by the [EmailAccountRequest] model to prevent attackers from
          // using the difference on the version bit of the uuid to determine whether
          // an email is registered or not.
          return const Uuid().v7obj();
        }
      },
    ),
  );
}