@monderks/nestjs-keycloak-auth 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/.eslintrc.js +26 -0
- package/.prettierrc +20 -0
- package/README.md +299 -0
- package/dist/decorators/current-user.decorator.d.ts +3 -0
- package/dist/decorators/current-user.decorator.d.ts.map +1 -0
- package/dist/decorators/current-user.decorator.js +10 -0
- package/dist/decorators/current-user.decorator.js.map +1 -0
- package/dist/guards/keycloak-auth.guard.d.ts +18 -0
- package/dist/guards/keycloak-auth.guard.d.ts.map +1 -0
- package/dist/guards/keycloak-auth.guard.js +81 -0
- package/dist/guards/keycloak-auth.guard.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +28 -0
- package/dist/index.js.map +1 -0
- package/dist/interfaces/keycloak-config.interface.d.ts +56 -0
- package/dist/interfaces/keycloak-config.interface.d.ts.map +1 -0
- package/dist/interfaces/keycloak-config.interface.js +3 -0
- package/dist/interfaces/keycloak-config.interface.js.map +1 -0
- package/dist/keycloak-auth.module.d.ts +5 -0
- package/dist/keycloak-auth.module.d.ts.map +1 -0
- package/dist/keycloak-auth.module.js +44 -0
- package/dist/keycloak-auth.module.js.map +1 -0
- package/dist/keycloak-auth.service.d.ts +16 -0
- package/dist/keycloak-auth.service.d.ts.map +1 -0
- package/dist/keycloak-auth.service.js +231 -0
- package/dist/keycloak-auth.service.js.map +1 -0
- package/examples/frontend-controlled-auth.ts +96 -0
- package/jest.config.js +14 -0
- package/package.json +52 -0
- package/src/decorators/current-user.decorator.ts +11 -0
- package/src/guards/keycloak-auth.guard.ts +93 -0
- package/src/index.ts +14 -0
- package/src/interfaces/keycloak-config.interface.ts +58 -0
- package/src/keycloak-auth.module.ts +32 -0
- package/src/keycloak-auth.service.ts +243 -0
- package/tsconfig.json +40 -0
package/.eslintrc.js
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
module.exports = {
|
2
|
+
parser: '@typescript-eslint/parser',
|
3
|
+
parserOptions: {
|
4
|
+
project: 'tsconfig.json',
|
5
|
+
tsconfigRootDir: __dirname,
|
6
|
+
sourceType: 'module',
|
7
|
+
},
|
8
|
+
plugins: ['@typescript-eslint/eslint-plugin'],
|
9
|
+
extends: [
|
10
|
+
'plugin:@typescript-eslint/recommended',
|
11
|
+
'plugin:prettier/recommended',
|
12
|
+
],
|
13
|
+
root: true,
|
14
|
+
env: {
|
15
|
+
node: true,
|
16
|
+
jest: true,
|
17
|
+
},
|
18
|
+
ignorePatterns: ['.eslintrc.js', 'dist/**/*'],
|
19
|
+
rules: {
|
20
|
+
'@typescript-eslint/interface-name-prefix': 'off',
|
21
|
+
'@typescript-eslint/explicit-function-return-type': 'off',
|
22
|
+
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
23
|
+
'@typescript-eslint/no-explicit-any': 'off',
|
24
|
+
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
|
25
|
+
},
|
26
|
+
};
|
package/.prettierrc
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
{
|
2
|
+
"arrowParens": "always",
|
3
|
+
"bracketSameLine": true,
|
4
|
+
"bracketSpacing": true,
|
5
|
+
"semi": true,
|
6
|
+
"singleQuote": true,
|
7
|
+
"jsxSingleQuote": false,
|
8
|
+
"quoteProps": "as-needed",
|
9
|
+
"trailingComma": "all",
|
10
|
+
"singleAttributePerLine": false,
|
11
|
+
"htmlWhitespaceSensitivity": "css",
|
12
|
+
"vueIndentScriptAndStyle": false,
|
13
|
+
"proseWrap": "preserve",
|
14
|
+
"insertPragma": false,
|
15
|
+
"printWidth": 120,
|
16
|
+
"requirePragma": false,
|
17
|
+
"tabWidth": 4,
|
18
|
+
"useTabs": false,
|
19
|
+
"embeddedLanguageFormatting": "auto"
|
20
|
+
}
|
package/README.md
ADDED
@@ -0,0 +1,299 @@
|
|
1
|
+
# Keycloak Auth Library
|
2
|
+
|
3
|
+
Librería para validación de tokens Keycloak en NestJS cuando el frontend controla la autenticación.
|
4
|
+
|
5
|
+
## Características
|
6
|
+
|
7
|
+
- 🎫 Validación de tokens JWT desde frontend
|
8
|
+
- 🔄 Renovación de tokens
|
9
|
+
- 👤 Obtención de información de usuario
|
10
|
+
- 🛡️ Guards de autorización con roles
|
11
|
+
- 🏷️ Decoradores para obtener usuario actual
|
12
|
+
- 🔧 Configuración flexible
|
13
|
+
- 🌐 Optimizada para frontend (Next.js, React, etc.)
|
14
|
+
|
15
|
+
## Instalación
|
16
|
+
|
17
|
+
```bash
|
18
|
+
npm install @monderks/keycloak-auth
|
19
|
+
```
|
20
|
+
|
21
|
+
## Configuración
|
22
|
+
|
23
|
+
### Configuración Básica
|
24
|
+
|
25
|
+
```typescript
|
26
|
+
import { Module } from '@nestjs/common';
|
27
|
+
import { KeycloakAuthModule } from '@monderks/keycloak-auth';
|
28
|
+
|
29
|
+
@Module({
|
30
|
+
imports: [
|
31
|
+
KeycloakAuthModule.forRoot({
|
32
|
+
config: {
|
33
|
+
serverUrl: 'http://localhost:8080',
|
34
|
+
realm: 'my-realm',
|
35
|
+
clientId: 'my-client',
|
36
|
+
clientSecret: 'my-client-secret', // Necesario para refresh y logout
|
37
|
+
verifyTokenAudience: true,
|
38
|
+
verifyTokenIssuer: true,
|
39
|
+
tokenExpirationTolerance: 30, // segundos
|
40
|
+
},
|
41
|
+
}),
|
42
|
+
],
|
43
|
+
})
|
44
|
+
export class AppModule {}
|
45
|
+
```
|
46
|
+
|
47
|
+
### Configuración Asíncrona
|
48
|
+
|
49
|
+
```typescript
|
50
|
+
import { Module } from '@nestjs/common';
|
51
|
+
import { ConfigModule, ConfigService } from '@nestjs/config';
|
52
|
+
import { KeycloakAuthModule } from '@monderks/keycloak-auth';
|
53
|
+
|
54
|
+
@Module({
|
55
|
+
imports: [
|
56
|
+
ConfigModule.forRoot(),
|
57
|
+
KeycloakAuthModule.forRootAsync({
|
58
|
+
useFactory: (configService: ConfigService) => ({
|
59
|
+
serverUrl: configService.get('KEYCLOAK_SERVER_URL'),
|
60
|
+
realm: configService.get('KEYCLOAK_REALM'),
|
61
|
+
clientId: configService.get('KEYCLOAK_CLIENT_ID'),
|
62
|
+
clientSecret: configService.get('KEYCLOAK_CLIENT_SECRET'),
|
63
|
+
verifyTokenAudience: true,
|
64
|
+
verifyTokenIssuer: true,
|
65
|
+
}),
|
66
|
+
inject: [ConfigService],
|
67
|
+
}),
|
68
|
+
],
|
69
|
+
})
|
70
|
+
export class AppModule {}
|
71
|
+
```
|
72
|
+
|
73
|
+
## ¿Cómo usar la librería?
|
74
|
+
|
75
|
+
Esta librería **no expone controladores**. Solo provee servicios, guards y decoradores para que tú crees tus propios endpoints y lógica de negocio.
|
76
|
+
|
77
|
+
### Ejemplo de uso en tu propio controlador
|
78
|
+
|
79
|
+
```typescript
|
80
|
+
import { Controller, Get, Post, Body, UseGuards } from '@nestjs/common';
|
81
|
+
import { KeycloakAuthService, KeycloakAuthGuard, KeycloakAuth, CurrentUser } from '@monderks/keycloak-auth';
|
82
|
+
import { DecodedToken } from '@monderks/keycloak-auth';
|
83
|
+
|
84
|
+
@Controller('api/auth')
|
85
|
+
export class AuthController {
|
86
|
+
constructor(private keycloakService: KeycloakAuthService) {}
|
87
|
+
|
88
|
+
@Post('validate')
|
89
|
+
async validateToken(@Body() body: { token: string }) {
|
90
|
+
return await this.keycloakService.validateToken(body.token);
|
91
|
+
}
|
92
|
+
|
93
|
+
@Get('protected')
|
94
|
+
@UseGuards(KeycloakAuthGuard)
|
95
|
+
@KeycloakAuth()
|
96
|
+
getProtectedData(@CurrentUser() user: DecodedToken) {
|
97
|
+
return {
|
98
|
+
message: 'Datos protegidos',
|
99
|
+
user,
|
100
|
+
};
|
101
|
+
}
|
102
|
+
}
|
103
|
+
```
|
104
|
+
|
105
|
+
## Flujo de Autenticación
|
106
|
+
|
107
|
+
### 1. Frontend (Next.js/React) - Login
|
108
|
+
|
109
|
+
```typescript
|
110
|
+
// Instalar keycloak-js
|
111
|
+
// npm install keycloak-js
|
112
|
+
|
113
|
+
import Keycloak from 'keycloak-js';
|
114
|
+
|
115
|
+
// Configurar Keycloak
|
116
|
+
const keycloak = new Keycloak({
|
117
|
+
url: 'http://localhost:8080',
|
118
|
+
realm: 'my-realm',
|
119
|
+
clientId: 'my-client'
|
120
|
+
});
|
121
|
+
|
122
|
+
// Inicializar y hacer login
|
123
|
+
await keycloak.init({
|
124
|
+
onLoad: 'login-required'
|
125
|
+
});
|
126
|
+
|
127
|
+
// Obtener el token
|
128
|
+
const token = keycloak.token;
|
129
|
+
```
|
130
|
+
|
131
|
+
### 2. Frontend - Enviar Requests al Backend
|
132
|
+
|
133
|
+
```typescript
|
134
|
+
// Endpoint protegido
|
135
|
+
const response = await fetch('/api/auth/protected', {
|
136
|
+
headers: {
|
137
|
+
'Authorization': `Bearer ${token}`
|
138
|
+
}
|
139
|
+
});
|
140
|
+
|
141
|
+
// Validar token
|
142
|
+
const validateResponse = await fetch('/api/auth/validate', {
|
143
|
+
method: 'POST',
|
144
|
+
headers: {
|
145
|
+
'Content-Type': 'application/json'
|
146
|
+
},
|
147
|
+
body: JSON.stringify({ token })
|
148
|
+
});
|
149
|
+
|
150
|
+
// Renovar token
|
151
|
+
const refreshResponse = await fetch('/api/auth/refresh', {
|
152
|
+
method: 'POST',
|
153
|
+
headers: {
|
154
|
+
'Content-Type': 'application/json'
|
155
|
+
},
|
156
|
+
body: JSON.stringify({ refreshToken: keycloak.refreshToken })
|
157
|
+
});
|
158
|
+
|
159
|
+
// Logout
|
160
|
+
const logoutResponse = await fetch('/api/auth/logout', {
|
161
|
+
method: 'POST',
|
162
|
+
headers: {
|
163
|
+
'Content-Type': 'application/json'
|
164
|
+
},
|
165
|
+
body: JSON.stringify({ refreshToken: keycloak.refreshToken })
|
166
|
+
});
|
167
|
+
```
|
168
|
+
|
169
|
+
## Endpoints recomendados (tú los creas)
|
170
|
+
|
171
|
+
- POST `/api/auth/validate` → Valida un token
|
172
|
+
- POST `/api/auth/user-info` → Obtiene info del usuario
|
173
|
+
- POST `/api/auth/refresh` → Renueva el token
|
174
|
+
- POST `/api/auth/logout` → Logout
|
175
|
+
- GET `/api/auth/protected` → Endpoint protegido
|
176
|
+
- GET `/api/auth/admin` → Endpoint con roles
|
177
|
+
- GET `/api/auth/public` → Endpoint público
|
178
|
+
|
179
|
+
## API Reference
|
180
|
+
|
181
|
+
### KeycloakAuthService
|
182
|
+
|
183
|
+
#### Métodos de Validación
|
184
|
+
- `validateToken(token: string): Promise<TokenValidationResult>`
|
185
|
+
- `getUserInfo(accessToken: string): Promise<DecodedToken>`
|
186
|
+
- `refreshToken(refreshToken: string): Promise<RefreshTokenResult>`
|
187
|
+
- `logout(refreshToken: string): Promise<boolean>`
|
188
|
+
- `hasRole(userId: string, roleName: string, clientId?: string): Promise<boolean>`
|
189
|
+
|
190
|
+
### Decoradores
|
191
|
+
|
192
|
+
- `@CurrentUser()` - Obtiene el usuario autenticado de la request
|
193
|
+
- `@CurrentUser('sub')` - Obtiene una propiedad específica del usuario
|
194
|
+
|
195
|
+
### Guards
|
196
|
+
|
197
|
+
- `@KeycloakAuth()` - Protege rutas con validación de tokens
|
198
|
+
- `@KeycloakAuth({ roles: ['admin'] })` - Requiere roles específicos
|
199
|
+
- `@KeycloakAuth({ clientRoles: { 'client-id': ['role'] } })` - Requiere roles de cliente
|
200
|
+
- `@KeycloakAuth({ optional: true })` - Permite acceso sin token
|
201
|
+
|
202
|
+
## Variables de Entorno
|
203
|
+
|
204
|
+
```env
|
205
|
+
KEYCLOAK_SERVER_URL=http://localhost:8080
|
206
|
+
KEYCLOAK_REALM=my-realm
|
207
|
+
KEYCLOAK_CLIENT_ID=my-client
|
208
|
+
KEYCLOAK_CLIENT_SECRET=my-client-secret
|
209
|
+
```
|
210
|
+
|
211
|
+
## Configuración Avanzada
|
212
|
+
|
213
|
+
### Opciones de Configuración Completas
|
214
|
+
|
215
|
+
```typescript
|
216
|
+
const keycloakConfig = {
|
217
|
+
serverUrl: 'http://localhost:8080',
|
218
|
+
realm: 'my-realm',
|
219
|
+
clientId: 'my-client',
|
220
|
+
clientSecret: 'my-client-secret',
|
221
|
+
|
222
|
+
// Clave pública del realm (opcional, se obtiene automáticamente)
|
223
|
+
publicKey: '-----BEGIN PUBLIC KEY-----...',
|
224
|
+
|
225
|
+
// Opciones de validación
|
226
|
+
verifyTokenAudience: true,
|
227
|
+
verifyTokenIssuer: true,
|
228
|
+
tokenExpirationTolerance: 30, // segundos
|
229
|
+
};
|
230
|
+
```
|
231
|
+
|
232
|
+
## Ejemplos de Uso
|
233
|
+
|
234
|
+
### Middleware Personalizado
|
235
|
+
|
236
|
+
```typescript
|
237
|
+
@Injectable()
|
238
|
+
export class KeycloakMiddleware implements NestMiddleware {
|
239
|
+
constructor(private keycloakService: KeycloakAuthService) {}
|
240
|
+
|
241
|
+
async use(req: Request, res: Response, next: Function) {
|
242
|
+
const token = req.headers.authorization?.replace('Bearer ', '');
|
243
|
+
|
244
|
+
if (token) {
|
245
|
+
const validation = await this.keycloakService.validateToken(token);
|
246
|
+
if (validation.valid) {
|
247
|
+
req.user = validation.decoded;
|
248
|
+
}
|
249
|
+
}
|
250
|
+
|
251
|
+
next();
|
252
|
+
}
|
253
|
+
}
|
254
|
+
```
|
255
|
+
|
256
|
+
### Hook de React para Next.js
|
257
|
+
|
258
|
+
```typescript
|
259
|
+
// hooks/useKeycloak.ts
|
260
|
+
import { useState, useEffect } from 'react';
|
261
|
+
import Keycloak from 'keycloak-js';
|
262
|
+
|
263
|
+
export const useKeycloak = () => {
|
264
|
+
const [keycloak, setKeycloak] = useState<Keycloak | null>(null);
|
265
|
+
const [authenticated, setAuthenticated] = useState(false);
|
266
|
+
const [loading, setLoading] = useState(true);
|
267
|
+
|
268
|
+
useEffect(() => {
|
269
|
+
const kc = new Keycloak({
|
270
|
+
url: process.env.NEXT_PUBLIC_KEYCLOAK_URL,
|
271
|
+
realm: process.env.NEXT_PUBLIC_KEYCLOAK_REALM,
|
272
|
+
clientId: process.env.NEXT_PUBLIC_KEYCLOAK_CLIENT_ID,
|
273
|
+
});
|
274
|
+
|
275
|
+
kc.init({
|
276
|
+
onLoad: 'check-sso',
|
277
|
+
silentCheckSsoRedirectUri: window.location.origin + '/silent-check-sso.html',
|
278
|
+
}).then((auth) => {
|
279
|
+
setKeycloak(kc);
|
280
|
+
setAuthenticated(auth);
|
281
|
+
setLoading(false);
|
282
|
+
});
|
283
|
+
}, []);
|
284
|
+
|
285
|
+
return { keycloak, authenticated, loading };
|
286
|
+
};
|
287
|
+
```
|
288
|
+
|
289
|
+
## Contribuir
|
290
|
+
|
291
|
+
1. Fork el proyecto
|
292
|
+
2. Crea una rama para tu feature (`git checkout -b feature/AmazingFeature`)
|
293
|
+
3. Commit tus cambios (`git commit -m 'Add some AmazingFeature'`)
|
294
|
+
4. Push a la rama (`git push origin feature/AmazingFeature`)
|
295
|
+
5. Abre un Pull Request
|
296
|
+
|
297
|
+
## Licencia
|
298
|
+
|
299
|
+
Este proyecto está bajo la Licencia MIT - ver el archivo [LICENSE](LICENSE) para detalles.
|
@@ -0,0 +1,3 @@
|
|
1
|
+
import { DecodedToken } from '../interfaces/keycloak-config.interface';
|
2
|
+
export declare const CurrentUser: (...dataOrPipes: (keyof DecodedToken | import("@nestjs/common").PipeTransform<any, any> | import("@nestjs/common").Type<import("@nestjs/common").PipeTransform<any, any>> | undefined)[]) => ParameterDecorator;
|
3
|
+
//# sourceMappingURL=current-user.decorator.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"current-user.decorator.d.ts","sourceRoot":"","sources":["../../src/decorators/current-user.decorator.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;AAEvE,eAAO,MAAM,WAAW,iNAOvB,CAAC"}
|
@@ -0,0 +1,10 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.CurrentUser = void 0;
|
4
|
+
const common_1 = require("@nestjs/common");
|
5
|
+
exports.CurrentUser = (0, common_1.createParamDecorator)((data, ctx) => {
|
6
|
+
const request = ctx.switchToHttp().getRequest();
|
7
|
+
const user = request.user;
|
8
|
+
return data ? user?.[data] : user;
|
9
|
+
});
|
10
|
+
//# sourceMappingURL=current-user.decorator.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"current-user.decorator.js","sourceRoot":"","sources":["../../src/decorators/current-user.decorator.ts"],"names":[],"mappings":";;;AAAA,2CAAwE;AAG3D,QAAA,WAAW,GAAG,IAAA,6BAAoB,EAC7C,CAAC,IAAoC,EAAE,GAAqB,EAAsB,EAAE;IAClF,MAAM,OAAO,GAAG,GAAG,CAAC,YAAY,EAAE,CAAC,UAAU,EAAE,CAAC;IAChD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAE1B,OAAO,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACpC,CAAC,CACF,CAAC"}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
import { CanActivate, ExecutionContext } from '@nestjs/common';
|
2
|
+
import { Reflector } from '@nestjs/core';
|
3
|
+
import { KeycloakAuthService } from '../keycloak-auth.service';
|
4
|
+
export interface KeycloakAuthOptions {
|
5
|
+
roles?: string[];
|
6
|
+
clientRoles?: Record<string, string[]>;
|
7
|
+
requireAllRoles?: boolean;
|
8
|
+
optional?: boolean;
|
9
|
+
}
|
10
|
+
export declare const KEYCLOAK_AUTH_KEY = "keycloak_auth";
|
11
|
+
export declare const KeycloakAuth: (options?: KeycloakAuthOptions) => (target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
|
12
|
+
export declare class KeycloakAuthGuard implements CanActivate {
|
13
|
+
private reflector;
|
14
|
+
private keycloakService;
|
15
|
+
constructor(reflector: Reflector, keycloakService: KeycloakAuthService);
|
16
|
+
canActivate(context: ExecutionContext): Promise<boolean>;
|
17
|
+
}
|
18
|
+
//# sourceMappingURL=keycloak-auth.guard.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"keycloak-auth.guard.d.ts","sourceRoot":"","sources":["../../src/guards/keycloak-auth.guard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,WAAW,EAAE,gBAAgB,EAAyB,MAAM,gBAAgB,CAAC;AAClG,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAE/D,MAAM,WAAW,mBAAmB;IAChC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACvC,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,eAAO,MAAM,iBAAiB,kBAAkB,CAAC;AAEjD,eAAO,MAAM,YAAY,GAAI,UAAS,mBAAwB,MAClD,QAAQ,GAAG,EAAE,aAAa,MAAM,EAAE,YAAY,kBAAkB,uBAI3E,CAAC;AAEF,qBACa,iBAAkB,YAAW,WAAW;IAE7C,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,eAAe;gBADf,SAAS,EAAE,SAAS,EACpB,eAAe,EAAE,mBAAmB;IAG1C,WAAW,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;CAiEjE"}
|
@@ -0,0 +1,81 @@
|
|
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.KeycloakAuthGuard = exports.KeycloakAuth = exports.KEYCLOAK_AUTH_KEY = void 0;
|
13
|
+
const common_1 = require("@nestjs/common");
|
14
|
+
const core_1 = require("@nestjs/core");
|
15
|
+
const keycloak_auth_service_1 = require("../keycloak-auth.service");
|
16
|
+
exports.KEYCLOAK_AUTH_KEY = 'keycloak_auth';
|
17
|
+
const KeycloakAuth = (options = {}) => {
|
18
|
+
return (target, propertyKey, descriptor) => {
|
19
|
+
Reflect.defineMetadata(exports.KEYCLOAK_AUTH_KEY, options, descriptor.value);
|
20
|
+
return descriptor;
|
21
|
+
};
|
22
|
+
};
|
23
|
+
exports.KeycloakAuth = KeycloakAuth;
|
24
|
+
let KeycloakAuthGuard = class KeycloakAuthGuard {
|
25
|
+
constructor(reflector, keycloakService) {
|
26
|
+
this.reflector = reflector;
|
27
|
+
this.keycloakService = keycloakService;
|
28
|
+
}
|
29
|
+
async canActivate(context) {
|
30
|
+
const request = context.switchToHttp().getRequest();
|
31
|
+
const options = this.reflector.getAllAndOverride(exports.KEYCLOAK_AUTH_KEY, [
|
32
|
+
context.getHandler(),
|
33
|
+
context.getClass(),
|
34
|
+
]);
|
35
|
+
const authHeader = request.headers.authorization;
|
36
|
+
if (options?.optional && (!authHeader || !authHeader.startsWith('Bearer '))) {
|
37
|
+
return true;
|
38
|
+
}
|
39
|
+
if (!authHeader || !authHeader.startsWith('Bearer ')) {
|
40
|
+
throw new common_1.UnauthorizedException('Token de autorización requerido');
|
41
|
+
}
|
42
|
+
const token = authHeader.substring(7);
|
43
|
+
const validationResult = await this.keycloakService.validateToken(token);
|
44
|
+
if (!validationResult.valid) {
|
45
|
+
throw new common_1.UnauthorizedException(validationResult.error || 'Token inválido');
|
46
|
+
}
|
47
|
+
request.user = validationResult.decoded;
|
48
|
+
if (!options || (!options.roles && !options.clientRoles)) {
|
49
|
+
return true;
|
50
|
+
}
|
51
|
+
if (options.roles && options.roles.length > 0) {
|
52
|
+
const userRoles = validationResult.decoded?.realm_access?.roles || [];
|
53
|
+
const hasRealmRole = options.requireAllRoles
|
54
|
+
? options.roles.every((role) => userRoles.includes(role))
|
55
|
+
: options.roles.some((role) => userRoles.includes(role));
|
56
|
+
if (!hasRealmRole) {
|
57
|
+
throw new common_1.UnauthorizedException('Roles insuficientes');
|
58
|
+
}
|
59
|
+
}
|
60
|
+
if (options.clientRoles) {
|
61
|
+
const userClientRoles = validationResult.decoded?.resource_access || {};
|
62
|
+
for (const [clientId, requiredRoles] of Object.entries(options.clientRoles)) {
|
63
|
+
const userRoles = userClientRoles[clientId]?.roles || [];
|
64
|
+
const hasClientRole = options.requireAllRoles
|
65
|
+
? requiredRoles.every((role) => userRoles.includes(role))
|
66
|
+
: requiredRoles.some((role) => userRoles.includes(role));
|
67
|
+
if (!hasClientRole) {
|
68
|
+
throw new common_1.UnauthorizedException(`Roles insuficientes para el cliente ${clientId}`);
|
69
|
+
}
|
70
|
+
}
|
71
|
+
}
|
72
|
+
return true;
|
73
|
+
}
|
74
|
+
};
|
75
|
+
exports.KeycloakAuthGuard = KeycloakAuthGuard;
|
76
|
+
exports.KeycloakAuthGuard = KeycloakAuthGuard = __decorate([
|
77
|
+
(0, common_1.Injectable)(),
|
78
|
+
__metadata("design:paramtypes", [core_1.Reflector,
|
79
|
+
keycloak_auth_service_1.KeycloakAuthService])
|
80
|
+
], KeycloakAuthGuard);
|
81
|
+
//# sourceMappingURL=keycloak-auth.guard.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"keycloak-auth.guard.js","sourceRoot":"","sources":["../../src/guards/keycloak-auth.guard.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
@@ -0,0 +1,6 @@
|
|
1
|
+
export { KeycloakAuthModule } from './keycloak-auth.module';
|
2
|
+
export { KeycloakAuthService } from './keycloak-auth.service';
|
3
|
+
export { KeycloakAuthGuard, KeycloakAuth } from './guards/keycloak-auth.guard';
|
4
|
+
export { CurrentUser } from './decorators/current-user.decorator';
|
5
|
+
export * from './interfaces/keycloak-config.interface';
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAG5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAG9D,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAG/E,OAAO,EAAE,WAAW,EAAE,MAAM,qCAAqC,CAAC;AAGlE,cAAc,wCAAwC,CAAC"}
|
package/dist/index.js
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
3
|
+
if (k2 === undefined) k2 = k;
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
7
|
+
}
|
8
|
+
Object.defineProperty(o, k2, desc);
|
9
|
+
}) : (function(o, m, k, k2) {
|
10
|
+
if (k2 === undefined) k2 = k;
|
11
|
+
o[k2] = m[k];
|
12
|
+
}));
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
15
|
+
};
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
17
|
+
exports.CurrentUser = exports.KeycloakAuth = exports.KeycloakAuthGuard = exports.KeycloakAuthService = exports.KeycloakAuthModule = void 0;
|
18
|
+
var keycloak_auth_module_1 = require("./keycloak-auth.module");
|
19
|
+
Object.defineProperty(exports, "KeycloakAuthModule", { enumerable: true, get: function () { return keycloak_auth_module_1.KeycloakAuthModule; } });
|
20
|
+
var keycloak_auth_service_1 = require("./keycloak-auth.service");
|
21
|
+
Object.defineProperty(exports, "KeycloakAuthService", { enumerable: true, get: function () { return keycloak_auth_service_1.KeycloakAuthService; } });
|
22
|
+
var keycloak_auth_guard_1 = require("./guards/keycloak-auth.guard");
|
23
|
+
Object.defineProperty(exports, "KeycloakAuthGuard", { enumerable: true, get: function () { return keycloak_auth_guard_1.KeycloakAuthGuard; } });
|
24
|
+
Object.defineProperty(exports, "KeycloakAuth", { enumerable: true, get: function () { return keycloak_auth_guard_1.KeycloakAuth; } });
|
25
|
+
var current_user_decorator_1 = require("./decorators/current-user.decorator");
|
26
|
+
Object.defineProperty(exports, "CurrentUser", { enumerable: true, get: function () { return current_user_decorator_1.CurrentUser; } });
|
27
|
+
__exportStar(require("./interfaces/keycloak-config.interface"), exports);
|
28
|
+
//# sourceMappingURL=index.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AACA,+DAA4D;AAAnD,0HAAA,kBAAkB,OAAA;AAG3B,iEAA8D;AAArD,4HAAA,mBAAmB,OAAA;AAG5B,oEAA+E;AAAtE,wHAAA,iBAAiB,OAAA;AAAE,mHAAA,YAAY,OAAA;AAGxC,8EAAkE;AAAzD,qHAAA,WAAW,OAAA;AAGpB,yEAAuD"}
|
@@ -0,0 +1,56 @@
|
|
1
|
+
export interface KeycloakConfig {
|
2
|
+
serverUrl: string;
|
3
|
+
realm: string;
|
4
|
+
clientId: string;
|
5
|
+
clientSecret?: string;
|
6
|
+
publicKey?: string;
|
7
|
+
verifyTokenAudience?: boolean;
|
8
|
+
verifyTokenIssuer?: boolean;
|
9
|
+
tokenExpirationTolerance?: number;
|
10
|
+
}
|
11
|
+
export interface DecodedToken {
|
12
|
+
sub: string;
|
13
|
+
iss: string;
|
14
|
+
aud: string | string[];
|
15
|
+
exp: number;
|
16
|
+
iat: number;
|
17
|
+
jti?: string;
|
18
|
+
azp?: string;
|
19
|
+
scope?: string;
|
20
|
+
realm_access?: {
|
21
|
+
roles: string[];
|
22
|
+
};
|
23
|
+
resource_access?: {
|
24
|
+
[clientId: string]: {
|
25
|
+
roles: string[];
|
26
|
+
};
|
27
|
+
};
|
28
|
+
preferred_username?: string;
|
29
|
+
email?: string;
|
30
|
+
email_verified?: boolean;
|
31
|
+
name?: string;
|
32
|
+
given_name?: string;
|
33
|
+
family_name?: string;
|
34
|
+
}
|
35
|
+
export interface TokenValidationResult {
|
36
|
+
valid: boolean;
|
37
|
+
decoded?: DecodedToken;
|
38
|
+
error?: string;
|
39
|
+
expired?: boolean;
|
40
|
+
invalidSignature?: boolean;
|
41
|
+
invalidAudience?: boolean;
|
42
|
+
invalidIssuer?: boolean;
|
43
|
+
}
|
44
|
+
export interface RefreshTokenResult {
|
45
|
+
success: boolean;
|
46
|
+
token?: {
|
47
|
+
access_token: string;
|
48
|
+
refresh_token?: string;
|
49
|
+
token_type: string;
|
50
|
+
expires_in: number;
|
51
|
+
scope?: string;
|
52
|
+
id_token?: string;
|
53
|
+
};
|
54
|
+
error?: string;
|
55
|
+
}
|
56
|
+
//# sourceMappingURL=keycloak-config.interface.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"keycloak-config.interface.d.ts","sourceRoot":"","sources":["../../src/interfaces/keycloak-config.interface.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,wBAAwB,CAAC,EAAE,MAAM,CAAC;CACnC;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE;QACb,KAAK,EAAE,MAAM,EAAE,CAAC;KACjB,CAAC;IACF,eAAe,CAAC,EAAE;QAChB,CAAC,QAAQ,EAAE,MAAM,GAAG;YAClB,KAAK,EAAE,MAAM,EAAE,CAAC;SACjB,CAAC;KACH,CAAC;IACF,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE;QACN,YAAY,EAAE,MAAM,CAAC;QACrB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"keycloak-config.interface.js","sourceRoot":"","sources":["../../src/interfaces/keycloak-config.interface.ts"],"names":[],"mappings":""}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"keycloak-auth.module.d.ts","sourceRoot":"","sources":["../src/keycloak-auth.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAMvD,qBACa,kBAAkB;IAC3B,MAAM,CAAC,cAAc,IAAI,aAAa;CAuBzC"}
|
@@ -0,0 +1,44 @@
|
|
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 KeycloakAuthModule_1;
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
10
|
+
exports.KeycloakAuthModule = void 0;
|
11
|
+
const common_1 = require("@nestjs/common");
|
12
|
+
const config_1 = require("@nestjs/config");
|
13
|
+
const keycloak_auth_service_1 = require("./keycloak-auth.service");
|
14
|
+
const keycloak_auth_guard_1 = require("./guards/keycloak-auth.guard");
|
15
|
+
let KeycloakAuthModule = KeycloakAuthModule_1 = class KeycloakAuthModule {
|
16
|
+
static forRootFromEnv() {
|
17
|
+
return {
|
18
|
+
module: KeycloakAuthModule_1,
|
19
|
+
imports: [config_1.ConfigModule],
|
20
|
+
providers: [
|
21
|
+
{
|
22
|
+
provide: 'KEYCLOAK_CONFIG',
|
23
|
+
useFactory: (configService) => ({
|
24
|
+
serverUrl: configService.get('KEYCLOAK_SERVER_URL', 'http://localhost:8080'),
|
25
|
+
realm: configService.get('KEYCLOAK_REALM', 'my-realm'),
|
26
|
+
clientId: configService.get('KEYCLOAK_CLIENT_ID', 'backend'),
|
27
|
+
clientSecret: configService.get('KEYCLOAK_CLIENT_SECRET'),
|
28
|
+
verifyTokenIssuer: configService.get('KEYCLOAK_VERIFY_ISSUER', 'true') === 'true',
|
29
|
+
verifyTokenAudience: configService.get('KEYCLOAK_VERIFY_AUDIENCE', 'true') === 'true',
|
30
|
+
}),
|
31
|
+
inject: [config_1.ConfigService],
|
32
|
+
},
|
33
|
+
keycloak_auth_service_1.KeycloakAuthService,
|
34
|
+
keycloak_auth_guard_1.KeycloakAuthGuard,
|
35
|
+
],
|
36
|
+
exports: [keycloak_auth_service_1.KeycloakAuthService, keycloak_auth_guard_1.KeycloakAuthGuard],
|
37
|
+
};
|
38
|
+
}
|
39
|
+
};
|
40
|
+
exports.KeycloakAuthModule = KeycloakAuthModule;
|
41
|
+
exports.KeycloakAuthModule = KeycloakAuthModule = KeycloakAuthModule_1 = __decorate([
|
42
|
+
(0, common_1.Module)({})
|
43
|
+
], KeycloakAuthModule);
|
44
|
+
//# sourceMappingURL=keycloak-auth.module.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"keycloak-auth.module.js","sourceRoot":"","sources":["../src/keycloak-auth.module.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAAuD;AACvD,2CAA6D;AAE7D,mEAA8D;AAC9D,sEAAiE;AAG1D,IAAM,kBAAkB,0BAAxB,MAAM,kBAAkB;IAC3B,MAAM,CAAC,cAAc;QACjB,OAAO;YACH,MAAM,EAAE,oBAAkB;YAC1B,OAAO,EAAE,CAAC,qBAAY,CAAC;YACvB,SAAS,EAAE;gBACP;oBACI,OAAO,EAAE,iBAAiB;oBAC1B,UAAU,EAAE,CAAC,aAA4B,EAAkB,EAAE,CAAC,CAAC;wBAC3D,SAAS,EAAE,aAAa,CAAC,GAAG,CAAS,qBAAqB,EAAE,uBAAuB,CAAC;wBACpF,KAAK,EAAE,aAAa,CAAC,GAAG,CAAS,gBAAgB,EAAE,UAAU,CAAC;wBAC9D,QAAQ,EAAE,aAAa,CAAC,GAAG,CAAS,oBAAoB,EAAE,SAAS,CAAC;wBACpE,YAAY,EAAE,aAAa,CAAC,GAAG,CAAS,wBAAwB,CAAC;wBACjE,iBAAiB,EAAE,aAAa,CAAC,GAAG,CAAS,wBAAwB,EAAE,MAAM,CAAC,KAAK,MAAM;wBACzF,mBAAmB,EAAE,aAAa,CAAC,GAAG,CAAS,0BAA0B,EAAE,MAAM,CAAC,KAAK,MAAM;qBAChG,CAAC;oBACF,MAAM,EAAE,CAAC,sBAAa,CAAC;iBAC1B;gBACD,2CAAmB;gBACnB,uCAAiB;aACpB;YACD,OAAO,EAAE,CAAC,2CAAmB,EAAE,uCAAiB,CAAC;SACpD,CAAC;IACN,CAAC;CACJ,CAAA;AAxBY,gDAAkB;6BAAlB,kBAAkB;IAD9B,IAAA,eAAM,EAAC,EAAE,CAAC;GACE,kBAAkB,CAwB9B"}
|