116 lines
2.8 KiB
TypeScript
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;
|
|
}
|