@clemax/nest-keycloak-connect 2.1.0 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/dist/constants.d.ts +69 -0
  2. package/dist/constants.js +76 -0
  3. package/dist/decorators/access-token.decorator.d.ts +5 -0
  4. package/dist/decorators/access-token.decorator.js +13 -0
  5. package/dist/decorators/enforcer-options.decorator.d.ts +8 -0
  6. package/dist/decorators/enforcer-options.decorator.js +12 -0
  7. package/dist/decorators/keycloak-user.decorator.d.ts +5 -0
  8. package/dist/decorators/keycloak-user.decorator.js +13 -0
  9. package/dist/decorators/public.decorator.d.ts +7 -0
  10. package/dist/decorators/public.decorator.js +12 -0
  11. package/dist/decorators/resource.decorator.d.ts +6 -0
  12. package/dist/decorators/resource.decorator.js +11 -0
  13. package/dist/decorators/roles.decorator.d.ts +10 -0
  14. package/dist/decorators/roles.decorator.js +15 -0
  15. package/dist/decorators/scopes.decorator.d.ts +19 -0
  16. package/dist/decorators/scopes.decorator.js +28 -0
  17. package/dist/guards/auth.guard.d.ts +19 -0
  18. package/dist/guards/auth.guard.js +172 -0
  19. package/dist/guards/resource.guard.d.ts +18 -0
  20. package/dist/guards/resource.guard.js +175 -0
  21. package/dist/guards/role.guard.d.ts +17 -0
  22. package/dist/guards/role.guard.js +139 -0
  23. package/dist/index.d.ts +1 -0
  24. package/dist/index.js +18 -0
  25. package/dist/interface/keycloak-connect-module-async-options.interface.d.ts +9 -0
  26. package/dist/interface/keycloak-connect-module-async-options.interface.js +2 -0
  27. package/dist/interface/keycloak-connect-options-factory.interface.d.ts +4 -0
  28. package/dist/interface/keycloak-connect-options-factory.interface.js +2 -0
  29. package/dist/interface/keycloak-connect-options.interface.d.ts +170 -0
  30. package/dist/interface/keycloak-connect-options.interface.js +3 -0
  31. package/dist/internal.util.d.ts +8 -0
  32. package/dist/internal.util.js +69 -0
  33. package/dist/keycloak-connect.module.d.ts +32 -0
  34. package/dist/keycloak-connect.module.js +126 -0
  35. package/dist/keycloak-connect.providers.d.ts +7 -0
  36. package/dist/keycloak-connect.providers.js +81 -0
  37. package/dist/services/keycloak-multitenant.service.d.ts +24 -0
  38. package/dist/services/keycloak-multitenant.service.js +174 -0
  39. package/dist/util.d.ts +1 -0
  40. package/dist/util.js +8 -0
  41. package/package.json +13 -11
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Used internally, provides keycloak options for the Nest guards.
3
+ */
4
+ export declare const KEYCLOAK_CONNECT_OPTIONS = "KEYCLOAK_CONNECT_OPTIONS";
5
+ /**
6
+ * Key for injecting a keycloak instance.
7
+ */
8
+ export declare const KEYCLOAK_INSTANCE = "KEYCLOAK_INSTANCE";
9
+ /**
10
+ * Key for injecting a keycloak multi tenant service.
11
+ */
12
+ export declare const KEYCLOAK_MULTITENANT_SERVICE = "KEYCLOAK_MULTITENANT_SERVICE";
13
+ /**
14
+ * Default cookie key.
15
+ */
16
+ export declare const KEYCLOAK_COOKIE_DEFAULT = "KEYCLOAK_JWT";
17
+ /**
18
+ * Role matching mode.
19
+ */
20
+ export declare enum RoleMatch {
21
+ /**
22
+ * Match all roles
23
+ */
24
+ ALL = "all",
25
+ /**
26
+ * Match any roles
27
+ */
28
+ ANY = "any"
29
+ }
30
+ /**
31
+ * Policy enforcement mode.
32
+ */
33
+ export declare enum PolicyEnforcementMode {
34
+ /**
35
+ * Deny all request when there is no matching resource.
36
+ */
37
+ ENFORCING = "enforcing",
38
+ /**
39
+ * Allow all request even when there's no matching resource.
40
+ */
41
+ PERMISSIVE = "permissive"
42
+ }
43
+ /**
44
+ * Token validation methods.
45
+ */
46
+ export declare enum TokenValidation {
47
+ /**
48
+ * The default validation method, performs live validation via Keycloak servers.
49
+ */
50
+ ONLINE = "online",
51
+ /**
52
+ * Validate offline against the configured keycloak options.
53
+ */
54
+ OFFLINE = "offline",
55
+ /**
56
+ * Does not check for any validation. Should only be used for special cases (i.e development, internal networks)
57
+ */
58
+ NONE = "none"
59
+ }
60
+ export declare enum RoleMerge {
61
+ /**
62
+ * Overrides roles if defined both controller and handlers, with controller taking over.
63
+ */
64
+ OVERRIDE = 0,
65
+ /**
66
+ * Merges all roles from both controller and handlers.
67
+ */
68
+ ALL = 1
69
+ }
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RoleMerge = exports.TokenValidation = exports.PolicyEnforcementMode = exports.RoleMatch = exports.KEYCLOAK_COOKIE_DEFAULT = exports.KEYCLOAK_MULTITENANT_SERVICE = exports.KEYCLOAK_INSTANCE = exports.KEYCLOAK_CONNECT_OPTIONS = void 0;
4
+ /**
5
+ * Used internally, provides keycloak options for the Nest guards.
6
+ */
7
+ exports.KEYCLOAK_CONNECT_OPTIONS = 'KEYCLOAK_CONNECT_OPTIONS';
8
+ /**
9
+ * Key for injecting a keycloak instance.
10
+ */
11
+ exports.KEYCLOAK_INSTANCE = 'KEYCLOAK_INSTANCE';
12
+ /**
13
+ * Key for injecting a keycloak multi tenant service.
14
+ */
15
+ exports.KEYCLOAK_MULTITENANT_SERVICE = 'KEYCLOAK_MULTITENANT_SERVICE';
16
+ /**
17
+ * Default cookie key.
18
+ */
19
+ exports.KEYCLOAK_COOKIE_DEFAULT = 'KEYCLOAK_JWT';
20
+ /**
21
+ * Role matching mode.
22
+ */
23
+ var RoleMatch;
24
+ (function (RoleMatch) {
25
+ /**
26
+ * Match all roles
27
+ */
28
+ RoleMatch["ALL"] = "all";
29
+ /**
30
+ * Match any roles
31
+ */
32
+ RoleMatch["ANY"] = "any";
33
+ })(RoleMatch || (exports.RoleMatch = RoleMatch = {}));
34
+ /**
35
+ * Policy enforcement mode.
36
+ */
37
+ var PolicyEnforcementMode;
38
+ (function (PolicyEnforcementMode) {
39
+ /**
40
+ * Deny all request when there is no matching resource.
41
+ */
42
+ PolicyEnforcementMode["ENFORCING"] = "enforcing";
43
+ /**
44
+ * Allow all request even when there's no matching resource.
45
+ */
46
+ PolicyEnforcementMode["PERMISSIVE"] = "permissive";
47
+ })(PolicyEnforcementMode || (exports.PolicyEnforcementMode = PolicyEnforcementMode = {}));
48
+ /**
49
+ * Token validation methods.
50
+ */
51
+ var TokenValidation;
52
+ (function (TokenValidation) {
53
+ /**
54
+ * The default validation method, performs live validation via Keycloak servers.
55
+ */
56
+ TokenValidation["ONLINE"] = "online";
57
+ /**
58
+ * Validate offline against the configured keycloak options.
59
+ */
60
+ TokenValidation["OFFLINE"] = "offline";
61
+ /**
62
+ * Does not check for any validation. Should only be used for special cases (i.e development, internal networks)
63
+ */
64
+ TokenValidation["NONE"] = "none";
65
+ })(TokenValidation || (exports.TokenValidation = TokenValidation = {}));
66
+ var RoleMerge;
67
+ (function (RoleMerge) {
68
+ /**
69
+ * Overrides roles if defined both controller and handlers, with controller taking over.
70
+ */
71
+ RoleMerge[RoleMerge["OVERRIDE"] = 0] = "OVERRIDE";
72
+ /**
73
+ * Merges all roles from both controller and handlers.
74
+ */
75
+ RoleMerge[RoleMerge["ALL"] = 1] = "ALL";
76
+ })(RoleMerge || (exports.RoleMerge = RoleMerge = {}));
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Retrieves the currently used access token
3
+ * @since 2.0.0
4
+ */
5
+ export declare const AccessToken: (...dataOrPipes: unknown[]) => ParameterDecorator;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AccessToken = void 0;
4
+ const common_1 = require("@nestjs/common");
5
+ const internal_util_1 = require("../internal.util");
6
+ /**
7
+ * Retrieves the currently used access token
8
+ * @since 2.0.0
9
+ */
10
+ exports.AccessToken = (0, common_1.createParamDecorator)((data, ctx) => {
11
+ const [req] = (0, internal_util_1.extractRequest)(ctx);
12
+ return req.accessToken;
13
+ });
@@ -0,0 +1,8 @@
1
+ import * as KeycloakConnect from 'keycloak-connect';
2
+ export declare const META_ENFORCER_OPTIONS = "enforcer-options";
3
+ /**
4
+ * Keycloak enforcer options
5
+ * @param opts - enforcer options
6
+ * @since 1.3.0
7
+ */
8
+ export declare const EnforcerOptions: (opts: KeycloakConnect.EnforcerOptions) => import("@nestjs/common").CustomDecorator<string>;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EnforcerOptions = exports.META_ENFORCER_OPTIONS = void 0;
4
+ const common_1 = require("@nestjs/common");
5
+ exports.META_ENFORCER_OPTIONS = 'enforcer-options';
6
+ /**
7
+ * Keycloak enforcer options
8
+ * @param opts - enforcer options
9
+ * @since 1.3.0
10
+ */
11
+ const EnforcerOptions = (opts) => (0, common_1.SetMetadata)(exports.META_ENFORCER_OPTIONS, opts);
12
+ exports.EnforcerOptions = EnforcerOptions;
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Retrieves the current Keycloak logged-in user.
3
+ * @since 1.5.0
4
+ */
5
+ export declare const KeycloakUser: (...dataOrPipes: unknown[]) => ParameterDecorator;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.KeycloakUser = void 0;
4
+ const common_1 = require("@nestjs/common");
5
+ const internal_util_1 = require("../internal.util");
6
+ /**
7
+ * Retrieves the current Keycloak logged-in user.
8
+ * @since 1.5.0
9
+ */
10
+ exports.KeycloakUser = (0, common_1.createParamDecorator)((data, ctx) => {
11
+ const [req] = (0, internal_util_1.extractRequest)(ctx);
12
+ return req.user;
13
+ });
@@ -0,0 +1,7 @@
1
+ export declare const META_PUBLIC = "public";
2
+ /**
3
+ * Allows unauthorized traffic to enter the route.
4
+ * @since 1.2.0
5
+ * @param skipAuth attaches authorization header to user object when `false`, defaults to `true`
6
+ */
7
+ export declare const Public: () => import("@nestjs/common").CustomDecorator<string>;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Public = exports.META_PUBLIC = void 0;
4
+ const common_1 = require("@nestjs/common");
5
+ exports.META_PUBLIC = 'public';
6
+ /**
7
+ * Allows unauthorized traffic to enter the route.
8
+ * @since 1.2.0
9
+ * @param skipAuth attaches authorization header to user object when `false`, defaults to `true`
10
+ */
11
+ const Public = () => (0, common_1.SetMetadata)(exports.META_PUBLIC, true);
12
+ exports.Public = Public;
@@ -0,0 +1,6 @@
1
+ export declare const META_RESOURCE = "resource";
2
+ /**
3
+ * Keycloak Resource.
4
+ * @param resource - name of resource
5
+ */
6
+ export declare const Resource: (resource: string) => import("@nestjs/common").CustomDecorator<string>;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Resource = exports.META_RESOURCE = void 0;
4
+ const common_1 = require("@nestjs/common");
5
+ exports.META_RESOURCE = 'resource';
6
+ /**
7
+ * Keycloak Resource.
8
+ * @param resource - name of resource
9
+ */
10
+ const Resource = (resource) => (0, common_1.SetMetadata)(exports.META_RESOURCE, resource);
11
+ exports.Resource = Resource;
@@ -0,0 +1,10 @@
1
+ import { RoleMatch } from '../constants';
2
+ export declare const META_ROLES = "roles";
3
+ export declare const META_ROLE_MATCHING_MODE = "role-matching-mode";
4
+ /**
5
+ * Keycloak user roles.
6
+ * @param roles - the roles to match
7
+ * @since 2.0.0
8
+ */
9
+ export declare const Roles: (...roles: string[]) => import("@nestjs/common").CustomDecorator<string>;
10
+ export declare const RoleMatchingMode: (mode: RoleMatch) => import("@nestjs/common").CustomDecorator<string>;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RoleMatchingMode = exports.Roles = exports.META_ROLE_MATCHING_MODE = exports.META_ROLES = void 0;
4
+ const common_1 = require("@nestjs/common");
5
+ exports.META_ROLES = 'roles';
6
+ exports.META_ROLE_MATCHING_MODE = 'role-matching-mode';
7
+ /**
8
+ * Keycloak user roles.
9
+ * @param roles - the roles to match
10
+ * @since 2.0.0
11
+ */
12
+ const Roles = (...roles) => (0, common_1.SetMetadata)(exports.META_ROLES, roles);
13
+ exports.Roles = Roles;
14
+ const RoleMatchingMode = (mode) => (0, common_1.SetMetadata)(exports.META_ROLE_MATCHING_MODE, mode);
15
+ exports.RoleMatchingMode = RoleMatchingMode;
@@ -0,0 +1,19 @@
1
+ import * as KeycloakConnect from 'keycloak-connect';
2
+ export declare const META_SCOPES = "scopes";
3
+ export declare const META_CONDITIONAL_SCOPES = "conditional-scopes";
4
+ export type ConditionalScopeFn = (request: any, token: KeycloakConnect.Token) => string[];
5
+ /**
6
+ * Keycloak authorization scopes.
7
+ * @param scopes - scopes that are associated with the resource
8
+ */
9
+ export declare const Scopes: (...scopes: string[]) => import("@nestjs/common").CustomDecorator<string>;
10
+ /**
11
+ * Keycloak authorization conditional scopes.
12
+ * @param scopes - scopes that are associated with the resource depending on the conditions
13
+ */
14
+ export declare const ConditionalScopes: (resolver: ConditionalScopeFn) => import("@nestjs/common").CustomDecorator<string>;
15
+ /**
16
+ * Retrieves the resolved scopes.
17
+ * @since 1.5.0
18
+ */
19
+ export declare const ResolvedScopes: (...dataOrPipes: unknown[]) => ParameterDecorator;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ResolvedScopes = exports.ConditionalScopes = exports.Scopes = exports.META_CONDITIONAL_SCOPES = exports.META_SCOPES = void 0;
4
+ const common_1 = require("@nestjs/common");
5
+ exports.META_SCOPES = 'scopes';
6
+ exports.META_CONDITIONAL_SCOPES = 'conditional-scopes';
7
+ /**
8
+ * Keycloak authorization scopes.
9
+ * @param scopes - scopes that are associated with the resource
10
+ */
11
+ const Scopes = (...scopes) => (0, common_1.SetMetadata)(exports.META_SCOPES, scopes);
12
+ exports.Scopes = Scopes;
13
+ /**
14
+ * Keycloak authorization conditional scopes.
15
+ * @param scopes - scopes that are associated with the resource depending on the conditions
16
+ */
17
+ const ConditionalScopes = (resolver) => (0, common_1.SetMetadata)(exports.META_CONDITIONAL_SCOPES, resolver);
18
+ exports.ConditionalScopes = ConditionalScopes;
19
+ const common_2 = require("@nestjs/common");
20
+ const internal_util_1 = require("../internal.util");
21
+ /**
22
+ * Retrieves the resolved scopes.
23
+ * @since 1.5.0
24
+ */
25
+ exports.ResolvedScopes = (0, common_2.createParamDecorator)((data, ctx) => {
26
+ const [req] = (0, internal_util_1.extractRequest)(ctx);
27
+ return req.scopes;
28
+ });
@@ -0,0 +1,19 @@
1
+ import { CanActivate, ExecutionContext } from '@nestjs/common';
2
+ import * as KeycloakConnect from 'keycloak-connect';
3
+ import { KeycloakConnectConfig } from '../interface/keycloak-connect-options.interface';
4
+ import { KeycloakMultiTenantService } from '../services/keycloak-multitenant.service';
5
+ /**
6
+ * An authentication guard. Will return a 401 unauthorized when it is unable to
7
+ * verify the JWT token or Bearer header is missing.
8
+ */
9
+ export declare class AuthGuard implements CanActivate {
10
+ private singleTenant;
11
+ private keycloakOpts;
12
+ private multiTenant;
13
+ private readonly logger;
14
+ private readonly reflector;
15
+ constructor(singleTenant: KeycloakConnect.Keycloak, keycloakOpts: KeycloakConnectConfig, multiTenant: KeycloakMultiTenantService);
16
+ canActivate(context: ExecutionContext): Promise<boolean>;
17
+ private validateToken;
18
+ private extractJwt;
19
+ }
@@ -0,0 +1,172 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
19
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
20
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
21
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
22
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
23
+ };
24
+ var __importStar = (this && this.__importStar) || function (mod) {
25
+ if (mod && mod.__esModule) return mod;
26
+ var result = {};
27
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
28
+ __setModuleDefault(result, mod);
29
+ return result;
30
+ };
31
+ var __metadata = (this && this.__metadata) || function (k, v) {
32
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
33
+ };
34
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
35
+ return function (target, key) { decorator(target, key, paramIndex); }
36
+ };
37
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
38
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
39
+ return new (P || (P = Promise))(function (resolve, reject) {
40
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
41
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
42
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
43
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
44
+ });
45
+ };
46
+ var AuthGuard_1;
47
+ Object.defineProperty(exports, "__esModule", { value: true });
48
+ exports.AuthGuard = void 0;
49
+ const common_1 = require("@nestjs/common");
50
+ const core_1 = require("@nestjs/core");
51
+ const KeycloakConnect = __importStar(require("keycloak-connect"));
52
+ const constants_1 = require("../constants");
53
+ const public_decorator_1 = require("../decorators/public.decorator");
54
+ const internal_util_1 = require("../internal.util");
55
+ const keycloak_multitenant_service_1 = require("../services/keycloak-multitenant.service");
56
+ const util_1 = require("../util");
57
+ /**
58
+ * An authentication guard. Will return a 401 unauthorized when it is unable to
59
+ * verify the JWT token or Bearer header is missing.
60
+ */
61
+ let AuthGuard = AuthGuard_1 = class AuthGuard {
62
+ constructor(singleTenant, keycloakOpts, multiTenant) {
63
+ this.singleTenant = singleTenant;
64
+ this.keycloakOpts = keycloakOpts;
65
+ this.multiTenant = multiTenant;
66
+ this.logger = new common_1.Logger(AuthGuard_1.name);
67
+ this.reflector = new core_1.Reflector();
68
+ }
69
+ canActivate(context) {
70
+ return __awaiter(this, void 0, void 0, function* () {
71
+ const isPublic = this.reflector.getAllAndOverride(public_decorator_1.META_PUBLIC, [
72
+ context.getClass(),
73
+ context.getHandler(),
74
+ ]);
75
+ // Extract request/response
76
+ const cookieKey = this.keycloakOpts.cookieKey || constants_1.KEYCLOAK_COOKIE_DEFAULT;
77
+ const [request] = (0, internal_util_1.extractRequestAndAttachCookie)(context, cookieKey);
78
+ // if is not an HTTP request ignore this guard
79
+ if (!request) {
80
+ return true;
81
+ }
82
+ const jwt = this.extractJwt(request.headers);
83
+ const isJwtEmpty = jwt === null || jwt === undefined;
84
+ // Not a public route, require jwt
85
+ if (!isPublic && isJwtEmpty) {
86
+ this.logger.verbose('Empty jwt, unauthorized');
87
+ throw new common_1.UnauthorizedException();
88
+ }
89
+ // Public route, no jwt sent
90
+ if (isPublic && isJwtEmpty) {
91
+ return true;
92
+ }
93
+ this.logger.verbose(`Validating jwt`, { jwt });
94
+ const keycloak = yield (0, internal_util_1.useKeycloak)(request, jwt, this.singleTenant, this.multiTenant, this.keycloakOpts);
95
+ const isValidToken = yield this.validateToken(keycloak, jwt);
96
+ if (isValidToken) {
97
+ // Attach user info object
98
+ request.user = (0, util_1.parseToken)(jwt);
99
+ // Attach raw access token JWT extracted from bearer/cookie
100
+ request.accessToken = jwt;
101
+ this.logger.verbose(`User authenticated`, { user: request.user });
102
+ return true;
103
+ }
104
+ // Valid token should return, this time we warn
105
+ if (isPublic) {
106
+ this.logger.warn(`A jwt token was retrieved but failed validation.`, {
107
+ jwt,
108
+ });
109
+ return true;
110
+ }
111
+ throw new common_1.UnauthorizedException();
112
+ });
113
+ }
114
+ validateToken(keycloak, jwt) {
115
+ return __awaiter(this, void 0, void 0, function* () {
116
+ const tokenValidation = this.keycloakOpts.tokenValidation || constants_1.TokenValidation.ONLINE;
117
+ const gm = keycloak.grantManager;
118
+ let grant;
119
+ try {
120
+ grant = yield gm.createGrant({ access_token: jwt });
121
+ }
122
+ catch (ex) {
123
+ this.logger.warn(`Cannot validate access token: ${ex}`);
124
+ // It will fail to create grants on invalid access token (i.e expired or wrong domain)
125
+ return false;
126
+ }
127
+ const token = grant.access_token;
128
+ this.logger.verbose(`Using token validation method: ${tokenValidation.toUpperCase()}`);
129
+ try {
130
+ let result;
131
+ switch (tokenValidation) {
132
+ case constants_1.TokenValidation.ONLINE:
133
+ result = yield gm.validateAccessToken(token);
134
+ return result === token;
135
+ case constants_1.TokenValidation.OFFLINE:
136
+ result = yield gm.validateToken(token, 'Bearer');
137
+ return result === token;
138
+ case constants_1.TokenValidation.NONE:
139
+ return true;
140
+ default:
141
+ this.logger.warn(`Unknown validation method: ${tokenValidation}`);
142
+ return false;
143
+ }
144
+ }
145
+ catch (ex) {
146
+ this.logger.warn(`Cannot validate access token: ${ex}`);
147
+ }
148
+ return false;
149
+ });
150
+ }
151
+ extractJwt(headers) {
152
+ if (headers && !headers.authorization) {
153
+ this.logger.verbose(`No authorization header`);
154
+ return null;
155
+ }
156
+ const auth = headers.authorization.split(' ');
157
+ // We only allow bearer
158
+ if (auth[0].toLowerCase() !== 'bearer') {
159
+ this.logger.verbose(`No bearer header`);
160
+ return null;
161
+ }
162
+ return auth[1];
163
+ }
164
+ };
165
+ exports.AuthGuard = AuthGuard;
166
+ exports.AuthGuard = AuthGuard = AuthGuard_1 = __decorate([
167
+ (0, common_1.Injectable)(),
168
+ __param(0, (0, common_1.Inject)(constants_1.KEYCLOAK_INSTANCE)),
169
+ __param(1, (0, common_1.Inject)(constants_1.KEYCLOAK_CONNECT_OPTIONS)),
170
+ __param(2, (0, common_1.Inject)(constants_1.KEYCLOAK_MULTITENANT_SERVICE)),
171
+ __metadata("design:paramtypes", [Object, Object, keycloak_multitenant_service_1.KeycloakMultiTenantService])
172
+ ], AuthGuard);
@@ -0,0 +1,18 @@
1
+ import { CanActivate, ExecutionContext } from '@nestjs/common';
2
+ import * as KeycloakConnect from 'keycloak-connect';
3
+ import { KeycloakConnectConfig } from '../interface/keycloak-connect-options.interface';
4
+ import { KeycloakMultiTenantService } from '../services/keycloak-multitenant.service';
5
+ /**
6
+ * This adds a resource guard, which is policy enforcement by default is permissive.
7
+ * Only controllers annotated with `@Resource` and methods with `@Scopes`
8
+ * are handled by this guard.
9
+ */
10
+ export declare class ResourceGuard implements CanActivate {
11
+ private singleTenant;
12
+ private keycloakOpts;
13
+ private multiTenant;
14
+ private readonly logger;
15
+ private readonly reflector;
16
+ constructor(singleTenant: KeycloakConnect.Keycloak, keycloakOpts: KeycloakConnectConfig, multiTenant: KeycloakMultiTenantService);
17
+ canActivate(context: ExecutionContext): Promise<boolean>;
18
+ }