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

98 lines
2.8 KiB
TypeScript

import { InvalidRequest, ServerError, InvalidGrant } from '../../model/error';
import { OAuth2, OAuth2Client, OAuth2Code, OAuth2TokenResponse } from '../../model/model';
/**
* Issue an access token by authorization code
* @param oauth2 - OAuth2 instance
* @param client - OAuth2 client
* @param providedCode - Authorization code
* @returns Access token.
*/
export async function authorizationCode(
oauth2: OAuth2,
client: OAuth2Client,
providedCode: string
): Promise<OAuth2TokenResponse> {
const respObj: OAuth2TokenResponse = {
token_type: 'bearer'
};
let code: OAuth2Code | null = 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;
}