@hemia/core 0.0.3 → 0.0.4

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.
@@ -4,7 +4,8 @@ import { METADATA_KEYS, ParamType, isRedirectResponse, ApiResponse } from '@hemi
4
4
  import { TRACE_METADATA_KEY } from '@hemia/trace-manager';
5
5
  import { traceMiddleware } from '@hemia/app-context';
6
6
  import { plainToInstance } from 'class-transformer';
7
- import { injectable } from 'inversify';
7
+ import { injectable, inject } from 'inversify';
8
+ import { AUTH_SERVICE_ID, AuthService } from '@hemia/auth-sdk';
8
9
 
9
10
  class GuardsConsumer {
10
11
  /**
@@ -206,6 +207,10 @@ function __decorate(decorators, target, key, desc) {
206
207
  return c > 3 && r && Object.defineProperty(target, key, r), r;
207
208
  }
208
209
 
210
+ function __param(paramIndex, decorator) {
211
+ return function (target, key) { decorator(target, key, paramIndex); }
212
+ }
213
+
209
214
  function __metadata(metadataKey, metadataValue) {
210
215
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
211
216
  }
@@ -299,6 +304,10 @@ class HemiaFactory {
299
304
  }
300
305
  }
301
306
 
307
+ /**
308
+ * Guardia de autorización que verifica roles y permisos definidos en los controladores y métodos.
309
+ * Utiliza los metadatos definidos con los decoradores @Roles y @Permissions.
310
+ */
302
311
  let AuthGuard = class AuthGuard {
303
312
  constructor(reflector) {
304
313
  this.reflector = reflector;
@@ -315,17 +324,19 @@ let AuthGuard = class AuthGuard {
315
324
  }
316
325
  const request = context.switchToHttp().getRequest();
317
326
  const user = request.user;
318
- if (!user || !user.roles) {
327
+ const permissions = request.permissions;
328
+ const contextData = request.context;
329
+ if (!user) {
319
330
  return false;
320
331
  }
321
332
  if (requiredRoles) {
322
- const userRoleNames = user.roles.map((r) => r.name);
333
+ const userRoleNames = Array.isArray(contextData.roles) ? contextData.roles : [];
323
334
  const hasRole = requiredRoles.some((role) => userRoleNames.includes(role));
324
335
  if (!hasRole)
325
336
  return false;
326
337
  }
327
338
  if (requiredPermissions) {
328
- const userPermissions = user.roles.flatMap((r) => r.permissions || []);
339
+ const userPermissions = Array.isArray(permissions) ? permissions : [];
329
340
  const hasPermission = requiredPermissions.some((perm) => userPermissions.includes(perm));
330
341
  if (!hasPermission)
331
342
  return false;
@@ -338,4 +349,66 @@ AuthGuard = __decorate([
338
349
  __metadata("design:paramtypes", [Reflector])
339
350
  ], AuthGuard);
340
351
 
341
- export { AuthGuard, GuardsConsumer, HemiaExecutionContext, HemiaFactory, Reflector, ResponseSerializer, registerRoutes };
352
+ /**
353
+ * Guardia para validar la presencia y validez de una API Key en las solicitudes entrantes.
354
+ * La API Key se espera en el encabezado 'x-api-key' o como parámetro de consulta 'api_key'.
355
+ * Las claves válidas se configuran mediante la variable de entorno 'API_KEY' y pueden ser múltiples, separadas por comas.
356
+ */
357
+ let ApiKeyGuard = class ApiKeyGuard {
358
+ constructor() {
359
+ this.validApiKeys = (process.env.API_KEY || "")
360
+ .split(",")
361
+ .map(key => key.trim())
362
+ .filter(key => !!key);
363
+ }
364
+ canActivate(context) {
365
+ const request = context.switchToHttp().getRequest();
366
+ const apiKey = request.headers['x-api-key'] || request.query['api_key'];
367
+ if (!apiKey)
368
+ return false;
369
+ return this.validApiKeys.includes(apiKey);
370
+ }
371
+ };
372
+ ApiKeyGuard = __decorate([
373
+ injectable(),
374
+ __metadata("design:paramtypes", [])
375
+ ], ApiKeyGuard);
376
+
377
+ /**
378
+ * Guardia para validar y procesar tokens JWT en las solicitudes entrantes.
379
+ * Extrae el token de sesión del encabezado 'x-session' o de las cookies,
380
+ * y utiliza el AuthService para validar el token y obtener los datos del usuario.
381
+ * Si el token es válido, adjunta la información del usuario, permisos y contexto a la solicitud.
382
+ */
383
+ let JWTGuard = class JWTGuard {
384
+ constructor(authService) {
385
+ this.authService = authService;
386
+ }
387
+ async canActivate(context) {
388
+ const request = context.switchToHttp().getRequest();
389
+ const sessionId = request.headers['x-session'] || request.cookies['x-session'];
390
+ if (!sessionId) {
391
+ return false;
392
+ }
393
+ try {
394
+ const accessTokenData = await this.authService.getSessionAccess(sessionId);
395
+ if (!accessTokenData) {
396
+ return false;
397
+ }
398
+ request.user = accessTokenData.user;
399
+ request.permissions = accessTokenData.permissions;
400
+ request.context = accessTokenData.context;
401
+ return true;
402
+ }
403
+ catch (error) {
404
+ return false;
405
+ }
406
+ }
407
+ };
408
+ JWTGuard = __decorate([
409
+ injectable(),
410
+ __param(0, inject(AUTH_SERVICE_ID)),
411
+ __metadata("design:paramtypes", [AuthService])
412
+ ], JWTGuard);
413
+
414
+ export { ApiKeyGuard, AuthGuard, GuardsConsumer, HemiaExecutionContext, HemiaFactory, JWTGuard, Reflector, ResponseSerializer, registerRoutes };
@@ -7,6 +7,7 @@ var traceManager = require('@hemia/trace-manager');
7
7
  var appContext = require('@hemia/app-context');
8
8
  var classTransformer = require('class-transformer');
9
9
  var inversify = require('inversify');
10
+ var authSdk = require('@hemia/auth-sdk');
10
11
 
11
12
  class GuardsConsumer {
12
13
  /**
@@ -208,6 +209,10 @@ function __decorate(decorators, target, key, desc) {
208
209
  return c > 3 && r && Object.defineProperty(target, key, r), r;
209
210
  }
210
211
 
212
+ function __param(paramIndex, decorator) {
213
+ return function (target, key) { decorator(target, key, paramIndex); }
214
+ }
215
+
211
216
  function __metadata(metadataKey, metadataValue) {
212
217
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
213
218
  }
@@ -301,6 +306,10 @@ class HemiaFactory {
301
306
  }
302
307
  }
303
308
 
309
+ /**
310
+ * Guardia de autorización que verifica roles y permisos definidos en los controladores y métodos.
311
+ * Utiliza los metadatos definidos con los decoradores @Roles y @Permissions.
312
+ */
304
313
  exports.AuthGuard = class AuthGuard {
305
314
  constructor(reflector) {
306
315
  this.reflector = reflector;
@@ -317,17 +326,19 @@ exports.AuthGuard = class AuthGuard {
317
326
  }
318
327
  const request = context.switchToHttp().getRequest();
319
328
  const user = request.user;
320
- if (!user || !user.roles) {
329
+ const permissions = request.permissions;
330
+ const contextData = request.context;
331
+ if (!user) {
321
332
  return false;
322
333
  }
323
334
  if (requiredRoles) {
324
- const userRoleNames = user.roles.map((r) => r.name);
335
+ const userRoleNames = Array.isArray(contextData.roles) ? contextData.roles : [];
325
336
  const hasRole = requiredRoles.some((role) => userRoleNames.includes(role));
326
337
  if (!hasRole)
327
338
  return false;
328
339
  }
329
340
  if (requiredPermissions) {
330
- const userPermissions = user.roles.flatMap((r) => r.permissions || []);
341
+ const userPermissions = Array.isArray(permissions) ? permissions : [];
331
342
  const hasPermission = requiredPermissions.some((perm) => userPermissions.includes(perm));
332
343
  if (!hasPermission)
333
344
  return false;
@@ -340,6 +351,68 @@ exports.AuthGuard = __decorate([
340
351
  __metadata("design:paramtypes", [exports.Reflector])
341
352
  ], exports.AuthGuard);
342
353
 
354
+ /**
355
+ * Guardia para validar la presencia y validez de una API Key en las solicitudes entrantes.
356
+ * La API Key se espera en el encabezado 'x-api-key' o como parámetro de consulta 'api_key'.
357
+ * Las claves válidas se configuran mediante la variable de entorno 'API_KEY' y pueden ser múltiples, separadas por comas.
358
+ */
359
+ exports.ApiKeyGuard = class ApiKeyGuard {
360
+ constructor() {
361
+ this.validApiKeys = (process.env.API_KEY || "")
362
+ .split(",")
363
+ .map(key => key.trim())
364
+ .filter(key => !!key);
365
+ }
366
+ canActivate(context) {
367
+ const request = context.switchToHttp().getRequest();
368
+ const apiKey = request.headers['x-api-key'] || request.query['api_key'];
369
+ if (!apiKey)
370
+ return false;
371
+ return this.validApiKeys.includes(apiKey);
372
+ }
373
+ };
374
+ exports.ApiKeyGuard = __decorate([
375
+ inversify.injectable(),
376
+ __metadata("design:paramtypes", [])
377
+ ], exports.ApiKeyGuard);
378
+
379
+ /**
380
+ * Guardia para validar y procesar tokens JWT en las solicitudes entrantes.
381
+ * Extrae el token de sesión del encabezado 'x-session' o de las cookies,
382
+ * y utiliza el AuthService para validar el token y obtener los datos del usuario.
383
+ * Si el token es válido, adjunta la información del usuario, permisos y contexto a la solicitud.
384
+ */
385
+ exports.JWTGuard = class JWTGuard {
386
+ constructor(authService) {
387
+ this.authService = authService;
388
+ }
389
+ async canActivate(context) {
390
+ const request = context.switchToHttp().getRequest();
391
+ const sessionId = request.headers['x-session'] || request.cookies['x-session'];
392
+ if (!sessionId) {
393
+ return false;
394
+ }
395
+ try {
396
+ const accessTokenData = await this.authService.getSessionAccess(sessionId);
397
+ if (!accessTokenData) {
398
+ return false;
399
+ }
400
+ request.user = accessTokenData.user;
401
+ request.permissions = accessTokenData.permissions;
402
+ request.context = accessTokenData.context;
403
+ return true;
404
+ }
405
+ catch (error) {
406
+ return false;
407
+ }
408
+ }
409
+ };
410
+ exports.JWTGuard = __decorate([
411
+ inversify.injectable(),
412
+ __param(0, inversify.inject(authSdk.AUTH_SERVICE_ID)),
413
+ __metadata("design:paramtypes", [authSdk.AuthService])
414
+ ], exports.JWTGuard);
415
+
343
416
  exports.GuardsConsumer = GuardsConsumer;
344
417
  exports.HemiaExecutionContext = HemiaExecutionContext;
345
418
  exports.HemiaFactory = HemiaFactory;
@@ -0,0 +1,11 @@
1
+ import { CanActivate, ExecutionContext } from "@hemia/common";
2
+ /**
3
+ * Guardia para validar la presencia y validez de una API Key en las solicitudes entrantes.
4
+ * La API Key se espera en el encabezado 'x-api-key' o como parámetro de consulta 'api_key'.
5
+ * Las claves válidas se configuran mediante la variable de entorno 'API_KEY' y pueden ser múltiples, separadas por comas.
6
+ */
7
+ export declare class ApiKeyGuard implements CanActivate {
8
+ private readonly validApiKeys;
9
+ constructor();
10
+ canActivate(context: ExecutionContext): boolean;
11
+ }
@@ -1,5 +1,9 @@
1
1
  import { CanActivate, ExecutionContext } from '@hemia/common';
2
2
  import { Reflector } from '../services';
3
+ /**
4
+ * Guardia de autorización que verifica roles y permisos definidos en los controladores y métodos.
5
+ * Utiliza los metadatos definidos con los decoradores @Roles y @Permissions.
6
+ */
3
7
  export declare class AuthGuard implements CanActivate {
4
8
  private reflector;
5
9
  constructor(reflector: Reflector);
@@ -1,2 +1,4 @@
1
1
  export * from "./auth.guard";
2
2
  export * from "./guards-consumer";
3
+ export * from "./api-key.guard";
4
+ export * from "./jwt.guard";
@@ -0,0 +1,13 @@
1
+ import { CanActivate, ExecutionContext } from "@hemia/common";
2
+ import { AuthService } from "@hemia/auth-sdk";
3
+ /**
4
+ * Guardia para validar y procesar tokens JWT en las solicitudes entrantes.
5
+ * Extrae el token de sesión del encabezado 'x-session' o de las cookies,
6
+ * y utiliza el AuthService para validar el token y obtener los datos del usuario.
7
+ * Si el token es válido, adjunta la información del usuario, permisos y contexto a la solicitud.
8
+ */
9
+ export declare class JWTGuard implements CanActivate {
10
+ private readonly authService;
11
+ constructor(authService: AuthService);
12
+ canActivate(context: ExecutionContext): Promise<boolean>;
13
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hemia/core",
3
- "version": "0.0.3",
3
+ "version": "0.0.4",
4
4
  "description": "Core utilities for Hemia projects",
5
5
  "main": "dist/hemia-core.js",
6
6
  "module": "dist/hemia-core.esm.js",
@@ -17,9 +17,10 @@
17
17
  "@rollup/plugin-commonjs": "^26.0.1",
18
18
  "@rollup/plugin-json": "^6.1.0",
19
19
  "@rollup/plugin-node-resolve": "^15.2.3",
20
- "@hemia/common": "^0.0.4",
20
+ "@hemia/common": "^0.0.5",
21
21
  "@hemia/app-context": "^0.0.6",
22
22
  "@hemia/trace-manager": "^0.0.9",
23
+ "@hemia/auth-sdk": "^0.0.9",
23
24
  "@types/express": "^5.0.5",
24
25
  "express": "^5.1.0",
25
26
  "inversify": "^7.10.4",
@@ -45,6 +46,6 @@
45
46
  "class-transformer": "^0.5.1",
46
47
  "express": "^5.0.0",
47
48
  "inversify": "^7.0.0",
48
- "reflect-metadata": "^0.1.13"
49
+ "reflect-metadata": "^0.2.2"
49
50
  }
50
51
  }