74 lines
1.7 KiB
JavaScript
Raw Normal View History

'use strict';
2021-10-27 18:54:58 +02:00
const { UnauthorizedError, ForbiddenError } = require('@strapi/utils').errors;
const constants = require('../services/constants');
const { getService } = require('../utils');
const isReadScope = scope => scope.endsWith('find') || scope.endsWith('findOne');
2021-11-15 17:54:17 +01:00
const extractToken = ctx => {
if (ctx.request && ctx.request.header && ctx.request.header.authorization) {
const parts = ctx.request.header.authorization.split(/\s+/);
2021-11-15 17:54:17 +01:00
if (parts[0].toLowerCase() !== 'bearer' || parts.length !== 2) {
return null;
}
return parts[1];
}
2021-11-15 17:54:17 +01:00
return null;
};
/** @type {import('.').AuthenticateFunction} */
const authenticate = async ctx => {
const apiTokenService = getService('api-token');
const token = extractToken(ctx);
2021-11-15 17:54:17 +01:00
if (!token) {
return { authenticated: false };
}
const apiToken = await apiTokenService.getBy({
accessKey: apiTokenService.hash(token),
});
if (!apiToken) {
return { authenticated: false };
}
return { authenticated: true, credentials: apiToken };
};
/** @type {import('.').VerifyFunction} */
const verify = (auth, config) => {
const { credentials: apiToken } = auth;
if (!apiToken) {
2021-10-27 18:54:58 +02:00
throw new UnauthorizedError();
}
if (apiToken.type === constants.API_TOKEN_TYPE.FULL_ACCESS) {
return;
}
/**
* If you don't have `full-access` you can only access `find` and `findOne`
* scopes. If the route has no scope, then you can't get access to it.
*/
const scopes = Array.isArray(config.scope) ? config.scope : [config.scope];
if (config.scope && scopes.every(isReadScope)) {
return;
}
2021-10-27 18:54:58 +02:00
throw new ForbiddenError();
};
/** @type {import('.').AuthStrategy} */
module.exports = {
name: 'api-token',
authenticate,
verify,
};