@bitblit/epsilon
Version:
Tiny adapter to simplify building API gateway Lambda APIS
152 lines • 8.92 kB
JavaScript
;
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