emilsoftware-utilities 2.0.0-dev.82 → 2.0.0-dev.84
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/dist/accessi/server/index.d.ts +4 -0
- package/dist/accessi/server/index.js +7 -1
- package/dist/accessi/server/index.js.map +1 -1
- package/dist/accessi/server/tenantRouter.d.ts +35 -0
- package/dist/accessi/server/tenantRouter.js +71 -0
- package/dist/accessi/server/tenantRouter.js.map +1 -0
- package/dist/accessi/server/tenantSupervisor.d.ts +60 -0
- package/dist/accessi/server/tenantSupervisor.js +296 -0
- package/dist/accessi/server/tenantSupervisor.js.map +1 -0
- package/dist/accessi/server/tenants.js +8 -0
- package/dist/accessi/server/tenants.js.map +1 -1
- package/dist/accessi-module/AccessiModule.js.map +1 -1
- package/dist/accessi-module/Console/console.js +1 -1
- package/dist/accessi-module/index.d.ts +1 -1
- package/dist/accessi-module/index.js +4 -3
- package/dist/accessi-module/index.js.map +1 -1
- package/dist/accessi-module/observability/metrics.js +13 -4
- package/dist/accessi-module/observability/metrics.js.map +1 -1
- package/dist/accessi-module/security/audit.d.ts +14 -4
- package/dist/accessi-module/security/audit.js +73 -48
- package/dist/accessi-module/security/audit.js.map +1 -1
- package/dist/accessi-module/tenancy/tenantContext.d.ts +15 -0
- package/dist/accessi-module/tenancy/tenantContext.js +26 -0
- package/dist/accessi-module/tenancy/tenantContext.js.map +1 -0
- package/dist/emilsoftware-utilities-2.0.0-dev.84.tgz +0 -0
- package/docs/adr/0002-multi-tenancy.md +9 -7
- package/docs/multi-tenancy.md +69 -3
- package/package.json +3 -3
- package/dist/emilsoftware-utilities-2.0.0-dev.82.tgz +0 -0
package/docs/multi-tenancy.md
CHANGED
|
@@ -126,8 +126,25 @@ Avvia un processo figlio per ogni tenant abilitato:
|
|
|
126
126
|
- non riavvia automaticamente un figlio: un loop su configurazione rotta è
|
|
127
127
|
peggio di un processo che resta giù; usare systemd/docker/Kubernetes.
|
|
128
128
|
|
|
129
|
-
Il supervisore legge la cartella all'avvio
|
|
130
|
-
|
|
129
|
+
Il supervisore legge la cartella all'avvio. Con `--watch` osserva i file
|
|
130
|
+
`*.environment.ts` e riapplica la configurazione:
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
npm run accessi:tenants -- --dir ./tenants --serve --watch
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Regole:
|
|
137
|
+
|
|
138
|
+
- un file invalido annulla il reload e lascia attivi i tenant correnti;
|
|
139
|
+
- i tenant invariati non vengono riavviati;
|
|
140
|
+
- un tenant modificato viene riavviato sulla stessa porta (breve interruzione);
|
|
141
|
+
- aggiunte e rimozioni avviano/fermano solo il tenant interessato;
|
|
142
|
+
- il polling è di 1 secondo con debounce di 200 ms (`pollIntervalMs`/
|
|
143
|
+
`debounceMs` nell'API del supervisore).
|
|
144
|
+
|
|
145
|
+
Senza `--watch` un cambiamento richiede il riavvio del supervisore. Non c'è
|
|
146
|
+
montaggio/smontaggio di moduli Nest a caldo: il reload riavvia i processi
|
|
147
|
+
interessati, non l'intero servizio.
|
|
131
148
|
|
|
132
149
|
### systemd (consigliato in produzione)
|
|
133
150
|
|
|
@@ -258,6 +275,54 @@ proxy_set_header X-Accessi-Tenant acme;
|
|
|
258
275
|
e avviare il router con `allowHeader: true` solo nel servizio che si fida del
|
|
259
276
|
proxy.
|
|
260
277
|
|
|
278
|
+
## Router in-process (opt-in, fase 4)
|
|
279
|
+
|
|
280
|
+
In alternativa al processo per tenant, un host può montare più app Accessi nello
|
|
281
|
+
stesso processo e usare `createAccessiTenantRouter`:
|
|
282
|
+
|
|
283
|
+
```ts
|
|
284
|
+
import {
|
|
285
|
+
configureAccessiTenantAudit,
|
|
286
|
+
createAccessiService,
|
|
287
|
+
createAccessiTenantRouter,
|
|
288
|
+
loadAccessiTenants,
|
|
289
|
+
} from 'emilsoftware-utilities/accessi/server';
|
|
290
|
+
|
|
291
|
+
const registry = loadAccessiTenants({ directory: './tenants' });
|
|
292
|
+
const acmeService = await createAccessiService({ accessiOptions: acmeOptions });
|
|
293
|
+
const betaService = await createAccessiService({ accessiOptions: betaOptions });
|
|
294
|
+
|
|
295
|
+
configureAccessiTenantAudit('acme', { store: acmeAuditStore, logger: false });
|
|
296
|
+
configureAccessiTenantAudit('beta', { store: betaAuditStore, logger: false });
|
|
297
|
+
|
|
298
|
+
const router = createAccessiTenantRouter({
|
|
299
|
+
registry,
|
|
300
|
+
handlers: { acme: acmeService.app, beta: betaService.app },
|
|
301
|
+
allowHeader: false,
|
|
302
|
+
});
|
|
303
|
+
app.use('/api/accessi', router);
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
Comportamento:
|
|
307
|
+
|
|
308
|
+
- risoluzione host → path → header fidato, senza fallback;
|
|
309
|
+
- `req.accessiTenant` contiene il tenant risolto;
|
|
310
|
+
- il handler gira dentro `runWithAccessiTenant`, quindi audit e metriche
|
|
311
|
+
ricevono il label `tenant`;
|
|
312
|
+
- tenant sconosciuto → `404 ACCESSI_TENANT_NOT_FOUND`;
|
|
313
|
+
- tenant senza handler → `501 ACCESSI_TENANT_HANDLER_MISSING`.
|
|
314
|
+
|
|
315
|
+
Limiti importanti:
|
|
316
|
+
|
|
317
|
+
- le app devono essere indipendenti (un `createAccessiService` per tenant);
|
|
318
|
+
- le API globali `authorizeAccessi` e `setAccessiAuthService` usano l'ultima
|
|
319
|
+
istanza inizializzata: in modalità router non sono tenant-aware e vanno
|
|
320
|
+
evitate; usare i guard/middleware dell'app del tenant;
|
|
321
|
+
- audit e metriche di background (fuori da una richiesta) usano la
|
|
322
|
+
configurazione di default del processo;
|
|
323
|
+
- il processo-per-tenant resta il default raccomandato: il router è opt-in e
|
|
324
|
+
non riduce i pool Firebird se le app sono comunque tutte inizializzate.
|
|
325
|
+
|
|
261
326
|
## Store Redis condivisi
|
|
262
327
|
|
|
263
328
|
Con Redis condiviso usare l'helper: crea tutti gli store con prefissi
|
|
@@ -332,7 +397,8 @@ schema.
|
|
|
332
397
|
## Limiti
|
|
333
398
|
|
|
334
399
|
- Un processo per tenant: più RAM, più pool Firebird, più connessioni SMTP.
|
|
335
|
-
-
|
|
400
|
+
- Il reload con `--watch` riavvia i processi modificati sulla stessa porta: c'è
|
|
401
|
+
una breve interruzione per il singolo tenant, non per gli altri.
|
|
336
402
|
- Migrazioni e backup per database.
|
|
337
403
|
- La risoluzione via header è ammessa solo dietro proxy fidato; il client non
|
|
338
404
|
deve poter scegliere il tenant.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "emilsoftware-utilities",
|
|
3
|
-
"version": "2.0.0-dev.
|
|
3
|
+
"version": "2.0.0-dev.84",
|
|
4
4
|
"description": "Utilities for EmilSoftware",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -141,8 +141,8 @@
|
|
|
141
141
|
"lint": "node scripts/lint.cjs",
|
|
142
142
|
"check:deploy": "node scripts/check-deploy-templates.cjs",
|
|
143
143
|
"test": "npm run typecheck && npm run lint && npm run test:unit",
|
|
144
|
-
"test:unit": "node --test test/angular-components.cjs test/menus-catalog.mjs test/menu-scopes.cjs test/accessi-regressions.cjs test/password-reset-regressions.cjs test/two-factor.cjs test/accessi-schema.cjs test/utilities-regressions.cjs test/service-token-regressions.cjs test/accessi-email-config.cjs test/accessi-catalog-scripts.cjs test/openapi-config.cjs test/resource-server.cjs test/accessi-security-standards.cjs test/accessi-service.cjs test/refresh-token.cjs test/token-revocation.cjs test/accessi-client.cjs test/accessi-client-scopes.cjs test/openapi-semantic-diff.cjs test/proxy-ip.cjs test/readiness.cjs test/jwt-key-rotation.cjs test/security-headers.cjs test/auth-cookies.cjs test/metrics.cjs test/audit.cjs test/import-entrypoints.cjs test/tenants.cjs test/tenant-stores.cjs test/deploy-templates.cjs",
|
|
145
|
-
"test:coverage": "node --experimental-test-coverage --test-coverage-lines=50 --test-coverage-functions=60 --test-coverage-branches=60 --test test/angular-components.cjs test/menus-catalog.mjs test/menu-scopes.cjs test/accessi-regressions.cjs test/password-reset-regressions.cjs test/two-factor.cjs test/accessi-schema.cjs test/utilities-regressions.cjs test/service-token-regressions.cjs test/accessi-email-config.cjs test/accessi-catalog-scripts.cjs test/openapi-config.cjs test/resource-server.cjs test/accessi-security-standards.cjs test/accessi-service.cjs test/refresh-token.cjs test/token-revocation.cjs test/accessi-client.cjs test/accessi-client-scopes.cjs test/openapi-semantic-diff.cjs test/proxy-ip.cjs test/readiness.cjs test/jwt-key-rotation.cjs test/security-headers.cjs test/auth-cookies.cjs test/metrics.cjs test/audit.cjs test/import-entrypoints.cjs test/tenants.cjs test/tenant-stores.cjs test/deploy-templates.cjs",
|
|
144
|
+
"test:unit": "node --test test/angular-components.cjs test/menus-catalog.mjs test/menu-scopes.cjs test/accessi-regressions.cjs test/password-reset-regressions.cjs test/two-factor.cjs test/accessi-schema.cjs test/utilities-regressions.cjs test/service-token-regressions.cjs test/accessi-email-config.cjs test/accessi-catalog-scripts.cjs test/openapi-config.cjs test/resource-server.cjs test/accessi-security-standards.cjs test/accessi-service.cjs test/refresh-token.cjs test/token-revocation.cjs test/accessi-client.cjs test/accessi-client-scopes.cjs test/openapi-semantic-diff.cjs test/proxy-ip.cjs test/readiness.cjs test/jwt-key-rotation.cjs test/security-headers.cjs test/auth-cookies.cjs test/metrics.cjs test/audit.cjs test/import-entrypoints.cjs test/tenants.cjs test/tenant-stores.cjs test/deploy-templates.cjs test/tenant-supervisor.cjs test/tenant-router.cjs",
|
|
145
|
+
"test:coverage": "node --experimental-test-coverage --test-coverage-lines=50 --test-coverage-functions=60 --test-coverage-branches=60 --test test/angular-components.cjs test/menus-catalog.mjs test/menu-scopes.cjs test/accessi-regressions.cjs test/password-reset-regressions.cjs test/two-factor.cjs test/accessi-schema.cjs test/utilities-regressions.cjs test/service-token-regressions.cjs test/accessi-email-config.cjs test/accessi-catalog-scripts.cjs test/openapi-config.cjs test/resource-server.cjs test/accessi-security-standards.cjs test/accessi-service.cjs test/refresh-token.cjs test/token-revocation.cjs test/accessi-client.cjs test/accessi-client-scopes.cjs test/openapi-semantic-diff.cjs test/proxy-ip.cjs test/readiness.cjs test/jwt-key-rotation.cjs test/security-headers.cjs test/auth-cookies.cjs test/metrics.cjs test/audit.cjs test/import-entrypoints.cjs test/tenants.cjs test/tenant-stores.cjs test/deploy-templates.cjs test/tenant-supervisor.cjs test/tenant-router.cjs",
|
|
146
146
|
"test:accessi": "npm run test:unit",
|
|
147
147
|
"test:all": "npm test && npm run test:integration && npm run test:integration:redis",
|
|
148
148
|
"test:integration": "node test/integration/run-firebird.cjs 5",
|
|
Binary file
|