UNPKG

@bitblit/epsilon

Version:

Tiny adapter to simplify building API gateway Lambda APIS

152 lines 8.92 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.BuiltInAuthFilters = void 0; const string_ratchet_1 = require("@bitblit/ratchet/common/string-ratchet"); const unauthorized_error_1 = require("../../http/error/unauthorized-error"); const misconfigured_error_1 = require("../../http/error/misconfigured-error"); const forbidden_error_1 = require("../../http/error/forbidden-error"); const event_util_1 = require("../../http/event-util"); const common_1 = require("@bitblit/ratchet/common"); class BuiltInAuthFilters { static requireAllRolesInCommonJwt(fCtx, requiredRoleAllOf) { var _a, _b; return __awaiter(this, void 0, void 0, function* () { if (!requiredRoleAllOf || requiredRoleAllOf.length === 0) { throw new misconfigured_error_1.MisconfiguredError('You must require at least 1 role'); } if (!((_b = (_a = fCtx.event) === null || _a === void 0 ? void 0 : _a.authorization) === null || _b === void 0 ? void 0 : _b.auth)) { throw new unauthorized_error_1.UnauthorizedError('May not proceed, not authenticated'); } else { const asJwt = fCtx.event.authorization.auth; if (!asJwt.roles || asJwt.roles.length === 0) { throw new unauthorized_error_1.UnauthorizedError('Required role not found'); } else { requiredRoleAllOf.forEach((r) => { if (!asJwt.roles.includes(r)) { // As soon as 1 is missing we are done throw new unauthorized_error_1.UnauthorizedError('Required role not found'); } }); } } return true; }); } static requireAnyRoleInCommonJwt(fCtx, requiredRoleOneOf) { var _a, _b; return __awaiter(this, void 0, void 0, function* () { if (!requiredRoleOneOf || requiredRoleOneOf.length === 0) { throw new misconfigured_error_1.MisconfiguredError('You must require at least 1 role'); } if (!((_b = (_a = fCtx.event) === null || _a === void 0 ? void 0 : _a.authorization) === null || _b === void 0 ? void 0 : _b.auth)) { throw new unauthorized_error_1.UnauthorizedError('May not proceed, not authenticated'); } else { const asJwt = fCtx.event.authorization.auth; if (!asJwt.roles || asJwt.roles.length === 0) { throw new unauthorized_error_1.UnauthorizedError('Required role not found'); } else { let found = false; requiredRoleOneOf.forEach((r) => { if (!found && asJwt.roles.includes(r)) { // Not found just to shortcut found = true; } }); if (!found) { throw new unauthorized_error_1.UnauthorizedError('Required role not found'); } } } return true; }); } static parseAuthorizationHeader(fCtx, webTokenManipulators) { var _a, _b; return __awaiter(this, void 0, void 0, function* () { if (!(fCtx === null || fCtx === void 0 ? void 0 : fCtx.event) || !webTokenManipulators || (Array.isArray(webTokenManipulators) && !webTokenManipulators.length)) { throw new misconfigured_error_1.MisconfiguredError('Cannot continue - missing event or encryption'); } else { // We dont throw errors if no token - just just decodes, it DOESNT enforce having tokens const tokenString = event_util_1.EventUtil.extractBearerTokenFromEvent(fCtx === null || fCtx === void 0 ? void 0 : fCtx.event); if (!Array.isArray(webTokenManipulators)) { webTokenManipulators = [webTokenManipulators]; } for (let i = 0; i < webTokenManipulators.length && !((_b = (_a = fCtx === null || fCtx === void 0 ? void 0 : fCtx.event) === null || _a === void 0 ? void 0 : _a.authorization) === null || _b === void 0 ? void 0 : _b.auth); i++) { const manipulator = webTokenManipulators[i]; try { // We include the prefix (like 'bearer') in case the token wants to code more than one type const token = yield manipulator.extractTokenFromAuthorizationHeader(tokenString); fCtx.event.authorization = { raw: tokenString, auth: token, error: null, authFailureException: null, }; } catch (err) { const toStore = common_1.RestfulApiHttpError.objectIsRestfulApiHttpError(err) ? err : new unauthorized_error_1.UnauthorizedError('You need to supply valid credentials for this endpoint'); fCtx.event.authorization = { raw: tokenString, auth: null, error: err['message'], authFailureException: toStore, }; } } } return true; }); } static applyOpenApiAuthorization(fCtx) { var _a, _b, _c, _d, _e, _f, _g, _h, _j; return __awaiter(this, void 0, void 0, function* () { // Check if this endpoint requires authorization // Use !== true below because commonly it just wont be spec'd if (string_ratchet_1.StringRatchet.trimToNull((_b = (_a = fCtx === null || fCtx === void 0 ? void 0 : fCtx.routeAndParse) === null || _a === void 0 ? void 0 : _a.mapping) === null || _b === void 0 ? void 0 : _b.authorizerName)) { const authorizer = (_c = fCtx === null || fCtx === void 0 ? void 0 : fCtx.authenticators) === null || _c === void 0 ? void 0 : _c.get(fCtx.routeAndParse.mapping.authorizerName); if (authorizer) { if ((_e = (_d = fCtx === null || fCtx === void 0 ? void 0 : fCtx.event) === null || _d === void 0 ? void 0 : _d.authorization) === null || _e === void 0 ? void 0 : _e.auth) { const allowed = yield authorizer(fCtx.event.authorization, fCtx.event, fCtx.routeAndParse.mapping); if (!allowed) { throw new forbidden_error_1.ForbiddenError('You lack privileges to see this endpoint'); } } else { if ((_g = (_f = fCtx === null || fCtx === void 0 ? void 0 : fCtx.event) === null || _f === void 0 ? void 0 : _f.authorization) === null || _g === void 0 ? void 0 : _g.authFailureException) { throw (_j = (_h = fCtx === null || fCtx === void 0 ? void 0 : fCtx.event) === null || _h === void 0 ? void 0 : _h.authorization) === null || _j === void 0 ? void 0 : _j.authFailureException; } else { // If no error but also no token, then likely they just didn't supply credentials at all throw new unauthorized_error_1.UnauthorizedError('You must supply valid credentials for this endpoint'); } } } else { throw new misconfigured_error_1.MisconfiguredError().withFormattedErrorMessage('Authorizer %s requested but not found', fCtx.routeAndParse.mapping.authorizerName); } } else { // Do nothing (unauthenticated endpoint) } return true; }); } } exports.BuiltInAuthFilters = BuiltInAuthFilters; //# sourceMappingURL=built-in-auth-filters.js.map