authenticate static method

Future<AuthenticationResponse> authenticate(
  1. Session session,
  2. String email,
  3. String password
)

Authenticates a user with email and password. Returns an AuthenticationResponse with the users information.

Implementation

static Future<AuthenticationResponse> authenticate(
  Session session,
  String email,
  String password,
) async {
  email = email.toLowerCase();
  password = password.trim();

  session.log('authenticate $email / XXXXXXXX', level: LogLevel.debug);

  // Fetch password entry
  var entry = await EmailAuth.db.findFirstRow(session, where: (t) {
    return t.email.equals(email);
  });

  if (entry == null) {
    return AuthenticationResponse(
      success: false,
      failReason: AuthenticationFailReason.invalidCredentials,
    );
  }

  if (await _hasTooManyFailedSignIns(session, email)) {
    return AuthenticationResponse(
      success: false,
      failReason: AuthenticationFailReason.tooManyFailedAttempts,
    );
  }

  session.log(' - found entry ', level: LogLevel.debug);

  // Check that password is correct
  if (!await Emails.validatePasswordHash(
    password,
    email,
    entry.hash,
    onValidationFailure: ({
      required String passwordHash,
      required String storedHash,
    }) =>
        session.log(
      ' - $passwordHash saved: $storedHash',
      level: LogLevel.debug,
    ),
    onError: (e) {
      session.log(
        ' - error when validating password hash: $e',
        level: LogLevel.error,
      );
    },
  )) {
    await _logFailedSignIn(session, email);
    return AuthenticationResponse(
      success: false,
      failReason: AuthenticationFailReason.invalidCredentials,
    );
  }

  session.log(' - password is correct, userId: ${entry.userId})',
      level: LogLevel.debug);

  if (AuthConfig.current.passwordHashGenerator.hashCode ==
          defaultGeneratePasswordHash.hashCode &&
      AuthConfig.current.passwordHashValidator.hashCode ==
          defaultValidatePasswordHash.hashCode) {
    var migratedAuth = await Emails.tryMigrateAuthEntry(
      password: password,
      entry: entry,
    );
    if (migratedAuth != null) {
      session.log(' - migrating authentication entry', level: LogLevel.debug);
      try {
        await EmailAuth.db.updateRow(session, migratedAuth);
      } catch (e) {
        session.log(
          ' - failed to update migrated auth: $e',
          level: LogLevel.error,
        );
      }
    }
  }

  var userInfo = await Users.findUserByUserId(session, entry.userId);
  if (userInfo == null) {
    return AuthenticationResponse(
      success: false,
      failReason: AuthenticationFailReason.invalidCredentials,
    );
  } else if (userInfo.blocked) {
    return AuthenticationResponse(
      success: false,
      failReason: AuthenticationFailReason.blocked,
    );
  }

  session.log(' - user found', level: LogLevel.debug);

  // Sign in user and return user info
  var auth = await UserAuthentication.signInUser(
    session,
    entry.userId,
    'email',
    scopes: userInfo.scopes,
  );

  session.log(' - user signed in', level: LogLevel.debug);

  return AuthenticationResponse(
    success: true,
    userInfo: userInfo,
    key: auth.key,
    keyId: auth.id,
  );
}