exchange method

Future<AuthToken> exchange(
  1. String? authCodeString,
  2. String clientID,
  3. String? clientSecret, {
  4. int expirationInSeconds = 3600,
})

Exchanges a valid authorization code for an AuthToken.

If the authorization code has not expired, has not been used, matches the client ID, and the client secret is correct, it will return a valid AuthToken. Otherwise, it will throw an appropriate AuthRequestError.

Implementation

Future<AuthToken> exchange(
  String? authCodeString,
  String clientID,
  String? clientSecret, {
  int expirationInSeconds = 3600,
}) async {
  if (clientID.isEmpty) {
    throw AuthServerException(AuthRequestError.invalidClient, null);
  }

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

  if (authCodeString == null) {
    throw AuthServerException(AuthRequestError.invalidRequest, null);
  }

  if (clientSecret == null) {
    throw AuthServerException(AuthRequestError.invalidClient, client);
  }

  if (client.hashedSecret != hashPassword(clientSecret, client.salt!)) {
    throw AuthServerException(AuthRequestError.invalidClient, client);
  }

  final authCode = await delegate.getCode(this, authCodeString);
  if (authCode == null) {
    throw AuthServerException(AuthRequestError.invalidGrant, client);
  }

  // check if valid still
  if (authCode.isExpired) {
    await delegate.removeCode(this, authCode.code);
    throw AuthServerException(AuthRequestError.invalidGrant, client);
  }

  // check that client ids match
  if (authCode.clientID != client.id) {
    throw AuthServerException(AuthRequestError.invalidGrant, client);
  }

  // check to see if has already been used
  if (authCode.hasBeenExchanged!) {
    await delegate.removeToken(this, authCode);

    throw AuthServerException(AuthRequestError.invalidGrant, client);
  }
  final token = _generateToken(
    authCode.resourceOwnerIdentifier,
    client.id,
    expirationInSeconds,
    scopes: authCode.requestedScopes,
  );
  await delegate.addToken(this, token, issuedFrom: authCode);

  return token;
}