refresh method

Future<Credentials> refresh({
  1. String? identifier,
  2. String? secret,
  3. Iterable<String>? newScopes,
  4. bool basicAuth = true,
  5. Client? httpClient,
})

Returns a new set of refreshed credentials.

See Client.identifier and Client.secret for explanations of those parameters.

You may request different scopes than the default by passing in newScopes. These must be a subset of scopes.

This throws an ArgumentError if secret is passed without identifier, a StateError if these credentials can't be refreshed, an AuthorizationException if refreshing the credentials fails, or a FormatException if the authorization server returns invalid responses.

Implementation

Future<Credentials> refresh(
    {String? identifier,
    String? secret,
    Iterable<String>? newScopes,
    bool basicAuth = true,
    http.Client? httpClient}) async {
  var scopes = this.scopes;
  if (newScopes != null) scopes = newScopes.toList();
  scopes ??= [];
  httpClient ??= http.Client();

  if (identifier == null && secret != null) {
    throw ArgumentError('secret may not be passed without identifier.');
  }

  var startTime = DateTime.now();
  var tokenEndpoint = this.tokenEndpoint;
  if (refreshToken == null) {
    throw StateError("Can't refresh credentials without a refresh "
        'token.');
  } else if (tokenEndpoint == null) {
    throw StateError("Can't refresh credentials without a token "
        'endpoint.');
  }

  var headers = <String, String>{};

  var body = {'grant_type': 'refresh_token', 'refresh_token': refreshToken};
  if (scopes.isNotEmpty) body['scope'] = scopes.join(_delimiter);

  if (basicAuth && secret != null) {
    headers['Authorization'] = basicAuthHeader(identifier!, secret);
  } else {
    if (identifier != null) body['client_id'] = identifier;
    if (secret != null) body['client_secret'] = secret;
  }

  var response =
      await httpClient.post(tokenEndpoint, headers: headers, body: body);
  var credentials = handleAccessTokenResponse(
      response, tokenEndpoint, startTime, scopes, _delimiter,
      getParameters: _getParameters);

  // The authorization server may issue a new refresh token. If it doesn't,
  // we should re-use the one we already have.
  if (credentials.refreshToken != null) return credentials;
  return Credentials(credentials.accessToken,
      refreshToken: refreshToken,
      idToken: credentials.idToken,
      tokenEndpoint: credentials.tokenEndpoint,
      scopes: credentials.scopes,
      expiration: credentials.expiration);
}