UNPKG

@loopback/authorization

Version:

A LoopBack component for authorization support.

162 lines 6.01 kB
"use strict"; // Copyright IBM Corp. and LoopBack contributors 2018,2020. All Rights Reserved. // Node module: @loopback/authorization // This file is licensed under the MIT License. // License text available at https://opensource.org/licenses/MIT Object.defineProperty(exports, "__esModule", { value: true }); exports.getAuthorizationMetadata = exports.authorize = exports.AuthorizeMethodDecoratorFactory = exports.AUTHORIZATION_CLASS_KEY = exports.AUTHORIZATION_METHOD_KEY = void 0; const core_1 = require("@loopback/core"); const types_1 = require("../types"); exports.AUTHORIZATION_METHOD_KEY = core_1.MetadataAccessor.create('authorization:method'); exports.AUTHORIZATION_CLASS_KEY = core_1.MetadataAccessor.create('authorization:class'); class AuthorizeClassDecoratorFactory extends core_1.ClassDecoratorFactory { } class AuthorizeMethodDecoratorFactory extends core_1.MethodDecoratorFactory { mergeWithOwn(ownMetadata, target, methodName, // eslint-disable-next-line @typescript-eslint/no-explicit-any methodDescriptor) { ownMetadata = ownMetadata || {}; let methodMeta = ownMetadata[methodName]; if (!methodMeta) { methodMeta = { ...this.spec }; ownMetadata[methodName] = methodMeta; } if (this.spec.allowedRoles) { methodMeta.allowedRoles = this.merge(methodMeta.allowedRoles, this.spec.allowedRoles); } if (this.spec.deniedRoles) { methodMeta.deniedRoles = this.merge(methodMeta.deniedRoles, this.spec.deniedRoles); } if (this.spec.scopes) { methodMeta.scopes = this.merge(methodMeta.scopes, this.spec.scopes); } if (this.spec.voters) { methodMeta.voters = this.merge(methodMeta.voters, this.spec.voters); } return ownMetadata; } merge(src, target) { const list = []; if (src === target) return src !== null && src !== void 0 ? src : list; const set = new Set(src !== null && src !== void 0 ? src : []); if (target) { for (const i of target) { set.add(i); } } for (const i of set.values()) list.push(i); return list; } } exports.AuthorizeMethodDecoratorFactory = AuthorizeMethodDecoratorFactory; /** * Decorator `@authorize` to mark methods that require authorization * * @param spec Authorization metadata */ function authorize(spec) { return function authorizeDecoratorForClassOrMethod( // Class or a prototype // eslint-disable-next-line @typescript-eslint/no-explicit-any target, method, // Use `any` to for `TypedPropertyDescriptor` // See https://github.com/loopbackio/loopback-next/pull/2704 // eslint-disable-next-line @typescript-eslint/no-explicit-any methodDescriptor) { if (method && methodDescriptor) { // Method return AuthorizeMethodDecoratorFactory.createDecorator(exports.AUTHORIZATION_METHOD_KEY, spec, { decoratorName: '@authorize' })(target, method, methodDescriptor); } if (typeof target === 'function' && !method && !methodDescriptor) { // Class return AuthorizeClassDecoratorFactory.createDecorator(exports.AUTHORIZATION_CLASS_KEY, spec, { decoratorName: '@authorize' })(target); } // Not on a class or method throw new Error('@intercept cannot be used on a property: ' + core_1.DecoratorFactory.getTargetName(target, method, methodDescriptor)); }; } exports.authorize = authorize; (function (authorize) { /** * Shortcut to configure allowed roles * @param roles */ authorize.allow = (...roles) => authorize({ allowedRoles: roles }); /** * Shortcut to configure denied roles * @param roles */ authorize.deny = (...roles) => authorize({ deniedRoles: roles }); /** * Shortcut to specify access scopes * @param scopes */ authorize.scope = (...scopes) => authorize({ scopes }); /** * Shortcut to configure voters * @param voters */ authorize.vote = (...voters) => authorize({ voters }); /** * Allows all */ authorize.allowAll = () => authorize.allow(types_1.EVERYONE); /** * Allow all but the given roles * @param roles */ authorize.allowAllExcept = (...roles) => authorize({ deniedRoles: roles, allowedRoles: [types_1.EVERYONE], }); /** * Deny all */ authorize.denyAll = () => authorize.deny(types_1.EVERYONE); /** * Deny all but the given roles * @param roles */ authorize.denyAllExcept = (...roles) => authorize({ allowedRoles: roles, deniedRoles: [types_1.EVERYONE], }); /** * Allow authenticated users */ authorize.allowAuthenticated = () => authorize.allow(types_1.AUTHENTICATED); /** * Deny unauthenticated users */ authorize.denyUnauthenticated = () => authorize.deny(types_1.UNAUTHENTICATED); /** * Skip authorization */ authorize.skip = () => authorize({ skip: true }); })(authorize || (exports.authorize = authorize = {})); /** * Fetch authorization metadata stored by `@authorize` decorator. * * @param target Target object/class * @param methodName Target method */ function getAuthorizationMetadata(target, methodName) { let targetClass; if (typeof target === 'function') { targetClass = target; target = target.prototype; } else { targetClass = target.constructor; } const metadata = core_1.MetadataInspector.getMethodMetadata(exports.AUTHORIZATION_METHOD_KEY, target, methodName); if (metadata) return metadata; // Check if the class level has `@authorize` return core_1.MetadataInspector.getClassMetadata(exports.AUTHORIZATION_CLASS_KEY, targetClass); } exports.getAuthorizationMetadata = getAuthorizationMetadata; //# sourceMappingURL=authorize.js.map