refresh method
Refreshes a valid AuthToken
instance.
This method will refresh a AuthToken
given the AuthToken
's refreshToken
for a given client ID.
This method coordinates with this instance's delegate to update the old token with a new access token and issue/expiration dates if successful.
If not successful, it will throw an AuthRequestError.
Implementation
Future<AuthToken> refresh(
String? refreshToken, String? clientID, String? clientSecret,
{List<AuthScope>? requestedScopes}) async {
if (clientID == null) {
throw AuthServerException(AuthRequestError.invalidClient, null);
}
final AuthClient? client = await getClient(clientID);
if (client == null) {
throw AuthServerException(AuthRequestError.invalidClient, null);
}
if (refreshToken == null) {
throw AuthServerException(AuthRequestError.invalidRequest, client);
}
final AuthToken? t =
await delegate.getToken(this, byRefreshToken: refreshToken);
if (t == null || t.clientID != clientID) {
throw AuthServerException(AuthRequestError.invalidGrant, client);
}
if (clientSecret == null) {
throw AuthServerException(AuthRequestError.invalidClient, client);
}
if (client.hashedSecret != hashPassword(clientSecret, client.salt!)) {
throw AuthServerException(AuthRequestError.invalidClient, client);
}
var updatedScopes = t.scopes;
if ((requestedScopes?.length ?? 0) != 0) {
// If we do specify scope
for (var incomingScope in requestedScopes!) {
final hasExistingScopeOrSuperset = t.scopes!.any(
(existingScope) => incomingScope.isSubsetOrEqualTo(existingScope));
if (!hasExistingScopeOrSuperset) {
throw AuthServerException(AuthRequestError.invalidScope, client);
}
if (!client.allowsScope(incomingScope)) {
throw AuthServerException(AuthRequestError.invalidScope, client);
}
}
updatedScopes = requestedScopes;
} else if (client.supportsScopes) {
// Ensure we still have access to same scopes if we didn't specify any
for (var incomingScope in t.scopes!) {
if (!client.allowsScope(incomingScope)) {
throw AuthServerException(AuthRequestError.invalidScope, client);
}
}
}
final diff = t.expirationDate!.difference(t.issueDate!);
final now = DateTime.now().toUtc();
final newToken = AuthToken()
..accessToken = randomStringOfLength(32)
..issueDate = now
..expirationDate = now.add(Duration(seconds: diff.inSeconds)).toUtc()
..refreshToken = t.refreshToken
..type = t.type
..scopes = updatedScopes
..resourceOwnerIdentifier = t.resourceOwnerIdentifier
..clientID = t.clientID;
await delegate.updateToken(this, t.accessToken!, newToken.accessToken!,
newToken.issueDate!, newToken.expirationDate!);
return newToken;
}