refresh method Null safety
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 client = await getClient(clientID);
if (client == null) {
throw AuthServerException(AuthRequestError.invalidClient, null);
}
if (refreshToken == null) {
throw AuthServerException(AuthRequestError.invalidRequest, client);
}
final 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 (final 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 (final 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;
}