UNPKG

4.29 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const tslib_1 = require("tslib");
4const common_1 = require("@nestjs/common");
5const core_1 = require("@nestjs/core");
6const common_2 = require("@nestjs/common");
7const logging_1 = require("../gcloud/logging");
8const context_1 = require("../datastore/context");
9const configuration_1 = require("../configuration");
10const logger = logging_1.createLogger('auth-guard');
11exports.Roles = (...roles) => common_2.ReflectMetadata('roles', roles);
12exports.AllowAnonymous = () => common_2.ReflectMetadata('allowAnonymous', true);
13exports.Task = () => common_2.ReflectMetadata('secure-header', 'x-appengine-taskname');
14exports.Cron = () => common_2.ReflectMetadata('secure-header', 'x-appengine-cron');
15exports.System = () => common_2.ReflectMetadata('system', true);
16const reflectValue = (reflector, key, context, defaultValue) => {
17 const methodValue = reflector.get(key, context.getHandler());
18 if (methodValue !== undefined) {
19 return methodValue;
20 }
21 const classValue = reflector.get(key, context.getClass());
22 if (classValue !== undefined) {
23 return classValue;
24 }
25 return defaultValue;
26};
27function isAllowAnonymous(reflector, context) {
28 return reflectValue(reflector, 'allowAnonymous', context, false);
29}
30function isUserAllowedAccess(reflector, context, user) {
31 if (!user) {
32 return false;
33 }
34 const roles = reflectValue(reflector, 'roles', context, []);
35 if (!roles.length) {
36 return true;
37 }
38 const { roles: userRoles = [] } = user;
39 const allowed = roles.some(role => userRoles.includes(role));
40 if (!allowed) {
41 logger.warn('User does not have the required role');
42 }
43 return allowed;
44}
45function isSystemCall(reflector, context) {
46 return reflectValue(reflector, 'system', context, false);
47}
48async function isAuthorizedSystemCall(reflector, context, secret) {
49 const { verify } = await Promise.resolve().then(() => require('jsonwebtoken'));
50 const { headers } = context.switchToHttp().getRequest();
51 if (!headers.authorization) {
52 return false;
53 }
54 const token = headers.authorization.substr(4);
55 return new Promise(resolve => verify(token, secret, {
56 maxAge: '5 min',
57 algorithms: ['HS256'],
58 }, err => {
59 if (err) {
60 logger.error('Error decoding system token', err);
61 resolve(false);
62 }
63 else {
64 resolve(true);
65 }
66 }));
67}
68function hasSecureHeader(reflector, context) {
69 const { headers } = context.switchToHttp().getRequest();
70 if (!headers) {
71 return false;
72 }
73 const secureHeader = reflectValue(reflector, 'secure-header', context, undefined);
74 if (secureHeader) {
75 return !!headers[secureHeader];
76 }
77 return false;
78}
79function getUser(context) {
80 const request = context.switchToHttp().getRequest();
81 if (request.context && request.context.user) {
82 return request.context.user;
83 }
84 else {
85 const args = context.getArgs();
86 if (args.length > 2) {
87 const ctxt = args[2];
88 if (context_1.isContext(ctxt)) {
89 return ctxt.user;
90 }
91 }
92 }
93 return undefined;
94}
95let AuthGuard = class AuthGuard {
96 constructor(reflector, configurationProvider) {
97 this.reflector = reflector;
98 this.configurationProvider = configurationProvider;
99 this.logger = logging_1.createLogger('auth-guard');
100 }
101 canActivate(context) {
102 if (isAllowAnonymous(this.reflector, context)) {
103 return true;
104 }
105 if (isSystemCall(this.reflector, context)) {
106 return isAuthorizedSystemCall(this.reflector, context, this.configurationProvider.systemSecret);
107 }
108 if (hasSecureHeader(this.reflector, context)) {
109 return true;
110 }
111 const user = getUser(context);
112 return isUserAllowedAccess(this.reflector, context, user);
113 }
114};
115AuthGuard = tslib_1.__decorate([
116 common_1.Injectable(),
117 tslib_1.__param(1, common_1.Inject(configuration_1.CONFIGURATION)),
118 tslib_1.__metadata("design:paramtypes", [core_1.Reflector, Object])
119], AuthGuard);
120exports.AuthGuard = AuthGuard;
121//# sourceMappingURL=auth.guard.js.map
\No newline at end of file