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 pRefreshToken - Refresh token * @returns Access token */ export async function refreshToken( oauth2: OAuth2, client: OAuth2Client, pRefreshToken: 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 (!pRefreshToken) { throw new InvalidRequest('refresh_token is mandatory for refresh_token grant type'); } try { refreshToken = await oauth2.model.refreshToken.fetchByToken(pRefreshToken); } 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)) { console.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; }