authenticateForCode method Null safety

Future<AuthCode> authenticateForCode(
  1. String? username,
  2. String? password,
  3. String? clientID,
  4. {int expirationInSeconds = 600,
  5. List<AuthScope>? requestedScopes}
)

Creates a one-time use authorization code for a given client ID and user credentials.

This methods works with this instance's delegate to generate and store the authorization code if the credentials are correct. If they are not correct, it will throw the appropriate AuthRequestError.

Implementation

Future<AuthCode> authenticateForCode(
  String? username,
  String? password,
  String? clientID, {
  int expirationInSeconds = 600,
  List<AuthScope>? requestedScopes,
}) async {
  if (clientID == null) {
    throw AuthServerException(AuthRequestError.invalidClient, null);
  }

  final client = await getClient(clientID);
  if (client == null) {
    throw AuthServerException(AuthRequestError.invalidClient, null);
  }

  if (username == null || password == null) {
    throw AuthServerException(AuthRequestError.invalidRequest, client);
  }

  if (client.redirectURI == null) {
    throw AuthServerException(AuthRequestError.unauthorizedClient, client);
  }

  final authenticatable = await delegate.getResourceOwner(this, username);
  if (authenticatable == null) {
    throw AuthServerException(AuthRequestError.accessDenied, client);
  }

  final dbSalt = authenticatable.salt;
  final dbPassword = authenticatable.hashedPassword;
  if (hashPassword(password, dbSalt!) != dbPassword) {
    throw AuthServerException(AuthRequestError.accessDenied, client);
  }

  final validScopes =
      _validatedScopes(client, authenticatable, requestedScopes);
  final authCode = _generateAuthCode(
    authenticatable.id,
    client,
    expirationInSeconds,
    scopes: validScopes,
  );
  await delegate.addCode(this, authCode);
  return authCode;
}