emilsoftware-utilities 2.0.0-dev.68 → 2.0.0-dev.69

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 (132) hide show
  1. package/dist/accessi/resource-server/errors.d.ts +1 -1
  2. package/dist/accessi/resource-server/errors.js.map +1 -1
  3. package/dist/accessi/resource-server/express.js +21 -0
  4. package/dist/accessi/resource-server/express.js.map +1 -1
  5. package/dist/accessi/resource-server/nest.js +13 -0
  6. package/dist/accessi/resource-server/nest.js.map +1 -1
  7. package/dist/accessi/resource-server/runtime.js +11 -1
  8. package/dist/accessi/resource-server/runtime.js.map +1 -1
  9. package/dist/accessi/resource-server/types.d.ts +7 -0
  10. package/dist/accessi/resource-server/types.js.map +1 -1
  11. package/dist/accessi/server/index.d.ts +1 -0
  12. package/dist/accessi/server/index.js +1 -0
  13. package/dist/accessi/server/index.js.map +1 -1
  14. package/dist/accessi/server/standalone.d.ts +41 -0
  15. package/dist/accessi/server/standalone.js +264 -0
  16. package/dist/accessi/server/standalone.js.map +1 -0
  17. package/dist/accessi-module/AccessiModule.d.ts +26 -1
  18. package/dist/accessi-module/AccessiModule.js +5 -2
  19. package/dist/accessi-module/AccessiModule.js.map +1 -1
  20. package/dist/accessi-module/Console/accessiFetch.d.ts +5 -0
  21. package/dist/accessi-module/Console/accessiFetch.js +7 -4
  22. package/dist/accessi-module/Console/accessiFetch.js.map +1 -1
  23. package/dist/accessi-module/Console/console.js +12 -4
  24. package/dist/accessi-module/Console/generated/emilsoftware-utilities.d.ts +31 -1
  25. package/dist/accessi-module/Console/generated/emilsoftware-utilities.js +28 -3
  26. package/dist/accessi-module/Console/generated/emilsoftware-utilities.js.map +1 -1
  27. package/dist/accessi-module/Console/generated/model/exchangeFederatedIdentityRequest.d.ts +12 -0
  28. package/dist/accessi-module/Console/generated/model/exchangeFederatedIdentityRequest.js +9 -0
  29. package/dist/accessi-module/Console/generated/model/exchangeFederatedIdentityRequest.js.map +1 -0
  30. package/dist/accessi-module/Console/generated/model/federatedAuthenticationResultDto.d.ts +15 -0
  31. package/dist/accessi-module/Console/generated/model/federatedAuthenticationResultDto.js +3 -0
  32. package/dist/accessi-module/Console/generated/model/federatedAuthenticationResultDto.js.map +1 -0
  33. package/dist/accessi-module/Console/generated/model/federatedExchangeResponse.d.ts +14 -0
  34. package/dist/accessi-module/Console/generated/model/federatedExchangeResponse.js +3 -0
  35. package/dist/accessi-module/Console/generated/model/federatedExchangeResponse.js.map +1 -0
  36. package/dist/accessi-module/Console/generated/model/index.d.ts +6 -0
  37. package/dist/accessi-module/Console/generated/model/index.js +6 -0
  38. package/dist/accessi-module/Console/generated/model/index.js.map +1 -1
  39. package/dist/accessi-module/Console/generated/model/loginResult.d.ts +2 -0
  40. package/dist/accessi-module/Console/generated/model/loginResult.js.map +1 -1
  41. package/dist/accessi-module/Console/generated/model/refreshTokenRequest.d.ts +10 -0
  42. package/dist/accessi-module/Console/generated/model/refreshTokenRequest.js +9 -0
  43. package/dist/accessi-module/Console/generated/model/refreshTokenRequest.js.map +1 -0
  44. package/dist/accessi-module/Console/generated/model/refreshTokenResponse.d.ts +14 -0
  45. package/dist/accessi-module/Console/generated/model/refreshTokenResponse.js +3 -0
  46. package/dist/accessi-module/Console/generated/model/refreshTokenResponse.js.map +1 -0
  47. package/dist/accessi-module/Console/generated/model/refreshTokenResult.d.ts +13 -0
  48. package/dist/accessi-module/Console/generated/model/refreshTokenResult.js +3 -0
  49. package/dist/accessi-module/Console/generated/model/refreshTokenResult.js.map +1 -0
  50. package/dist/accessi-module/Console/wiki.js +8 -1
  51. package/dist/accessi-module/Console/wiki.js.map +1 -1
  52. package/dist/accessi-module/Controllers/AccessiConsoleController.d.ts +6 -1
  53. package/dist/accessi-module/Controllers/AccessiConsoleController.js +24 -1
  54. package/dist/accessi-module/Controllers/AccessiConsoleController.js.map +1 -1
  55. package/dist/accessi-module/Controllers/AuthController.d.ts +3 -1
  56. package/dist/accessi-module/Controllers/AuthController.js +84 -2
  57. package/dist/accessi-module/Controllers/AuthController.js.map +1 -1
  58. package/dist/accessi-module/Dtos/FederatedExchangeDtos.d.ts +21 -0
  59. package/dist/accessi-module/Dtos/FederatedExchangeDtos.js +74 -0
  60. package/dist/accessi-module/Dtos/FederatedExchangeDtos.js.map +1 -0
  61. package/dist/accessi-module/Dtos/LoginResponse.d.ts +1 -0
  62. package/dist/accessi-module/Dtos/LoginResponse.js +6 -0
  63. package/dist/accessi-module/Dtos/LoginResponse.js.map +1 -1
  64. package/dist/accessi-module/Dtos/RefreshTokenDtos.d.ts +12 -0
  65. package/dist/accessi-module/Dtos/RefreshTokenDtos.js +50 -0
  66. package/dist/accessi-module/Dtos/RefreshTokenDtos.js.map +1 -0
  67. package/dist/accessi-module/Dtos/index.d.ts +2 -0
  68. package/dist/accessi-module/Dtos/index.js +2 -0
  69. package/dist/accessi-module/Dtos/index.js.map +1 -1
  70. package/dist/accessi-module/Services/AuthService/AuthService.d.ts +14 -0
  71. package/dist/accessi-module/Services/AuthService/AuthService.js +99 -6
  72. package/dist/accessi-module/Services/AuthService/AuthService.js.map +1 -1
  73. package/dist/accessi-module/database-updates/accessiOptionsFromEnv.js +1 -1
  74. package/dist/accessi-module/database-updates/accessiOptionsFromEnv.js.map +1 -1
  75. package/dist/accessi-module/federated-auth/FederatedAuthExchangeController.d.ts +15 -0
  76. package/dist/accessi-module/federated-auth/FederatedAuthExchangeController.js +85 -0
  77. package/dist/accessi-module/federated-auth/FederatedAuthExchangeController.js.map +1 -0
  78. package/dist/accessi-module/federated-auth/FederatedAuthService.js +7 -1
  79. package/dist/accessi-module/federated-auth/FederatedAuthService.js.map +1 -1
  80. package/dist/accessi-module/index.d.ts +8 -0
  81. package/dist/accessi-module/index.js +40 -4
  82. package/dist/accessi-module/index.js.map +1 -1
  83. package/dist/accessi-module/jwt/jwt.strategy.js +4 -0
  84. package/dist/accessi-module/jwt/jwt.strategy.js.map +1 -1
  85. package/dist/accessi-module/middleware/authenticateGen.js +4 -0
  86. package/dist/accessi-module/middleware/authenticateGen.js.map +1 -1
  87. package/dist/accessi-module/security/audit.d.ts +7 -0
  88. package/dist/accessi-module/security/audit.js +14 -0
  89. package/dist/accessi-module/security/audit.js.map +1 -0
  90. package/dist/accessi-module/security/authenticatedToken.d.ts +1 -1
  91. package/dist/accessi-module/security/authenticatedToken.js +3 -3
  92. package/dist/accessi-module/security/authenticatedToken.js.map +1 -1
  93. package/dist/accessi-module/security/consoleEntry.d.ts +2 -0
  94. package/dist/accessi-module/security/consoleEntry.js +16 -0
  95. package/dist/accessi-module/security/consoleEntry.js.map +1 -1
  96. package/dist/accessi-module/security/edgeRateLimit.d.ts +2 -0
  97. package/dist/accessi-module/security/edgeRateLimit.js +11 -0
  98. package/dist/accessi-module/security/edgeRateLimit.js.map +1 -1
  99. package/dist/accessi-module/security/jwksBootstrap.d.ts +15 -0
  100. package/dist/accessi-module/security/jwksBootstrap.js +44 -0
  101. package/dist/accessi-module/security/jwksBootstrap.js.map +1 -0
  102. package/dist/accessi-module/security/jwtTokenOptions.d.ts +9 -2
  103. package/dist/accessi-module/security/jwtTokenOptions.js +18 -4
  104. package/dist/accessi-module/security/jwtTokenOptions.js.map +1 -1
  105. package/dist/accessi-module/security/passwordResetToken.d.ts +1 -1
  106. package/dist/accessi-module/security/passwordResetToken.js.map +1 -1
  107. package/dist/accessi-module/security/publicAuthRateLimit.d.ts +1 -1
  108. package/dist/accessi-module/security/publicAuthRateLimit.js +1 -0
  109. package/dist/accessi-module/security/publicAuthRateLimit.js.map +1 -1
  110. package/dist/accessi-module/security/rateLimitStore.d.ts +2 -0
  111. package/dist/accessi-module/security/rateLimitStore.js +16 -0
  112. package/dist/accessi-module/security/rateLimitStore.js.map +1 -1
  113. package/dist/accessi-module/security/refreshTokenRotation.d.ts +40 -0
  114. package/dist/accessi-module/security/refreshTokenRotation.js +91 -0
  115. package/dist/accessi-module/security/refreshTokenRotation.js.map +1 -0
  116. package/dist/accessi-module/security/sessionRevocation.d.ts +52 -0
  117. package/dist/accessi-module/security/sessionRevocation.js +124 -0
  118. package/dist/accessi-module/security/sessionRevocation.js.map +1 -0
  119. package/dist/accessi-module/security/validateOptions.d.ts +19 -0
  120. package/dist/accessi-module/security/validateOptions.js +115 -0
  121. package/dist/accessi-module/security/validateOptions.js.map +1 -0
  122. package/dist/emilsoftware-utilities-2.0.0-dev.69.tgz +0 -0
  123. package/dist/initEmilsoftwareModule.js +22 -4
  124. package/dist/initEmilsoftwareModule.js.map +1 -1
  125. package/dist/scripts/startAccessiService.d.ts +1 -0
  126. package/dist/scripts/startAccessiService.js +11 -0
  127. package/dist/scripts/startAccessiService.js.map +1 -0
  128. package/docs/accessi-openapi-fingerprint.json +190 -0
  129. package/docs/standalone-service.md +176 -0
  130. package/integration-prompt.md +160 -0
  131. package/package.json +9 -4
  132. package/dist/emilsoftware-utilities-2.0.0-dev.68.tgz +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"initEmilsoftwareModule.js","sourceRoot":"","sources":["../src/initEmilsoftwareModule.ts"],"names":[],"mappings":"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","sourcesContent":["import express, { Application, Request } from \"express\";\nimport { NestFactory } from \"@nestjs/core\";\nimport { ExpressAdapter } from \"@nestjs/platform-express\";\nimport type { INestApplication } from \"@nestjs/common\";\nimport type { OpenAPIObject } from \"@nestjs/swagger\";\nimport {\n buildOpenApiExcludePaths,\n isOpenApiRequestPath,\n resolveAccessiOpenApiOptions,\n setupOpenApi\n} from \"./openapi/OpenApiConfig\";\nimport { Logger } from \"./Logger\";\nimport { EmilsoftwareModule, EmilsoftwareOptions } from \"./EmilsoftwareModule\";\nimport {\n beginAccessiAuthInitialization,\n failAccessiAuthInitialization,\n setAccessiAuthService\n} from \"./accessi-module/middleware/authenticateGen\";\nimport { registerAccessiModuleServices } from \"./accessi-module/accessiRuntime\";\nimport { logAccessiStartup } from \"./accessi-module/startupLog\";\nimport { createAccessiValidationPipe } from './accessi-module/security/accessiValidation';\nimport { AccessiHttpExceptionFilter } from './accessi-module/security/AccessiHttpExceptionFilter';\nimport { getAccessiJwksPath, setupAccessiJwks } from './accessi-module/security/jwks';\nimport { createAccessiEdgeRateLimitMiddleware } from './accessi-module/security/edgeRateLimit';\n\n/** Esito del bootstrap del modulo unificato. */\nexport interface EmilsoftwareModuleInitializationResult {\n /** Sotto-app Nest che serve Accessi, Allegati e la documentazione. */\n nestApp: INestApplication;\n /** Documento OpenAPI generato, mergiabile nel documento unico dell'host. */\n document: OpenAPIObject;\n}\n\n/**\n * Initializes the unified module that combines Accessi and Allegati functionality\n * @param app Express application instance\n * @param options Configuration options for both modules\n * @returns Il sotto-app Nest e il documento OpenAPI generato.\n */\nexport async function initEmilsoftwareModule(\n app: Application,\n options: EmilsoftwareOptions\n): Promise<EmilsoftwareModuleInitializationResult> {\n const logger: Logger = new Logger(initEmilsoftwareModule.name);\n if (options?.accessiOptions) {\n beginAccessiAuthInitialization();\n }\n\n try {\n // Isolate Nest on a dedicated Express instance and dispatch only module routes.\n // This keeps pre-existing routes/middlewares on the host app untouched.\n // Prefisso OpenAPI configurabile (default `accessi/openapi`), cosi' piu'\n // documentazioni possono convivere (backend su `/openapi`, moduli sotto\n // `/<modulo>/openapi`).\n // Precedenza: EmilsoftwareOptions.openapi > AccessiOptions.openapi > default.\n const resolvedOpenApi = resolveAccessiOpenApiOptions(\n options?.accessiOptions?.openapi,\n options?.openapi\n );\n\n const nestHostApp = express();\n const jwksPath = options?.accessiOptions\n ? getAccessiJwksPath(options.accessiOptions)\n : undefined;\n const isNestRoute = (path: string) =>\n path === \"/api\" ||\n path.startsWith(\"/api/\") ||\n isOpenApiRequestPath(path, resolvedOpenApi) ||\n (jwksPath !== undefined && path === jwksPath);\n const edgeRateLimit = options?.accessiOptions?.edgeRateLimit\n ? createAccessiEdgeRateLimitMiddleware({\n ...options.accessiOptions.edgeRateLimit,\n match: options.accessiOptions.edgeRateLimit.match ?? ((path) => isNestRoute(path)),\n })\n : undefined;\n if (edgeRateLimit) {\n app.use(edgeRateLimit);\n }\n\n app.use((req: Request, res, next) => {\n if (!isNestRoute(req.path)) {\n return next();\n }\n return nestHostApp(req, res, next);\n });\n\n if (options?.accessiOptions) {\n setupAccessiJwks(app, options.accessiOptions);\n if (jwksPath) {\n logger.info(`JWKS accessi disponibile su: ${jwksPath}`);\n }\n }\n\n const nestExpressInstance = new ExpressAdapter(nestHostApp);\n const nestApp = await NestFactory.create(EmilsoftwareModule.forRoot(options), nestExpressInstance, {\n bufferLogs: options?.bufferLogs !== false,\n ...(options?.logger ? { logger: options.logger } : {})\n });\n\n nestApp.enableCors();\n if (options?.accessiOptions) {\n // Keep the Accessi API contract identical for standalone and unified bootstraps.\n nestApp.useGlobalPipes(createAccessiValidationPipe());\n nestApp.useGlobalFilters(new AccessiHttpExceptionFilter());\n }\n\n nestApp.setGlobalPrefix('api', {\n exclude: buildOpenApiExcludePaths(resolvedOpenApi)\n });\n\n // Documentazione OpenAPI del modulo unificato (Accessi + Allegati).\n const document = setupOpenApi(nestApp, resolvedOpenApi);\n\n await nestApp.init();\n if (options?.accessiOptions) {\n const accessiServices = registerAccessiModuleServices(app, nestApp);\n app.locals.accessiAuthService = accessiServices.authenticateGenService;\n setAccessiAuthService(accessiServices.authenticateGenService);\n logAccessiStartup(options.accessiOptions, resolvedOpenApi);\n }\n\n logger.info(\"Emilsoftware module initialized successfully\");\n\n return { nestApp, document };\n } catch (error) {\n if (options?.accessiOptions) {\n failAccessiAuthInitialization(error);\n }\n logger.error(\"Error initializing Emilsoftware Module:\", error);\n throw error;\n }\n}\n"]}
1
+ {"version":3,"file":"initEmilsoftwareModule.js","sourceRoot":"","sources":["../src/initEmilsoftwareModule.ts"],"names":[],"mappings":"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","sourcesContent":["import express, { Application, Request } from \"express\";\nimport { NestFactory } from \"@nestjs/core\";\nimport { ExpressAdapter } from \"@nestjs/platform-express\";\nimport type { INestApplication } from \"@nestjs/common\";\nimport type { OpenAPIObject } from \"@nestjs/swagger\";\nimport {\n buildOpenApiExcludePaths,\n isOpenApiRequestPath,\n resolveAccessiOpenApiOptions,\n setupOpenApi\n} from \"./openapi/OpenApiConfig\";\nimport { Logger } from \"./Logger\";\nimport { EmilsoftwareModule, EmilsoftwareOptions } from \"./EmilsoftwareModule\";\nimport {\n beginAccessiAuthInitialization,\n failAccessiAuthInitialization,\n setAccessiAuthService\n} from \"./accessi-module/middleware/authenticateGen\";\nimport { registerAccessiModuleServices } from \"./accessi-module/accessiRuntime\";\nimport { logAccessiStartup } from \"./accessi-module/startupLog\";\nimport { createAccessiValidationPipe } from './accessi-module/security/accessiValidation';\nimport { AccessiHttpExceptionFilter } from './accessi-module/security/AccessiHttpExceptionFilter';\nimport { getAccessiJwksPath, setupAccessiJwks } from './accessi-module/security/jwks';\nimport { createAccessiEdgeRateLimitMiddleware } from './accessi-module/security/edgeRateLimit';\n\n/** Esito del bootstrap del modulo unificato. */\nexport interface EmilsoftwareModuleInitializationResult {\n /** Sotto-app Nest che serve Accessi, Allegati e la documentazione. */\n nestApp: INestApplication;\n /** Documento OpenAPI generato, mergiabile nel documento unico dell'host. */\n document: OpenAPIObject;\n}\n\n/**\n * Initializes the unified module that combines Accessi and Allegati functionality\n * @param app Express application instance\n * @param options Configuration options for both modules\n * @returns Il sotto-app Nest e il documento OpenAPI generato.\n */\nexport async function initEmilsoftwareModule(\n app: Application,\n options: EmilsoftwareOptions\n): Promise<EmilsoftwareModuleInitializationResult> {\n const logger: Logger = new Logger(initEmilsoftwareModule.name);\n if (options?.accessiOptions) {\n beginAccessiAuthInitialization();\n }\n\n try {\n // Isolate Nest on a dedicated Express instance and dispatch only module routes.\n // This keeps pre-existing routes/middlewares on the host app untouched.\n // Prefisso OpenAPI configurabile (default `accessi/openapi`), cosi' piu'\n // documentazioni possono convivere (backend su `/openapi`, moduli sotto\n // `/<modulo>/openapi`).\n // Precedenza: EmilsoftwareOptions.openapi > AccessiOptions.openapi > default.\n const resolvedOpenApi = resolveAccessiOpenApiOptions(\n options?.accessiOptions?.openapi,\n options?.openapi\n );\n\n const nestHostApp = express();\n if (options?.accessiOptions?.http?.trustProxy !== undefined) {\n app.set('trust proxy', options.accessiOptions.http.trustProxy);\n nestHostApp.set('trust proxy', options.accessiOptions.http.trustProxy);\n }\n const jwksPath = options?.accessiOptions\n ? getAccessiJwksPath(options.accessiOptions)\n : undefined;\n const isNestRoute = (path: string) =>\n path === \"/api\" ||\n path.startsWith(\"/api/\") ||\n isOpenApiRequestPath(path, resolvedOpenApi) ||\n (jwksPath !== undefined && path === jwksPath);\n const edgeRateLimit = options?.accessiOptions?.edgeRateLimit\n ? createAccessiEdgeRateLimitMiddleware({\n ...options.accessiOptions.edgeRateLimit,\n match: options.accessiOptions.edgeRateLimit.match ?? ((path) => isNestRoute(path)),\n })\n : undefined;\n if (edgeRateLimit) {\n app.use(edgeRateLimit);\n }\n if (options?.accessiOptions?.http?.securityHeaders !== false) {\n app.use((req: Request, res, next) => {\n if (!isNestRoute(req.path)) {\n return next();\n }\n res.setHeader('X-Content-Type-Options', 'nosniff');\n res.setHeader('X-Frame-Options', 'SAMEORIGIN');\n res.setHeader('Referrer-Policy', 'no-referrer');\n res.setHeader('Permissions-Policy', 'camera=(), microphone=(), geolocation=()');\n return next();\n });\n }\n\n app.use((req: Request, res, next) => {\n if (!isNestRoute(req.path)) {\n return next();\n }\n return nestHostApp(req, res, next);\n });\n\n if (options?.accessiOptions) {\n setupAccessiJwks(app, options.accessiOptions);\n if (jwksPath) {\n logger.info(`JWKS accessi disponibile su: ${jwksPath}`);\n }\n }\n\n const nestExpressInstance = new ExpressAdapter(nestHostApp);\n const nestApp = await NestFactory.create(EmilsoftwareModule.forRoot(options), nestExpressInstance, {\n bufferLogs: options?.bufferLogs !== false,\n ...(options?.logger ? { logger: options.logger } : {})\n });\n\n if (options?.accessiOptions?.http?.cors !== false) {\n nestApp.enableCors(options?.accessiOptions?.http?.cors);\n }\n if (options?.accessiOptions) {\n // Keep the Accessi API contract identical for standalone and unified bootstraps.\n nestApp.useGlobalPipes(createAccessiValidationPipe());\n nestApp.useGlobalFilters(new AccessiHttpExceptionFilter());\n }\n\n nestApp.setGlobalPrefix('api', {\n exclude: buildOpenApiExcludePaths(resolvedOpenApi)\n });\n\n // Documentazione OpenAPI del modulo unificato (Accessi + Allegati).\n const document = setupOpenApi(nestApp, resolvedOpenApi);\n\n await nestApp.init();\n if (options?.accessiOptions) {\n const accessiServices = registerAccessiModuleServices(app, nestApp);\n app.locals.accessiAuthService = accessiServices.authenticateGenService;\n setAccessiAuthService(accessiServices.authenticateGenService);\n logAccessiStartup(options.accessiOptions, resolvedOpenApi);\n }\n\n logger.info(\"Emilsoftware module initialized successfully\");\n\n return { nestApp, document };\n } catch (error) {\n if (options?.accessiOptions) {\n failAccessiAuthInitialization(error);\n }\n logger.error(\"Error initializing Emilsoftware Module:\", error);\n throw error;\n }\n}\n"]}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const server_1 = require("../accessi/server");
4
+ const Logger_1 = require("../Logger");
5
+ (0, server_1.startAccessiService)().catch((error) => {
6
+ new Logger_1.Logger('startAccessiService').error('Avvio Accessi Service fallito:', error instanceof Error
7
+ ? { name: error.name, message: error.message, stack: error.stack }
8
+ : { error: String(error) });
9
+ process.exitCode = 1;
10
+ });
11
+ //# sourceMappingURL=startAccessiService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"startAccessiService.js","sourceRoot":"","sources":["../../src/scripts/startAccessiService.ts"],"names":[],"mappings":";;AAAA,8CAAwD;AACxD,sCAAmC;AAEnC,IAAA,4BAAmB,GAAE,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;IAC7C,IAAI,eAAM,CAAC,qBAAqB,CAAC,CAAC,KAAK,CACrC,gCAAgC,EAChC,KAAK,YAAY,KAAK;QACpB,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE;QAClE,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAC7B,CAAC;IACF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC","sourcesContent":["import { startAccessiService } from '../accessi/server';\nimport { Logger } from '../Logger';\n\nstartAccessiService().catch((error: unknown) => {\n new Logger('startAccessiService').error(\n 'Avvio Accessi Service fallito:',\n error instanceof Error\n ? { name: error.name, message: error.message, stack: error.stack }\n : { error: String(error) },\n );\n process.exitCode = 1;\n});\n"]}
@@ -0,0 +1,190 @@
1
+ {
2
+ "paths": [
3
+ "DELETE /api/accessi/federated-auth/identities/{identityKey} disableFederatedIdentity",
4
+ "DELETE /api/accessi/federated-auth/providers/{provider} deleteFederatedProvider",
5
+ "DELETE /api/accessi/federated-auth/users/{codiceUtente}/identities/{identityKey} deleteFederatedIdentityPermanently",
6
+ "DELETE /api/accessi/filtri/tipi/{tipFil} deleteTipoFiltro",
7
+ "DELETE /api/accessi/permission/delete-role/{codiceRuolo} deleteRole",
8
+ "DELETE /api/accessi/permission/menu-groups/{codiceGruppo} deleteMenuGroup",
9
+ "DELETE /api/accessi/permission/menu-types/{codiceTipo} deleteMenuType",
10
+ "DELETE /api/accessi/permission/menus/{codiceMenu} deleteMenu",
11
+ "DELETE /api/accessi/permission/scopes/{codiceScope} deleteScope",
12
+ "DELETE /api/accessi/service-token/{tokenId} revokeServiceToken",
13
+ "DELETE /api/accessi/user/delete-user-permanent/{codiceUtente} deleteUserPermanently",
14
+ "DELETE /api/accessi/user/delete-user/{codiceUtente} deleteUser",
15
+ "GET /api/accessi/auth/bootstrap-admin/status getAdminBootstrapStatus",
16
+ "GET /api/accessi/email/reset-password-page/{token} serveResetPasswordPage",
17
+ "GET /api/accessi/federated-auth/providers getFederatedProviders",
18
+ "GET /api/accessi/federated-auth/users/{codiceUtente}/identities getFederatedIdentities",
19
+ "GET /api/accessi/filtri/tipi getTipiFiltro",
20
+ "GET /api/accessi/filtri/utente getFiltriUtente",
21
+ "GET /api/accessi/permission/grants/{codiceUtente} getUserRolesAndGrants",
22
+ "GET /api/accessi/permission/groups-with-menus getGroupsWithMenus",
23
+ "GET /api/accessi/permission/menu-types getMenuTypes",
24
+ "GET /api/accessi/permission/menus getMenus",
25
+ "GET /api/accessi/permission/menus/{codiceMenu}/scopes getMenuScopes",
26
+ "GET /api/accessi/permission/roles getRoles",
27
+ "GET /api/accessi/permission/scopes getScopes",
28
+ "GET /api/accessi/schema getSchema",
29
+ "GET /api/accessi/service-token getServiceTokens",
30
+ "GET /api/accessi/user/get-users getUsers",
31
+ "GET /api/accessi/user/reset-password/{token} serveResetPasswordPageUser",
32
+ "PATCH /api/accessi/configurator/groups/{codiceGruppo}/enabled setGroupEnabled",
33
+ "PATCH /api/accessi/configurator/menus/{codiceMenu}/enabled setMenuEnabled",
34
+ "PATCH /api/accessi/federated-auth/identities/{identityKey} updateFederatedIdentity",
35
+ "PATCH /api/accessi/federated-auth/providers/{provider} updateFederatedProvider",
36
+ "PATCH /api/accessi/federated-auth/users/{codiceUtente}/password-login setPasswordLoginPolicy",
37
+ "PATCH /api/accessi/user/set-gdpr/{codiceUtente} setGdpr",
38
+ "POST /api/accessi/auth/bootstrap-admin bootstrapAdmin",
39
+ "POST /api/accessi/auth/confirm-reset-password/{token} resetPassword",
40
+ "POST /api/accessi/auth/get-user-by-token getUserByToken",
41
+ "POST /api/accessi/auth/introspect introspectAccessiToken",
42
+ "POST /api/accessi/auth/login login",
43
+ "POST /api/accessi/auth/refresh refreshAccessToken",
44
+ "POST /api/accessi/auth/revoke-sessions revokeSessions",
45
+ "POST /api/accessi/auth/two-factor/resend resendTwoFactor",
46
+ "POST /api/accessi/auth/two-factor/verify verifyTwoFactor",
47
+ "POST /api/accessi/console/entry createConsoleEntryTicket",
48
+ "POST /api/accessi/console/entry/exchange exchangeConsoleEntryTicket",
49
+ "POST /api/accessi/email/send-reset-password-email sendPasswordResetEmail",
50
+ "POST /api/accessi/federated-auth/exchange exchangeFederatedIdentity",
51
+ "POST /api/accessi/federated-auth/providers createFederatedProvider",
52
+ "POST /api/accessi/federated-auth/users createFederatedUser",
53
+ "POST /api/accessi/federated-auth/users/{codiceUtente}/identities linkFederatedIdentity",
54
+ "POST /api/accessi/filtri/tipi createTipoFiltro",
55
+ "POST /api/accessi/filtri/utente saveFiltriUtente",
56
+ "POST /api/accessi/permission/assign-permissions/{codiceUtente} assignPermissionsToUser",
57
+ "POST /api/accessi/permission/assign-roles/{codiceUtente} assignRolesToUser",
58
+ "POST /api/accessi/permission/create-role createRole",
59
+ "POST /api/accessi/permission/menu-groups createMenuGroup",
60
+ "POST /api/accessi/permission/menu-types createMenuType",
61
+ "POST /api/accessi/permission/menus createMenu",
62
+ "POST /api/accessi/permission/scopes createScope",
63
+ "POST /api/accessi/service-token createServiceToken",
64
+ "POST /api/accessi/service-token/{tokenId}/rotate rotateServiceToken",
65
+ "POST /api/accessi/user/create-managed-user createManagedUser",
66
+ "POST /api/accessi/user/force-password-reset-legacy forcePasswordResetLegacy",
67
+ "POST /api/accessi/user/force-password-reset/{codiceUtente} forcePasswordReset",
68
+ "POST /api/accessi/user/login-as/{codiceUtente} createLoginAsUrl",
69
+ "POST /api/accessi/user/register register",
70
+ "POST /api/accessi/user/set-password/{codiceUtente} setUserPassword",
71
+ "POST /api/accessi/user/set-stato setStatoRegistrazione",
72
+ "PUT /api/accessi/filtri/tipi/{tipFil} updateTipoFiltro",
73
+ "PUT /api/accessi/permission/menu-groups/{codiceGruppo} updateMenuGroup",
74
+ "PUT /api/accessi/permission/menu-types/{codiceTipo} updateMenuType",
75
+ "PUT /api/accessi/permission/menus/{codiceMenu} updateMenu",
76
+ "PUT /api/accessi/permission/menus/{codiceMenu}/scopes setMenuScopes",
77
+ "PUT /api/accessi/permission/scopes/{codiceScope} updateScope",
78
+ "PUT /api/accessi/permission/scopes/{codiceScope}/menus setScopeMenus",
79
+ "PUT /api/accessi/permission/update-role/{codiceRuolo} updateRole",
80
+ "PUT /api/accessi/user/update-user/{codiceUtente} updateUtente"
81
+ ],
82
+ "schemas": [
83
+ "AbilitazioneMenu",
84
+ "AccessiIntrospectionResultDto",
85
+ "ActionResponse",
86
+ "AdminBootstrapStatusResponse",
87
+ "AdminBootstrapStatusResult",
88
+ "AssignPermissionsToUserRequest",
89
+ "AssignRolesToUserRequest",
90
+ "AuthenticatedTokenPayloadDto",
91
+ "AuthenticatedUserPayloadDto",
92
+ "BootstrapAdminRequest",
93
+ "BootstrapAdminResponse",
94
+ "BootstrapAdminResultDto",
95
+ "ConfirmResetPasswordRequest",
96
+ "ConsoleEntryExchangeRequest",
97
+ "ConsoleEntrySessionResponse",
98
+ "ConsoleEntrySessionResult",
99
+ "ConsoleEntryTicketResponse",
100
+ "ConsoleEntryTicketResult",
101
+ "ConsoleEntryTokenResult",
102
+ "CreateFederatedIdentityRequest",
103
+ "CreateFederatedProviderRequest",
104
+ "CreateFederatedUserRequest",
105
+ "CreateFilterTypeRequest",
106
+ "CreateMenuGroupRequest",
107
+ "CreateMenuRequest",
108
+ "CreateMenuTypeRequest",
109
+ "CreateScopeRequest",
110
+ "CreateServiceTokenRequest",
111
+ "CreateServiceTokenResponse",
112
+ "ErrorResponse",
113
+ "ExchangeFederatedIdentityRequest",
114
+ "FederatedAuthenticationResultDto",
115
+ "FederatedExchangeResponse",
116
+ "FederatedIdentityListResponse",
117
+ "FederatedIdentityResponse",
118
+ "FederatedIdentityResponseDto",
119
+ "FederatedProviderListResponse",
120
+ "FederatedProviderResponse",
121
+ "FederatedProviderResponseDto",
122
+ "FiltriUtente",
123
+ "GetFiltriResponse",
124
+ "GetFiltriUtenteResponse",
125
+ "GetGroupsWithMenusResponse",
126
+ "GetMenuScopesResponse",
127
+ "GetMenuTypesResponse",
128
+ "GetMenusResponse",
129
+ "GetRolesResponse",
130
+ "GetSchemaResponse",
131
+ "GetScopesResponse",
132
+ "GetServiceTokensResponse",
133
+ "GetUserByTokenRequest",
134
+ "GetUserByTokenResponse",
135
+ "GetUsersResponse",
136
+ "GetUsersResult",
137
+ "GroupWithMenusEntity",
138
+ "IntrospectAccessiTokenRequest",
139
+ "IntrospectAccessiTokenResponse",
140
+ "IssuedServiceTokenDto",
141
+ "LoginAsRequest",
142
+ "LoginAsResponse",
143
+ "LoginAsResult",
144
+ "LoginRequest",
145
+ "LoginResponse",
146
+ "LoginResult",
147
+ "MenuEntity",
148
+ "MenuTypeEntity",
149
+ "PasswordExpiredResponse",
150
+ "Permission",
151
+ "PublicRegisterRequest",
152
+ "RefreshTokenRequest",
153
+ "RefreshTokenResponse",
154
+ "RefreshTokenResult",
155
+ "RegisterRequest",
156
+ "RegisterResponse",
157
+ "ResendTwoFactorRequest",
158
+ "Role",
159
+ "RuoliMenu",
160
+ "SchemaDdlResult",
161
+ "SchemaDdlSection",
162
+ "ScopeEntity",
163
+ "SendResetPasswordEmailRequest",
164
+ "ServiceTokenDto",
165
+ "SetMenuScopesRequest",
166
+ "SetPasswordLoginPolicyRequest",
167
+ "SetScopeMenusRequest",
168
+ "SetStatoRegistrazioneDto",
169
+ "SetUserPasswordRequest",
170
+ "Status",
171
+ "TipoFiltro",
172
+ "TokenResult",
173
+ "TwoFactorChallengeDto",
174
+ "UpdateEnabledStatusRequest",
175
+ "UpdateFederatedIdentityRequest",
176
+ "UpdateFederatedProviderRequest",
177
+ "UpdateFilterTypeRequest",
178
+ "UpdateMenuGroupRequest",
179
+ "UpdateMenuRequest",
180
+ "UpdateMenuTypeRequest",
181
+ "UpdateScopeRequest",
182
+ "UserDto",
183
+ "UserGrantsDto",
184
+ "UserGrantsResponse",
185
+ "VerifyTwoFactorRequest"
186
+ ],
187
+ "securitySchemes": [
188
+ "bearer"
189
+ ]
190
+ }
@@ -0,0 +1,176 @@
1
+ # Accessi Service standalone
2
+
3
+ Accessi puo girare come servizio autonomo, senza un backend ospitante.
4
+
5
+ ## Avvio da codice
6
+
7
+ ```ts
8
+ import { startAccessiService } from "emilsoftware-utilities/accessi/server";
9
+
10
+ await startAccessiService({
11
+ port: Number(process.env.PORT ?? 3000),
12
+ healthPath: "/health",
13
+ metrics: true,
14
+ });
15
+ ```
16
+
17
+ `startAccessiService`:
18
+
19
+ - valida `AccessiOptions` con `assertValidAccessiOptions`
20
+ - crea l'app Express
21
+ - monta `/health/live`, `/health/ready`, `/health/metrics`
22
+ - inizializza Accessi
23
+ - avvia il server
24
+ - registra `SIGTERM`/`SIGINT` per lo shutdown graceful
25
+ - chiude Nest e i pool Firebird
26
+
27
+ Per un controllo manuale usare `createAccessiService`, che restituisce `start()` e `stop()`.
28
+
29
+ ## Avvio da CLI
30
+
31
+ ```bash
32
+ npm run accessi:serve
33
+ npm run accessi:serve:dist
34
+ ```
35
+
36
+ La configurazione viene letta da `createAccessiOptionsFromEnv()`.
37
+
38
+ ## Health
39
+
40
+ ```text
41
+ GET /health/live -> 200 se il processo e vivo
42
+ GET /health/ready -> 200 se DB e store configurati sono pronti
43
+ GET /health/metrics -> metriche Prometheus testuali
44
+ ```
45
+
46
+ `/health/ready` controlla:
47
+
48
+ - bootstrap completato
49
+ - database Accessi raggiungibile e schema inizializzato
50
+ - `healthCheck()` degli store Redis configurati
51
+ - `readinessChecks` aggiuntivi passati dal chiamante
52
+
53
+ ## Esecuzione come processo
54
+
55
+ In produzione il servizio viene eseguito come processo Node gestito da systemd, PM2 o dal supervisor del cliente:
56
+
57
+ ```bash
58
+ npm run accessi:serve:dist
59
+ # oppure
60
+ node dist/scripts/startAccessiService.js
61
+ ```
62
+
63
+ Esempio systemd minimale:
64
+
65
+ ```ini
66
+ [Unit]
67
+ Description=Accessi Service
68
+ After=network.target
69
+
70
+ [Service]
71
+ WorkingDirectory=/opt/accessi-service
72
+ EnvironmentFile=/etc/accessi/accessi.env
73
+ ExecStart=/usr/bin/node dist/scripts/startAccessiService.js
74
+ Restart=on-failure
75
+ RestartSec=5
76
+ KillSignal=SIGTERM
77
+ TimeoutStopSec=15
78
+
79
+ [Install]
80
+ WantedBy=multi-user.target
81
+ ```
82
+
83
+ Il readiness endpoint `/health/ready` va usato dal load balancer o dal supervisore per decidere quando inviare traffico.
84
+
85
+ ## Configurazione consigliata
86
+
87
+ - `ACCESSI_DB_*`
88
+ - `ACCESSI_ENCRYPTION_KEY`
89
+ - `ACCESSI_JWT_SECRET`
90
+ - `ACCESSI_JWT_ISSUER`
91
+ - `ACCESSI_JWT_AUDIENCE`
92
+ - `ACCESSI_JWT_ALGORITHM`, `ACCESSI_JWT_PRIVATE_KEY`, `ACCESSI_JWT_PUBLIC_KEY`, `ACCESSI_JWT_KEY_ID` per RS/ES
93
+ - `ACCESSI_JWKS_PATH`
94
+ - SMTP
95
+ - `PORT`
96
+
97
+ Per Redis, passare gli store nel bootstrap applicativo:
98
+
99
+ ```ts
100
+ import { createRedisRateLimitStore, createRedisConsoleEntryStore } from "emilsoftware-utilities/accessi/server";
101
+ ```
102
+
103
+ ## Generazione chiavi JWT
104
+
105
+ ```bash
106
+ npm run accessi:generate-jwt-keys -- --algorithm RS256 --out ./keys
107
+ ```
108
+
109
+ Genera:
110
+
111
+ - `jwt-private.pem`
112
+ - `jwt-public.pem`
113
+ - `jwks.json`
114
+ - `jwt-keys.json` con `algorithm` e `keyId`
115
+
116
+ Configurare poi:
117
+
118
+ ```env
119
+ ACCESSI_JWT_ALGORITHM=RS256
120
+ ACCESSI_JWT_PRIVATE_KEY=<contenuto jwt-private.pem>
121
+ ACCESSI_JWT_PUBLIC_KEY=<contenuto jwt-public.pem>
122
+ ACCESSI_JWT_KEY_ID=<keyId>
123
+ ```
124
+
125
+ ## Revoca sessioni
126
+
127
+ ```ts
128
+ import { createRedisSessionRevocationStore } from "emilsoftware-utilities/accessi/server";
129
+
130
+ sessionRevocation: {
131
+ store: createRedisSessionRevocationStore({
132
+ client: redis,
133
+ ttlMs: 30 * 24 * 60 * 60 * 1000, // maggiore della durata massima dei token
134
+ }),
135
+ }
136
+ ```
137
+
138
+ Endpoint utente:
139
+
140
+ ```http
141
+ POST /api/accessi/auth/revoke-sessions
142
+ Authorization: Bearer <access-token>
143
+ ```
144
+
145
+ I resource server fratelli devono ricevere lo stesso store in `revocation.store`.
146
+
147
+ ## Console su dominio separato
148
+
149
+ Se la console è servita da un dominio diverso dall’API:
150
+
151
+ ```ts
152
+ accessiOptions: {
153
+ ...options,
154
+ consoleApiBaseUrl: "https://accessi.example.com",
155
+ }
156
+ ```
157
+
158
+ Accessi inietta `window.__ACCESSI_API_BASE_URL__` nella pagina della console.
159
+
160
+ ## CORS e proxy
161
+
162
+ ```ts
163
+ accessiOptions: {
164
+ ...options,
165
+ http: {
166
+ cors: {
167
+ origin: ["https://app.example.com"],
168
+ credentials: false,
169
+ },
170
+ trustProxy: 1, // load balancer/reverse proxy
171
+ securityHeaders: true,
172
+ },
173
+ }
174
+ ```
175
+
176
+ Con Bearer token non serve CSRF. Se in futuro si passasse a cookie httpOnly, aggiungere CSRF e configurazione cookie same-site.
@@ -74,6 +74,60 @@ const { nestApp, document } = await initializeAccessiModule(app, options);
74
74
 
75
75
  Aprire la porta HTTP solo dopo l'await.
76
76
 
77
+ ### Avvio standalone
78
+
79
+ Per un servizio Accessi autonomo:
80
+
81
+ ```ts
82
+ import { startAccessiService } from "emilsoftware-utilities/accessi/server";
83
+
84
+ await startAccessiService({
85
+ port: Number(process.env.PORT ?? 3000),
86
+ healthPath: "/health",
87
+ metrics: true,
88
+ });
89
+ ```
90
+
91
+ Oppure:
92
+
93
+ ```bash
94
+ npm run accessi:serve
95
+ ```
96
+
97
+ Endpoint:
98
+
99
+ ```text
100
+ GET /health/live
101
+ GET /health/ready
102
+ GET /health/metrics
103
+ ```
104
+
105
+ `/health/ready` controlla bootstrap, database, schema, store Redis configurati e `readinessChecks` custom. `startAccessiService` registra SIGTERM/SIGINT e chiude Nest e i pool Firebird.
106
+
107
+ In produzione il servizio viene eseguito come processo Node con systemd/PM2/supervisor:
108
+
109
+ ```bash
110
+ npm run accessi:serve:dist
111
+ ```
112
+
113
+ Dettagli e esempio systemd: `docs/standalone-service.md`.
114
+
115
+ ### Validazione configurazione
116
+
117
+ ```ts
118
+ import {
119
+ assertValidAccessiOptions,
120
+ validateAccessiOptions,
121
+ } from "emilsoftware-utilities/accessi/server";
122
+
123
+ const validation = validateAccessiOptions(options);
124
+ // validation.errors / validation.warnings
125
+
126
+ assertValidAccessiOptions(options); // fail-fast
127
+ ```
128
+
129
+ `createAccessiService` la applica automaticamente. Controlla JWT/key, DB, encryption key, URL email, rate limit, console entry e `http`.
130
+
77
131
  ### Bootstrap Nest
78
132
 
79
133
  ```ts
@@ -150,6 +204,24 @@ const merged = mergeOpenApiDocuments(hostDocument, accessiDocument, {
150
204
  });
151
205
  ```
152
206
 
207
+ ### HTTP, CORS e proxy
208
+
209
+ ```ts
210
+ http: {
211
+ cors: {
212
+ origin: ["https://app.example.com"],
213
+ credentials: false,
214
+ },
215
+ trustProxy: 1, // load balancer/reverse proxy
216
+ securityHeaders: true,
217
+ }
218
+ ```
219
+
220
+ - `cors: false` disabilita CORS.
221
+ - `trustProxy` e obbligatorio per rate limit corretti dietro proxy.
222
+ - `securityHeaders` aggiunge `X-Content-Type-Options`, `X-Frame-Options`, `Referrer-Policy`, `Permissions-Policy`.
223
+ - Con Bearer token non serve CSRF. Se usi cookie httpOnly, aggiungi CSRF e cookie same-site.
224
+
153
225
  ### JWKS e rotazione chiavi
154
226
 
155
227
  Con RS256/ES256 Accessi pubblica automaticamente:
@@ -271,6 +343,12 @@ Il gateway/API gateway resta consigliato per:
271
343
 
272
344
  Configurazioni di riferimento: `docs/gateway-rate-limit.md`.
273
345
 
346
+ ### Audit
347
+
348
+ Resource server ed edge rate limit producono eventi strutturati tramite `auditAccessi`. I campi sensibili vengono redatti dal Logger. Disattivabile con `audit: false` nelle rispettive opzioni.
349
+
350
+ Nel servizio standalone le metriche Prometheus sono su `/health/metrics`.
351
+
274
352
  ---
275
353
 
276
354
  ## 4. Backend fratello — Express
@@ -397,6 +475,60 @@ Risposta:
397
475
  - Il resource server cachea i risultati attivi per `cacheTtlMs` (default 30s). I risultati inattivi non sono cachati.
398
476
  - Fail closed: se Accessi Service non risponde, la richiesta non viene autorizzata.
399
477
 
478
+ ### SSO exchange service-to-service
479
+
480
+ Se un backend fratello valida un provider SSO proprio, non deve duplicare utenti o grant. Dopo aver verificato firma, issuer, audience e subject del provider, chiama:
481
+
482
+ ```http
483
+ POST /api/accessi/federated-auth/exchange
484
+ Authorization: Bearer <service-token>
485
+ Content-Type: application/json
486
+
487
+ { "provider": "azure-ad-acme-produzione", "subject": "<oid o sub>" }
488
+ ```
489
+
490
+ Scope richiesto: `accessi:federated:exchange`.
491
+
492
+ La risposta contiene:
493
+
494
+ - `codiceUtente`
495
+ - `login` con profilo, grant e token
496
+ - `token` assente quando è richiesta la verifica 2FA
497
+
498
+ Accessi non riceve il token del provider: riceve solo l'identità esterna già verificata.
499
+
500
+ ### Revoca sessioni
501
+
502
+ Configurazione:
503
+
504
+ ```ts
505
+ import { createRedisSessionRevocationStore } from "emilsoftware-utilities/accessi/server";
506
+
507
+ sessionRevocation: {
508
+ store: createRedisSessionRevocationStore({
509
+ client: redis,
510
+ ttlMs: 30 * 24 * 60 * 60 * 1000, // maggiore della durata massima dei token
511
+ }),
512
+ }
513
+ ```
514
+
515
+ Endpoint utente:
516
+
517
+ ```http
518
+ POST /api/accessi/auth/revoke-sessions
519
+ Authorization: Bearer <access-token>
520
+ ```
521
+
522
+ Invalida i token emessi prima della chiamata. I token emessi dopo restano validi. Per i backend fratelli configurare lo stesso store anche nel resource server:
523
+
524
+ ```ts
525
+ revocation: {
526
+ store: revocationStore,
527
+ }
528
+ ```
529
+
530
+ Senza store condiviso la revoca vale solo nel processo che la esegue.
531
+
400
532
  ---
401
533
 
402
534
  ## 7. Frontend
@@ -426,6 +558,29 @@ configureAccessiClient({
426
558
  });
427
559
  ```
428
560
 
561
+ Se `jwtOptions.refreshExpiresIn` è configurato, la risposta contiene anche `refreshToken`. Conservarlo separatamente dall’access token e usarlo su:
562
+
563
+ ```http
564
+ POST /api/accessi/auth/refresh
565
+ Content-Type: application/json
566
+
567
+ { "refreshToken": "<refresh-token>" }
568
+ ```
569
+
570
+ La risposta contiene un nuovo `token` e un nuovo `refreshToken`. Il refresh token ha `typ: "refresh"` e non va mai usato come Bearer sulle API.
571
+
572
+ Per rendere il refresh token monouso anche in multi-istanza:
573
+
574
+ ```ts
575
+ import { createRedisRefreshTokenRotationStore } from "emilsoftware-utilities/accessi/server";
576
+
577
+ refreshTokenRotation: {
578
+ store: createRedisRefreshTokenRotationStore({ client: redis }),
579
+ }
580
+ ```
581
+
582
+ Ogni refresh consuma il vecchio `jti` in modo atomico. Due refresh concorrenti dello stesso token producono un solo successo.
583
+
429
584
  Per token che cambiano nel tempo:
430
585
 
431
586
  ```ts
@@ -455,6 +610,7 @@ const consoleUrl = buildAccessiConsoleUrl("https://accessi.example.com", {
455
610
  - Il ticket e monouso, dura 60 secondi.
456
611
  - Per il 2FA handoff usare `twoFactorChallengeId`.
457
612
  - Se la console deve stare sullo stesso dominio, fare reverse proxy di `/api/accessi/*` verso Accessi Service, non copiare gli asset.
613
+ - Se la UI della console è su un dominio diverso dall’API, configurare `consoleApiBaseUrl`: Accessi inietta `window.__ACCESSI_API_BASE_URL__` nella pagina servita.
458
614
 
459
615
  ### Web component
460
616
 
@@ -485,6 +641,7 @@ Per chiamare l'introspection o API tecniche:
485
641
  2. Creare un token dalla console o con `POST /api/accessi/service-token`.
486
642
  3. Assegnare lo scope minimo necessario:
487
643
  - `accessi:introspect` per l'introspection
644
+ - `accessi:federated:exchange` per scambiare un'identita SSO verificata
488
645
  - altri scope applicativi secondo necessita
489
646
  4. Conservarlo come secret nel backend fratello.
490
647
  5. Ruotarlo periodicamente; il segreto e mostrato una sola volta.
@@ -520,6 +677,7 @@ ACCESSI_DB_PASSWORD=
520
677
  ACCESSI_ENCRYPTION_KEY=
521
678
  ACCESSI_JWT_SECRET=
522
679
  ACCESSI_JWT_EXPIRES=24h
680
+ ACCESSI_JWT_REFRESH_EXPIRES=30d
523
681
  ACCESSI_JWT_ISSUER=accessi
524
682
  ACCESSI_JWT_AUDIENCE=backend-app
525
683
  # Opzionale RS256
@@ -584,6 +742,8 @@ Checklist:
584
742
  - rotazione JWKS con vecchia chiave ancora valida
585
743
  11. Aggiornare CORS se i frontend cambiano dominio.
586
744
  12. Aggiornare monitoraggio e log senza includere token.
745
+ 13. Eseguire `npm run check:accessi-openapi` e `npm run typecheck` prima del rilascio.
746
+ 14. Dopo una modifica intenzionale al contratto, aggiornare il fingerprint con `npm run accessi:update-openapi-fingerprint` e includerlo nel commit.
587
747
 
588
748
  ---
589
749