oauth2-provider/src/controller/tokens/refreshToken.ts

116 lines
2.8 KiB
TypeScript

import {
InvalidRequest,
ServerError,
InvalidGrant,
InvalidClient,
} from '../../model/error';
import {
OAuth2,
OAuth2AccessToken,
OAuth2Client,
OAuth2RefreshToken,
OAuth2User,
OAuth2TokenResponse,
} from '../../model/model';
/**
* Get a new access token from a refresh token. Scope change may not be requested.
* @param oauth2 - OAuth2 instance
* @param client - OAuth2 client
* @param providedToken - Refresh token
* @returns Access token
*/
export async function refreshToken(
oauth2: OAuth2,
client: OAuth2Client,
providedToken: string
): Promise<OAuth2TokenResponse> {
let user: OAuth2User | null = null;
let ttl: number | null = null;
let refreshToken: OAuth2RefreshToken | null = null;
let accessToken: OAuth2AccessToken | null = null;
const resObj: OAuth2TokenResponse = {
token_type: 'bearer',
};
if (!providedToken) {
throw new InvalidRequest(
'refresh_token is mandatory for refresh_token grant type'
);
}
try {
refreshToken = await oauth2.model.refreshToken.fetchByToken(providedToken);
} catch (err) {
throw new ServerError('Failed to call refreshToken.fetchByToken function');
}
if (!refreshToken) {
throw new InvalidGrant('Refresh token not found');
}
if (
oauth2.model.refreshToken.getClientId(refreshToken) !==
oauth2.model.client.getId(client)
) {
oauth2.logger.warn(
'Client %s tried to fetch a refresh token which belongs to client %s!',
oauth2.model.client.getId(client),
oauth2.model.refreshToken.getClientId(refreshToken)
);
throw new InvalidGrant('Refresh token not found');
}
try {
user = await oauth2.model.user.fetchById(
oauth2.model.refreshToken.getUserId(refreshToken)
);
} catch (err) {
throw new InvalidClient('User not found');
}
if (!user) {
throw new InvalidClient('User not found');
}
try {
accessToken = await oauth2.model.accessToken.fetchByUserIdClientId(
oauth2.model.user.getId(user),
oauth2.model.client.getId(client)
);
} catch (err) {
throw new ServerError(
'Failed to call accessToken.fetchByUserIdClientId function'
);
}
if (accessToken) {
ttl = oauth2.model.accessToken.getTTL(accessToken);
if (!ttl) {
accessToken = null;
} else {
resObj.access_token = oauth2.model.accessToken.getToken(accessToken);
resObj.expires_in = ttl;
}
}
if (!accessToken) {
try {
resObj.access_token = await oauth2.model.accessToken.create(
oauth2.model.user.getId(user),
oauth2.model.client.getId(client),
oauth2.model.refreshToken.getScope(refreshToken),
oauth2.model.accessToken.ttl
);
} catch (err) {
throw new ServerError('Failed to call accessToken.create function');
}
resObj.expires_in = oauth2.model.accessToken.ttl;
}
return resObj;
}