import { InvalidRequest, ServerError, InvalidGrant } from '../../error' export async function authorizationCode (oauth2, client, providedCode) { const respObj = { token_type: 'bearer' } let code = null if (!providedCode) { throw new InvalidRequest('code is mandatory for authorization_code grant type') } try { code = await oauth2.model.code.fetchByCode(providedCode) } catch (err) { console.error(err) throw new ServerError('Failed to call code.fetchByCode function') } if (code) { if (oauth2.model.code.getClientId(code) !== oauth2.model.client.getId(client)) { throw new InvalidGrant('Code was issued by another client') } if (!oauth2.model.code.checkTTL(code)) { throw new InvalidGrant('Code has already expired') } } else { throw new InvalidGrant('Code not found') } console.debug('Code fetched ', code) try { await oauth2.model.refreshToken.removeByUserIdClientId(oauth2.model.code.getUserId(code), oauth2.model.code.getClientId(code)) } catch (err) { console.error(err) throw new ServerError('Failed to call refreshToken.removeByUserIdClientId function') } console.debug('Refresh token removed') if (!oauth2.model.client.checkGrantType(client, 'refresh_token')) { console.debug('Client does not allow grant type refresh_token, skip creation') } else { try { respObj.refresh_token = await oauth2.model.refreshToken.create(oauth2.model.code.getUserId(code), oauth2.model.code.getClientId(code), oauth2.model.code.getScope(code)) } catch (err) { console.error(err) throw new ServerError('Failed to call refreshToken.create function') } } try { respObj.access_token = await oauth2.model.accessToken.create(oauth2.model.code.getUserId(code), oauth2.model.code.getClientId(code), oauth2.model.code.getScope(code), oauth2.model.accessToken.ttl) } catch (err) { console.error(err) throw new ServerError('Failed to call accessToken.create function') } respObj.expires_in = oauth2.model.accessToken.ttl console.debug('Access token saved: ', respObj.access_token) try { await oauth2.model.code.removeByCode(providedCode) } catch (err) { console.error(err) throw new ServerError('Failed to call code.removeByCode function') } return respObj }