@adatechnology/auth-keycloak 0.0.2 → 0.0.3

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.
@@ -0,0 +1,320 @@
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 KeycloakClient_1;
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.KeycloakClient = void 0;
17
+ const common_1 = require("@nestjs/common");
18
+ const http_client_1 = require("@adatechnology/http-client");
19
+ const logger_1 = require("@adatechnology/logger");
20
+ const keycloak_error_1 = require("./errors/keycloak-error");
21
+ const LIB_NAME = "@adatechnology/auth-keycloak";
22
+ const LIB_VERSION = "0.0.2";
23
+ function extractErrorInfo(err) {
24
+ // Support both raw AxiosError and our mapped HttpClientError
25
+ const statusCode = err?.status ?? err?.response?.status;
26
+ const details = err?.response?.data ?? err?.context?.data ?? err?.context ?? err?.details;
27
+ const errorCode = err?.code ?? err?.response?.data?.error;
28
+ let keycloakError = undefined;
29
+ if (details && typeof details === "object" && details !== null) {
30
+ const raw = details.error;
31
+ if (typeof raw === "string") {
32
+ keycloakError = raw;
33
+ }
34
+ else if (raw) {
35
+ try {
36
+ keycloakError = JSON.stringify(raw);
37
+ }
38
+ catch {
39
+ keycloakError = String(raw);
40
+ }
41
+ }
42
+ }
43
+ return {
44
+ statusCode,
45
+ details: details ?? err?.message,
46
+ keycloakError: keycloakError ??
47
+ (errorCode ? `NETWORK_ERROR_${String(errorCode)}` : undefined),
48
+ };
49
+ }
50
+ /**
51
+ * Minimal Keycloak client implementation without external shared infra dependencies.
52
+ */
53
+ let KeycloakClient = KeycloakClient_1 = class KeycloakClient {
54
+ config;
55
+ httpProvider;
56
+ logger;
57
+ tokenCache = null;
58
+ tokenPromise = null;
59
+ constructor(config, httpProvider, logger) {
60
+ this.config = config;
61
+ this.httpProvider = httpProvider;
62
+ this.logger = logger;
63
+ }
64
+ log(level, message, libMethod, meta) {
65
+ if (!this.logger)
66
+ return;
67
+ // Support correlation by checking HTTP request context for a requestId
68
+ const httpCtx = (0, http_client_1.getHttpRequestContext)();
69
+ const requestId = httpCtx?.requestId;
70
+ const source = httpCtx?.className && httpCtx?.methodName
71
+ ? `${httpCtx.className}.${httpCtx.methodName}`
72
+ : undefined;
73
+ const payload = {
74
+ message,
75
+ context: "KeycloakClient",
76
+ lib: LIB_NAME,
77
+ libVersion: LIB_VERSION,
78
+ libMethod,
79
+ source,
80
+ requestId,
81
+ meta,
82
+ };
83
+ if (level === "debug")
84
+ this.logger.debug(payload);
85
+ else if (level === "info")
86
+ this.logger.info(payload);
87
+ else if (level === "warn")
88
+ this.logger.warn(payload);
89
+ else if (level === "error")
90
+ this.logger.error(payload);
91
+ }
92
+ async getAccessToken() {
93
+ const method = "getAccessToken";
94
+ this.log("debug", `${method} - Start`, method);
95
+ // Check cache
96
+ const now = Date.now();
97
+ if (this.tokenCache && now < this.tokenCache.expiresAt) {
98
+ this.log("debug", `${method} - Returning cached token`, method);
99
+ return this.tokenCache.token;
100
+ }
101
+ if (this.tokenPromise) {
102
+ this.log("debug", `${method} - Waiting for existing token request`, method);
103
+ return this.tokenPromise;
104
+ }
105
+ this.tokenPromise = (async () => {
106
+ try {
107
+ const tokenResponse = await this.requestToken();
108
+ const expiresAt = this.config.tokenCacheTtl
109
+ ? Date.now() + this.config.tokenCacheTtl
110
+ : Date.now() + (tokenResponse.expires_in - 60) * 1000;
111
+ this.tokenCache = { token: tokenResponse.access_token, expiresAt };
112
+ this.log("debug", `${method} - Token obtained and cached`, method);
113
+ return tokenResponse.access_token;
114
+ }
115
+ finally {
116
+ this.tokenPromise = null;
117
+ }
118
+ })();
119
+ return this.tokenPromise;
120
+ }
121
+ async getTokenWithCredentials(params) {
122
+ const method = "getTokenWithCredentials";
123
+ const { username } = params;
124
+ this.log("info", `${method} - Start for user: ${username}`, method);
125
+ const { password } = params;
126
+ const tokenUrl = `${this.config.baseUrl}/realms/${this.config.realm}/protocol/openid-connect/token`;
127
+ const body = new URLSearchParams();
128
+ body.append("client_id", this.config.credentials.clientId);
129
+ body.append("grant_type", "password");
130
+ body.append("username", username);
131
+ body.append("password", password);
132
+ if (this.config.credentials.clientSecret) {
133
+ body.append("client_secret", this.config.credentials.clientSecret);
134
+ }
135
+ // include configured scopes (default to openid/profile/email)
136
+ body.append("scope", KeycloakClient_1.scopesToString(this.config.scopes));
137
+ try {
138
+ const response = await this.httpProvider.post({
139
+ url: tokenUrl,
140
+ data: body,
141
+ config: {
142
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
143
+ logContext: { className: "KeycloakClient", methodName: method },
144
+ },
145
+ });
146
+ this.log("info", `${method} - Success for user: ${username}`, method);
147
+ return response.data;
148
+ }
149
+ catch (err) {
150
+ const { statusCode, details, keycloakError } = extractErrorInfo(err);
151
+ this.log("error", `${method} - Failed for user: ${username}`, method, { statusCode, keycloakError });
152
+ throw new keycloak_error_1.KeycloakError("Failed to obtain token with credentials", {
153
+ statusCode,
154
+ details,
155
+ keycloakError,
156
+ });
157
+ }
158
+ }
159
+ async requestToken() {
160
+ const method = "requestToken";
161
+ this.log("debug", `${method} - Start`, method);
162
+ const tokenUrl = `${this.config.baseUrl}/realms/${this.config.realm}/protocol/openid-connect/token`;
163
+ const data = new URLSearchParams();
164
+ data.append("client_id", this.config.credentials.clientId);
165
+ data.append("grant_type", this.config.credentials.grantType);
166
+ if (this.config.credentials.clientSecret) {
167
+ data.append("client_secret", this.config.credentials.clientSecret);
168
+ }
169
+ if (this.config.credentials.grantType === "password") {
170
+ if (this.config.credentials.username &&
171
+ this.config.credentials.password) {
172
+ data.append("username", this.config.credentials.username);
173
+ data.append("password", this.config.credentials.password);
174
+ // include configured scopes for resource-owner password grants
175
+ data.append("scope", KeycloakClient_1.scopesToString(this.config.scopes));
176
+ }
177
+ }
178
+ try {
179
+ const response = await this.httpProvider.post({
180
+ url: tokenUrl,
181
+ data,
182
+ config: {
183
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
184
+ logContext: { className: "KeycloakClient", methodName: method },
185
+ },
186
+ });
187
+ this.log("debug", `${method} - Success`, method);
188
+ return response.data;
189
+ }
190
+ catch (err) {
191
+ const { statusCode, details, keycloakError } = extractErrorInfo(err);
192
+ this.log("error", `${method} - Failed`, method, { statusCode, keycloakError });
193
+ throw new keycloak_error_1.KeycloakError("Failed to request token", {
194
+ statusCode,
195
+ details,
196
+ keycloakError,
197
+ });
198
+ }
199
+ }
200
+ async refreshToken(refreshToken) {
201
+ const method = "refreshToken";
202
+ this.log("debug", `${method} - Start`, method);
203
+ const tokenUrl = `${this.config.baseUrl}/realms/${this.config.realm}/protocol/openid-connect/token`;
204
+ const data = new URLSearchParams();
205
+ data.append("client_id", this.config.credentials.clientId);
206
+ data.append("grant_type", "refresh_token");
207
+ data.append("refresh_token", refreshToken);
208
+ if (this.config.credentials.clientSecret) {
209
+ data.append("client_secret", this.config.credentials.clientSecret);
210
+ }
211
+ try {
212
+ const response = await this.httpProvider.post({
213
+ url: tokenUrl,
214
+ data,
215
+ config: {
216
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
217
+ logContext: { className: "KeycloakClient", methodName: method },
218
+ },
219
+ });
220
+ const expiresAt = this.config.tokenCacheTtl
221
+ ? Date.now() + this.config.tokenCacheTtl
222
+ : Date.now() + (response.data.expires_in - 60) * 1000;
223
+ this.tokenCache = { token: response.data.access_token, expiresAt };
224
+ this.log("debug", `${method} - Success`, method);
225
+ return response.data;
226
+ }
227
+ catch (err) {
228
+ const { statusCode, details, keycloakError } = extractErrorInfo(err);
229
+ this.log("error", `${method} - Failed`, method, { statusCode, keycloakError });
230
+ throw new keycloak_error_1.KeycloakError("Failed to refresh token", {
231
+ statusCode,
232
+ details,
233
+ keycloakError,
234
+ });
235
+ }
236
+ }
237
+ async validateToken(token) {
238
+ const method = "validateToken";
239
+ this.log("debug", `${method} - Start`, method);
240
+ try {
241
+ const introspectUrl = `${this.config.baseUrl}/realms/${this.config.realm}/protocol/openid-connect/token/introspect`;
242
+ const data = new URLSearchParams();
243
+ data.append("token", token);
244
+ data.append("client_id", this.config.credentials.clientId);
245
+ if (this.config.credentials.clientSecret) {
246
+ data.append("client_secret", this.config.credentials.clientSecret);
247
+ }
248
+ const response = await this.httpProvider.post({
249
+ url: introspectUrl,
250
+ data,
251
+ config: {
252
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
253
+ logContext: { className: "KeycloakClient", methodName: method },
254
+ },
255
+ });
256
+ const active = response.data?.active === true;
257
+ this.log("debug", `${method} - Success (Active: ${active})`, method);
258
+ return active;
259
+ }
260
+ catch (error) {
261
+ const { statusCode, details, keycloakError } = extractErrorInfo(error);
262
+ this.log("error", `${method} - Failed`, method, { statusCode, keycloakError });
263
+ // wrap introspection errors for callers
264
+ throw new keycloak_error_1.KeycloakError("Token introspection failed", {
265
+ statusCode,
266
+ details,
267
+ keycloakError,
268
+ });
269
+ }
270
+ }
271
+ async getUserInfo(token) {
272
+ const method = "getUserInfo";
273
+ this.log("debug", `${method} - Start`, method);
274
+ const userInfoUrl = `${this.config.baseUrl}/realms/${this.config.realm}/protocol/openid-connect/userinfo`;
275
+ try {
276
+ const response = await this.httpProvider.get({
277
+ url: userInfoUrl,
278
+ config: {
279
+ headers: { Authorization: `Bearer ${token}` },
280
+ logContext: { className: "KeycloakClient", methodName: method },
281
+ },
282
+ });
283
+ this.log("debug", `${method} - Success`, method);
284
+ return response.data;
285
+ }
286
+ catch (err) {
287
+ const { statusCode, details, keycloakError } = extractErrorInfo(err);
288
+ this.log("error", `${method} - Failed`, method, { statusCode, keycloakError });
289
+ throw new keycloak_error_1.KeycloakError("Failed to retrieve userinfo", {
290
+ statusCode,
291
+ details,
292
+ keycloakError,
293
+ });
294
+ }
295
+ }
296
+ clearTokenCache() {
297
+ this.tokenCache = null;
298
+ }
299
+ static maskToken(token, visibleChars = 8) {
300
+ if (!token || typeof token !== "string")
301
+ return "";
302
+ return token.length <= visibleChars
303
+ ? token
304
+ : `${token.slice(0, visibleChars)}...`;
305
+ }
306
+ static scopesToString(scopes) {
307
+ if (!scopes)
308
+ return "openid profile email";
309
+ return Array.isArray(scopes) ? scopes.join(" ") : String(scopes);
310
+ }
311
+ };
312
+ exports.KeycloakClient = KeycloakClient;
313
+ exports.KeycloakClient = KeycloakClient = KeycloakClient_1 = __decorate([
314
+ (0, common_1.Injectable)(),
315
+ __param(1, (0, common_1.Inject)(http_client_1.HTTP_PROVIDER)),
316
+ __param(2, (0, common_1.Optional)()),
317
+ __param(2, (0, common_1.Inject)(logger_1.LOGGER_PROVIDER)),
318
+ __metadata("design:paramtypes", [Object, Object, Object])
319
+ ], KeycloakClient);
320
+ //# sourceMappingURL=keycloak.client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keycloak.client.js","sourceRoot":"","sources":["../src/keycloak.client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { CallHandler, ExecutionContext, NestInterceptor } from "@nestjs/common";
2
+ import { Observable } from "rxjs";
3
+ /**
4
+ * HTTP interceptor that automatically adds Keycloak tokens to requests
5
+ */
6
+ export declare class KeycloakHttpInterceptor implements NestInterceptor {
7
+ constructor();
8
+ intercept(context: ExecutionContext, next: CallHandler): Observable<unknown>;
9
+ }
@@ -0,0 +1,37 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.KeycloakHttpInterceptor = void 0;
13
+ const common_1 = require("@nestjs/common");
14
+ /**
15
+ * HTTP interceptor that automatically adds Keycloak tokens to requests
16
+ */
17
+ let KeycloakHttpInterceptor = class KeycloakHttpInterceptor {
18
+ constructor() { }
19
+ intercept(context, next) {
20
+ const request = context
21
+ .switchToHttp()
22
+ .getRequest();
23
+ // Only add token for external API calls (not Keycloak itself)
24
+ if (typeof request.url === "string" && !request.url.includes("keycloak")) {
25
+ // Note: In a real implementation, you might want to add the token here
26
+ // But since we're using HttpProvider, the token addition should be handled there
27
+ // This interceptor could be used for other HTTP client libraries
28
+ }
29
+ return next.handle();
30
+ }
31
+ };
32
+ exports.KeycloakHttpInterceptor = KeycloakHttpInterceptor;
33
+ exports.KeycloakHttpInterceptor = KeycloakHttpInterceptor = __decorate([
34
+ (0, common_1.Injectable)(),
35
+ __metadata("design:paramtypes", [])
36
+ ], KeycloakHttpInterceptor);
37
+ //# sourceMappingURL=keycloak.http.interceptor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keycloak.http.interceptor.js","sourceRoot":"","sources":["../src/keycloak.http.interceptor.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAMwB;AAMxB;;GAEG;AAEI,IAAM,uBAAuB,GAA7B,MAAM,uBAAuB;IAClC,gBAAe,CAAC;IAEhB,SAAS,CAAC,OAAyB,EAAE,IAAiB;QACpD,MAAM,OAAO,GAA4B,OAAO;aAC7C,YAAY,EAAE;aACd,UAAU,EAAE,CAAC;QAEhB,8DAA8D;QAC9D,IAAI,OAAO,OAAO,CAAC,GAAG,KAAK,QAAQ,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YACzE,uEAAuE;YACvE,iFAAiF;YACjF,iEAAiE;QACnE,CAAC;QAED,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;IACvB,CAAC;CACF,CAAA;AAjBY,0DAAuB;kCAAvB,uBAAuB;IADnC,IAAA,mBAAU,GAAE;;GACA,uBAAuB,CAiBnC"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Keycloak token response
3
+ */
4
+ export interface KeycloakTokenResponse {
5
+ access_token: string;
6
+ expires_in: number;
7
+ refresh_expires_in: number;
8
+ refresh_token: string;
9
+ token_type: string;
10
+ "not-before-policy": number;
11
+ session_state: string;
12
+ scope: string;
13
+ }
14
+ /**
15
+ * Keycloak client credentials
16
+ */
17
+ export interface KeycloakCredentials {
18
+ clientId: string;
19
+ clientSecret: string;
20
+ username?: string;
21
+ password?: string;
22
+ grantType: "client_credentials" | "password";
23
+ }
24
+ /**
25
+ * Keycloak configuration
26
+ */
27
+ export interface KeycloakConfig {
28
+ baseUrl: string;
29
+ realm: string;
30
+ credentials: KeycloakCredentials;
31
+ /**
32
+ * Optional scopes to request when fetching tokens. Can be a space-separated string or array of scopes.
33
+ * Defaults to ['openid', 'profile', 'email'] when omitted.
34
+ */
35
+ scopes?: string | string[];
36
+ /**
37
+ * Optional token cache TTL in milliseconds. If provided, KeycloakClient will use this value to
38
+ * determine how long to cache the access token instead of deriving TTL from the token's expires_in.
39
+ */
40
+ tokenCacheTtl?: number;
41
+ }
42
+ /**
43
+ * Keycloak client interface
44
+ */
45
+ export interface KeycloakClientInterface {
46
+ /**
47
+ * Get access token
48
+ */
49
+ getAccessToken(): Promise<string>;
50
+ /**
51
+ * Refresh access token
52
+ */
53
+ refreshToken(refreshToken: string): Promise<KeycloakTokenResponse>;
54
+ /**
55
+ * Validate token
56
+ */
57
+ validateToken(token: string): Promise<boolean>;
58
+ /**
59
+ * Get user info
60
+ */
61
+ getUserInfo(token: string): Promise<Record<string, unknown>>;
62
+ }
63
+ /**
64
+ * Minimal shape for decoded JWT payloads used by the RolesGuard.
65
+ */
66
+ export interface KeycloakJwtPayload {
67
+ realm_access?: {
68
+ roles?: string[];
69
+ };
70
+ resource_access?: Record<string, {
71
+ roles?: string[];
72
+ }>;
73
+ [key: string]: unknown;
74
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=keycloak.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keycloak.interface.js","sourceRoot":"","sources":["../src/keycloak.interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,6 @@
1
+ import { DynamicModule } from "@nestjs/common";
2
+ import type { AxiosRequestConfig, AxiosInstance } from "axios";
3
+ import { KeycloakConfig } from "./keycloak.interface";
4
+ export declare class KeycloakModule {
5
+ static forRoot(config: KeycloakConfig, httpConfig?: AxiosRequestConfig | AxiosInstance): DynamicModule;
6
+ }
@@ -0,0 +1,63 @@
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 KeycloakModule_1;
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.KeycloakModule = void 0;
11
+ const common_1 = require("@nestjs/common");
12
+ const core_1 = require("@nestjs/core");
13
+ const http_client_1 = require("@adatechnology/http-client");
14
+ const logger_1 = require("@adatechnology/logger");
15
+ const keycloak_client_1 = require("./keycloak.client");
16
+ const keycloak_http_interceptor_1 = require("./keycloak.http.interceptor");
17
+ const roles_guard_1 = require("./roles.guard");
18
+ const keycloak_token_1 = require("./keycloak.token");
19
+ const keycloak_token_2 = require("./keycloak.token");
20
+ let KeycloakModule = KeycloakModule_1 = class KeycloakModule {
21
+ static forRoot(config, httpConfig) {
22
+ return {
23
+ module: KeycloakModule_1,
24
+ global: true,
25
+ imports: [
26
+ http_client_1.HttpModule.forRoot(httpConfig || { baseURL: config.baseUrl, timeout: 5000 }, {
27
+ logging: {
28
+ enabled: true,
29
+ includeBody: true,
30
+ context: "KeycloakHttpClient",
31
+ environments: ["development", "test"],
32
+ },
33
+ }),
34
+ ],
35
+ providers: [
36
+ { provide: core_1.Reflector, useClass: core_1.Reflector },
37
+ { provide: keycloak_token_2.KEYCLOAK_CONFIG, useValue: config },
38
+ {
39
+ provide: keycloak_token_1.KEYCLOAK_CLIENT,
40
+ useFactory: (cfg, httpProvider, logger) => new keycloak_client_1.KeycloakClient(cfg, httpProvider, logger),
41
+ inject: [keycloak_token_2.KEYCLOAK_CONFIG, http_client_1.HTTP_PROVIDER, { token: logger_1.LOGGER_PROVIDER, optional: true }],
42
+ },
43
+ {
44
+ provide: keycloak_token_1.KEYCLOAK_HTTP_INTERCEPTOR,
45
+ useFactory: () => new keycloak_http_interceptor_1.KeycloakHttpInterceptor(),
46
+ },
47
+ roles_guard_1.RolesGuard,
48
+ ],
49
+ exports: [
50
+ core_1.Reflector,
51
+ keycloak_token_1.KEYCLOAK_CLIENT,
52
+ keycloak_token_1.KEYCLOAK_HTTP_INTERCEPTOR,
53
+ keycloak_token_2.KEYCLOAK_CONFIG,
54
+ roles_guard_1.RolesGuard,
55
+ ],
56
+ };
57
+ }
58
+ };
59
+ exports.KeycloakModule = KeycloakModule;
60
+ exports.KeycloakModule = KeycloakModule = KeycloakModule_1 = __decorate([
61
+ (0, common_1.Module)({})
62
+ ], KeycloakModule);
63
+ //# sourceMappingURL=keycloak.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keycloak.module.js","sourceRoot":"","sources":["../src/keycloak.module.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAAuD;AACvD,uCAAyC;AACzC,4DAAuE;AAEvE,kDAAwD;AAIxD,uDAAmD;AACnD,2EAAsE;AACtE,+CAA2C;AAC3C,qDAA8E;AAE9E,qDAAmD;AAG5C,IAAM,cAAc,sBAApB,MAAM,cAAc;IACzB,MAAM,CAAC,OAAO,CACZ,MAAsB,EACtB,UAA+C;QAE/C,OAAO;YACL,MAAM,EAAE,gBAAc;YACtB,MAAM,EAAE,IAAI;YACZ,OAAO,EAAE;gBACP,wBAAU,CAAC,OAAO,CAChB,UAAU,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,EACxD;oBACE,OAAO,EAAE;wBACP,OAAO,EAAE,IAAI;wBACb,WAAW,EAAE,IAAI;wBACjB,OAAO,EAAE,oBAAoB;wBAC7B,YAAY,EAAE,CAAC,aAAa,EAAE,MAAM,CAAC;qBACtC;iBACF,CACF;aACF;YACD,SAAS,EAAE;gBACT,EAAE,OAAO,EAAE,gBAAS,EAAE,QAAQ,EAAE,gBAAS,EAAE;gBAC3C,EAAE,OAAO,EAAE,gCAAe,EAAE,QAAQ,EAAE,MAAM,EAAE;gBAC9C;oBACE,OAAO,EAAE,gCAAe;oBACxB,UAAU,EAAE,CACV,GAAmB,EACnB,YAAmC,EACnC,MAAgC,EAChC,EAAE,CAAC,IAAI,gCAAc,CAAC,GAAG,EAAE,YAAY,EAAE,MAAM,CAAC;oBAClD,MAAM,EAAE,CAAC,gCAAe,EAAE,2BAAa,EAAE,EAAE,KAAK,EAAE,wBAAe,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;iBACrF;gBACD;oBACE,OAAO,EAAE,0CAAyB;oBAClC,UAAU,EAAE,GAAG,EAAE,CAAC,IAAI,mDAAuB,EAAE;iBAChD;gBACD,wBAAU;aACX;YACD,OAAO,EAAE;gBACP,gBAAS;gBACT,gCAAe;gBACf,0CAAyB;gBACzB,gCAAe;gBACf,wBAAU;aACX;SACF,CAAC;IACJ,CAAC;CACF,CAAA;AAhDY,wCAAc;yBAAd,cAAc;IAD1B,IAAA,eAAM,EAAC,EAAE,CAAC;GACE,cAAc,CAgD1B"}
@@ -0,0 +1,3 @@
1
+ export declare const KEYCLOAK_CONFIG = "KEYCLOAK_CONFIG";
2
+ export declare const KEYCLOAK_CLIENT = "KEYCLOAK_CLIENT";
3
+ export declare const KEYCLOAK_HTTP_INTERCEPTOR = "KEYCLOAK_HTTP_INTERCEPTOR";
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.KEYCLOAK_HTTP_INTERCEPTOR = exports.KEYCLOAK_CLIENT = exports.KEYCLOAK_CONFIG = void 0;
4
+ exports.KEYCLOAK_CONFIG = 'KEYCLOAK_CONFIG';
5
+ exports.KEYCLOAK_CLIENT = 'KEYCLOAK_CLIENT';
6
+ exports.KEYCLOAK_HTTP_INTERCEPTOR = 'KEYCLOAK_HTTP_INTERCEPTOR';
7
+ //# sourceMappingURL=keycloak.token.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keycloak.token.js","sourceRoot":"","sources":["../src/keycloak.token.ts"],"names":[],"mappings":";;;AAAa,QAAA,eAAe,GAAG,iBAAiB,CAAC;AACpC,QAAA,eAAe,GAAG,iBAAiB,CAAC;AACpC,QAAA,yBAAyB,GAAG,2BAA2B,CAAC"}
@@ -0,0 +1,19 @@
1
+ export declare const ROLES_META_KEY = "roles";
2
+ export type RolesMode = "any" | "all";
3
+ export type RolesType = "realm" | "client" | "both";
4
+ export type RolesOptions = {
5
+ roles: string[];
6
+ mode?: RolesMode;
7
+ type?: RolesType;
8
+ };
9
+ /**
10
+ * Decorator to declare required roles for a route or controller.
11
+ * Accepts either a list of strings or a single options object.
12
+ * Examples:
13
+ * @Roles('admin')
14
+ * @Roles('admin','editor')
15
+ * @Roles(['admin','editor'])
16
+ * @Roles({ roles: ['a','b'], mode: 'all', type: 'client' })
17
+ */
18
+ export declare function Roles(...args: Array<string | string[] | RolesOptions>): import("@nestjs/common").CustomDecorator<string>;
19
+ export default Roles;
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ROLES_META_KEY = void 0;
4
+ exports.Roles = Roles;
5
+ const common_1 = require("@nestjs/common");
6
+ exports.ROLES_META_KEY = "roles";
7
+ /**
8
+ * Decorator to declare required roles for a route or controller.
9
+ * Accepts either a list of strings or a single options object.
10
+ * Examples:
11
+ * @Roles('admin')
12
+ * @Roles('admin','editor')
13
+ * @Roles(['admin','editor'])
14
+ * @Roles({ roles: ['a','b'], mode: 'all', type: 'client' })
15
+ */
16
+ function Roles(...args) {
17
+ let payload;
18
+ if (args.length === 1 &&
19
+ typeof args[0] === "object" &&
20
+ !Array.isArray(args[0])) {
21
+ payload = args[0];
22
+ }
23
+ else {
24
+ // flatten strings/arrays into roles array
25
+ const roles = [].concat(...args.map((a) => (Array.isArray(a) ? a : String(a))));
26
+ payload = { roles };
27
+ }
28
+ // defaults
29
+ payload.mode = payload.mode ?? "any";
30
+ payload.type = payload.type ?? "both";
31
+ return (0, common_1.SetMetadata)(exports.ROLES_META_KEY, payload);
32
+ }
33
+ exports.default = Roles;
34
+ //# sourceMappingURL=roles.decorator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"roles.decorator.js","sourceRoot":"","sources":["../src/roles.decorator.ts"],"names":[],"mappings":";;;AAsBA,sBAsBC;AA5CD,2CAA6C;AAEhC,QAAA,cAAc,GAAG,OAAO,CAAC;AAWtC;;;;;;;;GAQG;AACH,SAAgB,KAAK,CAAC,GAAG,IAA6C;IACpE,IAAI,OAAqB,CAAC;IAE1B,IACE,IAAI,CAAC,MAAM,KAAK,CAAC;QACjB,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ;QAC3B,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EACvB,CAAC;QACD,OAAO,GAAG,IAAI,CAAC,CAAC,CAAiB,CAAC;IACpC,CAAC;SAAM,CAAC;QACN,0CAA0C;QAC1C,MAAM,KAAK,GAAc,EAAe,CAAC,MAAM,CAC7C,GAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAc,CACrE,CAAC;QACF,OAAO,GAAG,EAAE,KAAK,EAAE,CAAC;IACtB,CAAC;IAED,WAAW;IACX,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,KAAK,CAAC;IACrC,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,MAAM,CAAC;IAEtC,OAAO,IAAA,oBAAW,EAAC,sBAAc,EAAE,OAAO,CAAC,CAAC;AAC9C,CAAC;AAED,kBAAe,KAAK,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { CanActivate, ExecutionContext } from "@nestjs/common";
2
+ import { Reflector } from "@nestjs/core";
3
+ import type { KeycloakConfig } from "./keycloak.interface";
4
+ export declare class RolesGuard implements CanActivate {
5
+ private readonly reflector;
6
+ private readonly config?;
7
+ constructor(reflector: Reflector, config?: KeycloakConfig);
8
+ canActivate(context: ExecutionContext): boolean | Promise<boolean>;
9
+ private decodeJwtPayload;
10
+ }