@adatechnology/auth-keycloak 0.0.8 → 0.1.0

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 CHANGED
@@ -10,7 +10,8 @@ e um interceptor opcional. O módulo foi projetado para ser usado junto ao `@ada
10
10
  - `KeycloakModule` — módulo principal. Suporta `KeycloakModule.forRoot(config?)`.
11
11
  - `KEYCLOAK_CLIENT` — provider token para injetar o cliente Keycloak (`@Inject(KEYCLOAK_CLIENT)`).
12
12
  - `KEYCLOAK_HTTP_INTERCEPTOR` — provider token para injetar o interceptor (opcional).
13
- - `Roles` / `RolesGuard` decorator e guard para autorização baseada em roles.
13
+ - `BearerTokenGuard` guard que valida o token Bearer via introspecção no Keycloak (401 em falha).
14
+ - `Roles` / `RolesGuard` — decorator e guard para autorização baseada em roles (403 em falha).
14
15
  - `KeycloakError` — classe de erro tipada com `statusCode` e `details`.
15
16
 
16
17
  ### Instalação
@@ -128,6 +129,35 @@ Resultado no log:
128
129
  [MyController.getToken][InMemoryCacheProvider.set] → token cached
129
130
  ```
130
131
 
132
+ ### BearerTokenGuard — autenticação B2B via introspecção
133
+
134
+ Valida que o header `Authorization: Bearer <token>` contém um token ativo chamando
135
+ `POST /token/introspect` no Keycloak. Use sempre em conjunto com `RolesGuard` em rotas B2B.
136
+
137
+ ```ts
138
+ import { Controller, Headers, Post, UseGuards } from "@nestjs/common";
139
+ import { BearerTokenGuard, Roles, RolesGuard } from "@adatechnology/auth-keycloak";
140
+
141
+ @Controller("orders")
142
+ export class OrdersController {
143
+ @Post()
144
+ @Roles("manage-requests")
145
+ @UseGuards(BearerTokenGuard, RolesGuard)
146
+ create(@Headers("x-user-id") keycloakId: string) {}
147
+ }
148
+ ```
149
+
150
+ **Por que dois guards em sequência?**
151
+
152
+ | Guard | Mecanismo | HTTP? | Falha |
153
+ |---|---|---|---|
154
+ | `BearerTokenGuard` | `POST /token/introspect` ao Keycloak | Sim | 401 — token inativo/expirado/forjado |
155
+ | `RolesGuard` | Decode local do payload JWT | Não | 403 — permissão insuficiente |
156
+
157
+ O `RolesGuard` sozinho **não é seguro** para autenticação: ele apenas decodifica o payload JWT
158
+ sem verificar a assinatura, o que significa que um token forjado passaria. O `BearerTokenGuard`
159
+ é quem garante autenticidade via introspecção.
160
+
131
161
  ### Autorização com @Roles
132
162
 
133
163
  ```ts
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import * as _nestjs_common from '@nestjs/common';
2
2
  import { DynamicModule, CanActivate, ExecutionContext } from '@nestjs/common';
3
3
  import { AxiosRequestConfig, AxiosInstance } from 'axios';
4
+ import { LoggerProviderInterface } from '@adatechnology/logger';
4
5
  import { Reflector } from '@nestjs/core';
5
6
 
6
7
  /**
@@ -87,6 +88,32 @@ declare class KeycloakModule {
87
88
  static forRoot(config: KeycloakConfig, httpConfig?: AxiosRequestConfig | AxiosInstance): DynamicModule;
88
89
  }
89
90
 
91
+ /**
92
+ * Guard that validates the Bearer token in the Authorization header via
93
+ * Keycloak token introspection (POST /token/introspect).
94
+ *
95
+ * Use together with RolesGuard for B2B (service-to-service) routes that trust
96
+ * an X-User-Id header injected by an upstream authenticated service:
97
+ *
98
+ * @example
99
+ * ```ts
100
+ * @Roles('manage-requests')
101
+ * @UseGuards(BearerTokenGuard, RolesGuard)
102
+ * async create(@Headers('x-user-id') keycloakId: string) {}
103
+ * ```
104
+ *
105
+ * Execution order:
106
+ * 1. BearerTokenGuard — validates token is active (HTTP → Keycloak) → 401 on failure
107
+ * 2. RolesGuard — checks roles from decoded JWT payload (local) → 403 on failure
108
+ */
109
+ declare class BearerTokenGuard implements CanActivate {
110
+ private readonly keycloakClient?;
111
+ private readonly logger?;
112
+ constructor(keycloakClient?: KeycloakClientInterface, logger?: LoggerProviderInterface);
113
+ private log;
114
+ canActivate(context: ExecutionContext): Promise<boolean>;
115
+ }
116
+
90
117
  declare const KEYCLOAK_CONFIG = "KEYCLOAK_CONFIG";
91
118
  declare const KEYCLOAK_CLIENT = "KEYCLOAK_CLIENT";
92
119
  declare const KEYCLOAK_HTTP_INTERCEPTOR = "KEYCLOAK_HTTP_INTERCEPTOR";
@@ -129,4 +156,4 @@ declare class KeycloakError extends Error {
129
156
  });
130
157
  }
131
158
 
132
- export { KEYCLOAK_CLIENT, KEYCLOAK_CONFIG, KEYCLOAK_HTTP_INTERCEPTOR, KEYCLOAK_PROVIDER, type KeycloakClientInterface, type KeycloakConfig, KeycloakError, KeycloakModule, type KeycloakProviderInterface, type KeycloakTokenResponse, Roles, RolesGuard };
159
+ export { BearerTokenGuard, KEYCLOAK_CLIENT, KEYCLOAK_CONFIG, KEYCLOAK_HTTP_INTERCEPTOR, KEYCLOAK_PROVIDER, type KeycloakClientInterface, type KeycloakConfig, KeycloakError, KeycloakModule, type KeycloakProviderInterface, type KeycloakTokenResponse, Roles, RolesGuard };
package/dist/index.js CHANGED
@@ -68,7 +68,7 @@ var require_base_app_error = __commonJS({
68
68
  "use strict";
69
69
  Object.defineProperty(exports2, "__esModule", { value: true });
70
70
  exports2.BaseAppError = void 0;
71
- var BaseAppError2 = class extends Error {
71
+ var BaseAppError3 = class extends Error {
72
72
  code;
73
73
  status;
74
74
  context;
@@ -83,7 +83,7 @@ var require_base_app_error = __commonJS({
83
83
  (_a = capturable.captureStackTrace) == null ? void 0 : _a.call(capturable, this, this.constructor);
84
84
  }
85
85
  };
86
- exports2.BaseAppError = BaseAppError2;
86
+ exports2.BaseAppError = BaseAppError3;
87
87
  }
88
88
  });
89
89
 
@@ -268,6 +268,7 @@ var require_dist = __commonJS({
268
268
  // src/index.ts
269
269
  var index_exports = {};
270
270
  __export(index_exports, {
271
+ BearerTokenGuard: () => BearerTokenGuard,
271
272
  KEYCLOAK_CLIENT: () => KEYCLOAK_CLIENT,
272
273
  KEYCLOAK_CONFIG: () => KEYCLOAK_CONFIG,
273
274
  KEYCLOAK_HTTP_INTERCEPTOR: () => KEYCLOAK_HTTP_INTERCEPTOR,
@@ -280,16 +281,174 @@ __export(index_exports, {
280
281
  module.exports = __toCommonJS(index_exports);
281
282
 
282
283
  // src/keycloak.module.ts
283
- var import_common5 = require("@nestjs/common");
284
+ var import_common6 = require("@nestjs/common");
284
285
  var import_core2 = require("@nestjs/core");
285
- var import_http_client2 = require("@adatechnology/http-client");
286
- var import_logger2 = require("@adatechnology/logger");
286
+ var import_http_client3 = require("@adatechnology/http-client");
287
+ var import_logger3 = require("@adatechnology/logger");
287
288
  var import_cache3 = require("@adatechnology/cache");
288
289
 
289
- // src/keycloak.client.ts
290
+ // src/bearer-token.guard.ts
290
291
  var import_common = require("@nestjs/common");
291
- var import_http_client = require("@adatechnology/http-client");
292
292
  var import_logger = require("@adatechnology/logger");
293
+ var import_http_client = require("@adatechnology/http-client");
294
+ var import_shared = __toESM(require_dist());
295
+
296
+ // src/keycloak.token.ts
297
+ var KEYCLOAK_CONFIG = "KEYCLOAK_CONFIG";
298
+ var KEYCLOAK_CLIENT = "KEYCLOAK_CLIENT";
299
+ var KEYCLOAK_HTTP_INTERCEPTOR = "KEYCLOAK_HTTP_INTERCEPTOR";
300
+ var KEYCLOAK_PROVIDER = "KEYCLOAK_PROVIDER";
301
+
302
+ // package.json
303
+ var package_default = {
304
+ name: "@adatechnology/auth-keycloak",
305
+ version: "0.1.0",
306
+ publishConfig: {
307
+ access: "public"
308
+ },
309
+ main: "dist/index.js",
310
+ module: "dist/index.mjs",
311
+ types: "dist/index.d.ts",
312
+ files: [
313
+ "dist"
314
+ ],
315
+ scripts: {
316
+ build: "rm -rf dist && tsup",
317
+ "build:watch": "tsup --watch",
318
+ check: "tsc -p tsconfig.json --noEmit",
319
+ test: 'echo "no tests"'
320
+ },
321
+ dependencies: {
322
+ "@adatechnology/cache": "workspace:*",
323
+ "@adatechnology/http-client": "workspace:*",
324
+ "@adatechnology/logger": "workspace:*"
325
+ },
326
+ peerDependencies: {
327
+ "@nestjs/common": "^11.0.16",
328
+ "@nestjs/core": "^11"
329
+ },
330
+ devDependencies: {
331
+ "@adatechnology/shared": "workspace:*",
332
+ "@esbuild-plugins/tsconfig-paths": "^0.1.2",
333
+ tsup: "^8.5.1",
334
+ typescript: "^5.2.0"
335
+ }
336
+ };
337
+
338
+ // src/keycloak.constants.ts
339
+ var LIB_NAME = package_default.name;
340
+ var LIB_VERSION = package_default.version;
341
+ var TOKEN_CACHE_KEY = "keycloak:access_token";
342
+ var LOG_CONTEXT = {
343
+ KEYCLOAK_CLIENT: "KeycloakClient",
344
+ BEARER_TOKEN_GUARD: "BearerTokenGuard"
345
+ };
346
+ var HTTP_STATUS = {
347
+ UNAUTHORIZED: 401,
348
+ FORBIDDEN: 403
349
+ };
350
+ var BEARER_ERROR_CODE = {
351
+ MISSING_TOKEN: "UNAUTHORIZED_MISSING_TOKEN",
352
+ KEYCLOAK_NOT_CONFIGURED: "UNAUTHORIZED_KEYCLOAK_NOT_CONFIGURED",
353
+ TOKEN_VALIDATION_FAILED: "UNAUTHORIZED_TOKEN_VALIDATION_FAILED",
354
+ INACTIVE_TOKEN: "UNAUTHORIZED_INACTIVE_TOKEN"
355
+ };
356
+ var ROLES_ERROR_CODE = {
357
+ MISSING_TOKEN: "FORBIDDEN_MISSING_TOKEN",
358
+ INSUFFICIENT_ROLES: "FORBIDDEN_INSUFFICIENT_ROLES"
359
+ };
360
+
361
+ // src/bearer-token.guard.ts
362
+ var BearerTokenGuard = class {
363
+ constructor(keycloakClient, logger) {
364
+ this.keycloakClient = keycloakClient;
365
+ this.logger = logger;
366
+ }
367
+ log(level, message, libMethod, meta) {
368
+ if (!this.logger) return;
369
+ const loggerCtx = (0, import_logger.getContext)();
370
+ const httpCtx = (0, import_http_client.getHttpRequestContext)();
371
+ const logContext = loggerCtx == null ? void 0 : loggerCtx.logContext;
372
+ const requestId = (loggerCtx == null ? void 0 : loggerCtx.requestId) ?? (httpCtx == null ? void 0 : httpCtx.requestId);
373
+ const source = (logContext == null ? void 0 : logContext.className) && (logContext == null ? void 0 : logContext.methodName) ? `${logContext.className}.${logContext.methodName}` : (httpCtx == null ? void 0 : httpCtx.className) && (httpCtx == null ? void 0 : httpCtx.methodName) ? `${httpCtx.className}.${httpCtx.methodName}` : void 0;
374
+ const payload = {
375
+ message,
376
+ context: LOG_CONTEXT.BEARER_TOKEN_GUARD,
377
+ lib: LIB_NAME,
378
+ libVersion: LIB_VERSION,
379
+ libMethod,
380
+ source,
381
+ requestId,
382
+ meta
383
+ };
384
+ if (level === "debug") this.logger.debug(payload);
385
+ else if (level === "info") this.logger.info(payload);
386
+ else if (level === "warn") this.logger.warn(payload);
387
+ else if (level === "error") this.logger.error(payload);
388
+ }
389
+ async canActivate(context) {
390
+ var _a, _b;
391
+ const method = "canActivate";
392
+ this.log("debug", `${method} - Start`, method);
393
+ const request = context.switchToHttp().getRequest();
394
+ const authorization = ((_a = request.headers) == null ? void 0 : _a.authorization) ?? ((_b = request.headers) == null ? void 0 : _b.Authorization);
395
+ if (!(authorization == null ? void 0 : authorization.startsWith("Bearer "))) {
396
+ this.log("warn", `${method} - Missing or invalid Authorization header`, method);
397
+ throw new import_shared.BaseAppError({
398
+ message: "Missing or invalid Authorization header",
399
+ status: HTTP_STATUS.UNAUTHORIZED,
400
+ code: BEARER_ERROR_CODE.MISSING_TOKEN,
401
+ context: {}
402
+ });
403
+ }
404
+ if (!this.keycloakClient) {
405
+ this.log("error", `${method} - Keycloak client not configured`, method);
406
+ throw new import_shared.BaseAppError({
407
+ message: "Keycloak client not configured",
408
+ status: HTTP_STATUS.UNAUTHORIZED,
409
+ code: BEARER_ERROR_CODE.KEYCLOAK_NOT_CONFIGURED,
410
+ context: {}
411
+ });
412
+ }
413
+ const token = authorization.slice(7);
414
+ let isValid;
415
+ try {
416
+ isValid = await this.keycloakClient.validateToken(token);
417
+ } catch (err) {
418
+ const detail = err instanceof Error ? err.message : String(err);
419
+ this.log("error", `${method} - Token validation failed`, method, { detail });
420
+ throw new import_shared.BaseAppError({
421
+ message: "Token validation failed",
422
+ status: HTTP_STATUS.UNAUTHORIZED,
423
+ code: BEARER_ERROR_CODE.TOKEN_VALIDATION_FAILED,
424
+ context: { detail }
425
+ });
426
+ }
427
+ if (!isValid) {
428
+ this.log("warn", `${method} - Inactive or expired token`, method);
429
+ throw new import_shared.BaseAppError({
430
+ message: "Inactive or expired token",
431
+ status: HTTP_STATUS.UNAUTHORIZED,
432
+ code: BEARER_ERROR_CODE.INACTIVE_TOKEN,
433
+ context: {}
434
+ });
435
+ }
436
+ this.log("debug", `${method} - Token valid`, method);
437
+ return true;
438
+ }
439
+ };
440
+ BearerTokenGuard = __decorateClass([
441
+ (0, import_common.Injectable)(),
442
+ __decorateParam(0, (0, import_common.Optional)()),
443
+ __decorateParam(0, (0, import_common.Inject)(KEYCLOAK_CLIENT)),
444
+ __decorateParam(1, (0, import_common.Optional)()),
445
+ __decorateParam(1, (0, import_common.Inject)(import_logger.LOGGER_PROVIDER))
446
+ ], BearerTokenGuard);
447
+
448
+ // src/keycloak.client.ts
449
+ var import_common2 = require("@nestjs/common");
450
+ var import_http_client2 = require("@adatechnology/http-client");
451
+ var import_logger2 = require("@adatechnology/logger");
293
452
  var import_cache = require("@adatechnology/cache");
294
453
  var import_cache2 = require("@adatechnology/cache");
295
454
 
@@ -309,9 +468,6 @@ var KeycloakError = class _KeycloakError extends Error {
309
468
  };
310
469
 
311
470
  // src/keycloak.client.ts
312
- var LIB_NAME = "@adatechnology/auth-keycloak";
313
- var LIB_VERSION = "0.0.7";
314
- var TOKEN_CACHE_KEY = "keycloak:access_token";
315
471
  function extractErrorInfo(err) {
316
472
  var _a, _b, _c, _d, _e;
317
473
  const statusCode = (err == null ? void 0 : err.status) ?? ((_a = err == null ? void 0 : err.response) == null ? void 0 : _a.status);
@@ -347,14 +503,14 @@ var KeycloakClient = class {
347
503
  tokenPromise = null;
348
504
  log(level, message, libMethod, meta) {
349
505
  if (!this.logger) return;
350
- const loggerCtx = (0, import_logger.getContext)();
351
- const httpCtx = (0, import_http_client.getHttpRequestContext)();
506
+ const loggerCtx = (0, import_logger2.getContext)();
507
+ const httpCtx = (0, import_http_client2.getHttpRequestContext)();
352
508
  const logContext = loggerCtx == null ? void 0 : loggerCtx.logContext;
353
509
  const requestId = (loggerCtx == null ? void 0 : loggerCtx.requestId) ?? (httpCtx == null ? void 0 : httpCtx.requestId);
354
510
  const source = (logContext == null ? void 0 : logContext.className) && (logContext == null ? void 0 : logContext.methodName) ? `${logContext.className}.${logContext.methodName}` : (httpCtx == null ? void 0 : httpCtx.className) && (httpCtx == null ? void 0 : httpCtx.methodName) ? `${httpCtx.className}.${httpCtx.methodName}` : void 0;
355
511
  const payload = {
356
512
  message,
357
- context: "KeycloakClient",
513
+ context: LOG_CONTEXT.KEYCLOAK_CLIENT,
358
514
  lib: LIB_NAME,
359
515
  libVersion: LIB_VERSION,
360
516
  libMethod,
@@ -413,7 +569,7 @@ var KeycloakClient = class {
413
569
  data: body,
414
570
  config: {
415
571
  headers: { "Content-Type": "application/x-www-form-urlencoded" },
416
- logContext: { className: "KeycloakClient", methodName: method }
572
+ logContext: { className: LOG_CONTEXT.KEYCLOAK_CLIENT, methodName: method }
417
573
  }
418
574
  });
419
575
  this.log("info", `${method} - Success for user: ${username}`, method);
@@ -451,7 +607,7 @@ var KeycloakClient = class {
451
607
  data,
452
608
  config: {
453
609
  headers: { "Content-Type": "application/x-www-form-urlencoded" },
454
- logContext: { className: "KeycloakClient", methodName: method }
610
+ logContext: { className: LOG_CONTEXT.KEYCLOAK_CLIENT, methodName: method }
455
611
  }
456
612
  });
457
613
  this.log("debug", `${method} - Success`, method);
@@ -483,7 +639,7 @@ var KeycloakClient = class {
483
639
  data,
484
640
  config: {
485
641
  headers: { "Content-Type": "application/x-www-form-urlencoded" },
486
- logContext: { className: "KeycloakClient", methodName: method }
642
+ logContext: { className: LOG_CONTEXT.KEYCLOAK_CLIENT, methodName: method }
487
643
  }
488
644
  });
489
645
  const ttlSeconds = this.config.tokenCacheTtl ? Math.floor(this.config.tokenCacheTtl / 1e3) : response.data.expires_in - 60;
@@ -517,7 +673,7 @@ var KeycloakClient = class {
517
673
  data,
518
674
  config: {
519
675
  headers: { "Content-Type": "application/x-www-form-urlencoded" },
520
- logContext: { className: "KeycloakClient", methodName: method }
676
+ logContext: { className: LOG_CONTEXT.KEYCLOAK_CLIENT, methodName: method }
521
677
  }
522
678
  });
523
679
  const active = ((_a = response.data) == null ? void 0 : _a.active) === true;
@@ -542,7 +698,7 @@ var KeycloakClient = class {
542
698
  url: userInfoUrl,
543
699
  config: {
544
700
  headers: { Authorization: `Bearer ${token}` },
545
- logContext: { className: "KeycloakClient", methodName: method }
701
+ logContext: { className: LOG_CONTEXT.KEYCLOAK_CLIENT, methodName: method }
546
702
  }
547
703
  });
548
704
  this.log("debug", `${method} - Success`, method);
@@ -566,16 +722,16 @@ var KeycloakClient = class {
566
722
  }
567
723
  };
568
724
  KeycloakClient = __decorateClass([
569
- (0, import_common.Injectable)(),
570
- __decorateParam(1, (0, import_common.Inject)(import_http_client.HTTP_PROVIDER)),
571
- __decorateParam(2, (0, import_common.Optional)()),
572
- __decorateParam(2, (0, import_common.Inject)(import_logger.LOGGER_PROVIDER)),
573
- __decorateParam(3, (0, import_common.Optional)()),
574
- __decorateParam(3, (0, import_common.Inject)(import_cache2.CACHE_PROVIDER))
725
+ (0, import_common2.Injectable)(),
726
+ __decorateParam(1, (0, import_common2.Inject)(import_http_client2.HTTP_PROVIDER)),
727
+ __decorateParam(2, (0, import_common2.Optional)()),
728
+ __decorateParam(2, (0, import_common2.Inject)(import_logger2.LOGGER_PROVIDER)),
729
+ __decorateParam(3, (0, import_common2.Optional)()),
730
+ __decorateParam(3, (0, import_common2.Inject)(import_cache2.CACHE_PROVIDER))
575
731
  ], KeycloakClient);
576
732
 
577
733
  // src/keycloak.http.interceptor.ts
578
- var import_common2 = require("@nestjs/common");
734
+ var import_common3 = require("@nestjs/common");
579
735
  var KeycloakHttpInterceptor = class {
580
736
  constructor() {
581
737
  }
@@ -587,15 +743,15 @@ var KeycloakHttpInterceptor = class {
587
743
  }
588
744
  };
589
745
  KeycloakHttpInterceptor = __decorateClass([
590
- (0, import_common2.Injectable)()
746
+ (0, import_common3.Injectable)()
591
747
  ], KeycloakHttpInterceptor);
592
748
 
593
749
  // src/roles.guard.ts
594
- var import_common4 = require("@nestjs/common");
750
+ var import_common5 = require("@nestjs/common");
595
751
  var import_core = require("@nestjs/core");
596
752
 
597
753
  // src/roles.decorator.ts
598
- var import_common3 = require("@nestjs/common");
754
+ var import_common4 = require("@nestjs/common");
599
755
  var ROLES_META_KEY = "roles";
600
756
  function Roles(...args) {
601
757
  let payload;
@@ -609,17 +765,11 @@ function Roles(...args) {
609
765
  }
610
766
  payload.mode = payload.mode ?? "any";
611
767
  payload.type = payload.type ?? "both";
612
- return (0, import_common3.SetMetadata)(ROLES_META_KEY, payload);
768
+ return (0, import_common4.SetMetadata)(ROLES_META_KEY, payload);
613
769
  }
614
770
 
615
- // src/keycloak.token.ts
616
- var KEYCLOAK_CONFIG = "KEYCLOAK_CONFIG";
617
- var KEYCLOAK_CLIENT = "KEYCLOAK_CLIENT";
618
- var KEYCLOAK_HTTP_INTERCEPTOR = "KEYCLOAK_HTTP_INTERCEPTOR";
619
- var KEYCLOAK_PROVIDER = "KEYCLOAK_PROVIDER";
620
-
621
771
  // src/roles.guard.ts
622
- var import_shared = __toESM(require_dist());
772
+ var import_shared2 = __toESM(require_dist());
623
773
  var RolesGuard = class {
624
774
  constructor(reflector, config) {
625
775
  this.reflector = reflector;
@@ -633,10 +783,10 @@ var RolesGuard = class {
633
783
  const authHeader = ((_a = req.headers) == null ? void 0 : _a.authorization) || ((_b = req.headers) == null ? void 0 : _b.Authorization);
634
784
  const token = authHeader ? String(authHeader).split(" ")[1] : (_c = req.query) == null ? void 0 : _c.token;
635
785
  if (!token)
636
- throw new import_shared.BaseAppError({
786
+ throw new import_shared2.BaseAppError({
637
787
  message: "Authorization token not provided",
638
- status: 403,
639
- code: "FORBIDDEN_MISSING_TOKEN",
788
+ status: HTTP_STATUS.FORBIDDEN,
789
+ code: ROLES_ERROR_CODE.MISSING_TOKEN,
640
790
  context: {}
641
791
  });
642
792
  const payload = this.decodeJwtPayload(token);
@@ -663,10 +813,10 @@ var RolesGuard = class {
663
813
  const hasMatch = required.map((r) => availableRoles.has(r));
664
814
  const result = meta.mode === "all" ? hasMatch.every(Boolean) : hasMatch.some(Boolean);
665
815
  if (!result)
666
- throw new import_shared.BaseAppError({
816
+ throw new import_shared2.BaseAppError({
667
817
  message: "Insufficient roles",
668
- status: 403,
669
- code: "FORBIDDEN_INSUFFICIENT_ROLES",
818
+ status: HTTP_STATUS.FORBIDDEN,
819
+ code: ROLES_ERROR_CODE.INSUFFICIENT_ROLES,
670
820
  context: { required }
671
821
  });
672
822
  return true;
@@ -686,10 +836,10 @@ var RolesGuard = class {
686
836
  }
687
837
  };
688
838
  RolesGuard = __decorateClass([
689
- (0, import_common4.Injectable)(),
690
- __decorateParam(0, (0, import_common4.Inject)(import_core.Reflector)),
691
- __decorateParam(1, (0, import_common4.Optional)()),
692
- __decorateParam(1, (0, import_common4.Inject)(KEYCLOAK_CONFIG))
839
+ (0, import_common5.Injectable)(),
840
+ __decorateParam(0, (0, import_common5.Inject)(import_core.Reflector)),
841
+ __decorateParam(1, (0, import_common5.Optional)()),
842
+ __decorateParam(1, (0, import_common5.Inject)(KEYCLOAK_CONFIG))
693
843
  ], RolesGuard);
694
844
 
695
845
  // src/keycloak.module.ts
@@ -699,7 +849,7 @@ var KeycloakModule = class {
699
849
  module: KeycloakModule,
700
850
  global: true,
701
851
  imports: [
702
- import_http_client2.HttpModule.forRoot(
852
+ import_http_client3.HttpModule.forRoot(
703
853
  httpConfig || { baseURL: config.baseUrl, timeout: 5e3 },
704
854
  {
705
855
  logging: {
@@ -719,8 +869,8 @@ var KeycloakModule = class {
719
869
  useFactory: (cfg, httpProvider, logger, cacheProvider) => new KeycloakClient(cfg, httpProvider, logger, cacheProvider),
720
870
  inject: [
721
871
  KEYCLOAK_CONFIG,
722
- import_http_client2.HTTP_PROVIDER,
723
- { token: import_logger2.LOGGER_PROVIDER, optional: true },
872
+ import_http_client3.HTTP_PROVIDER,
873
+ { token: import_logger3.LOGGER_PROVIDER, optional: true },
724
874
  { token: import_cache3.CACHE_PROVIDER, optional: true }
725
875
  ]
726
876
  },
@@ -732,7 +882,8 @@ var KeycloakModule = class {
732
882
  provide: KEYCLOAK_HTTP_INTERCEPTOR,
733
883
  useFactory: () => new KeycloakHttpInterceptor()
734
884
  },
735
- RolesGuard
885
+ RolesGuard,
886
+ BearerTokenGuard
736
887
  ],
737
888
  exports: [
738
889
  import_core2.Reflector,
@@ -740,16 +891,18 @@ var KeycloakModule = class {
740
891
  KEYCLOAK_PROVIDER,
741
892
  KEYCLOAK_HTTP_INTERCEPTOR,
742
893
  KEYCLOAK_CONFIG,
743
- RolesGuard
894
+ RolesGuard,
895
+ BearerTokenGuard
744
896
  ]
745
897
  };
746
898
  }
747
899
  };
748
900
  KeycloakModule = __decorateClass([
749
- (0, import_common5.Module)({})
901
+ (0, import_common6.Module)({})
750
902
  ], KeycloakModule);
751
903
  // Annotate the CommonJS export names for ESM import in node:
752
904
  0 && (module.exports = {
905
+ BearerTokenGuard,
753
906
  KEYCLOAK_CLIENT,
754
907
  KEYCLOAK_CONFIG,
755
908
  KEYCLOAK_HTTP_INTERCEPTOR,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adatechnology/auth-keycloak",
3
- "version": "0.0.8",
3
+ "version": "0.1.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -11,9 +11,9 @@
11
11
  "dist"
12
12
  ],
13
13
  "dependencies": {
14
- "@adatechnology/cache": "0.0.7",
15
- "@adatechnology/http-client": "0.0.8",
16
- "@adatechnology/logger": "0.0.6"
14
+ "@adatechnology/cache": "0.0.8",
15
+ "@adatechnology/http-client": "0.0.9",
16
+ "@adatechnology/logger": "0.0.7"
17
17
  },
18
18
  "peerDependencies": {
19
19
  "@nestjs/common": "^11.0.16",