@pawells/nestjs-auth 1.0.0-dev.3052c75

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 (194) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +602 -0
  3. package/build/LICENSE +21 -0
  4. package/build/README.md +602 -0
  5. package/build/admin/client/client.d.ts +82 -0
  6. package/build/admin/client/client.d.ts.map +1 -0
  7. package/build/admin/client/client.js +157 -0
  8. package/build/admin/client/client.js.map +1 -0
  9. package/build/admin/client/errors/base-error.d.ts +58 -0
  10. package/build/admin/client/errors/base-error.d.ts.map +1 -0
  11. package/build/admin/client/errors/base-error.js +100 -0
  12. package/build/admin/client/errors/base-error.js.map +1 -0
  13. package/build/admin/client/errors/index.d.ts +2 -0
  14. package/build/admin/client/errors/index.d.ts.map +1 -0
  15. package/build/admin/client/errors/index.js +2 -0
  16. package/build/admin/client/errors/index.js.map +1 -0
  17. package/build/admin/client/index.d.ts +6 -0
  18. package/build/admin/client/index.d.ts.map +1 -0
  19. package/build/admin/client/index.js +11 -0
  20. package/build/admin/client/index.js.map +1 -0
  21. package/build/admin/client/services/authentication.service.d.ts +54 -0
  22. package/build/admin/client/services/authentication.service.d.ts.map +1 -0
  23. package/build/admin/client/services/authentication.service.js +99 -0
  24. package/build/admin/client/services/authentication.service.js.map +1 -0
  25. package/build/admin/client/services/base-service.d.ts +39 -0
  26. package/build/admin/client/services/base-service.d.ts.map +1 -0
  27. package/build/admin/client/services/base-service.js +107 -0
  28. package/build/admin/client/services/base-service.js.map +1 -0
  29. package/build/admin/client/services/client.service.d.ts +86 -0
  30. package/build/admin/client/services/client.service.d.ts.map +1 -0
  31. package/build/admin/client/services/client.service.js +193 -0
  32. package/build/admin/client/services/client.service.js.map +1 -0
  33. package/build/admin/client/services/event.service.d.ts +84 -0
  34. package/build/admin/client/services/event.service.d.ts.map +1 -0
  35. package/build/admin/client/services/event.service.js +155 -0
  36. package/build/admin/client/services/event.service.js.map +1 -0
  37. package/build/admin/client/services/federated-identity.service.d.ts +89 -0
  38. package/build/admin/client/services/federated-identity.service.d.ts.map +1 -0
  39. package/build/admin/client/services/federated-identity.service.js +120 -0
  40. package/build/admin/client/services/federated-identity.service.js.map +1 -0
  41. package/build/admin/client/services/group.service.d.ts +52 -0
  42. package/build/admin/client/services/group.service.d.ts.map +1 -0
  43. package/build/admin/client/services/group.service.js +105 -0
  44. package/build/admin/client/services/group.service.js.map +1 -0
  45. package/build/admin/client/services/identity-provider.service.d.ts +47 -0
  46. package/build/admin/client/services/identity-provider.service.d.ts.map +1 -0
  47. package/build/admin/client/services/identity-provider.service.js +86 -0
  48. package/build/admin/client/services/identity-provider.service.js.map +1 -0
  49. package/build/admin/client/services/index.d.ts +11 -0
  50. package/build/admin/client/services/index.d.ts.map +1 -0
  51. package/build/admin/client/services/index.js +11 -0
  52. package/build/admin/client/services/index.js.map +1 -0
  53. package/build/admin/client/services/realm.service.d.ts +41 -0
  54. package/build/admin/client/services/realm.service.d.ts.map +1 -0
  55. package/build/admin/client/services/realm.service.js +80 -0
  56. package/build/admin/client/services/realm.service.js.map +1 -0
  57. package/build/admin/client/services/role.service.d.ts +45 -0
  58. package/build/admin/client/services/role.service.d.ts.map +1 -0
  59. package/build/admin/client/services/role.service.js +92 -0
  60. package/build/admin/client/services/role.service.js.map +1 -0
  61. package/build/admin/client/services/user.service.d.ts +84 -0
  62. package/build/admin/client/services/user.service.d.ts.map +1 -0
  63. package/build/admin/client/services/user.service.js +216 -0
  64. package/build/admin/client/services/user.service.js.map +1 -0
  65. package/build/admin/client/types/config.types.d.ts +59 -0
  66. package/build/admin/client/types/config.types.d.ts.map +1 -0
  67. package/build/admin/client/types/config.types.js +13 -0
  68. package/build/admin/client/types/config.types.js.map +1 -0
  69. package/build/admin/client/types/event.types.d.ts +176 -0
  70. package/build/admin/client/types/event.types.d.ts.map +1 -0
  71. package/build/admin/client/types/event.types.js +2 -0
  72. package/build/admin/client/types/event.types.js.map +1 -0
  73. package/build/admin/client/types/index.d.ts +4 -0
  74. package/build/admin/client/types/index.d.ts.map +1 -0
  75. package/build/admin/client/types/index.js +4 -0
  76. package/build/admin/client/types/index.js.map +1 -0
  77. package/build/admin/client/types/keycloak.types.d.ts +169 -0
  78. package/build/admin/client/types/keycloak.types.d.ts.map +1 -0
  79. package/build/admin/client/types/keycloak.types.js +2 -0
  80. package/build/admin/client/types/keycloak.types.js.map +1 -0
  81. package/build/admin/client/utils/index.d.ts +2 -0
  82. package/build/admin/client/utils/index.d.ts.map +1 -0
  83. package/build/admin/client/utils/index.js +2 -0
  84. package/build/admin/client/utils/index.js.map +1 -0
  85. package/build/admin/client/utils/retry.d.ts +40 -0
  86. package/build/admin/client/utils/retry.d.ts.map +1 -0
  87. package/build/admin/client/utils/retry.js +72 -0
  88. package/build/admin/client/utils/retry.js.map +1 -0
  89. package/build/admin/config/keycloak.config.d.ts +33 -0
  90. package/build/admin/config/keycloak.config.d.ts.map +1 -0
  91. package/build/admin/config/keycloak.config.js +2 -0
  92. package/build/admin/config/keycloak.config.js.map +1 -0
  93. package/build/admin/config/keycloak.defaults.d.ts +11 -0
  94. package/build/admin/config/keycloak.defaults.d.ts.map +1 -0
  95. package/build/admin/config/keycloak.defaults.js +60 -0
  96. package/build/admin/config/keycloak.defaults.js.map +1 -0
  97. package/build/admin/health/keycloak.health.d.ts +13 -0
  98. package/build/admin/health/keycloak.health.d.ts.map +1 -0
  99. package/build/admin/health/keycloak.health.js +54 -0
  100. package/build/admin/health/keycloak.health.js.map +1 -0
  101. package/build/admin/index.d.ts +10 -0
  102. package/build/admin/index.d.ts.map +1 -0
  103. package/build/admin/index.js +9 -0
  104. package/build/admin/index.js.map +1 -0
  105. package/build/admin/keycloak-admin.interfaces.d.ts +45 -0
  106. package/build/admin/keycloak-admin.interfaces.d.ts.map +1 -0
  107. package/build/admin/keycloak-admin.interfaces.js +2 -0
  108. package/build/admin/keycloak-admin.interfaces.js.map +1 -0
  109. package/build/admin/keycloak-admin.module.d.ts +23 -0
  110. package/build/admin/keycloak-admin.module.d.ts.map +1 -0
  111. package/build/admin/keycloak-admin.module.js +101 -0
  112. package/build/admin/keycloak-admin.module.js.map +1 -0
  113. package/build/admin/keycloak.constants.d.ts +16 -0
  114. package/build/admin/keycloak.constants.d.ts.map +1 -0
  115. package/build/admin/keycloak.constants.js +16 -0
  116. package/build/admin/keycloak.constants.js.map +1 -0
  117. package/build/admin/permissions/index.d.ts +2 -0
  118. package/build/admin/permissions/index.d.ts.map +1 -0
  119. package/build/admin/permissions/index.js +2 -0
  120. package/build/admin/permissions/index.js.map +1 -0
  121. package/build/admin/permissions/keycloak-admin.permissions.d.ts +45 -0
  122. package/build/admin/permissions/keycloak-admin.permissions.d.ts.map +1 -0
  123. package/build/admin/permissions/keycloak-admin.permissions.js +68 -0
  124. package/build/admin/permissions/keycloak-admin.permissions.js.map +1 -0
  125. package/build/admin/services/keycloak-admin.service.d.ts +64 -0
  126. package/build/admin/services/keycloak-admin.service.d.ts.map +1 -0
  127. package/build/admin/services/keycloak-admin.service.js +152 -0
  128. package/build/admin/services/keycloak-admin.service.js.map +1 -0
  129. package/build/decorators/auth-decorators.d.ts +217 -0
  130. package/build/decorators/auth-decorators.d.ts.map +1 -0
  131. package/build/decorators/auth-decorators.js +251 -0
  132. package/build/decorators/auth-decorators.js.map +1 -0
  133. package/build/decorators/context-utils.d.ts +101 -0
  134. package/build/decorators/context-utils.d.ts.map +1 -0
  135. package/build/decorators/context-utils.js +178 -0
  136. package/build/decorators/context-utils.js.map +1 -0
  137. package/build/decorators/graphql-auth-decorators.d.ts +144 -0
  138. package/build/decorators/graphql-auth-decorators.d.ts.map +1 -0
  139. package/build/decorators/graphql-auth-decorators.js +152 -0
  140. package/build/decorators/graphql-auth-decorators.js.map +1 -0
  141. package/build/decorators/index.d.ts +5 -0
  142. package/build/decorators/index.d.ts.map +1 -0
  143. package/build/decorators/index.js +4 -0
  144. package/build/decorators/index.js.map +1 -0
  145. package/build/guards/index.d.ts +4 -0
  146. package/build/guards/index.d.ts.map +1 -0
  147. package/build/guards/index.js +4 -0
  148. package/build/guards/index.js.map +1 -0
  149. package/build/guards/jwt-auth.guard.d.ts +52 -0
  150. package/build/guards/jwt-auth.guard.d.ts.map +1 -0
  151. package/build/guards/jwt-auth.guard.js +97 -0
  152. package/build/guards/jwt-auth.guard.js.map +1 -0
  153. package/build/guards/permission.guard.d.ts +37 -0
  154. package/build/guards/permission.guard.d.ts.map +1 -0
  155. package/build/guards/permission.guard.js +73 -0
  156. package/build/guards/permission.guard.js.map +1 -0
  157. package/build/guards/role.guard.d.ts +33 -0
  158. package/build/guards/role.guard.d.ts.map +1 -0
  159. package/build/guards/role.guard.js +69 -0
  160. package/build/guards/role.guard.js.map +1 -0
  161. package/build/index.d.ts +92 -0
  162. package/build/index.d.ts.map +1 -0
  163. package/build/index.js +98 -0
  164. package/build/index.js.map +1 -0
  165. package/build/keycloak/index.d.ts +7 -0
  166. package/build/keycloak/index.d.ts.map +1 -0
  167. package/build/keycloak/index.js +5 -0
  168. package/build/keycloak/index.js.map +1 -0
  169. package/build/keycloak/keycloak.constants.d.ts +2 -0
  170. package/build/keycloak/keycloak.constants.d.ts.map +1 -0
  171. package/build/keycloak/keycloak.constants.js +2 -0
  172. package/build/keycloak/keycloak.constants.js.map +1 -0
  173. package/build/keycloak/keycloak.interfaces.d.ts +12 -0
  174. package/build/keycloak/keycloak.interfaces.d.ts.map +1 -0
  175. package/build/keycloak/keycloak.interfaces.js +2 -0
  176. package/build/keycloak/keycloak.interfaces.js.map +1 -0
  177. package/build/keycloak/keycloak.module.d.ts +56 -0
  178. package/build/keycloak/keycloak.module.d.ts.map +1 -0
  179. package/build/keycloak/keycloak.module.js +104 -0
  180. package/build/keycloak/keycloak.module.js.map +1 -0
  181. package/build/keycloak/keycloak.types.d.ts +60 -0
  182. package/build/keycloak/keycloak.types.d.ts.map +1 -0
  183. package/build/keycloak/keycloak.types.js +2 -0
  184. package/build/keycloak/keycloak.types.js.map +1 -0
  185. package/build/keycloak/services/jwks-cache.service.d.ts +64 -0
  186. package/build/keycloak/services/jwks-cache.service.d.ts.map +1 -0
  187. package/build/keycloak/services/jwks-cache.service.js +176 -0
  188. package/build/keycloak/services/jwks-cache.service.js.map +1 -0
  189. package/build/keycloak/services/keycloak-token-validation.service.d.ts +88 -0
  190. package/build/keycloak/services/keycloak-token-validation.service.d.ts.map +1 -0
  191. package/build/keycloak/services/keycloak-token-validation.service.js +243 -0
  192. package/build/keycloak/services/keycloak-token-validation.service.js.map +1 -0
  193. package/build/package.json +72 -0
  194. package/package.json +93 -0
@@ -0,0 +1,52 @@
1
+ import { CanActivate, ExecutionContext } from '@nestjs/common';
2
+ import { Reflector } from '@nestjs/core';
3
+ import { KeycloakTokenValidationService } from '../keycloak/services/keycloak-token-validation.service.js';
4
+ import type { KeycloakUser, KeycloakTokenClaims } from '../keycloak/keycloak.types.js';
5
+ /**
6
+ * JWT Authentication Guard
7
+ *
8
+ * Validates Keycloak-issued JWT tokens on every request using KeycloakTokenValidationService.
9
+ * Extracts the token from the Authorization header (Bearer scheme), validates it,
10
+ * and attaches the authenticated user and claims to the request object.
11
+ *
12
+ * On successful validation, attaches:
13
+ * - `request.user` — KeycloakUser object with identity and roles
14
+ * - `request.keycloakClaims` — Raw token claims for advanced use cases
15
+ *
16
+ * Respects the `@Public()` decorator — routes marked as public bypass authentication entirely.
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * @UseGuards(JwtAuthGuard)
21
+ * @Controller('api')
22
+ * export class MyController {
23
+ * @Get('profile')
24
+ * getProfile(@CurrentUser() user: KeycloakUser) {
25
+ * // user.id, user.roles, etc.
26
+ * return user;
27
+ * }
28
+ *
29
+ * @Public()
30
+ * @Get('health')
31
+ * health() {
32
+ * // No authentication required
33
+ * return { status: 'ok' };
34
+ * }
35
+ * }
36
+ * ```
37
+ */
38
+ export declare class JwtAuthGuard implements CanActivate {
39
+ private readonly reflector;
40
+ private readonly tokenValidation;
41
+ constructor(reflector: Reflector, tokenValidation: KeycloakTokenValidationService);
42
+ canActivate(context: ExecutionContext): Promise<boolean>;
43
+ }
44
+ declare global {
45
+ namespace Express {
46
+ interface Request {
47
+ user?: KeycloakUser;
48
+ keycloakClaims?: KeycloakTokenClaims;
49
+ }
50
+ }
51
+ }
52
+ //# sourceMappingURL=jwt-auth.guard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwt-auth.guard.d.ts","sourceRoot":"","sources":["../../src/guards/jwt-auth.guard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAqC,MAAM,gBAAgB,CAAC;AAClG,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,8BAA8B,EAAE,MAAM,2DAA2D,CAAC;AAG3G,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAEvF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,qBACa,YAAa,YAAW,WAAW;IAC/C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IAEtC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAiC;gBAGhE,SAAS,EAAE,SAAS,EACpB,eAAe,EAAE,8BAA8B;IAMnC,WAAW,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;CA8CrE;AAGD,OAAO,CAAC,MAAM,CAAC;IACd,UAAU,OAAO,CAAC;QACjB,UAAU,OAAO;YAChB,IAAI,CAAC,EAAE,YAAY,CAAC;YACpB,cAAc,CAAC,EAAE,mBAAmB,CAAC;SACrC;KACD;CACD"}
@@ -0,0 +1,97 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ 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;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { Injectable, UnauthorizedException } from '@nestjs/common';
11
+ import { Reflector } from '@nestjs/core';
12
+ import { KeycloakTokenValidationService } from '../keycloak/services/keycloak-token-validation.service.js';
13
+ import { IS_PUBLIC_KEY } from '../decorators/auth-decorators.js';
14
+ import { ExtractRequestFromContext } from '../decorators/context-utils.js';
15
+ /**
16
+ * JWT Authentication Guard
17
+ *
18
+ * Validates Keycloak-issued JWT tokens on every request using KeycloakTokenValidationService.
19
+ * Extracts the token from the Authorization header (Bearer scheme), validates it,
20
+ * and attaches the authenticated user and claims to the request object.
21
+ *
22
+ * On successful validation, attaches:
23
+ * - `request.user` — KeycloakUser object with identity and roles
24
+ * - `request.keycloakClaims` — Raw token claims for advanced use cases
25
+ *
26
+ * Respects the `@Public()` decorator — routes marked as public bypass authentication entirely.
27
+ *
28
+ * @example
29
+ * ```typescript
30
+ * @UseGuards(JwtAuthGuard)
31
+ * @Controller('api')
32
+ * export class MyController {
33
+ * @Get('profile')
34
+ * getProfile(@CurrentUser() user: KeycloakUser) {
35
+ * // user.id, user.roles, etc.
36
+ * return user;
37
+ * }
38
+ *
39
+ * @Public()
40
+ * @Get('health')
41
+ * health() {
42
+ * // No authentication required
43
+ * return { status: 'ok' };
44
+ * }
45
+ * }
46
+ * ```
47
+ */
48
+ let JwtAuthGuard = class JwtAuthGuard {
49
+ reflector;
50
+ tokenValidation;
51
+ constructor(reflector, tokenValidation) {
52
+ this.reflector = reflector;
53
+ this.tokenValidation = tokenValidation;
54
+ }
55
+ async canActivate(context) {
56
+ // Check for @Public() decorator — if true, allow access without authentication
57
+ const isPublic = this.reflector.getAllAndOverride(IS_PUBLIC_KEY, [
58
+ context.getHandler(),
59
+ context.getClass(),
60
+ ]);
61
+ if (isPublic) {
62
+ return true;
63
+ }
64
+ // Extract request from context (supports HTTP, GraphQL, WebSocket)
65
+ const request = ExtractRequestFromContext(context);
66
+ // Extract token from Authorization header
67
+ const authHeader = request.headers?.authorization ?? request.headers?.Authorization;
68
+ if (!authHeader || typeof authHeader !== 'string') {
69
+ throw new UnauthorizedException('No authentication token provided');
70
+ }
71
+ // Strip "Bearer " prefix
72
+ const token = authHeader.replace(/^Bearer\s+/i, '');
73
+ if (!token) {
74
+ throw new UnauthorizedException('No authentication token provided');
75
+ }
76
+ // Validate token
77
+ const result = await this.tokenValidation.validateToken(token);
78
+ if (!result.valid) {
79
+ throw new UnauthorizedException(result.error ?? 'Invalid token');
80
+ }
81
+ // Extract user from claims and attach to request
82
+ if (!result.claims) {
83
+ throw new UnauthorizedException('Missing token claims');
84
+ }
85
+ const user = this.tokenValidation.extractUser(result.claims);
86
+ request.user = user;
87
+ request.keycloakClaims = result.claims;
88
+ return true;
89
+ }
90
+ };
91
+ JwtAuthGuard = __decorate([
92
+ Injectable(),
93
+ __metadata("design:paramtypes", [Reflector,
94
+ KeycloakTokenValidationService])
95
+ ], JwtAuthGuard);
96
+ export { JwtAuthGuard };
97
+ //# sourceMappingURL=jwt-auth.guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwt-auth.guard.js","sourceRoot":"","sources":["../../src/guards/jwt-auth.guard.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAiC,UAAU,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAClG,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,8BAA8B,EAAE,MAAM,2DAA2D,CAAC;AAC3G,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AACjE,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAG3E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEI,IAAM,YAAY,GAAlB,MAAM,YAAY;IACP,SAAS,CAAY;IAErB,eAAe,CAAiC;IAEjE,YACC,SAAoB,EACpB,eAA+C;QAE/C,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,eAAe,GAAG,eAAe,CAAC;IACxC,CAAC;IAEM,KAAK,CAAC,WAAW,CAAC,OAAyB;QACjD,+EAA+E;QAC/E,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAU,aAAa,EAAE;YACzE,OAAO,CAAC,UAAU,EAAE;YACpB,OAAO,CAAC,QAAQ,EAAE;SAClB,CAAC,CAAC;QAEH,IAAI,QAAQ,EAAE,CAAC;YACd,OAAO,IAAI,CAAC;QACb,CAAC;QAED,mEAAmE;QACnE,MAAM,OAAO,GAAG,yBAAyB,CAAC,OAAO,CAAC,CAAC;QAEnD,0CAA0C;QAC1C,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,EAAE,aAAa,IAAI,OAAO,CAAC,OAAO,EAAE,aAAa,CAAC;QAEpF,IAAI,CAAC,UAAU,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;YACnD,MAAM,IAAI,qBAAqB,CAAC,kCAAkC,CAAC,CAAC;QACrE,CAAC;QAED,yBAAyB;QACzB,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;QAEpD,IAAI,CAAC,KAAK,EAAE,CAAC;YACZ,MAAM,IAAI,qBAAqB,CAAC,kCAAkC,CAAC,CAAC;QACrE,CAAC;QAED,iBAAiB;QACjB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAE/D,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YACnB,MAAM,IAAI,qBAAqB,CAAC,MAAM,CAAC,KAAK,IAAI,eAAe,CAAC,CAAC;QAClE,CAAC;QAED,iDAAiD;QACjD,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACpB,MAAM,IAAI,qBAAqB,CAAC,sBAAsB,CAAC,CAAC;QACzD,CAAC;QAED,MAAM,IAAI,GAAiB,IAAI,CAAC,eAAe,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC3E,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;QACpB,OAAO,CAAC,cAAc,GAAG,MAAM,CAAC,MAA6B,CAAC;QAE9D,OAAO,IAAI,CAAC;IACb,CAAC;CACD,CAAA;AA3DY,YAAY;IADxB,UAAU,EAAE;qCAOA,SAAS;QACH,8BAA8B;GAPpC,YAAY,CA2DxB"}
@@ -0,0 +1,37 @@
1
+ import { CanActivate, ExecutionContext } from '@nestjs/common';
2
+ import { Reflector } from '@nestjs/core';
3
+ /**
4
+ * Permission-based Authorization Guard
5
+ *
6
+ * Authorizes access based on user permissions specified by the `@Permissions()` decorator.
7
+ * Uses roles-as-permissions semantics: checks that the authenticated user has at least one
8
+ * role whose name matches a required permission string. Permission strings are matched directly
9
+ * against Keycloak role names (both realm-level and client-specific roles are checked).
10
+ *
11
+ * Uses OR logic — access is granted if the user has ANY of the required permissions (i.e., if
12
+ * any user role name matches any required permission string).
13
+ * If no permissions are specified via `@Permissions()`, access is allowed by default.
14
+ *
15
+ * Throws `UnauthorizedException` if the user is not authenticated (missing from request).
16
+ * Throws `ForbiddenException` if the user is authenticated but lacks all required permissions.
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * @UseGuards(JwtAuthGuard, PermissionGuard)
21
+ * @Controller('data')
22
+ * export class DataController {
23
+ * @Permissions('read:data', 'write:data')
24
+ * @Get(':id')
25
+ * getData(@Param('id') id: string) {
26
+ * // User must have a role named 'read:data' OR 'write:data' (roles-as-permissions)
27
+ * return {};
28
+ * }
29
+ * }
30
+ * ```
31
+ */
32
+ export declare class PermissionGuard implements CanActivate {
33
+ private readonly reflector;
34
+ constructor(reflector: Reflector);
35
+ canActivate(context: ExecutionContext): boolean;
36
+ }
37
+ //# sourceMappingURL=permission.guard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permission.guard.d.ts","sourceRoot":"","sources":["../../src/guards/permission.guard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,WAAW,EAAE,gBAAgB,EAA6C,MAAM,gBAAgB,CAAC;AACtH,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAKzC;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,qBACa,eAAgB,YAAW,WAAW;IAClD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;gBAE1B,SAAS,EAAE,SAAS;IAIzB,WAAW,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO;CAyBtD"}
@@ -0,0 +1,73 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ 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;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { Injectable, ForbiddenException, UnauthorizedException } from '@nestjs/common';
11
+ import { Reflector } from '@nestjs/core';
12
+ import { ExtractRequestFromContext } from '../decorators/context-utils.js';
13
+ import { PERMISSIONS_KEY } from '../decorators/auth-decorators.js';
14
+ /**
15
+ * Permission-based Authorization Guard
16
+ *
17
+ * Authorizes access based on user permissions specified by the `@Permissions()` decorator.
18
+ * Uses roles-as-permissions semantics: checks that the authenticated user has at least one
19
+ * role whose name matches a required permission string. Permission strings are matched directly
20
+ * against Keycloak role names (both realm-level and client-specific roles are checked).
21
+ *
22
+ * Uses OR logic — access is granted if the user has ANY of the required permissions (i.e., if
23
+ * any user role name matches any required permission string).
24
+ * If no permissions are specified via `@Permissions()`, access is allowed by default.
25
+ *
26
+ * Throws `UnauthorizedException` if the user is not authenticated (missing from request).
27
+ * Throws `ForbiddenException` if the user is authenticated but lacks all required permissions.
28
+ *
29
+ * @example
30
+ * ```typescript
31
+ * @UseGuards(JwtAuthGuard, PermissionGuard)
32
+ * @Controller('data')
33
+ * export class DataController {
34
+ * @Permissions('read:data', 'write:data')
35
+ * @Get(':id')
36
+ * getData(@Param('id') id: string) {
37
+ * // User must have a role named 'read:data' OR 'write:data' (roles-as-permissions)
38
+ * return {};
39
+ * }
40
+ * }
41
+ * ```
42
+ */
43
+ let PermissionGuard = class PermissionGuard {
44
+ reflector;
45
+ constructor(reflector) {
46
+ this.reflector = reflector;
47
+ }
48
+ canActivate(context) {
49
+ const requiredPermissions = this.reflector.getAllAndOverride(PERMISSIONS_KEY, [context.getHandler(), context.getClass()]);
50
+ if (!requiredPermissions || requiredPermissions.length === 0) {
51
+ // No permissions required, allow access
52
+ return true;
53
+ }
54
+ const request = ExtractRequestFromContext(context);
55
+ const user = request.user;
56
+ if (!user) {
57
+ throw new UnauthorizedException('User not authenticated');
58
+ }
59
+ // Check if user has any of the required permissions in realmRoles or clientRoles
60
+ const userRoles = [...user.realmRoles, ...user.clientRoles];
61
+ const hasRequiredPermission = requiredPermissions.some(permission => userRoles.includes(permission));
62
+ if (!hasRequiredPermission) {
63
+ throw new ForbiddenException('Insufficient permissions');
64
+ }
65
+ return true;
66
+ }
67
+ };
68
+ PermissionGuard = __decorate([
69
+ Injectable(),
70
+ __metadata("design:paramtypes", [Reflector])
71
+ ], PermissionGuard);
72
+ export { PermissionGuard };
73
+ //# sourceMappingURL=permission.guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permission.guard.js","sourceRoot":"","sources":["../../src/guards/permission.guard.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,UAAU,EAAiC,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACtH,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAC3E,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAGnE;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEI,IAAM,eAAe,GAArB,MAAM,eAAe;IACV,SAAS,CAAY;IAEtC,YAAY,SAAoB;QAC/B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC5B,CAAC;IAEM,WAAW,CAAC,OAAyB;QAC3C,MAAM,mBAAmB,GAAG,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAW,eAAe,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;QAEpI,IAAI,CAAC,mBAAmB,IAAI,mBAAmB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9D,wCAAwC;YACxC,OAAO,IAAI,CAAC;QACb,CAAC;QAED,MAAM,OAAO,GAAG,yBAAyB,CAAC,OAAO,CAAC,CAAC;QACnD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAgC,CAAC;QAEtD,IAAI,CAAC,IAAI,EAAE,CAAC;YACX,MAAM,IAAI,qBAAqB,CAAC,wBAAwB,CAAC,CAAC;QAC3D,CAAC;QAED,iFAAiF;QACjF,MAAM,SAAS,GAAG,CAAC,GAAG,IAAI,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC;QAC5D,MAAM,qBAAqB,GAAG,mBAAmB,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC;QAErG,IAAI,CAAC,qBAAqB,EAAE,CAAC;YAC5B,MAAM,IAAI,kBAAkB,CAAC,0BAA0B,CAAC,CAAC;QAC1D,CAAC;QAED,OAAO,IAAI,CAAC;IACb,CAAC;CACD,CAAA;AAhCY,eAAe;IAD3B,UAAU,EAAE;qCAIW,SAAS;GAHpB,eAAe,CAgC3B"}
@@ -0,0 +1,33 @@
1
+ import { CanActivate, ExecutionContext } from '@nestjs/common';
2
+ import { Reflector } from '@nestjs/core';
3
+ /**
4
+ * Role-based Authorization Guard
5
+ *
6
+ * Authorizes access based on user roles specified by the `@Roles()` decorator.
7
+ * Checks both realm-level roles (`user.realmRoles`) and client-specific roles (`user.clientRoles`).
8
+ *
9
+ * Uses OR logic — access is granted if the user has ANY of the required roles.
10
+ * If no roles are specified via `@Roles()`, access is allowed by default.
11
+ *
12
+ * Throws `ForbiddenException` if the user lacks all required roles.
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * @UseGuards(JwtAuthGuard, RoleGuard)
17
+ * @Controller('admin')
18
+ * export class AdminController {
19
+ * @Roles('admin', 'moderator')
20
+ * @Get('users')
21
+ * listUsers() {
22
+ * // User must have 'admin' OR 'moderator' role
23
+ * return [];
24
+ * }
25
+ * }
26
+ * ```
27
+ */
28
+ export declare class RoleGuard implements CanActivate {
29
+ private readonly reflector;
30
+ constructor(reflector: Reflector);
31
+ canActivate(context: ExecutionContext): boolean;
32
+ }
33
+ //# sourceMappingURL=role.guard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"role.guard.d.ts","sourceRoot":"","sources":["../../src/guards/role.guard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,WAAW,EAAE,gBAAgB,EAA6C,MAAM,gBAAgB,CAAC;AACtH,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAKzC;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,qBACa,SAAU,YAAW,WAAW;IAC5C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;gBAE1B,SAAS,EAAE,SAAS;IAIzB,WAAW,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO;CAyBtD"}
@@ -0,0 +1,69 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ 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;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { Injectable, ForbiddenException, UnauthorizedException } from '@nestjs/common';
11
+ import { Reflector } from '@nestjs/core';
12
+ import { ExtractRequestFromContext } from '../decorators/context-utils.js';
13
+ import { ROLES_KEY } from '../decorators/auth-decorators.js';
14
+ /**
15
+ * Role-based Authorization Guard
16
+ *
17
+ * Authorizes access based on user roles specified by the `@Roles()` decorator.
18
+ * Checks both realm-level roles (`user.realmRoles`) and client-specific roles (`user.clientRoles`).
19
+ *
20
+ * Uses OR logic — access is granted if the user has ANY of the required roles.
21
+ * If no roles are specified via `@Roles()`, access is allowed by default.
22
+ *
23
+ * Throws `ForbiddenException` if the user lacks all required roles.
24
+ *
25
+ * @example
26
+ * ```typescript
27
+ * @UseGuards(JwtAuthGuard, RoleGuard)
28
+ * @Controller('admin')
29
+ * export class AdminController {
30
+ * @Roles('admin', 'moderator')
31
+ * @Get('users')
32
+ * listUsers() {
33
+ * // User must have 'admin' OR 'moderator' role
34
+ * return [];
35
+ * }
36
+ * }
37
+ * ```
38
+ */
39
+ let RoleGuard = class RoleGuard {
40
+ reflector;
41
+ constructor(reflector) {
42
+ this.reflector = reflector;
43
+ }
44
+ canActivate(context) {
45
+ const requiredRoles = this.reflector.getAllAndOverride(ROLES_KEY, [context.getHandler(), context.getClass()]);
46
+ if (!requiredRoles || requiredRoles.length === 0) {
47
+ // No roles required, allow access
48
+ return true;
49
+ }
50
+ const request = ExtractRequestFromContext(context);
51
+ const user = request.user;
52
+ if (!user) {
53
+ throw new UnauthorizedException('User not authenticated');
54
+ }
55
+ // Check if user has any of the required roles in realmRoles or clientRoles
56
+ const userRoles = [...user.realmRoles, ...user.clientRoles];
57
+ const hasRequiredRole = requiredRoles.some(role => userRoles.includes(role));
58
+ if (!hasRequiredRole) {
59
+ throw new ForbiddenException('Insufficient permissions');
60
+ }
61
+ return true;
62
+ }
63
+ };
64
+ RoleGuard = __decorate([
65
+ Injectable(),
66
+ __metadata("design:paramtypes", [Reflector])
67
+ ], RoleGuard);
68
+ export { RoleGuard };
69
+ //# sourceMappingURL=role.guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"role.guard.js","sourceRoot":"","sources":["../../src/guards/role.guard.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,UAAU,EAAiC,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACtH,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAC3E,OAAO,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;AAG7D;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEI,IAAM,SAAS,GAAf,MAAM,SAAS;IACJ,SAAS,CAAY;IAEtC,YAAY,SAAoB;QAC/B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC5B,CAAC;IAEM,WAAW,CAAC,OAAyB;QAC3C,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAW,SAAS,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;QAExH,IAAI,CAAC,aAAa,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAClD,kCAAkC;YAClC,OAAO,IAAI,CAAC;QACb,CAAC;QAED,MAAM,OAAO,GAAG,yBAAyB,CAAC,OAAO,CAAC,CAAC;QACnD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAgC,CAAC;QAEtD,IAAI,CAAC,IAAI,EAAE,CAAC;YACX,MAAM,IAAI,qBAAqB,CAAC,wBAAwB,CAAC,CAAC;QAC3D,CAAC;QAED,2EAA2E;QAC3E,MAAM,SAAS,GAAG,CAAC,GAAG,IAAI,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC;QAC5D,MAAM,eAAe,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;QAE7E,IAAI,CAAC,eAAe,EAAE,CAAC;YACtB,MAAM,IAAI,kBAAkB,CAAC,0BAA0B,CAAC,CAAC;QAC1D,CAAC;QAED,OAAO,IAAI,CAAC;IACb,CAAC;CACD,CAAA;AAhCY,SAAS;IADrB,UAAU,EAAE;qCAIW,SAAS;GAHpB,SAAS,CAgCrB"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * @packageDocumentation
3
+ *
4
+ * Keycloak integration library for NestJS resource servers. Provides token validation,
5
+ * role and permission guards, authentication decorators, and a typed Admin REST API client.
6
+ *
7
+ * ## Key Features
8
+ *
9
+ * - **Token Validation**: Online introspection (default) detects revoked tokens immediately;
10
+ * offline JWKS mode validates signatures locally without network hops
11
+ * - **Guards & Decorators**: `@Public()`, `@Auth()`, `@Roles()`, `@Permissions()`, `@CurrentUser()`,
12
+ * and `@AuthToken()` for HTTP routes; GraphQL-specific variants for resolvers
13
+ * - **Admin REST API Client**: Typed service for user management, role/group administration,
14
+ * federated identity linking, and event polling
15
+ * - **Security Defaults**: Introspection by default, CORS localhost validation, path normalization
16
+ * for metrics cardinality control
17
+ *
18
+ * ## Quick Start
19
+ *
20
+ * ```typescript
21
+ * import { Module } from '@nestjs/common';
22
+ * import { APP_GUARD } from '@nestjs/core';
23
+ * import { ConfigModule, ConfigService } from '@nestjs/config';
24
+ * import { KeycloakModule, JwtAuthGuard } from '@pawells/nestjs-auth';
25
+ *
26
+ * @Module({
27
+ * imports: [
28
+ * KeycloakModule.forRootAsync({
29
+ * imports: [ConfigModule],
30
+ * inject: [ConfigService],
31
+ * useFactory: (config: ConfigService) => ({
32
+ * authServerUrl: config.get('KEYCLOAK_AUTH_SERVER_URL'),
33
+ * realm: config.get('KEYCLOAK_REALM'),
34
+ * clientId: config.get('KEYCLOAK_CLIENT_ID'),
35
+ * clientSecret: config.get('KEYCLOAK_CLIENT_SECRET'),
36
+ * }),
37
+ * }),
38
+ * ],
39
+ * providers: [
40
+ * {
41
+ * provide: APP_GUARD,
42
+ * useClass: JwtAuthGuard,
43
+ * },
44
+ * ],
45
+ * })
46
+ * export class AppModule {}
47
+ * ```
48
+ *
49
+ * @see {@link KeycloakModule} for token validation configuration
50
+ * @see {@link KeycloakAdminModule} for admin API setup
51
+ * @see {@link JwtAuthGuard} for authentication enforcement
52
+ */
53
+ export { KeycloakModule } from './keycloak/keycloak.module.js';
54
+ export { KeycloakTokenValidationService } from './keycloak/services/keycloak-token-validation.service.js';
55
+ export { JwksCacheService } from './keycloak/services/jwks-cache.service.js';
56
+ export type { TokenValidationResult } from './keycloak/services/keycloak-token-validation.service.js';
57
+ export type { KeycloakModuleOptions, KeycloakTokenClaims, KeycloakUser } from './keycloak/keycloak.types.js';
58
+ export type { KeycloakModuleAsyncOptions } from './keycloak/keycloak.interfaces.js';
59
+ export { KEYCLOAK_MODULE_OPTIONS } from './keycloak/keycloak.constants.js';
60
+ export { KeycloakAdminModule } from './admin/keycloak-admin.module.js';
61
+ export { KeycloakAdminService } from './admin/services/keycloak-admin.service.js';
62
+ export { KeycloakHealthIndicator } from './admin/health/keycloak.health.js';
63
+ export type { KeycloakAdminConfig } from './admin/config/keycloak.config.js';
64
+ export type { KeycloakAdminModuleAsyncOptions } from './admin/keycloak-admin.interfaces.js';
65
+ export { KeycloakAdminDefaults, validateKeycloakAdminConfig } from './admin/config/keycloak.defaults.js';
66
+ export { KEYCLOAK_ADMIN_CONFIG_TOKEN } from './admin/keycloak.constants.js';
67
+ export type { KeycloakAdminScope } from './admin/permissions/keycloak-admin.permissions.js';
68
+ export { KEYCLOAK_DEFAULT_SCOPES, KEYCLOAK_ALL_SCOPES, KeycloakAdminScopeError } from './admin/permissions/keycloak-admin.permissions.js';
69
+ export { KeycloakClient } from './admin/client/client.js';
70
+ export { BaseService } from './admin/client/services/base-service.js';
71
+ export { RealmService } from './admin/client/services/realm.service.js';
72
+ export { UserService } from './admin/client/services/user.service.js';
73
+ export { ClientService } from './admin/client/services/client.service.js';
74
+ export { RoleService } from './admin/client/services/role.service.js';
75
+ export { GroupService } from './admin/client/services/group.service.js';
76
+ export { IdentityProviderService } from './admin/client/services/identity-provider.service.js';
77
+ export { AuthenticationService } from './admin/client/services/authentication.service.js';
78
+ export { FederatedIdentityService } from './admin/client/services/federated-identity.service.js';
79
+ export type { FederatedIdentityLink } from './admin/client/services/federated-identity.service.js';
80
+ export { EventService } from './admin/client/services/event.service.js';
81
+ export type { KeycloakClientConfig } from './admin/client/types/config.types.js';
82
+ export type { AdminEventQuery, AccessEventQuery, KeycloakAdminEvent, KeycloakAccessEvent } from './admin/client/types/event.types.js';
83
+ export { KeycloakClientError, AuthenticationError, AuthorizationError, NotFoundError, ValidationError, RateLimitError, TimeoutError, NetworkError, ConflictError, } from './admin/client/errors/base-error.js';
84
+ export { withRetry } from './admin/client/utils/retry.js';
85
+ export { JwtAuthGuard } from './guards/jwt-auth.guard.js';
86
+ export { RoleGuard } from './guards/role.guard.js';
87
+ export { PermissionGuard } from './guards/permission.guard.js';
88
+ export { Auth, Public, Roles, Permissions, CurrentUser, AuthToken, IS_PUBLIC_KEY, ROLES_KEY, PERMISSIONS_KEY, detectContextType, extractRequestFromContext, extractUserFromContext, extractAuthTokenFromContext, } from './decorators/auth-decorators.js';
89
+ export type { ContextOptions } from './decorators/auth-decorators.js';
90
+ export { GraphQLPublic, GraphQLAuth, GraphQLRoles, GraphQLCurrentUser, GraphQLAuthToken, GraphQLContextParam, GraphQLUser, } from './decorators/graphql-auth-decorators.js';
91
+ export { ExtractRequestFromContext, ExtractUserFromContext, ExtractAuthTokenFromContext, DetectContextType } from './decorators/context-utils.js';
92
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AAKH,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,8BAA8B,EAAE,MAAM,0DAA0D,CAAC;AAC1G,OAAO,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAC;AAC7E,YAAY,EAAE,qBAAqB,EAAE,MAAM,0DAA0D,CAAC;AACtG,YAAY,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC7G,YAAY,EAAE,0BAA0B,EAAE,MAAM,mCAAmC,CAAC;AACpF,OAAO,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AAK3E,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AACvE,OAAO,EAAE,oBAAoB,EAAE,MAAM,4CAA4C,CAAC;AAClF,OAAO,EAAE,uBAAuB,EAAE,MAAM,mCAAmC,CAAC;AAC5E,YAAY,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAC7E,YAAY,EAAE,+BAA+B,EAAE,MAAM,sCAAsC,CAAC;AAC5F,OAAO,EAAE,qBAAqB,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AACzG,OAAO,EAAE,2BAA2B,EAAE,MAAM,+BAA+B,CAAC;AAG5E,YAAY,EAAE,kBAAkB,EAAE,MAAM,mDAAmD,CAAC;AAC5F,OAAO,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,mDAAmD,CAAC;AAG1I,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAG1D,OAAO,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,0CAA0C,CAAC;AACxE,OAAO,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,2CAA2C,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,0CAA0C,CAAC;AACxE,OAAO,EAAE,uBAAuB,EAAE,MAAM,sDAAsD,CAAC;AAC/F,OAAO,EAAE,qBAAqB,EAAE,MAAM,mDAAmD,CAAC;AAC1F,OAAO,EAAE,wBAAwB,EAAE,MAAM,uDAAuD,CAAC;AACjG,YAAY,EAAE,qBAAqB,EAAE,MAAM,uDAAuD,CAAC;AACnG,OAAO,EAAE,YAAY,EAAE,MAAM,0CAA0C,CAAC;AAGxE,YAAY,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AACjF,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAGtI,OAAO,EACN,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,EAClB,aAAa,EACb,eAAe,EACf,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,aAAa,GACb,MAAM,qCAAqC,CAAC;AAG7C,OAAO,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAK1D,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAK/D,OAAO,EACN,IAAI,EACJ,MAAM,EACN,KAAK,EACL,WAAW,EACX,WAAW,EACX,SAAS,EACT,aAAa,EACb,SAAS,EACT,eAAe,EACf,iBAAiB,EACjB,yBAAyB,EACzB,sBAAsB,EACtB,2BAA2B,GAC3B,MAAM,iCAAiC,CAAC;AAEzC,YAAY,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAEtE,OAAO,EACN,aAAa,EACb,WAAW,EACX,YAAY,EACZ,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,WAAW,GACX,MAAM,yCAAyC,CAAC;AAEjD,OAAO,EAAE,yBAAyB,EAAE,sBAAsB,EAAE,2BAA2B,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC"}
package/build/index.js ADDED
@@ -0,0 +1,98 @@
1
+ /**
2
+ * @packageDocumentation
3
+ *
4
+ * Keycloak integration library for NestJS resource servers. Provides token validation,
5
+ * role and permission guards, authentication decorators, and a typed Admin REST API client.
6
+ *
7
+ * ## Key Features
8
+ *
9
+ * - **Token Validation**: Online introspection (default) detects revoked tokens immediately;
10
+ * offline JWKS mode validates signatures locally without network hops
11
+ * - **Guards & Decorators**: `@Public()`, `@Auth()`, `@Roles()`, `@Permissions()`, `@CurrentUser()`,
12
+ * and `@AuthToken()` for HTTP routes; GraphQL-specific variants for resolvers
13
+ * - **Admin REST API Client**: Typed service for user management, role/group administration,
14
+ * federated identity linking, and event polling
15
+ * - **Security Defaults**: Introspection by default, CORS localhost validation, path normalization
16
+ * for metrics cardinality control
17
+ *
18
+ * ## Quick Start
19
+ *
20
+ * ```typescript
21
+ * import { Module } from '@nestjs/common';
22
+ * import { APP_GUARD } from '@nestjs/core';
23
+ * import { ConfigModule, ConfigService } from '@nestjs/config';
24
+ * import { KeycloakModule, JwtAuthGuard } from '@pawells/nestjs-auth';
25
+ *
26
+ * @Module({
27
+ * imports: [
28
+ * KeycloakModule.forRootAsync({
29
+ * imports: [ConfigModule],
30
+ * inject: [ConfigService],
31
+ * useFactory: (config: ConfigService) => ({
32
+ * authServerUrl: config.get('KEYCLOAK_AUTH_SERVER_URL'),
33
+ * realm: config.get('KEYCLOAK_REALM'),
34
+ * clientId: config.get('KEYCLOAK_CLIENT_ID'),
35
+ * clientSecret: config.get('KEYCLOAK_CLIENT_SECRET'),
36
+ * }),
37
+ * }),
38
+ * ],
39
+ * providers: [
40
+ * {
41
+ * provide: APP_GUARD,
42
+ * useClass: JwtAuthGuard,
43
+ * },
44
+ * ],
45
+ * })
46
+ * export class AppModule {}
47
+ * ```
48
+ *
49
+ * @see {@link KeycloakModule} for token validation configuration
50
+ * @see {@link KeycloakAdminModule} for admin API setup
51
+ * @see {@link JwtAuthGuard} for authentication enforcement
52
+ */
53
+ // ============================================================================
54
+ // Keycloak Module — Token Validation and JWT Authentication
55
+ // ============================================================================
56
+ export { KeycloakModule } from './keycloak/keycloak.module.js';
57
+ export { KeycloakTokenValidationService } from './keycloak/services/keycloak-token-validation.service.js';
58
+ export { JwksCacheService } from './keycloak/services/jwks-cache.service.js';
59
+ export { KEYCLOAK_MODULE_OPTIONS } from './keycloak/keycloak.constants.js';
60
+ // ============================================================================
61
+ // Keycloak Admin Module — Admin REST API
62
+ // ============================================================================
63
+ export { KeycloakAdminModule } from './admin/keycloak-admin.module.js';
64
+ export { KeycloakAdminService } from './admin/services/keycloak-admin.service.js';
65
+ export { KeycloakHealthIndicator } from './admin/health/keycloak.health.js';
66
+ export { KeycloakAdminDefaults, validateKeycloakAdminConfig } from './admin/config/keycloak.defaults.js';
67
+ export { KEYCLOAK_ADMIN_CONFIG_TOKEN } from './admin/keycloak.constants.js';
68
+ export { KEYCLOAK_DEFAULT_SCOPES, KEYCLOAK_ALL_SCOPES, KeycloakAdminScopeError } from './admin/permissions/keycloak-admin.permissions.js';
69
+ // Keycloak Admin Client
70
+ export { KeycloakClient } from './admin/client/client.js';
71
+ // Keycloak Admin Services
72
+ export { BaseService } from './admin/client/services/base-service.js';
73
+ export { RealmService } from './admin/client/services/realm.service.js';
74
+ export { UserService } from './admin/client/services/user.service.js';
75
+ export { ClientService } from './admin/client/services/client.service.js';
76
+ export { RoleService } from './admin/client/services/role.service.js';
77
+ export { GroupService } from './admin/client/services/group.service.js';
78
+ export { IdentityProviderService } from './admin/client/services/identity-provider.service.js';
79
+ export { AuthenticationService } from './admin/client/services/authentication.service.js';
80
+ export { FederatedIdentityService } from './admin/client/services/federated-identity.service.js';
81
+ export { EventService } from './admin/client/services/event.service.js';
82
+ // Keycloak Admin Errors
83
+ export { KeycloakClientError, AuthenticationError, AuthorizationError, NotFoundError, ValidationError, RateLimitError, TimeoutError, NetworkError, ConflictError, } from './admin/client/errors/base-error.js';
84
+ // Keycloak Admin Utils
85
+ export { withRetry } from './admin/client/utils/retry.js';
86
+ // ============================================================================
87
+ // Guards — Authorization and JWT
88
+ // ============================================================================
89
+ export { JwtAuthGuard } from './guards/jwt-auth.guard.js';
90
+ export { RoleGuard } from './guards/role.guard.js';
91
+ export { PermissionGuard } from './guards/permission.guard.js';
92
+ // ============================================================================
93
+ // Decorators — Auth Context and Metadata
94
+ // ============================================================================
95
+ export { Auth, Public, Roles, Permissions, CurrentUser, AuthToken, IS_PUBLIC_KEY, ROLES_KEY, PERMISSIONS_KEY, detectContextType, extractRequestFromContext, extractUserFromContext, extractAuthTokenFromContext, } from './decorators/auth-decorators.js';
96
+ export { GraphQLPublic, GraphQLAuth, GraphQLRoles, GraphQLCurrentUser, GraphQLAuthToken, GraphQLContextParam, GraphQLUser, } from './decorators/graphql-auth-decorators.js';
97
+ export { ExtractRequestFromContext, ExtractUserFromContext, ExtractAuthTokenFromContext, DetectContextType } from './decorators/context-utils.js';
98
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AAEH,+EAA+E;AAC/E,4DAA4D;AAC5D,+EAA+E;AAC/E,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,8BAA8B,EAAE,MAAM,0DAA0D,CAAC;AAC1G,OAAO,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAC;AAI7E,OAAO,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AAE3E,+EAA+E;AAC/E,yCAAyC;AACzC,+EAA+E;AAC/E,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AACvE,OAAO,EAAE,oBAAoB,EAAE,MAAM,4CAA4C,CAAC;AAClF,OAAO,EAAE,uBAAuB,EAAE,MAAM,mCAAmC,CAAC;AAG5E,OAAO,EAAE,qBAAqB,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AACzG,OAAO,EAAE,2BAA2B,EAAE,MAAM,+BAA+B,CAAC;AAI5E,OAAO,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,mDAAmD,CAAC;AAE1I,wBAAwB;AACxB,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,0BAA0B;AAC1B,OAAO,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,0CAA0C,CAAC;AACxE,OAAO,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,2CAA2C,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,0CAA0C,CAAC;AACxE,OAAO,EAAE,uBAAuB,EAAE,MAAM,sDAAsD,CAAC;AAC/F,OAAO,EAAE,qBAAqB,EAAE,MAAM,mDAAmD,CAAC;AAC1F,OAAO,EAAE,wBAAwB,EAAE,MAAM,uDAAuD,CAAC;AAEjG,OAAO,EAAE,YAAY,EAAE,MAAM,0CAA0C,CAAC;AAMxE,wBAAwB;AACxB,OAAO,EACN,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,EAClB,aAAa,EACb,eAAe,EACf,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,aAAa,GACb,MAAM,qCAAqC,CAAC;AAE7C,uBAAuB;AACvB,OAAO,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAE1D,+EAA+E;AAC/E,iCAAiC;AACjC,+EAA+E;AAC/E,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAE/D,+EAA+E;AAC/E,yCAAyC;AACzC,+EAA+E;AAC/E,OAAO,EACN,IAAI,EACJ,MAAM,EACN,KAAK,EACL,WAAW,EACX,WAAW,EACX,SAAS,EACT,aAAa,EACb,SAAS,EACT,eAAe,EACf,iBAAiB,EACjB,yBAAyB,EACzB,sBAAsB,EACtB,2BAA2B,GAC3B,MAAM,iCAAiC,CAAC;AAIzC,OAAO,EACN,aAAa,EACb,WAAW,EACX,YAAY,EACZ,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,WAAW,GACX,MAAM,yCAAyC,CAAC;AAEjD,OAAO,EAAE,yBAAyB,EAAE,sBAAsB,EAAE,2BAA2B,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC"}
@@ -0,0 +1,7 @@
1
+ export { KeycloakModule } from './keycloak.module.js';
2
+ export { KeycloakTokenValidationService } from './services/keycloak-token-validation.service.js';
3
+ export { JwksCacheService } from './services/jwks-cache.service.js';
4
+ export type { TokenValidationResult } from './services/keycloak-token-validation.service.js';
5
+ export type { KeycloakModuleOptions, KeycloakTokenClaims, KeycloakUser } from './keycloak.types.js';
6
+ export { KEYCLOAK_MODULE_OPTIONS } from './keycloak.constants.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/keycloak/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,8BAA8B,EAAE,MAAM,iDAAiD,CAAC;AACjG,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACpE,YAAY,EAAE,qBAAqB,EAAE,MAAM,iDAAiD,CAAC;AAC7F,YAAY,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACpG,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC"}
@@ -0,0 +1,5 @@
1
+ export { KeycloakModule } from './keycloak.module.js';
2
+ export { KeycloakTokenValidationService } from './services/keycloak-token-validation.service.js';
3
+ export { JwksCacheService } from './services/jwks-cache.service.js';
4
+ export { KEYCLOAK_MODULE_OPTIONS } from './keycloak.constants.js';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/keycloak/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,8BAA8B,EAAE,MAAM,iDAAiD,CAAC;AACjG,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAGpE,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const KEYCLOAK_MODULE_OPTIONS: unique symbol;
2
+ //# sourceMappingURL=keycloak.constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keycloak.constants.d.ts","sourceRoot":"","sources":["../../src/keycloak/keycloak.constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,uBAAuB,eAAoC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export const KEYCLOAK_MODULE_OPTIONS = Symbol('KEYCLOAK_MODULE_OPTIONS');
2
+ //# sourceMappingURL=keycloak.constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keycloak.constants.js","sourceRoot":"","sources":["../../src/keycloak/keycloak.constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,uBAAuB,GAAG,MAAM,CAAC,yBAAyB,CAAC,CAAC"}