startRegistration method

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

Starts the account creation process for creating a new email account.

Given a valid email address, this method will create a new account request and call sendRegistrationVerificationCode with a verification code and the account request ID. The verification code together with the account request ID should be used to verify the account request via verifyRegistrationCode.

The method will throw the following EmailAccountRequestServerException subclasses:

It is important that the caller does not leak the existence of the account request to the outside client.

If successful, this method returns the ID of the account request. This can be used in as a reference to add additional information to the account once it has been completed.

Implementation

Future<UuidValue> startRegistration(
  final Session session, {
  required String email,
  required final Transaction transaction,
}) async {
  email = email.normalizedEmail;

  if (!EmailValidator.validate(email)) {
    throw EmailAccountRequestInvalidEmailException();
  }

  final existingAccountCount = await EmailAccount.db.count(
    session,
    where: (final t) => t.email.equals(email),
    transaction: transaction,
  );
  if (existingAccountCount > 0) {
    throw EmailAccountAlreadyRegisteredException();
  }

  final verificationCode = _config.registrationVerificationCodeGenerator();

  final pendingAccountRequest = await EmailAccountRequest.db.findFirstRow(
    session,
    where: (final t) => t.email.equals(email),
    transaction: transaction,
  );
  if (pendingAccountRequest != null) {
    await EmailAccountRequest.db.deleteRow(
      session,
      pendingAccountRequest,
      transaction: transaction,
    );
  }

  final challenge = await _challengeUtil.createChallenge(
    session,
    verificationCode: verificationCode,
    transaction: transaction,
  );

  final emailAccountRequest = await EmailAccountRequest.db.insertRow(
    session,
    EmailAccountRequest(
      email: email,
      challengeId: challenge.id!,
      createdAt: clock.now(),
    ),
    transaction: transaction,
  );

  await _config.sendRegistrationVerificationCode?.call(
    session,
    email: email,
    accountRequestId: emailAccountRequest.id!,
    verificationCode: verificationCode,
    transaction: transaction,
  );

  return emailAccountRequest.id!;
}