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 { 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; }