@cifra-x/nest-keycloak 0.0.2
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.
- package/README.md +45 -0
- package/dist/src/async-class-provider.type-guard.d.ts +9 -0
- package/dist/src/async-class-provider.type-guard.js +6 -0
- package/dist/src/common/interfaces/authentication-request.interface.d.ts +11 -0
- package/dist/src/common/interfaces/authentication-request.interface.js +2 -0
- package/dist/src/common/interfaces/jwt-payload.interface.d.ts +12 -0
- package/dist/src/common/interfaces/jwt-payload.interface.js +2 -0
- package/dist/src/common/interfaces/token.interface.d.ts +2 -0
- package/dist/src/common/interfaces/token.interface.js +2 -0
- package/dist/src/common/utils/extract-request.util.d.ts +2 -0
- package/dist/src/common/utils/extract-request.util.js +27 -0
- package/dist/src/common/utils/extract-request.util.spec.d.ts +1 -0
- package/dist/src/common/utils/extract-request.util.spec.js +64 -0
- package/dist/src/common/utils/get-keycloak.util.d.ts +4 -0
- package/dist/src/common/utils/get-keycloak.util.js +25 -0
- package/dist/src/common/utils/get-keycloak.util.spec.d.ts +1 -0
- package/dist/src/common/utils/get-keycloak.util.spec.js +55 -0
- package/dist/src/common/utils/parse-token.util.d.ts +2 -0
- package/dist/src/common/utils/parse-token.util.js +7 -0
- package/dist/src/common/utils/parse-token.util.spec.d.ts +1 -0
- package/dist/src/common/utils/parse-token.util.spec.js +19 -0
- package/dist/src/constants/index.d.ts +5 -0
- package/dist/src/constants/index.js +21 -0
- package/dist/src/constants/keycloak-module.constants.d.ts +20 -0
- package/dist/src/constants/keycloak-module.constants.js +23 -0
- package/dist/src/constants/policy-enforcement-mode.enum.d.ts +13 -0
- package/dist/src/constants/policy-enforcement-mode.enum.js +17 -0
- package/dist/src/constants/role-matching-mode.enum.d.ts +13 -0
- package/dist/src/constants/role-matching-mode.enum.js +17 -0
- package/dist/src/constants/role-merge.enum.d.ts +10 -0
- package/dist/src/constants/role-merge.enum.js +14 -0
- package/dist/src/constants/token-validation.enum.d.ts +17 -0
- package/dist/src/constants/token-validation.enum.js +21 -0
- package/dist/src/decorators/authenticated-user.decorator.d.ts +4 -0
- package/dist/src/decorators/authenticated-user.decorator.js +12 -0
- package/dist/src/decorators/authenticated-user.decorator.spec.d.ts +1 -0
- package/dist/src/decorators/authenticated-user.decorator.spec.js +28 -0
- package/dist/src/decorators/enforcer-options.decorator.d.ts +8 -0
- package/dist/src/decorators/enforcer-options.decorator.js +12 -0
- package/dist/src/decorators/public.decorator.d.ts +14 -0
- package/dist/src/decorators/public.decorator.js +20 -0
- package/dist/src/decorators/resource.decorator.d.ts +6 -0
- package/dist/src/decorators/resource.decorator.js +11 -0
- package/dist/src/decorators/roles.decorator.d.ts +8 -0
- package/dist/src/decorators/roles.decorator.js +12 -0
- package/dist/src/decorators/scopes.decorator.d.ts +6 -0
- package/dist/src/decorators/scopes.decorator.js +11 -0
- package/dist/src/guards/auth.guard.d.ts +21 -0
- package/dist/src/guards/auth.guard.js +179 -0
- package/dist/src/guards/resource.guard.d.ts +19 -0
- package/dist/src/guards/resource.guard.js +151 -0
- package/dist/src/guards/role.guard.d.ts +18 -0
- package/dist/src/guards/role.guard.js +140 -0
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +18 -0
- package/dist/src/interface/keycloak-connect-module-async-options.interface.d.ts +9 -0
- package/dist/src/interface/keycloak-connect-module-async-options.interface.js +2 -0
- package/dist/src/interface/keycloak-connect-options-factory.interface.d.ts +4 -0
- package/dist/src/interface/keycloak-connect-options-factory.interface.js +2 -0
- package/dist/src/interface/keycloak-connect-options.interface.d.ts +121 -0
- package/dist/src/interface/keycloak-connect-options.interface.js +2 -0
- package/dist/src/interface/role-decorator-options.interface.d.ts +11 -0
- package/dist/src/interface/role-decorator-options.interface.js +2 -0
- package/dist/src/keycloak-connect.module.d.ts +37 -0
- package/dist/src/keycloak-connect.module.js +142 -0
- package/dist/src/providers/keycloak.provider.d.ts +2 -0
- package/dist/src/providers/keycloak.provider.js +25 -0
- package/dist/src/providers/logger.provider.d.ts +2 -0
- package/dist/src/providers/logger.provider.js +20 -0
- package/dist/src/services/keycloak-multitenant.service.d.ts +23 -0
- package/dist/src/services/keycloak-multitenant.service.js +139 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +135 -0
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { LogLevel } from '@nestjs/common';
|
|
2
|
+
import { TokenValidation } from '../constants';
|
|
3
|
+
import { PolicyEnforcementMode } from '../constants';
|
|
4
|
+
import { RoleMerge } from '../constants';
|
|
5
|
+
/**
|
|
6
|
+
* Keycloak Connect options.
|
|
7
|
+
* @see {@link https://github.com/keycloak/keycloak-nodejs-connect/blob/f8e011aea5/middleware/auth-utils/config.js}
|
|
8
|
+
*/
|
|
9
|
+
export interface KeycloakConnectOptions extends NestKeycloakConfig {
|
|
10
|
+
/**
|
|
11
|
+
* Realm ID.
|
|
12
|
+
*/
|
|
13
|
+
realm?: string;
|
|
14
|
+
/**
|
|
15
|
+
* Client/Application ID.
|
|
16
|
+
*/
|
|
17
|
+
resource?: string;
|
|
18
|
+
/**
|
|
19
|
+
* Client/Application ID.
|
|
20
|
+
* @see {KeycloakConnectOptions#resource}
|
|
21
|
+
*/
|
|
22
|
+
clientId?: string;
|
|
23
|
+
/**
|
|
24
|
+
* Client/Application secret.
|
|
25
|
+
*/
|
|
26
|
+
credentials?: KeycloakCredentials;
|
|
27
|
+
/**
|
|
28
|
+
* Client/Application secret.
|
|
29
|
+
* @see {KeycloakCredentials#secret}
|
|
30
|
+
*/
|
|
31
|
+
secret?: string;
|
|
32
|
+
/**
|
|
33
|
+
* If this is a public application or confidential.
|
|
34
|
+
* @see {KeycloakConnectOptions#public}
|
|
35
|
+
*/
|
|
36
|
+
public?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Authentication server URL.
|
|
39
|
+
* @see {KeycloakConnectOptions#authServerUrl}
|
|
40
|
+
*/
|
|
41
|
+
authServerUrl: string;
|
|
42
|
+
/**
|
|
43
|
+
* How many minutes before retrying getting the keys.
|
|
44
|
+
* @see {KeycloakConnectOptions#minTimeBetweenJwksRequests}
|
|
45
|
+
*/
|
|
46
|
+
minTimeBetweenJwksRequests?: number;
|
|
47
|
+
/**
|
|
48
|
+
* If this is a Bearer Only application.
|
|
49
|
+
* @see {KeycloakConnectOptions#bearerOnly}
|
|
50
|
+
*/
|
|
51
|
+
bearerOnly?: boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Formatted public-key.
|
|
54
|
+
* @see {KeycloakConnectOptions#realmPublicKey}
|
|
55
|
+
*/
|
|
56
|
+
realmPublicKey?: string;
|
|
57
|
+
/**
|
|
58
|
+
* Verify token audience.
|
|
59
|
+
* @see {KeycloakConnectOptions#verifyTokenAudience}
|
|
60
|
+
*/
|
|
61
|
+
verifyTokenAudience?: boolean;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Multi tenant configuration.
|
|
65
|
+
*/
|
|
66
|
+
export interface MultiTenantOptions {
|
|
67
|
+
/**
|
|
68
|
+
* Option to always resolve the realm and secret. Disabled by default.
|
|
69
|
+
*/
|
|
70
|
+
resolveAlways?: boolean;
|
|
71
|
+
/**
|
|
72
|
+
* The realm resolver function.
|
|
73
|
+
*/
|
|
74
|
+
realmResolver: (request: any) => Promise<string> | string;
|
|
75
|
+
/**
|
|
76
|
+
* The realm secret resolver function.
|
|
77
|
+
*/
|
|
78
|
+
realmSecretResolver?: (realm: string, request?: any) => Promise<string> | string;
|
|
79
|
+
/**
|
|
80
|
+
* The realm auth server url resolver function.
|
|
81
|
+
*/
|
|
82
|
+
realmAuthServerUrlResolver?: (realm: string, request?: any) => Promise<string> | string;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Library only configuration.
|
|
86
|
+
*/
|
|
87
|
+
export interface NestKeycloakConfig {
|
|
88
|
+
/**
|
|
89
|
+
* Cookie key.
|
|
90
|
+
*/
|
|
91
|
+
cookieKey?: string;
|
|
92
|
+
/**
|
|
93
|
+
* Log level.
|
|
94
|
+
*/
|
|
95
|
+
logLevels?: LogLevel[];
|
|
96
|
+
/**
|
|
97
|
+
* Sets the policy enforcement mode for this adapter, defaults to {@link PolicyEnforcementMode.PERMISSIVE}.
|
|
98
|
+
*/
|
|
99
|
+
policyEnforcement?: PolicyEnforcementMode;
|
|
100
|
+
/**
|
|
101
|
+
* Sets the token validation method, defaults to {@link TokenValidation.ONLINE}.
|
|
102
|
+
*/
|
|
103
|
+
tokenValidation?: TokenValidation;
|
|
104
|
+
/**
|
|
105
|
+
* Multi tenant options.
|
|
106
|
+
*/
|
|
107
|
+
multiTenant?: MultiTenantOptions;
|
|
108
|
+
/**
|
|
109
|
+
* Role merging options.
|
|
110
|
+
*/
|
|
111
|
+
roleMerge?: RoleMerge;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Represents Keycloak credentials.
|
|
115
|
+
*/
|
|
116
|
+
export interface KeycloakCredentials {
|
|
117
|
+
/**
|
|
118
|
+
* Client/Application secret.
|
|
119
|
+
*/
|
|
120
|
+
secret: string;
|
|
121
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { RoleMatchingMode } from '../constants';
|
|
2
|
+
export interface RoleDecoratorOptionsInterface {
|
|
3
|
+
/**
|
|
4
|
+
* The roles to match at the application/client, prefix any realm-level roles with "realm:" (i.e realm:admin)
|
|
5
|
+
*/
|
|
6
|
+
roles: string[];
|
|
7
|
+
/**
|
|
8
|
+
* Role matching mode, defaults to {@link RoleMatchingMode.ANY}
|
|
9
|
+
*/
|
|
10
|
+
mode?: RoleMatchingMode;
|
|
11
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { DynamicModule, Logger } from '@nestjs/common';
|
|
2
|
+
import { KeycloakConnectModuleAsyncOptions } from './interface/keycloak-connect-module-async-options.interface';
|
|
3
|
+
import { KeycloakConnectOptions } from './interface/keycloak-connect-options.interface';
|
|
4
|
+
export * from './constants';
|
|
5
|
+
export * from './decorators/authenticated-user.decorator';
|
|
6
|
+
export * from './decorators/enforcer-options.decorator';
|
|
7
|
+
export * from './decorators/public.decorator';
|
|
8
|
+
export * from './decorators/resource.decorator';
|
|
9
|
+
export * from './decorators/roles.decorator';
|
|
10
|
+
export * from './decorators/scopes.decorator';
|
|
11
|
+
export * from './guards/auth.guard';
|
|
12
|
+
export * from './guards/resource.guard';
|
|
13
|
+
export * from './guards/role.guard';
|
|
14
|
+
export * from './interface/keycloak-connect-module-async-options.interface';
|
|
15
|
+
export * from './interface/keycloak-connect-options-factory.interface';
|
|
16
|
+
export * from './interface/keycloak-connect-options.interface';
|
|
17
|
+
export * from './interface/role-decorator-options.interface';
|
|
18
|
+
export * from './services/keycloak-multitenant.service';
|
|
19
|
+
export declare class KeycloakConnectModule {
|
|
20
|
+
static logger: Logger;
|
|
21
|
+
/**
|
|
22
|
+
* Register the `KeycloakConnect` module.
|
|
23
|
+
* @param opts {@link KeycloakConnectOptions} object.
|
|
24
|
+
* @returns
|
|
25
|
+
*/
|
|
26
|
+
static register(opts: KeycloakConnectOptions): DynamicModule;
|
|
27
|
+
static registerAsync(opts: KeycloakConnectModuleAsyncOptions): DynamicModule;
|
|
28
|
+
private static createAsyncProviders;
|
|
29
|
+
private static createAsyncOptionsProvider;
|
|
30
|
+
}
|
|
31
|
+
export { KEYCLOAK_COOKIE_DEFAULT } from './constants/keycloak-module.constants';
|
|
32
|
+
export { KEYCLOAK_LOGGER } from './constants/keycloak-module.constants';
|
|
33
|
+
export { KEYCLOAK_MULTITENANT_SERVICE } from './constants/keycloak-module.constants';
|
|
34
|
+
export { KEYCLOAK_INSTANCE } from './constants/keycloak-module.constants';
|
|
35
|
+
export { KEYCLOAK_CONNECT_OPTIONS } from './constants/keycloak-module.constants';
|
|
36
|
+
export { PolicyEnforcementMode } from './constants/policy-enforcement-mode.enum';
|
|
37
|
+
export { RoleMerge } from './constants/role-merge.enum';
|
|
@@ -0,0 +1,142 @@
|
|
|
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 __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
14
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
15
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
16
|
+
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;
|
|
17
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
18
|
+
};
|
|
19
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
20
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
21
|
+
};
|
|
22
|
+
var KeycloakConnectModule_1;
|
|
23
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
+
exports.RoleMerge = exports.PolicyEnforcementMode = exports.KEYCLOAK_CONNECT_OPTIONS = exports.KEYCLOAK_INSTANCE = exports.KEYCLOAK_MULTITENANT_SERVICE = exports.KEYCLOAK_LOGGER = exports.KEYCLOAK_COOKIE_DEFAULT = exports.KeycloakConnectModule = void 0;
|
|
25
|
+
const common_1 = require("@nestjs/common");
|
|
26
|
+
const keycloak_multitenant_service_1 = require("./services/keycloak-multitenant.service");
|
|
27
|
+
const core_1 = require("@nestjs/core");
|
|
28
|
+
const constants_1 = require("./constants");
|
|
29
|
+
const logger_provider_1 = require("./providers/logger.provider");
|
|
30
|
+
const async_class_provider_type_guard_1 = require("./async-class-provider.type-guard");
|
|
31
|
+
const keycloak_provider_1 = require("./providers/keycloak.provider");
|
|
32
|
+
__exportStar(require("./constants"), exports);
|
|
33
|
+
__exportStar(require("./decorators/authenticated-user.decorator"), exports);
|
|
34
|
+
__exportStar(require("./decorators/enforcer-options.decorator"), exports);
|
|
35
|
+
__exportStar(require("./decorators/public.decorator"), exports);
|
|
36
|
+
__exportStar(require("./decorators/resource.decorator"), exports);
|
|
37
|
+
__exportStar(require("./decorators/roles.decorator"), exports);
|
|
38
|
+
__exportStar(require("./decorators/scopes.decorator"), exports);
|
|
39
|
+
__exportStar(require("./guards/auth.guard"), exports);
|
|
40
|
+
__exportStar(require("./guards/resource.guard"), exports);
|
|
41
|
+
__exportStar(require("./guards/role.guard"), exports);
|
|
42
|
+
__exportStar(require("./interface/keycloak-connect-module-async-options.interface"), exports);
|
|
43
|
+
__exportStar(require("./interface/keycloak-connect-options-factory.interface"), exports);
|
|
44
|
+
__exportStar(require("./interface/keycloak-connect-options.interface"), exports);
|
|
45
|
+
__exportStar(require("./interface/role-decorator-options.interface"), exports);
|
|
46
|
+
__exportStar(require("./services/keycloak-multitenant.service"), exports);
|
|
47
|
+
let KeycloakConnectModule = KeycloakConnectModule_1 = class KeycloakConnectModule {
|
|
48
|
+
/**
|
|
49
|
+
* Register the `KeycloakConnect` module.
|
|
50
|
+
* @param opts {@link KeycloakConnectOptions} object.
|
|
51
|
+
* @returns
|
|
52
|
+
*/
|
|
53
|
+
static register(opts) {
|
|
54
|
+
const keycloakConnectProviders = [
|
|
55
|
+
{
|
|
56
|
+
provide: constants_1.KEYCLOAK_CONNECT_OPTIONS,
|
|
57
|
+
useValue: opts,
|
|
58
|
+
},
|
|
59
|
+
logger_provider_1.loggerProvider,
|
|
60
|
+
keycloak_provider_1.keycloakProvider,
|
|
61
|
+
keycloak_multitenant_service_1.KeycloakMultiTenantService,
|
|
62
|
+
{
|
|
63
|
+
provide: constants_1.KEYCLOAK_MULTITENANT_SERVICE,
|
|
64
|
+
useClass: keycloak_multitenant_service_1.KeycloakMultiTenantService,
|
|
65
|
+
},
|
|
66
|
+
core_1.Reflector,
|
|
67
|
+
];
|
|
68
|
+
return {
|
|
69
|
+
module: KeycloakConnectModule_1,
|
|
70
|
+
providers: keycloakConnectProviders,
|
|
71
|
+
exports: keycloakConnectProviders,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
static registerAsync(opts) {
|
|
75
|
+
const optsProvider = this.createAsyncProviders(opts);
|
|
76
|
+
return {
|
|
77
|
+
module: KeycloakConnectModule_1,
|
|
78
|
+
imports: opts.imports || [],
|
|
79
|
+
providers: optsProvider,
|
|
80
|
+
exports: optsProvider,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
static createAsyncProviders(options) {
|
|
84
|
+
const providers = [
|
|
85
|
+
this.createAsyncOptionsProvider(options),
|
|
86
|
+
logger_provider_1.loggerProvider,
|
|
87
|
+
keycloak_provider_1.keycloakProvider,
|
|
88
|
+
keycloak_multitenant_service_1.KeycloakMultiTenantService,
|
|
89
|
+
{
|
|
90
|
+
provide: constants_1.KEYCLOAK_MULTITENANT_SERVICE,
|
|
91
|
+
useClass: keycloak_multitenant_service_1.KeycloakMultiTenantService,
|
|
92
|
+
},
|
|
93
|
+
core_1.Reflector,
|
|
94
|
+
];
|
|
95
|
+
if (options.useExisting || options.useFactory) {
|
|
96
|
+
return providers;
|
|
97
|
+
}
|
|
98
|
+
if (options.useClass) {
|
|
99
|
+
providers.push({
|
|
100
|
+
provide: options.useClass,
|
|
101
|
+
useClass: options.useClass,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
return providers;
|
|
105
|
+
}
|
|
106
|
+
static createAsyncOptionsProvider(options) {
|
|
107
|
+
if (options.useFactory) {
|
|
108
|
+
return {
|
|
109
|
+
provide: constants_1.KEYCLOAK_CONNECT_OPTIONS,
|
|
110
|
+
useFactory: options.useFactory,
|
|
111
|
+
inject: options.inject || [],
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
if (!(0, async_class_provider_type_guard_1.hasAsyncClassProvider)(options)) {
|
|
115
|
+
throw new Error('Invalid configuration. Must provide either useExisting or useClass.');
|
|
116
|
+
}
|
|
117
|
+
return {
|
|
118
|
+
provide: constants_1.KEYCLOAK_CONNECT_OPTIONS,
|
|
119
|
+
useFactory: async (optionsFactory) => await optionsFactory.createKeycloakConnectOptions(),
|
|
120
|
+
inject: [options.useExisting || options.useClass],
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
exports.KeycloakConnectModule = KeycloakConnectModule;
|
|
125
|
+
KeycloakConnectModule.logger = new common_1.Logger(KeycloakConnectModule_1.name);
|
|
126
|
+
exports.KeycloakConnectModule = KeycloakConnectModule = KeycloakConnectModule_1 = __decorate([
|
|
127
|
+
(0, common_1.Module)({})
|
|
128
|
+
], KeycloakConnectModule);
|
|
129
|
+
var keycloak_module_constants_1 = require("./constants/keycloak-module.constants");
|
|
130
|
+
Object.defineProperty(exports, "KEYCLOAK_COOKIE_DEFAULT", { enumerable: true, get: function () { return keycloak_module_constants_1.KEYCLOAK_COOKIE_DEFAULT; } });
|
|
131
|
+
var keycloak_module_constants_2 = require("./constants/keycloak-module.constants");
|
|
132
|
+
Object.defineProperty(exports, "KEYCLOAK_LOGGER", { enumerable: true, get: function () { return keycloak_module_constants_2.KEYCLOAK_LOGGER; } });
|
|
133
|
+
var keycloak_module_constants_3 = require("./constants/keycloak-module.constants");
|
|
134
|
+
Object.defineProperty(exports, "KEYCLOAK_MULTITENANT_SERVICE", { enumerable: true, get: function () { return keycloak_module_constants_3.KEYCLOAK_MULTITENANT_SERVICE; } });
|
|
135
|
+
var keycloak_module_constants_4 = require("./constants/keycloak-module.constants");
|
|
136
|
+
Object.defineProperty(exports, "KEYCLOAK_INSTANCE", { enumerable: true, get: function () { return keycloak_module_constants_4.KEYCLOAK_INSTANCE; } });
|
|
137
|
+
var keycloak_module_constants_5 = require("./constants/keycloak-module.constants");
|
|
138
|
+
Object.defineProperty(exports, "KEYCLOAK_CONNECT_OPTIONS", { enumerable: true, get: function () { return keycloak_module_constants_5.KEYCLOAK_CONNECT_OPTIONS; } });
|
|
139
|
+
var policy_enforcement_mode_enum_1 = require("./constants/policy-enforcement-mode.enum");
|
|
140
|
+
Object.defineProperty(exports, "PolicyEnforcementMode", { enumerable: true, get: function () { return policy_enforcement_mode_enum_1.PolicyEnforcementMode; } });
|
|
141
|
+
var role_merge_enum_1 = require("./constants/role-merge.enum");
|
|
142
|
+
Object.defineProperty(exports, "RoleMerge", { enumerable: true, get: function () { return role_merge_enum_1.RoleMerge; } });
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.keycloakProvider = void 0;
|
|
7
|
+
const keycloak_connect_1 = __importDefault(require("keycloak-connect"));
|
|
8
|
+
const constants_1 = require("../constants");
|
|
9
|
+
const keycloak_connect_module_1 = require("../keycloak-connect.module");
|
|
10
|
+
exports.keycloakProvider = {
|
|
11
|
+
provide: constants_1.KEYCLOAK_INSTANCE,
|
|
12
|
+
useFactory: (opts) => {
|
|
13
|
+
const keycloakOpts = opts;
|
|
14
|
+
const keycloak = new keycloak_connect_1.default({}, keycloakOpts);
|
|
15
|
+
if (opts.tokenValidation === constants_1.TokenValidation.NONE) {
|
|
16
|
+
keycloak_connect_module_1.KeycloakConnectModule.logger.warn(`Token validation is disabled, please only do this on development/special use-cases.`);
|
|
17
|
+
}
|
|
18
|
+
// Access denied is called, add a flag to request so our resource guard knows
|
|
19
|
+
keycloak.accessDenied = (req, _) => {
|
|
20
|
+
req.resourceDenied = true;
|
|
21
|
+
};
|
|
22
|
+
return keycloak;
|
|
23
|
+
},
|
|
24
|
+
inject: [constants_1.KEYCLOAK_CONNECT_OPTIONS],
|
|
25
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.loggerProvider = void 0;
|
|
7
|
+
const common_1 = require("@nestjs/common");
|
|
8
|
+
const keycloak_connect_1 = __importDefault(require("keycloak-connect"));
|
|
9
|
+
const constants_1 = require("../constants");
|
|
10
|
+
exports.loggerProvider = {
|
|
11
|
+
provide: constants_1.KEYCLOAK_LOGGER,
|
|
12
|
+
useFactory: (opts) => {
|
|
13
|
+
const loggerOptions = {};
|
|
14
|
+
if (opts.logLevels) {
|
|
15
|
+
loggerOptions.logLevels = opts.logLevels;
|
|
16
|
+
}
|
|
17
|
+
return new common_1.Logger(keycloak_connect_1.default.name, loggerOptions);
|
|
18
|
+
},
|
|
19
|
+
inject: [constants_1.KEYCLOAK_CONNECT_OPTIONS],
|
|
20
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import KeycloakConnect from 'keycloak-connect';
|
|
2
|
+
import { KeycloakConnectOptions } from '../interface/keycloak-connect-options.interface';
|
|
3
|
+
/**
|
|
4
|
+
* Stores all keycloak instances when multi tenant option is defined.
|
|
5
|
+
*/
|
|
6
|
+
export declare class KeycloakMultiTenantService {
|
|
7
|
+
private keycloakOpts;
|
|
8
|
+
private instances;
|
|
9
|
+
constructor(keycloakOpts: KeycloakConnectOptions);
|
|
10
|
+
/**
|
|
11
|
+
* Clears the cached Keycloak instances.
|
|
12
|
+
*/
|
|
13
|
+
clear(): void;
|
|
14
|
+
/**
|
|
15
|
+
* Retrieves a keycloak instance based on the realm provided.
|
|
16
|
+
* @param realm the realm to retrieve from
|
|
17
|
+
* @param request the request instance, defaults to undefined
|
|
18
|
+
* @returns the multi tenant keycloak instance
|
|
19
|
+
*/
|
|
20
|
+
get(realm: string, request?: any): Promise<KeycloakConnect.Keycloak>;
|
|
21
|
+
resolveAuthServerUrl(realm: string, request?: any): Promise<string>;
|
|
22
|
+
resolveSecret(realm: string, request?: any): Promise<string>;
|
|
23
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
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;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
15
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
16
|
+
};
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.KeycloakMultiTenantService = void 0;
|
|
19
|
+
const common_1 = require("@nestjs/common");
|
|
20
|
+
const keycloak_connect_1 = __importDefault(require("keycloak-connect"));
|
|
21
|
+
const constants_1 = require("../constants");
|
|
22
|
+
/**
|
|
23
|
+
* Stores all keycloak instances when multi tenant option is defined.
|
|
24
|
+
*/
|
|
25
|
+
let KeycloakMultiTenantService = class KeycloakMultiTenantService {
|
|
26
|
+
constructor(keycloakOpts) {
|
|
27
|
+
this.keycloakOpts = keycloakOpts;
|
|
28
|
+
this.instances = new Map();
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Clears the cached Keycloak instances.
|
|
32
|
+
*/
|
|
33
|
+
clear() {
|
|
34
|
+
this.instances.clear();
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Retrieves a keycloak instance based on the realm provided.
|
|
38
|
+
* @param realm the realm to retrieve from
|
|
39
|
+
* @param request the request instance, defaults to undefined
|
|
40
|
+
* @returns the multi tenant keycloak instance
|
|
41
|
+
*/
|
|
42
|
+
async get(realm, request = undefined) {
|
|
43
|
+
if (typeof this.keycloakOpts === 'string') {
|
|
44
|
+
throw new Error('Keycloak configuration is a configuration path. This should not happen after module load.');
|
|
45
|
+
}
|
|
46
|
+
if (this.keycloakOpts.multiTenant === null ||
|
|
47
|
+
this.keycloakOpts.multiTenant === undefined) {
|
|
48
|
+
throw new Error('Multi tenant is not defined yet multi tenant service is being called.');
|
|
49
|
+
}
|
|
50
|
+
const authServerUrl = await this.resolveAuthServerUrl(realm, request);
|
|
51
|
+
const secret = await this.resolveSecret(realm, request);
|
|
52
|
+
// Check if existing
|
|
53
|
+
if (this.instances.has(realm)) {
|
|
54
|
+
// If resolve always is enabled, resolve everything again
|
|
55
|
+
if (this.keycloakOpts.multiTenant.resolveAlways) {
|
|
56
|
+
const keycloak = this.instances.get(realm);
|
|
57
|
+
keycloak.config.authServerUrl = authServerUrl;
|
|
58
|
+
keycloak.config.secret = secret;
|
|
59
|
+
keycloak.grantManager.secret = secret;
|
|
60
|
+
// Save instance
|
|
61
|
+
this.instances.set(realm, keycloak);
|
|
62
|
+
return keycloak;
|
|
63
|
+
}
|
|
64
|
+
// Otherwise return the instance
|
|
65
|
+
const instanse = this.instances.get(realm);
|
|
66
|
+
if (!instanse) {
|
|
67
|
+
throw new Error('[KeycloakMultiTenantService] -> get -> No instanse');
|
|
68
|
+
}
|
|
69
|
+
return instanse;
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
// TODO: Repeating code from provider, will need to rework this in 2.0
|
|
73
|
+
// Override realm, secret, and authServerUrl
|
|
74
|
+
const keycloakOpts = Object.assign(this.keycloakOpts, {
|
|
75
|
+
authServerUrl,
|
|
76
|
+
realm,
|
|
77
|
+
secret,
|
|
78
|
+
});
|
|
79
|
+
const keycloak = new keycloak_connect_1.default({}, keycloakOpts);
|
|
80
|
+
// The most important part
|
|
81
|
+
keycloak.accessDenied = (req, res, next) => {
|
|
82
|
+
req.resourceDenied = true;
|
|
83
|
+
next();
|
|
84
|
+
};
|
|
85
|
+
// Save instance
|
|
86
|
+
this.instances.set(realm, keycloak);
|
|
87
|
+
return keycloak;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
async resolveAuthServerUrl(realm, request = undefined) {
|
|
91
|
+
if (typeof this.keycloakOpts === 'string') {
|
|
92
|
+
throw new Error('Keycloak configuration is a configuration path. This should not happen after module load.');
|
|
93
|
+
}
|
|
94
|
+
if (this.keycloakOpts.multiTenant === null ||
|
|
95
|
+
this.keycloakOpts.multiTenant === undefined) {
|
|
96
|
+
throw new Error('Multi tenant is not defined yet multi tenant service is being called.');
|
|
97
|
+
}
|
|
98
|
+
// If no realm auth server url resolver is defined, return defaults
|
|
99
|
+
if (!this.keycloakOpts.multiTenant.realmAuthServerUrlResolver) {
|
|
100
|
+
return this.keycloakOpts.authServerUrl;
|
|
101
|
+
}
|
|
102
|
+
// Resolve realm authServerUrl
|
|
103
|
+
const resolvedAuthServerUrl = this.keycloakOpts.multiTenant.realmAuthServerUrlResolver(realm, request);
|
|
104
|
+
const authServerUrl = resolvedAuthServerUrl ||
|
|
105
|
+
resolvedAuthServerUrl instanceof Promise
|
|
106
|
+
? await resolvedAuthServerUrl
|
|
107
|
+
: resolvedAuthServerUrl;
|
|
108
|
+
// Override auth server url
|
|
109
|
+
// Order of priority: resolved realm auth server url > provided auth server url
|
|
110
|
+
return authServerUrl || this.keycloakOpts.authServerUrl;
|
|
111
|
+
}
|
|
112
|
+
async resolveSecret(realm, request = undefined) {
|
|
113
|
+
if (typeof this.keycloakOpts === 'string') {
|
|
114
|
+
throw new Error('Keycloak configuration is a configuration path. This should not happen after module load.');
|
|
115
|
+
}
|
|
116
|
+
if (this.keycloakOpts.multiTenant === null ||
|
|
117
|
+
this.keycloakOpts.multiTenant === undefined) {
|
|
118
|
+
throw new Error('Multi tenant is not defined yet multi tenant service is being called.');
|
|
119
|
+
}
|
|
120
|
+
// If no realm secret resolver is defined, return defaults
|
|
121
|
+
if (!this.keycloakOpts.multiTenant.realmSecretResolver) {
|
|
122
|
+
return this.keycloakOpts.secret;
|
|
123
|
+
}
|
|
124
|
+
// Resolve realm secret
|
|
125
|
+
const resolvedRealmSecret = this.keycloakOpts.multiTenant.realmSecretResolver(realm, request);
|
|
126
|
+
const realmSecret = resolvedRealmSecret || resolvedRealmSecret instanceof Promise
|
|
127
|
+
? await resolvedRealmSecret
|
|
128
|
+
: resolvedRealmSecret;
|
|
129
|
+
// Override secret
|
|
130
|
+
// Order of priority: resolved realm secret > default global secret
|
|
131
|
+
return realmSecret || this.keycloakOpts.secret;
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
exports.KeycloakMultiTenantService = KeycloakMultiTenantService;
|
|
135
|
+
exports.KeycloakMultiTenantService = KeycloakMultiTenantService = __decorate([
|
|
136
|
+
(0, common_1.Injectable)(),
|
|
137
|
+
__param(0, (0, common_1.Inject)(constants_1.KEYCLOAK_CONNECT_OPTIONS)),
|
|
138
|
+
__metadata("design:paramtypes", [Object])
|
|
139
|
+
], KeycloakMultiTenantService);
|