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

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 (165) hide show
  1. package/dist/EmilsoftwareModule.d.ts +11 -3
  2. package/dist/EmilsoftwareModule.js +1 -1
  3. package/dist/EmilsoftwareModule.js.map +1 -1
  4. package/dist/accessi/client/index.d.ts +26 -0
  5. package/dist/accessi/client/index.js +49 -0
  6. package/dist/accessi/client/index.js.map +1 -0
  7. package/dist/accessi/console/index.d.ts +15 -0
  8. package/dist/accessi/console/index.js +25 -0
  9. package/dist/accessi/console/index.js.map +1 -0
  10. package/dist/accessi/contracts/dtos.d.ts +8 -0
  11. package/dist/accessi/contracts/dtos.js +25 -0
  12. package/dist/accessi/contracts/dtos.js.map +1 -0
  13. package/dist/accessi/contracts/index.d.ts +25 -0
  14. package/dist/accessi/contracts/index.js +28 -0
  15. package/dist/accessi/contracts/index.js.map +1 -0
  16. package/dist/accessi/openapi/index.d.ts +2 -0
  17. package/dist/accessi/openapi/index.js +19 -0
  18. package/dist/accessi/openapi/index.js.map +1 -0
  19. package/dist/accessi/resource-server/core.d.ts +6 -0
  20. package/dist/accessi/resource-server/core.js +23 -0
  21. package/dist/accessi/resource-server/core.js.map +1 -0
  22. package/dist/accessi/resource-server/errors.d.ts +10 -0
  23. package/dist/accessi/resource-server/errors.js +19 -0
  24. package/dist/accessi/resource-server/errors.js.map +1 -0
  25. package/dist/accessi/resource-server/express.d.ts +17 -0
  26. package/dist/accessi/resource-server/express.js +66 -0
  27. package/dist/accessi/resource-server/express.js.map +1 -0
  28. package/dist/accessi/resource-server/index.d.ts +3 -0
  29. package/dist/accessi/resource-server/index.js +20 -0
  30. package/dist/accessi/resource-server/index.js.map +1 -0
  31. package/dist/accessi/resource-server/introspection.d.ts +16 -0
  32. package/dist/accessi/resource-server/introspection.js +115 -0
  33. package/dist/accessi/resource-server/introspection.js.map +1 -0
  34. package/dist/accessi/resource-server/keys.d.ts +11 -0
  35. package/dist/accessi/resource-server/keys.js +22 -0
  36. package/dist/accessi/resource-server/keys.js.map +1 -0
  37. package/dist/accessi/resource-server/nest.d.ts +9 -0
  38. package/dist/accessi/resource-server/nest.js +62 -0
  39. package/dist/accessi/resource-server/nest.js.map +1 -0
  40. package/dist/accessi/resource-server/runtime.d.ts +27 -0
  41. package/dist/accessi/resource-server/runtime.js +128 -0
  42. package/dist/accessi/resource-server/runtime.js.map +1 -0
  43. package/dist/accessi/resource-server/token.d.ts +23 -0
  44. package/dist/accessi/resource-server/token.js +230 -0
  45. package/dist/accessi/resource-server/token.js.map +1 -0
  46. package/dist/accessi/resource-server/types.d.ts +78 -0
  47. package/dist/accessi/resource-server/types.js +3 -0
  48. package/dist/accessi/resource-server/types.js.map +1 -0
  49. package/dist/accessi/server/index.d.ts +10 -0
  50. package/dist/accessi/server/index.js +29 -0
  51. package/dist/accessi/server/index.js.map +1 -0
  52. package/dist/accessi/ui/index.d.ts +13 -0
  53. package/dist/accessi/ui/index.js +19 -0
  54. package/dist/accessi/ui/index.js.map +1 -0
  55. package/dist/accessi-module/AccessiModule.d.ts +52 -2
  56. package/dist/accessi-module/AccessiModule.js +2 -0
  57. package/dist/accessi-module/AccessiModule.js.map +1 -1
  58. package/dist/accessi-module/Console/accessiFetch.d.ts +4 -0
  59. package/dist/accessi-module/Console/accessiFetch.js +18 -4
  60. package/dist/accessi-module/Console/accessiFetch.js.map +1 -1
  61. package/dist/accessi-module/Console/console.js +122 -11
  62. package/dist/accessi-module/Console/console.js.map +1 -1
  63. package/dist/accessi-module/Console/generated/{accessiApi.d.ts → emilsoftware-utilities.d.ts} +11 -1
  64. package/dist/accessi-module/Console/generated/{accessiApi.js → emilsoftware-utilities.js} +10 -2
  65. package/dist/accessi-module/Console/generated/emilsoftware-utilities.js.map +1 -0
  66. package/dist/accessi-module/Console/generated/model/accessiIntrospectionResultDto.d.ts +16 -0
  67. package/dist/accessi-module/Console/generated/model/accessiIntrospectionResultDto.js +3 -0
  68. package/dist/accessi-module/Console/generated/model/accessiIntrospectionResultDto.js.map +1 -0
  69. package/dist/accessi-module/Console/generated/model/index.d.ts +3 -0
  70. package/dist/accessi-module/Console/generated/model/index.js +3 -0
  71. package/dist/accessi-module/Console/generated/model/index.js.map +1 -1
  72. package/dist/accessi-module/Console/generated/model/introspectAccessiTokenRequest.d.ts +10 -0
  73. package/dist/accessi-module/Console/generated/model/introspectAccessiTokenRequest.js +9 -0
  74. package/dist/accessi-module/Console/generated/model/introspectAccessiTokenRequest.js.map +1 -0
  75. package/dist/accessi-module/Console/generated/model/introspectAccessiTokenResponse.d.ts +14 -0
  76. package/dist/accessi-module/Console/generated/model/introspectAccessiTokenResponse.js +3 -0
  77. package/dist/accessi-module/Console/generated/model/introspectAccessiTokenResponse.js.map +1 -0
  78. package/dist/accessi-module/Console/wiki.js +106 -5
  79. package/dist/accessi-module/Console/wiki.js.map +1 -1
  80. package/dist/accessi-module/Controllers/AccessiIntrospectionController.d.ts +17 -0
  81. package/dist/accessi-module/Controllers/AccessiIntrospectionController.js +93 -0
  82. package/dist/accessi-module/Controllers/AccessiIntrospectionController.js.map +1 -0
  83. package/dist/accessi-module/Controllers/AuthController.js +6 -6
  84. package/dist/accessi-module/Controllers/AuthController.js.map +1 -1
  85. package/dist/accessi-module/Controllers/ConsoleEntryController.d.ts +2 -0
  86. package/dist/accessi-module/Controllers/ConsoleEntryController.js +11 -3
  87. package/dist/accessi-module/Controllers/ConsoleEntryController.js.map +1 -1
  88. package/dist/accessi-module/Controllers/EmailController.js +1 -1
  89. package/dist/accessi-module/Controllers/EmailController.js.map +1 -1
  90. package/dist/accessi-module/Controllers/UserController.js +1 -1
  91. package/dist/accessi-module/Controllers/UserController.js.map +1 -1
  92. package/dist/accessi-module/Dtos/IntrospectionDtos.d.ts +16 -0
  93. package/dist/accessi-module/Dtos/IntrospectionDtos.js +59 -0
  94. package/dist/accessi-module/Dtos/IntrospectionDtos.js.map +1 -0
  95. package/dist/accessi-module/Dtos/index.d.ts +1 -0
  96. package/dist/accessi-module/Dtos/index.js +1 -0
  97. package/dist/accessi-module/Dtos/index.js.map +1 -1
  98. package/dist/accessi-module/Services/AuthService/AuthService.d.ts +13 -0
  99. package/dist/accessi-module/Services/AuthService/AuthService.js +42 -10
  100. package/dist/accessi-module/Services/AuthService/AuthService.js.map +1 -1
  101. package/dist/accessi-module/database-updates/accessiOptionsFromEnv.js +18 -19
  102. package/dist/accessi-module/database-updates/accessiOptionsFromEnv.js.map +1 -1
  103. package/dist/accessi-module/database-updates/menuScopeSeed.d.ts +2 -2
  104. package/dist/accessi-module/database-updates/menuScopeSeed.js +101 -53
  105. package/dist/accessi-module/database-updates/menuScopeSeed.js.map +1 -1
  106. package/dist/accessi-module/database-updates/menuScopeSeeder.js +1 -1
  107. package/dist/accessi-module/database-updates/menuScopeSeeder.js.map +1 -1
  108. package/dist/accessi-module/index.d.ts +25 -4
  109. package/dist/accessi-module/index.js +47 -21
  110. package/dist/accessi-module/index.js.map +1 -1
  111. package/dist/accessi-module/jwt/jwt.strategy.js +5 -5
  112. package/dist/accessi-module/jwt/jwt.strategy.js.map +1 -1
  113. package/dist/accessi-module/middleware/authenticateGen.js +5 -5
  114. package/dist/accessi-module/middleware/authenticateGen.js.map +1 -1
  115. package/dist/accessi-module/security/consoleEntry.d.ts +56 -11
  116. package/dist/accessi-module/security/consoleEntry.js +165 -31
  117. package/dist/accessi-module/security/consoleEntry.js.map +1 -1
  118. package/dist/accessi-module/security/edgeRateLimit.d.ts +31 -0
  119. package/dist/accessi-module/security/edgeRateLimit.js +70 -0
  120. package/dist/accessi-module/security/edgeRateLimit.js.map +1 -0
  121. package/dist/accessi-module/security/jwks.d.ts +33 -0
  122. package/dist/accessi-module/security/jwks.js +83 -0
  123. package/dist/accessi-module/security/jwks.js.map +1 -0
  124. package/dist/accessi-module/security/jwtTokenOptions.d.ts +15 -0
  125. package/dist/accessi-module/security/jwtTokenOptions.js +44 -0
  126. package/dist/accessi-module/security/jwtTokenOptions.js.map +1 -0
  127. package/dist/accessi-module/security/publicAuthRateLimit.d.ts +8 -6
  128. package/dist/accessi-module/security/publicAuthRateLimit.js +54 -78
  129. package/dist/accessi-module/security/publicAuthRateLimit.js.map +1 -1
  130. package/dist/accessi-module/security/rateLimitStore.d.ts +32 -0
  131. package/dist/accessi-module/security/rateLimitStore.js +129 -0
  132. package/dist/accessi-module/security/rateLimitStore.js.map +1 -0
  133. package/dist/accessi-module/security/serviceTokenGuard.d.ts +3 -1
  134. package/dist/accessi-module/security/serviceTokenGuard.js +11 -6
  135. package/dist/accessi-module/security/serviceTokenGuard.js.map +1 -1
  136. package/dist/accessi-module/security/serviceTokenRateLimit.d.ts +5 -4
  137. package/dist/accessi-module/security/serviceTokenRateLimit.js +33 -29
  138. package/dist/accessi-module/security/serviceTokenRateLimit.js.map +1 -1
  139. package/dist/accessi-module/startupLog.d.ts +3 -2
  140. package/dist/accessi-module/startupLog.js +8 -4
  141. package/dist/accessi-module/startupLog.js.map +1 -1
  142. package/dist/allegati-module/index.js +2 -2
  143. package/dist/allegati-module/index.js.map +1 -1
  144. package/dist/angular-components/aree-disponibili/demo.html +4 -4
  145. package/dist/emilsoftware-utilities-2.0.0-dev.68.tgz +0 -0
  146. package/dist/index.d.ts +2 -1
  147. package/dist/index.js +2 -1
  148. package/dist/index.js.map +1 -1
  149. package/dist/initEmilsoftwareModule.d.ts +11 -1
  150. package/dist/initEmilsoftwareModule.js +29 -23
  151. package/dist/initEmilsoftwareModule.js.map +1 -1
  152. package/dist/openapi/OpenApiConfig.d.ts +68 -0
  153. package/dist/openapi/OpenApiConfig.js +157 -0
  154. package/dist/openapi/OpenApiConfig.js.map +1 -0
  155. package/dist/openapi/OpenApiMerge.d.ts +15 -0
  156. package/dist/openapi/OpenApiMerge.js +119 -0
  157. package/dist/openapi/OpenApiMerge.js.map +1 -0
  158. package/docs/gateway-rate-limit.md +98 -0
  159. package/integration-prompt.md +612 -0
  160. package/package.json +89 -5
  161. package/dist/accessi-module/Console/generated/accessiApi.js.map +0 -1
  162. package/dist/emilsoftware-utilities-2.0.0-dev.66.tgz +0 -0
  163. package/dist/swagger/SwaggerConfig.d.ts +0 -8
  164. package/dist/swagger/SwaggerConfig.js +0 -41
  165. package/dist/swagger/SwaggerConfig.js.map +0 -1
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.mergeOpenApiDocuments = mergeOpenApiDocuments;
4
+ function isRecord(value) {
5
+ return typeof value === "object" && value !== null && !Array.isArray(value);
6
+ }
7
+ function cloneDocument(document) {
8
+ return JSON.parse(JSON.stringify(document));
9
+ }
10
+ function sameValue(left, right) {
11
+ return JSON.stringify(left) === JSON.stringify(right);
12
+ }
13
+ function mergeRecord(target, source, policy, section) {
14
+ if (!source)
15
+ return target;
16
+ const merged = Object.assign({}, (target !== null && target !== void 0 ? target : {}));
17
+ for (const [key, value] of Object.entries(source)) {
18
+ if (!(key in merged)) {
19
+ merged[key] = value;
20
+ continue;
21
+ }
22
+ if (sameValue(merged[key], value))
23
+ continue;
24
+ if (policy === "keep")
25
+ continue;
26
+ if (policy === "overwrite") {
27
+ merged[key] = value;
28
+ continue;
29
+ }
30
+ throw new Error(`Conflitto OpenAPI in ${section}.${key}.`);
31
+ }
32
+ return merged;
33
+ }
34
+ function mergeTags(target, source, policy) {
35
+ if (!Array.isArray(target) || !Array.isArray(source))
36
+ return target !== null && target !== void 0 ? target : source;
37
+ const merged = [...target];
38
+ for (const tag of source) {
39
+ if (!isRecord(tag) || typeof tag.name !== "string") {
40
+ merged.push(tag);
41
+ continue;
42
+ }
43
+ const existingIndex = merged.findIndex((candidate) => isRecord(candidate) && candidate.name === tag.name);
44
+ if (existingIndex < 0) {
45
+ merged.push(tag);
46
+ continue;
47
+ }
48
+ const existing = merged[existingIndex];
49
+ if (sameValue(existing, tag))
50
+ continue;
51
+ if (policy === "keep")
52
+ continue;
53
+ if (policy === "overwrite") {
54
+ merged[existingIndex] = tag;
55
+ continue;
56
+ }
57
+ throw new Error(`Conflitto OpenAPI nel tag "${tag.name}".`);
58
+ }
59
+ return merged;
60
+ }
61
+ function mergeServers(target, source, policy) {
62
+ if (!Array.isArray(target) || !Array.isArray(source))
63
+ return target !== null && target !== void 0 ? target : source;
64
+ const merged = [...target];
65
+ for (const server of source) {
66
+ if (!isRecord(server) || typeof server.url !== "string") {
67
+ merged.push(server);
68
+ continue;
69
+ }
70
+ const existingIndex = merged.findIndex((candidate) => isRecord(candidate) && candidate.url === server.url);
71
+ if (existingIndex < 0) {
72
+ merged.push(server);
73
+ continue;
74
+ }
75
+ const existing = merged[existingIndex];
76
+ if (sameValue(existing, server))
77
+ continue;
78
+ if (policy === "keep")
79
+ continue;
80
+ if (policy === "overwrite") {
81
+ merged[existingIndex] = server;
82
+ continue;
83
+ }
84
+ throw new Error(`Conflitto OpenAPI nel server "${server.url}".`);
85
+ }
86
+ return merged;
87
+ }
88
+ /**
89
+ * Unisce il documento Accessi nel documento OpenAPI dell'host.
90
+ *
91
+ * Per default un conflitto su path, schema o security scheme produce errore:
92
+ * e meglio accorgersi subito di due contratti incompatibili. Usare
93
+ * `conflict: "overwrite"` solo quando il documento host deve vincere.
94
+ */
95
+ function mergeOpenApiDocuments(target, source, options = {}) {
96
+ var _a;
97
+ if (!target || !source) {
98
+ throw new Error("mergeOpenApiDocuments richiede due documenti OpenAPI validi.");
99
+ }
100
+ const policy = (_a = options.conflict) !== null && _a !== void 0 ? _a : "error";
101
+ const result = cloneDocument(target);
102
+ const sourceDocument = source;
103
+ result.paths = mergeRecord(isRecord(result.paths) ? result.paths : undefined, isRecord(sourceDocument.paths) ? sourceDocument.paths : undefined, policy, "paths");
104
+ const targetComponents = isRecord(result.components) ? result.components : {};
105
+ const sourceComponents = isRecord(sourceDocument.components) ? sourceDocument.components : {};
106
+ const componentSections = new Set([
107
+ ...Object.keys(targetComponents),
108
+ ...Object.keys(sourceComponents),
109
+ ]);
110
+ const mergedComponents = Object.assign({}, targetComponents);
111
+ for (const section of componentSections) {
112
+ mergedComponents[section] = mergeRecord(isRecord(targetComponents[section]) ? targetComponents[section] : undefined, isRecord(sourceComponents[section]) ? sourceComponents[section] : undefined, policy, `components.${section}`);
113
+ }
114
+ result.components = mergedComponents;
115
+ result.tags = mergeTags(result.tags, sourceDocument.tags, policy);
116
+ result.servers = mergeServers(result.servers, sourceDocument.servers, policy);
117
+ return result;
118
+ }
119
+ //# sourceMappingURL=OpenApiMerge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OpenApiMerge.js","sourceRoot":"","sources":["../../src/openapi/OpenApiMerge.ts"],"names":[],"mappings":"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","sourcesContent":["import type { OpenAPIObject } from \"@nestjs/swagger\";\n\n/** Politica di risoluzione quando due documenti definiscono la stessa chiave. */\nexport type OpenApiMergeConflictPolicy = \"error\" | \"keep\" | \"overwrite\";\n\nexport interface MergeOpenApiOptions {\n /** Default: `error`. */\n conflict?: OpenApiMergeConflictPolicy;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction cloneDocument(document: OpenAPIObject): Record<string, unknown> {\n return JSON.parse(JSON.stringify(document)) as Record<string, unknown>;\n}\n\nfunction sameValue(left: unknown, right: unknown): boolean {\n return JSON.stringify(left) === JSON.stringify(right);\n}\n\nfunction mergeRecord(\n target: Record<string, unknown> | undefined,\n source: Record<string, unknown> | undefined,\n policy: OpenApiMergeConflictPolicy,\n section: string,\n): Record<string, unknown> | undefined {\n if (!source) return target;\n const merged: Record<string, unknown> = { ...(target ?? {}) };\n\n for (const [key, value] of Object.entries(source)) {\n if (!(key in merged)) {\n merged[key] = value;\n continue;\n }\n if (sameValue(merged[key], value)) continue;\n if (policy === \"keep\") continue;\n if (policy === \"overwrite\") {\n merged[key] = value;\n continue;\n }\n throw new Error(`Conflitto OpenAPI in ${section}.${key}.`);\n }\n\n return merged;\n}\n\nfunction mergeTags(\n target: unknown,\n source: unknown,\n policy: OpenApiMergeConflictPolicy,\n): unknown {\n if (!Array.isArray(target) || !Array.isArray(source)) return target ?? source;\n const merged = [...target];\n for (const tag of source) {\n if (!isRecord(tag) || typeof tag.name !== \"string\") {\n merged.push(tag);\n continue;\n }\n const existingIndex = merged.findIndex(\n (candidate) => isRecord(candidate) && candidate.name === tag.name,\n );\n if (existingIndex < 0) {\n merged.push(tag);\n continue;\n }\n const existing = merged[existingIndex];\n if (sameValue(existing, tag)) continue;\n if (policy === \"keep\") continue;\n if (policy === \"overwrite\") {\n merged[existingIndex] = tag;\n continue;\n }\n throw new Error(`Conflitto OpenAPI nel tag \"${tag.name}\".`);\n }\n return merged;\n}\n\nfunction mergeServers(\n target: unknown,\n source: unknown,\n policy: OpenApiMergeConflictPolicy,\n): unknown {\n if (!Array.isArray(target) || !Array.isArray(source)) return target ?? source;\n const merged = [...target];\n for (const server of source) {\n if (!isRecord(server) || typeof server.url !== \"string\") {\n merged.push(server);\n continue;\n }\n const existingIndex = merged.findIndex(\n (candidate) => isRecord(candidate) && candidate.url === server.url,\n );\n if (existingIndex < 0) {\n merged.push(server);\n continue;\n }\n const existing = merged[existingIndex];\n if (sameValue(existing, server)) continue;\n if (policy === \"keep\") continue;\n if (policy === \"overwrite\") {\n merged[existingIndex] = server;\n continue;\n }\n throw new Error(`Conflitto OpenAPI nel server \"${server.url}\".`);\n }\n return merged;\n}\n\n/**\n * Unisce il documento Accessi nel documento OpenAPI dell'host.\n *\n * Per default un conflitto su path, schema o security scheme produce errore:\n * e meglio accorgersi subito di due contratti incompatibili. Usare\n * `conflict: \"overwrite\"` solo quando il documento host deve vincere.\n */\nexport function mergeOpenApiDocuments(\n target: OpenAPIObject,\n source: OpenAPIObject,\n options: MergeOpenApiOptions = {},\n): OpenAPIObject {\n if (!target || !source) {\n throw new Error(\"mergeOpenApiDocuments richiede due documenti OpenAPI validi.\");\n }\n\n const policy = options.conflict ?? \"error\";\n const result = cloneDocument(target);\n const sourceDocument = source as unknown as Record<string, unknown>;\n\n result.paths = mergeRecord(\n isRecord(result.paths) ? result.paths : undefined,\n isRecord(sourceDocument.paths) ? sourceDocument.paths : undefined,\n policy,\n \"paths\",\n );\n\n const targetComponents = isRecord(result.components) ? result.components : {};\n const sourceComponents = isRecord(sourceDocument.components) ? sourceDocument.components : {};\n const componentSections = new Set([\n ...Object.keys(targetComponents),\n ...Object.keys(sourceComponents),\n ]);\n const mergedComponents: Record<string, unknown> = { ...targetComponents };\n for (const section of componentSections) {\n mergedComponents[section] = mergeRecord(\n isRecord(targetComponents[section]) ? targetComponents[section] : undefined,\n isRecord(sourceComponents[section]) ? sourceComponents[section] : undefined,\n policy,\n `components.${section}`,\n );\n }\n result.components = mergedComponents;\n\n result.tags = mergeTags(result.tags, sourceDocument.tags, policy);\n result.servers = mergeServers(result.servers, sourceDocument.servers, policy);\n\n return result as unknown as OpenAPIObject;\n}\n"]}
@@ -0,0 +1,98 @@
1
+ # Gateway rate limit per Accessi Service
2
+
3
+ Il rate limit applicativo di Accessi protegge login, 2FA, reset password, console entry e service token. Il gateway/API gateway resta utile per una protezione per IP, connessioni e bot prima che la richiesta raggiunga Node.
4
+
5
+ Regole consigliate:
6
+
7
+ - `/api/accessi/auth/*`: soglia bassa, burst contenuto
8
+ - `/api/accessi/console/entry/exchange`: soglia bassa
9
+ - `/api/accessi/*`: soglia media
10
+ - `/accessi/openapi*` e `/accessi/.well-known/jwks.json`: soglia alta o cache CDN
11
+
12
+ ## Nginx
13
+
14
+ ```nginx
15
+ limit_req_zone $binary_remote_addr zone=accessi_auth:10m rate=2r/s;
16
+ limit_req_zone $binary_remote_addr zone=accessi_api:10m rate=10r/s;
17
+ limit_conn_zone $binary_remote_addr zone=accessi_conn:10m;
18
+
19
+ server {
20
+ # Se Accessi e dietro un proxy/load balancer, configura real_ip
21
+ # prima di usare $binary_remote_addr.
22
+
23
+ location /api/accessi/auth/ {
24
+ limit_req zone=accessi_auth burst=10 nodelay;
25
+ limit_conn accessi_conn 20;
26
+ proxy_pass http://accessi_service;
27
+ }
28
+
29
+ location /api/accessi/ {
30
+ limit_req zone=accessi_api burst=50 nodelay;
31
+ limit_conn accessi_conn 20;
32
+ proxy_pass http://accessi_service;
33
+ }
34
+
35
+ location /accessi/ {
36
+ limit_req zone=accessi_api burst=50 nodelay;
37
+ proxy_pass http://accessi_service;
38
+ }
39
+ }
40
+ ```
41
+
42
+ ## Traefik
43
+
44
+ ```yaml
45
+ http:
46
+ middlewares:
47
+ accessi-auth-ratelimit:
48
+ rateLimit:
49
+ average: 2
50
+ burst: 10
51
+ period: 1s
52
+ accessi-api-ratelimit:
53
+ rateLimit:
54
+ average: 10
55
+ burst: 50
56
+ period: 1s
57
+ routers:
58
+ accessi-auth:
59
+ rule: PathPrefix(`/api/accessi/auth/`)
60
+ middlewares: [accessi-auth-ratelimit]
61
+ service: accessi
62
+ accessi-api:
63
+ rule: PathPrefix(`/api/accessi/`) || PathPrefix(`/accessi/`)
64
+ middlewares: [accessi-api-ratelimit]
65
+ service: accessi
66
+ ```
67
+
68
+ ## Cloudflare
69
+
70
+ Regole di rate limiting:
71
+
72
+ - path `/api/accessi/auth/*`: 10 richieste/minuto per IP, azione `managed challenge`
73
+ - path `/api/accessi/console/entry/exchange`: 30 richieste/5 minuti per IP
74
+ - path `/api/accessi/*`: 300 richieste/minuto per IP, azione `block`
75
+ - path `/accessi/.well-known/jwks.json`: cache CDN, limite alto
76
+
77
+ Aggiungere bot fight mode/WAF secondo il piano disponibile.
78
+
79
+ ## AWS WAF / API Gateway
80
+
81
+ - rate-based rule: 300 richieste/5 minuti per IP
82
+ - scope-down statement: `URI starts with /api/accessi`
83
+ - regola più severa su `/api/accessi/auth/*`
84
+ - AWS Shield/WAF Bot Control se disponibile
85
+
86
+ ## Rapporto con `edgeRateLimit` della libreria
87
+
88
+ `edgeRateLimit` e un ultimo livello applicativo:
89
+
90
+ - usa lo stesso `RateLimitStore` Redis dei rate limit per account;
91
+ - copre Accessi anche se il gateway non ha regole specifiche;
92
+ - non sostituisce WAF, bot protection, limiti di connessione o protezione DDoS.
93
+
94
+ In produzione usare entrambi:
95
+
96
+ ```text
97
+ Client -> CDN/WAF -> API gateway -> edgeRateLimit Accessi -> rate limit per account
98
+ ```