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 storage to update the old token with a new access token and issue/expiration dates if successful.
If not successful, it will throw an AuthRequestError.
Source
Future<AuthToken> refresh(
String refreshToken, String clientID, String clientSecret, {List<AuthScope> requestedScopes}) async {
if (clientID == null) {
throw new AuthServerException(AuthRequestError.invalidClient, null);
}
AuthClient client = await clientForID(clientID);
if (client == null) {
throw new AuthServerException(AuthRequestError.invalidClient, null);
}
if (refreshToken == null) {
throw new AuthServerException(AuthRequestError.invalidRequest, client);
}
var t = await storage.fetchTokenByRefreshToken(this, refreshToken);
if (t == null || t.clientID != clientID) {
throw new AuthServerException(AuthRequestError.invalidGrant, client);
}
if (clientSecret == null) {
throw new AuthServerException(AuthRequestError.invalidClient, client);
}
if (client.hashedSecret !=
AuthUtility.generatePasswordHash(clientSecret, client.salt)) {
throw new AuthServerException(AuthRequestError.invalidClient, client);
}
var updatedScopes = t.scopes;
if ((requestedScopes?.length ?? 0) != 0) {
for (var incomingScope in requestedScopes) {
var hasExistingScopeOrSuperset = t.scopes
.any((existingScope) => incomingScope.isSubsetOrEqualTo(existingScope));
if (!hasExistingScopeOrSuperset) {
throw new AuthServerException(AuthRequestError.invalidScope, client);
}
if (!client.allowsScope(incomingScope)) {
throw new 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 new AuthServerException(AuthRequestError.invalidScope, client);
}
}
}
var diff = t.expirationDate.difference(t.issueDate);
var now = new DateTime.now().toUtc();
var newToken = new AuthToken()
..accessToken = randomStringOfLength(32)
..issueDate = now
..expirationDate = now.add(new Duration(seconds: diff.inSeconds)).toUtc()
..refreshToken = t.refreshToken
..type = t.type
..scopes = updatedScopes
..resourceOwnerIdentifier = t.resourceOwnerIdentifier
..clientID = t.clientID;
await storage.refreshTokenWithAccessToken(this, t.accessToken,
newToken.accessToken, newToken.issueDate, newToken.expirationDate);
return newToken;
}