emilsoftware-utilities 2.0.0-dev.23 → 2.0.0-dev.25
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/README.MD +147 -0
- package/dist/ContractGenerator.d.ts +4 -3
- package/dist/ContractGenerator.js +15 -5
- package/dist/ContractGenerator.js.map +1 -1
- package/dist/DailyFileTransport.d.ts +8 -2
- package/dist/DailyFileTransport.js +9 -2
- package/dist/DailyFileTransport.js.map +1 -1
- package/dist/DatabaseUpdater.js +8 -3
- package/dist/DatabaseUpdater.js.map +1 -1
- package/dist/ExecutionTimeLogger.d.ts +2 -2
- package/dist/ExecutionTimeLogger.js +3 -2
- package/dist/ExecutionTimeLogger.js.map +1 -1
- package/dist/Logger.d.ts +22 -9
- package/dist/Logger.js +131 -54
- package/dist/Logger.js.map +1 -1
- package/dist/Orm.d.ts +26 -6
- package/dist/Orm.js +144 -40
- package/dist/Orm.js.map +1 -1
- package/dist/Utilities.d.ts +12 -7
- package/dist/Utilities.js +57 -22
- package/dist/Utilities.js.map +1 -1
- package/dist/accessi-module/AccessiModule.d.ts +9 -0
- package/dist/accessi-module/AccessiModule.js +12 -4
- package/dist/accessi-module/AccessiModule.js.map +1 -1
- package/dist/accessi-module/Console/console.css +529 -281
- package/dist/accessi-module/Console/console.js +2081 -85
- package/dist/accessi-module/Console/console.js.map +1 -1
- package/dist/accessi-module/Console/generated/accessiApi.d.ts +167 -1
- package/dist/accessi-module/Console/generated/accessiApi.js +156 -2
- package/dist/accessi-module/Console/generated/accessiApi.js.map +1 -1
- package/dist/accessi-module/Console/generated/model/abilitazioneMenu.d.ts +20 -8
- package/dist/accessi-module/Console/generated/model/abilitazioneMenu.js.map +1 -1
- package/dist/accessi-module/Console/generated/model/createFilterTypeRequest.d.ts +23 -0
- package/dist/accessi-module/Console/generated/model/createFilterTypeRequest.js +3 -0
- package/dist/accessi-module/Console/generated/model/createFilterTypeRequest.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/createFilterTypeRequestFlgEnabled.d.ts +14 -0
- package/dist/accessi-module/Console/generated/model/createFilterTypeRequestFlgEnabled.js +15 -0
- package/dist/accessi-module/Console/generated/model/createFilterTypeRequestFlgEnabled.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/createMenuGroupRequest.d.ts +27 -0
- package/dist/accessi-module/Console/generated/model/createMenuGroupRequest.js +9 -0
- package/dist/accessi-module/Console/generated/model/createMenuGroupRequest.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/createMenuRequest.d.ts +52 -0
- package/dist/accessi-module/Console/generated/model/createMenuRequest.js +9 -0
- package/dist/accessi-module/Console/generated/model/createMenuRequest.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/createMenuTypeRequest.d.ts +18 -0
- package/dist/accessi-module/Console/generated/model/createMenuTypeRequest.js +9 -0
- package/dist/accessi-module/Console/generated/model/createMenuTypeRequest.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/createServiceTokenRequest.d.ts +16 -0
- package/dist/accessi-module/Console/generated/model/createServiceTokenRequest.js +9 -0
- package/dist/accessi-module/Console/generated/model/createServiceTokenRequest.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/createServiceTokenResponse.d.ts +14 -0
- package/dist/accessi-module/Console/generated/model/createServiceTokenResponse.js +3 -0
- package/dist/accessi-module/Console/generated/model/createServiceTokenResponse.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/getMenuTypesResponse.d.ts +14 -0
- package/dist/accessi-module/Console/generated/model/getMenuTypesResponse.js +3 -0
- package/dist/accessi-module/Console/generated/model/getMenuTypesResponse.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/getServiceTokensParams.d.ts +12 -0
- package/dist/accessi-module/Console/generated/model/getServiceTokensParams.js +9 -0
- package/dist/accessi-module/Console/generated/model/getServiceTokensParams.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/getServiceTokensResponse.d.ts +14 -0
- package/dist/accessi-module/Console/generated/model/getServiceTokensResponse.js +3 -0
- package/dist/accessi-module/Console/generated/model/getServiceTokensResponse.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/getUsersParams.d.ts +8 -0
- package/dist/accessi-module/Console/generated/model/getUsersParams.js.map +1 -1
- package/dist/accessi-module/Console/generated/model/index.d.ts +18 -0
- package/dist/accessi-module/Console/generated/model/index.js +18 -0
- package/dist/accessi-module/Console/generated/model/index.js.map +1 -1
- package/dist/accessi-module/Console/generated/model/issuedServiceTokenDto.d.ts +30 -0
- package/dist/accessi-module/Console/generated/model/issuedServiceTokenDto.js +9 -0
- package/dist/accessi-module/Console/generated/model/issuedServiceTokenDto.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/menuTypeEntity.d.ts +12 -0
- package/dist/accessi-module/Console/generated/model/menuTypeEntity.js +9 -0
- package/dist/accessi-module/Console/generated/model/menuTypeEntity.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/serviceTokenDto.d.ts +28 -0
- package/dist/accessi-module/Console/generated/model/serviceTokenDto.js +9 -0
- package/dist/accessi-module/Console/generated/model/serviceTokenDto.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/updateFilterTypeRequest.d.ts +21 -0
- package/dist/accessi-module/Console/generated/model/updateFilterTypeRequest.js +3 -0
- package/dist/accessi-module/Console/generated/model/updateFilterTypeRequest.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/updateFilterTypeRequestFlgEnabled.d.ts +14 -0
- package/dist/accessi-module/Console/generated/model/updateFilterTypeRequestFlgEnabled.js +15 -0
- package/dist/accessi-module/Console/generated/model/updateFilterTypeRequestFlgEnabled.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/updateMenuGroupRequest.d.ts +22 -0
- package/dist/accessi-module/Console/generated/model/updateMenuGroupRequest.js +9 -0
- package/dist/accessi-module/Console/generated/model/updateMenuGroupRequest.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/updateMenuRequest.d.ts +47 -0
- package/dist/accessi-module/Console/generated/model/updateMenuRequest.js +9 -0
- package/dist/accessi-module/Console/generated/model/updateMenuRequest.js.map +1 -0
- package/dist/accessi-module/Console/generated/model/updateMenuTypeRequest.d.ts +13 -0
- package/dist/accessi-module/Console/generated/model/updateMenuTypeRequest.js +9 -0
- package/dist/accessi-module/Console/generated/model/updateMenuTypeRequest.js.map +1 -0
- package/dist/accessi-module/Console/help.d.ts +13 -0
- package/dist/accessi-module/Console/help.js +348 -0
- package/dist/accessi-module/Console/help.js.map +1 -0
- package/dist/accessi-module/Console/index.html +89 -21
- package/dist/accessi-module/Console/wiki.d.ts +52 -0
- package/dist/accessi-module/Console/wiki.js +689 -0
- package/dist/accessi-module/Console/wiki.js.map +1 -0
- package/dist/accessi-module/Controllers/AccessiConsoleController.d.ts +8 -1
- package/dist/accessi-module/Controllers/AccessiConsoleController.js +52 -15
- package/dist/accessi-module/Controllers/AccessiConsoleController.js.map +1 -1
- package/dist/accessi-module/Controllers/ConfiguratorController.d.ts +1 -3
- package/dist/accessi-module/Controllers/ConfiguratorController.js +6 -8
- package/dist/accessi-module/Controllers/ConfiguratorController.js.map +1 -1
- package/dist/accessi-module/Controllers/EmailController.d.ts +1 -1
- package/dist/accessi-module/Controllers/EmailController.js +1 -1
- package/dist/accessi-module/Controllers/EmailController.js.map +1 -1
- package/dist/accessi-module/Controllers/FiltriController.d.ts +5 -4
- package/dist/accessi-module/Controllers/FiltriController.js +92 -4
- package/dist/accessi-module/Controllers/FiltriController.js.map +1 -1
- package/dist/accessi-module/Controllers/PermissionController.d.ts +11 -0
- package/dist/accessi-module/Controllers/PermissionController.js +273 -8
- package/dist/accessi-module/Controllers/PermissionController.js.map +1 -1
- package/dist/accessi-module/Controllers/ServiceTokenController.d.ts +23 -0
- package/dist/accessi-module/Controllers/ServiceTokenController.js +176 -0
- package/dist/accessi-module/Controllers/ServiceTokenController.js.map +1 -0
- package/dist/accessi-module/Controllers/UserController.d.ts +2 -2
- package/dist/accessi-module/Controllers/UserController.js +25 -9
- package/dist/accessi-module/Controllers/UserController.js.map +1 -1
- package/dist/accessi-module/Dtos/Abilitazione.js.map +1 -1
- package/dist/accessi-module/Dtos/AbilitazioneMenu.js +16 -8
- package/dist/accessi-module/Dtos/AbilitazioneMenu.js.map +1 -1
- package/dist/accessi-module/Dtos/AssignPermissionsToUserRequest.js.map +1 -1
- package/dist/accessi-module/Dtos/AssignRolesToUserRequest.js.map +1 -1
- package/dist/accessi-module/Dtos/AuthenticatedUserPayloadDto.js.map +1 -1
- package/dist/accessi-module/Dtos/BaseResponse.js.map +1 -1
- package/dist/accessi-module/Dtos/CatalogDtos.d.ts +66 -0
- package/dist/accessi-module/Dtos/CatalogDtos.js +336 -0
- package/dist/accessi-module/Dtos/CatalogDtos.js.map +1 -0
- package/dist/accessi-module/Dtos/ConfirmResetPasswordRequest.js.map +1 -1
- package/dist/accessi-module/Dtos/FiltriUtente.js.map +1 -1
- package/dist/accessi-module/Dtos/GetGroupsWithMenusResponse.js.map +1 -1
- package/dist/accessi-module/Dtos/GetMenusResponse.js +1 -1
- package/dist/accessi-module/Dtos/GetMenusResponse.js.map +1 -1
- package/dist/accessi-module/Dtos/GetRolesResponse.js.map +1 -1
- package/dist/accessi-module/Dtos/GetUserByTokenRequest.js.map +1 -1
- package/dist/accessi-module/Dtos/GetUserByTokenResponse.js.map +1 -1
- package/dist/accessi-module/Dtos/GetUsersResponse.d.ts +1 -1
- package/dist/accessi-module/Dtos/GetUsersResponse.js.map +1 -1
- package/dist/accessi-module/Dtos/LoginRequest.js.map +1 -1
- package/dist/accessi-module/Dtos/LoginResponse.d.ts +1 -1
- package/dist/accessi-module/Dtos/LoginResponse.js +1 -1
- package/dist/accessi-module/Dtos/LoginResponse.js.map +1 -1
- package/dist/accessi-module/Dtos/MenuItem.js +1 -0
- package/dist/accessi-module/Dtos/Permission.js.map +1 -1
- package/dist/accessi-module/Dtos/RegisterRequest.js +2 -1
- package/dist/accessi-module/Dtos/RegisterRequest.js.map +1 -1
- package/dist/accessi-module/Dtos/RegisterResponse.js.map +1 -1
- package/dist/accessi-module/Dtos/Role.js.map +1 -1
- package/dist/accessi-module/Dtos/RuoliMenu.js.map +1 -1
- package/dist/accessi-module/Dtos/SendResetPasswordEmailRequest.js.map +1 -1
- package/dist/accessi-module/Dtos/ServiceToken.d.ts +34 -0
- package/dist/accessi-module/Dtos/ServiceToken.js +128 -0
- package/dist/accessi-module/Dtos/ServiceToken.js.map +1 -0
- package/dist/accessi-module/Dtos/SetStatoRegistrazione.js.map +1 -1
- package/dist/accessi-module/Dtos/TipoFiltro.js.map +1 -1
- package/dist/accessi-module/Dtos/TokenResult.js.map +1 -1
- package/dist/accessi-module/Dtos/TwoFactorDtos.js.map +1 -1
- package/dist/accessi-module/Dtos/UpdateEnabledStatusRequest.js.map +1 -1
- package/dist/accessi-module/Dtos/UserDto.js +4 -2
- package/dist/accessi-module/Dtos/UserDto.js.map +1 -1
- package/dist/accessi-module/Dtos/UserGrantsDto.js.map +1 -1
- package/dist/accessi-module/Dtos/UserGrantsResponse.js.map +1 -1
- package/dist/accessi-module/Dtos/index.d.ts +2 -0
- package/dist/accessi-module/Dtos/index.js +2 -0
- package/dist/accessi-module/Dtos/index.js.map +1 -1
- package/dist/accessi-module/Services/AuthService/AuthService.d.ts +2 -2
- package/dist/accessi-module/Services/AuthService/AuthService.js +36 -36
- package/dist/accessi-module/Services/AuthService/AuthService.js.map +1 -1
- package/dist/accessi-module/Services/EmailService/EmailService.d.ts +2 -1
- package/dist/accessi-module/Services/EmailService/EmailService.js +9 -6
- package/dist/accessi-module/Services/EmailService/EmailService.js.map +1 -1
- package/dist/accessi-module/Services/FiltriService/FiltriService.d.ts +10 -3
- package/dist/accessi-module/Services/FiltriService/FiltriService.js +64 -6
- package/dist/accessi-module/Services/FiltriService/FiltriService.js.map +1 -1
- package/dist/accessi-module/Services/PermissionService/PermissionService.d.ts +44 -1
- package/dist/accessi-module/Services/PermissionService/PermissionService.js +418 -110
- package/dist/accessi-module/Services/PermissionService/PermissionService.js.map +1 -1
- package/dist/accessi-module/Services/ServiceTokenService/ServiceTokenService.d.ts +75 -0
- package/dist/accessi-module/Services/ServiceTokenService/ServiceTokenService.js +265 -0
- package/dist/accessi-module/Services/ServiceTokenService/ServiceTokenService.js.map +1 -0
- package/dist/accessi-module/Services/TwoFactorService/TwoFactorService.js +23 -27
- package/dist/accessi-module/Services/TwoFactorService/TwoFactorService.js.map +1 -1
- package/dist/accessi-module/Services/UserService/UserService.d.ts +10 -3
- package/dist/accessi-module/Services/UserService/UserService.js +170 -84
- package/dist/accessi-module/Services/UserService/UserService.js.map +1 -1
- package/dist/accessi-module/database-updates/AccessiDatabaseUpdater.d.ts +9 -0
- package/dist/accessi-module/database-updates/AccessiDatabaseUpdater.js +76 -28
- package/dist/accessi-module/database-updates/AccessiDatabaseUpdater.js.map +1 -1
- package/dist/accessi-module/database-updates/accessiSchema.d.ts +1 -1
- package/dist/accessi-module/database-updates/accessiSchema.js +9 -1
- package/dist/accessi-module/database-updates/accessiSchema.js.map +1 -1
- package/dist/accessi-module/database-updates/optionalColumns.d.ts +2 -0
- package/dist/accessi-module/database-updates/optionalColumns.js +33 -1
- package/dist/accessi-module/database-updates/optionalColumns.js.map +1 -1
- package/dist/accessi-module/database-updates/runAccessiDbUpdate.js +7 -2
- package/dist/accessi-module/database-updates/runAccessiDbUpdate.js.map +1 -1
- package/dist/accessi-module/federated-auth/FederatedAuthController.d.ts +1 -0
- package/dist/accessi-module/federated-auth/FederatedAuthController.js +26 -0
- package/dist/accessi-module/federated-auth/FederatedAuthController.js.map +1 -1
- package/dist/accessi-module/federated-auth/FederatedAuthService.d.ts +6 -0
- package/dist/accessi-module/federated-auth/FederatedAuthService.js +28 -1
- package/dist/accessi-module/federated-auth/FederatedAuthService.js.map +1 -1
- package/dist/accessi-module/index.d.ts +4 -1
- package/dist/accessi-module/index.js +8 -2
- package/dist/accessi-module/index.js.map +1 -1
- package/dist/accessi-module/jwt/jwt.strategy.js +8 -5
- package/dist/accessi-module/jwt/jwt.strategy.js.map +1 -1
- package/dist/accessi-module/middleware/accessiRequirements.d.ts +1 -1
- package/dist/accessi-module/middleware/accessiRequirements.js.map +1 -1
- package/dist/accessi-module/middleware/authenticateGen.js +11 -7
- package/dist/accessi-module/middleware/authenticateGen.js.map +1 -1
- package/dist/accessi-module/security/accessControl.js +8 -3
- package/dist/accessi-module/security/accessControl.js.map +1 -1
- package/dist/accessi-module/security/authenticatedToken.d.ts +1 -1
- package/dist/accessi-module/security/authenticatedToken.js +2 -1
- package/dist/accessi-module/security/authenticatedToken.js.map +1 -1
- package/dist/accessi-module/security/passwordResetToken.d.ts +9 -3
- package/dist/accessi-module/security/passwordResetToken.js +9 -5
- package/dist/accessi-module/security/passwordResetToken.js.map +1 -1
- package/dist/accessi-module/security/publicAuthRateLimit.d.ts +1 -1
- package/dist/accessi-module/security/publicAuthRateLimit.js +28 -8
- package/dist/accessi-module/security/publicAuthRateLimit.js.map +1 -1
- package/dist/accessi-module/security/serviceTokenGuard.d.ts +25 -0
- package/dist/accessi-module/security/serviceTokenGuard.js +85 -0
- package/dist/accessi-module/security/serviceTokenGuard.js.map +1 -0
- package/dist/accessi-module/security/serviceTokenRateLimit.d.ts +8 -0
- package/dist/accessi-module/security/serviceTokenRateLimit.js +49 -0
- package/dist/accessi-module/security/serviceTokenRateLimit.js.map +1 -0
- package/dist/allegati-module/AllegatiModule.d.ts +11 -0
- package/dist/allegati-module/AllegatiModule.js +11 -1
- package/dist/allegati-module/AllegatiModule.js.map +1 -1
- package/dist/allegati-module/Controllers/AllegatiController.d.ts +2 -1
- package/dist/allegati-module/Controllers/AllegatiController.js +23 -15
- package/dist/allegati-module/Controllers/AllegatiController.js.map +1 -1
- package/dist/allegati-module/Dtos/AllegatoDto.js.map +1 -1
- package/dist/allegati-module/Dtos/BaseResponse.js.map +1 -1
- package/dist/allegati-module/Dtos/UploadSingleFileRequest.js.map +1 -1
- package/dist/allegati-module/Dtos/responses/DownloadAllegatoResponseDto.js.map +1 -1
- package/dist/allegati-module/Dtos/responses/GetListResponse.js.map +1 -1
- package/dist/allegati-module/Dtos/responses/UploadAllegatoResponseDto.js.map +1 -1
- package/dist/allegati-module/Services/AllegatiService/AllegatiService.d.ts +10 -3
- package/dist/allegati-module/Services/AllegatiService/AllegatiService.js +101 -52
- package/dist/allegati-module/Services/AllegatiService/AllegatiService.js.map +1 -1
- package/dist/allegati-module/security/allegatiAuthorizationGuard.d.ts +14 -0
- package/dist/allegati-module/security/allegatiAuthorizationGuard.js +70 -0
- package/dist/allegati-module/security/allegatiAuthorizationGuard.js.map +1 -0
- package/dist/autobind.d.ts +10 -3
- package/dist/autobind.js +24 -9
- package/dist/autobind.js.map +1 -1
- package/dist/emilsoftware-utilities-2.0.0-dev.25.tgz +0 -0
- package/dist/firebird-compat.d.ts +13 -0
- package/dist/firebird-compat.js +3 -2
- package/dist/firebird-compat.js.map +1 -1
- package/dist/scripts/generateAccessiWiki.d.ts +1 -0
- package/dist/scripts/generateAccessiWiki.js +131 -0
- package/dist/scripts/generateAccessiWiki.js.map +1 -0
- package/dist/swagger/SwaggerConfig.js +6 -3
- package/dist/swagger/SwaggerConfig.js.map +1 -1
- package/package.json +19 -8
- package/dist/emilsoftware-utilities-2.0.0-dev.23.tgz +0 -0
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.HELP = void 0;
|
|
4
|
+
const p = (text) => ({ kind: 'p', text });
|
|
5
|
+
const list = (items) => ({ kind: 'list', items });
|
|
6
|
+
const code = (language, codeText, title) => ({ kind: 'code', language, title, code: codeText });
|
|
7
|
+
const note = (tone, title, text) => ({ kind: 'callout', tone, title, text });
|
|
8
|
+
const table = (head, rows) => ({ kind: 'table', head, rows });
|
|
9
|
+
exports.HELP = {
|
|
10
|
+
// ------------------------------------------------------------------ SSO
|
|
11
|
+
'sso-provider': {
|
|
12
|
+
title: 'Provider SSO',
|
|
13
|
+
blocks: [
|
|
14
|
+
p(`La chiave del provider censito in Accessi. Deve coincidere esattamente con quella usata dal backend quando valida il login SSO e chiama FederatedAuthService.authenticate({ provider, subject }).`),
|
|
15
|
+
p(`Se il backend usa la chiave azure-ad-acme-prod, qui va la stessa stringa: una differenza, anche di un carattere, fa fallire il collegamento.`),
|
|
16
|
+
note('info', 'Chi crea il provider', `Prima si censisce il provider in "SSO → Provider" (superutente), poi lo si sceglie qui. Se l'elenco è vuoto, non ci sono provider attivi.`),
|
|
17
|
+
],
|
|
18
|
+
},
|
|
19
|
+
'sso-subject': {
|
|
20
|
+
title: 'ID utente del provider (subject)',
|
|
21
|
+
blocks: [
|
|
22
|
+
p(`È l'identificatore STABILE della persona nel provider, non l'email. Il backend lo ottiene dopo aver validato il token del provider e lo passa ad Accessi; Accessi non vede mai il token esterno.`),
|
|
23
|
+
p(`Ecco il claim corretto per i provider più comuni:`),
|
|
24
|
+
table(['Provider', 'Claim da usare', 'Note'], [
|
|
25
|
+
['Azure AD / Entra ID', 'oid', 'Object ID. Non usare preferred_username né email.'],
|
|
26
|
+
['Google', 'sub', 'ID numerico di 21 cifre. Non l indirizzo email.'],
|
|
27
|
+
['Apple', 'sub', 'Identificatore stabile per la tua app; disponibile solo al primo login, va salvato subito.'],
|
|
28
|
+
['Okta', 'sub', 'Claim standard OIDC.'],
|
|
29
|
+
['Auth0', 'sub', 'Formato auth0|... oppure google-oauth2|... .'],
|
|
30
|
+
['Keycloak', 'sub', 'Claim standard OIDC.'],
|
|
31
|
+
['Microsoft personale (MSA)', 'sub', 'Account outlook/live.'],
|
|
32
|
+
['SAML 2.0', 'NameID', 'Identificatore persistente dell utente.'],
|
|
33
|
+
['OIDC generico', 'sub', 'Claim standard OIDC.'],
|
|
34
|
+
]),
|
|
35
|
+
note('danger', 'Mai usare l email', `L'email può cambiare e non è un identificatore stabile: usarla come subject crea duplicati e collegamenti errati.`),
|
|
36
|
+
code('ts', [
|
|
37
|
+
'// Nel backend, dopo aver validato il token del provider:',
|
|
38
|
+
'// Azure AD / Entra ID',
|
|
39
|
+
"const subject = claims.oid;",
|
|
40
|
+
'// Google / Okta / Keycloak / OIDC generico',
|
|
41
|
+
"const subject = claims.sub;",
|
|
42
|
+
'// Apple (disponibile al primo login, salvalo subito)',
|
|
43
|
+
"const subject = claims.sub;",
|
|
44
|
+
'// SAML',
|
|
45
|
+
"const subject = assertion.nameId;",
|
|
46
|
+
].join('\n'), 'Come ricavare il subject'),
|
|
47
|
+
],
|
|
48
|
+
},
|
|
49
|
+
'sso-note': {
|
|
50
|
+
title: 'Nota',
|
|
51
|
+
blocks: [
|
|
52
|
+
p(`Nota interna per gli amministratori, utile a ricordare perché il collegamento esiste (per esempio "migrato da AD il 2026-01-10"). Non viene inviata al provider.`),
|
|
53
|
+
],
|
|
54
|
+
},
|
|
55
|
+
'provider-key': {
|
|
56
|
+
title: 'Chiave provider',
|
|
57
|
+
blocks: [
|
|
58
|
+
p(`Identificativo tecnico del provider, usato dal backend nel payload SSO. Scegli una chiave descrittiva e stabile, per esempio azure-ad-acme-prod o google-workspace-acme.`),
|
|
59
|
+
note('warn', 'Immutabile', `Dopo il censimento la chiave non si modifica: identità e configurazione del backend la referenziano. Se serve cambiarla, disabilita il provider e creane uno nuovo.`),
|
|
60
|
+
],
|
|
61
|
+
},
|
|
62
|
+
'provider-description': {
|
|
63
|
+
title: 'Descrizione',
|
|
64
|
+
blocks: [
|
|
65
|
+
p(`Nome leggibile mostrato agli amministratori (per esempio "Azure AD – Acme produzione"). Non è la chiave tecnica: può contenere spazi.`),
|
|
66
|
+
],
|
|
67
|
+
},
|
|
68
|
+
'provider-note': {
|
|
69
|
+
title: 'Nota',
|
|
70
|
+
blocks: [
|
|
71
|
+
p(`Nota interna del catalogo. Non inserire segreti, issuer, client id o dati personali: quei valori restano nel backend.`),
|
|
72
|
+
],
|
|
73
|
+
},
|
|
74
|
+
'provider-active': {
|
|
75
|
+
title: 'Provider attivo',
|
|
76
|
+
blocks: [
|
|
77
|
+
p(`Se disattivato, il provider non accetta nuovi login e nuovi collegamenti; le identità e lo storico restano. Riattivalo quando il backend è pronto.`),
|
|
78
|
+
],
|
|
79
|
+
},
|
|
80
|
+
// --------------------------------------------------------- service token
|
|
81
|
+
'token-label': {
|
|
82
|
+
title: 'Descrizione del token',
|
|
83
|
+
blocks: [
|
|
84
|
+
p(`Nome del token, mostrato agli amministratori (per esempio "Integrazione IA – produzione"). Non è un segreto.`),
|
|
85
|
+
],
|
|
86
|
+
},
|
|
87
|
+
'token-scopes': {
|
|
88
|
+
title: 'Scope',
|
|
89
|
+
blocks: [
|
|
90
|
+
p(`Etichette che il backend controlla per autorizzare le chiamate tecniche. Un token non è un superutente: abilita solo le rotte protette con ServiceTokenGuard e @RequireServiceTokenScopes.`),
|
|
91
|
+
list([
|
|
92
|
+
`Formato: lettere, numeri, ':', '_' o '-', massimo 40 caratteri.`,
|
|
93
|
+
`Esempi: ia, chat, tools, report:read.`,
|
|
94
|
+
`Separa gli scope con una virgola.`,
|
|
95
|
+
]),
|
|
96
|
+
code('ts', [
|
|
97
|
+
'@UseGuards(ServiceTokenGuard)',
|
|
98
|
+
"@RequireServiceTokenScopes('ia')",
|
|
99
|
+
'@Post("internal/ask")',
|
|
100
|
+
'ask() { /* il token deve avere lo scope ia */ }',
|
|
101
|
+
].join('\n'), 'Come li usa il backend'),
|
|
102
|
+
note('warn', 'Scope vuoto', `Senza scope il token non soddisfa nessun @RequireServiceTokenScopes, ma passa comunque le rotte protette senza scope richiesto.`),
|
|
103
|
+
],
|
|
104
|
+
},
|
|
105
|
+
'token-ttl': {
|
|
106
|
+
title: 'Durata (giorni)',
|
|
107
|
+
blocks: [
|
|
108
|
+
p(`Giorni di validità del token. Alla scadenza il token smette di funzionare.`),
|
|
109
|
+
note('danger', 'Nessuna scadenza', `Se lasci vuoto questo campo e non imposti una data, il token non scade mai: sconsigliato in produzione.`),
|
|
110
|
+
],
|
|
111
|
+
},
|
|
112
|
+
// ----------------------------------------------------------------- utenti
|
|
113
|
+
'user-email': {
|
|
114
|
+
title: 'Email',
|
|
115
|
+
blocks: [
|
|
116
|
+
p(`Identificativo di accesso dell'utente e recapito per le email di reset o codici. Deve essere univoca.`),
|
|
117
|
+
],
|
|
118
|
+
},
|
|
119
|
+
'user-name': {
|
|
120
|
+
title: 'Nome e cognome',
|
|
121
|
+
blocks: [
|
|
122
|
+
p(`Dati anagrafici mostrati in console e restituiti nel profilo. Non incidono sull'autenticazione.`),
|
|
123
|
+
],
|
|
124
|
+
},
|
|
125
|
+
'user-password-login': {
|
|
126
|
+
title: 'Login con password',
|
|
127
|
+
blocks: [
|
|
128
|
+
p(`Se disattivato, il login con email e password viene rifiutato (PASSWORD_LOGIN_DISABLED). Restano validi i login con identità SSO attive.`),
|
|
129
|
+
note('info', 'Utente solo SSO', `È l'opzione tipica per gli utenti federati: nessuna password locale, accesso solo dal provider.`),
|
|
130
|
+
],
|
|
131
|
+
},
|
|
132
|
+
'user-2fa': {
|
|
133
|
+
title: 'Codice via email (2FA)',
|
|
134
|
+
blocks: [
|
|
135
|
+
p(`Richiede un codice monouso inviato per email dopo la password o dopo il provider SSO. È per-utente e disattivata per impostazione predefinita.`),
|
|
136
|
+
list([
|
|
137
|
+
`Codice a 6 cifre, valido 10 minuti, 5 tentativi, massimo 3 invii.`,
|
|
138
|
+
`Non sono token: fino alla verifica non esiste alcun JWT.`,
|
|
139
|
+
]),
|
|
140
|
+
],
|
|
141
|
+
},
|
|
142
|
+
'user-passwordless': {
|
|
143
|
+
title: 'Accesso con il solo codice email',
|
|
144
|
+
blocks: [
|
|
145
|
+
p(`Abilita il login senza password: si inserisce solo l'email e si usa il codice ricevuto. Richiede il codice email (2FA) attivo.`),
|
|
146
|
+
note('warn', 'Non sono due fattori', `L'accesso con il solo codice è autenticazione tramite possesso della casella email: un solo fattore.`),
|
|
147
|
+
],
|
|
148
|
+
},
|
|
149
|
+
'user-state': {
|
|
150
|
+
title: 'Stato di registrazione',
|
|
151
|
+
blocks: [
|
|
152
|
+
table(['Stato', 'Significato'], [
|
|
153
|
+
['Non definito / Inserito', 'Utente non confermato.'],
|
|
154
|
+
['Invitato (10)', 'Richiede il rinnovo della password.'],
|
|
155
|
+
['Confermato (20)', 'Utente valido, può accedere.'],
|
|
156
|
+
['Eliminato (50)', 'Soft delete: login bloccato.'],
|
|
157
|
+
['Bloccato (99)', 'Login bloccato.'],
|
|
158
|
+
]),
|
|
159
|
+
],
|
|
160
|
+
},
|
|
161
|
+
// ------------------------------------------------------------------ ruoli
|
|
162
|
+
'role-description': {
|
|
163
|
+
title: 'Descrizione del ruolo',
|
|
164
|
+
blocks: [
|
|
165
|
+
p(`Nome del ruolo (per esempio "Gestore ordini"). Deve avere almeno un menu selezionato: il salvataggio sostituisce integralmente i menu del ruolo.`),
|
|
166
|
+
],
|
|
167
|
+
},
|
|
168
|
+
'role-level': {
|
|
169
|
+
title: 'Livello di abilitazione',
|
|
170
|
+
blocks: [
|
|
171
|
+
table(['Livello', 'Valore', 'Uso tipico'], [
|
|
172
|
+
['Lettura', '10', 'Sola consultazione.'],
|
|
173
|
+
['Scrittura', '20', 'Modifica dei dati.'],
|
|
174
|
+
['Legacy (30)', '30', 'Valore storico, mantenuto senza perdita.'],
|
|
175
|
+
]),
|
|
176
|
+
p(`Il controllo confronta tipoAbilitazione >= soglia: un livello 20 soddisfa anche una richiesta di livello 10.`),
|
|
177
|
+
],
|
|
178
|
+
},
|
|
179
|
+
// --------------------------------------------------------- catalogo menu
|
|
180
|
+
'menu-code': {
|
|
181
|
+
title: 'Codice menu',
|
|
182
|
+
blocks: [
|
|
183
|
+
p(`Chiave tecnica del menu, stabile e senza spazi (per esempio ORDINI o MNU001). È la chiave primaria: non si modifica dopo la creazione.`),
|
|
184
|
+
note('warn', 'Immutabile', `Il codice è referenziato da ruoli e grant: per cambiarlo, elimina e ricrea il menu.`),
|
|
185
|
+
],
|
|
186
|
+
},
|
|
187
|
+
'menu-group-code': {
|
|
188
|
+
title: 'Codice gruppo',
|
|
189
|
+
blocks: [
|
|
190
|
+
p(`Un solo carattere (per esempio A). Raggruppa i menu nella navigazione. Immutabile dopo la creazione.`),
|
|
191
|
+
],
|
|
192
|
+
},
|
|
193
|
+
'menu-type-code': {
|
|
194
|
+
title: 'Codice tipo menu',
|
|
195
|
+
blocks: [
|
|
196
|
+
p(`Un solo carattere (per esempio X). Classifica i menu (amministrazione, operativo, ...). Immutabile dopo la creazione.`),
|
|
197
|
+
],
|
|
198
|
+
},
|
|
199
|
+
'menu-group-order': {
|
|
200
|
+
title: 'Ordine del gruppo',
|
|
201
|
+
blocks: [
|
|
202
|
+
p(`Numero che determina l'ordine dei gruppi nella navigazione: valori più bassi compaiono prima.`),
|
|
203
|
+
],
|
|
204
|
+
},
|
|
205
|
+
'menu-order': {
|
|
206
|
+
title: 'Ordine del menu',
|
|
207
|
+
blocks: [
|
|
208
|
+
p(`Numero che determina l'ordine dei menu all'interno del gruppo: valori più bassi compaiono prima.`),
|
|
209
|
+
],
|
|
210
|
+
},
|
|
211
|
+
'menu-page': {
|
|
212
|
+
title: 'Pagina',
|
|
213
|
+
blocks: [
|
|
214
|
+
p(`Percorso o nome della pagina del frontend associata al menu (per esempio /ordini). È informativo: lo usano la UI host e i client.`),
|
|
215
|
+
],
|
|
216
|
+
},
|
|
217
|
+
'menu-icon': {
|
|
218
|
+
title: 'Icona',
|
|
219
|
+
blocks: [
|
|
220
|
+
p(`Identificatore dell'icona usato dalla UI host (per esempio fa-box o un nome concordato). Accessi non impone un set di icone.`),
|
|
221
|
+
],
|
|
222
|
+
},
|
|
223
|
+
'menu-rifmenu': {
|
|
224
|
+
title: 'Menu di riferimento',
|
|
225
|
+
blocks: [
|
|
226
|
+
p(`Codice di un altro menu che fa da padre, per costruire gerarchie di menu. Lascia vuoto per un menu di primo livello.`),
|
|
227
|
+
],
|
|
228
|
+
},
|
|
229
|
+
'menu-note': {
|
|
230
|
+
title: 'Nota',
|
|
231
|
+
blocks: [
|
|
232
|
+
p(`Nota descrittiva mostrata agli amministratori. Non incide sui permessi.`),
|
|
233
|
+
],
|
|
234
|
+
},
|
|
235
|
+
'menu-enabled': {
|
|
236
|
+
title: 'Menu abilitato',
|
|
237
|
+
blocks: [
|
|
238
|
+
p(`Se disattivato, il menu non compare nel catalogo attivo e non viene considerato nel calcolo dei grant. I collegamenti a ruoli e utenti restano.`),
|
|
239
|
+
],
|
|
240
|
+
},
|
|
241
|
+
'menu-group-enabled': {
|
|
242
|
+
title: 'Gruppo abilitato',
|
|
243
|
+
blocks: [
|
|
244
|
+
p(`Disattiva l'intero gruppo: i menu al suo interno non sono considerati attivi, ma restano configurabili per una riattivazione futura.`),
|
|
245
|
+
],
|
|
246
|
+
},
|
|
247
|
+
// ----------------------------------------------------------------- filtri
|
|
248
|
+
'filter-type-code': {
|
|
249
|
+
title: 'Codice tipo filtro',
|
|
250
|
+
blocks: [
|
|
251
|
+
p(`Numero identificativo del tipo filtro. È la chiave primaria: non si modifica dopo la creazione.`),
|
|
252
|
+
],
|
|
253
|
+
},
|
|
254
|
+
'filter-type-field': {
|
|
255
|
+
title: 'Campo',
|
|
256
|
+
blocks: [
|
|
257
|
+
p(`Nome della colonna applicativa della tabella FILTRI a cui il tipo è associato (per esempio CODCLI). Deve esistere nello schema, altrimenti i filtri che lo usano vengono rifiutati.`),
|
|
258
|
+
],
|
|
259
|
+
},
|
|
260
|
+
'filter-type-enabled': {
|
|
261
|
+
title: 'Tipo filtro abilitato',
|
|
262
|
+
blocks: [
|
|
263
|
+
p(`Se disattivato, il tipo non è proposto ai client, ma i filtri già salvati restano nel database.`),
|
|
264
|
+
],
|
|
265
|
+
},
|
|
266
|
+
'filters-json': {
|
|
267
|
+
title: 'Filtro JSON',
|
|
268
|
+
blocks: [
|
|
269
|
+
p(`Rappresentazione JSON dei filtri applicativi dell'utente. Usa "Carica" per partire dalla struttura esistente, modifica i valori e poi "Salva".`),
|
|
270
|
+
note('info', 'Campi ammessi', `Sono accettati solo i campi mappati nello schema (FILTRI_UTENTE_DB_MAPPING). Un campo non configurato viene rifiutato con un errore esplicito.`),
|
|
271
|
+
],
|
|
272
|
+
},
|
|
273
|
+
'filters-user': {
|
|
274
|
+
title: 'Utente',
|
|
275
|
+
blocks: [
|
|
276
|
+
p(`Utente a cui appartengono i filtri. Selezionalo prima di caricare o salvare: i filtri sono sempre per singolo utente.`),
|
|
277
|
+
],
|
|
278
|
+
},
|
|
279
|
+
// ------------------------------------------------------------ assegnazioni
|
|
280
|
+
'role-assignment': {
|
|
281
|
+
title: 'Assegnazione dei ruoli',
|
|
282
|
+
blocks: [
|
|
283
|
+
p(`Il salvataggio SOSTITUISCE integralmente i ruoli dell'utente: la lista selezionata diventa l'unico set di ruoli.`),
|
|
284
|
+
list([
|
|
285
|
+
`Per aggiungere un ruolo, selezionalo mantenendo quelli già presenti.`,
|
|
286
|
+
`Per rimuovere un ruolo, deselezionalo.`,
|
|
287
|
+
`Non modificare i grant diretti: quelli si gestiscono nella scheda "Grant diretti".`,
|
|
288
|
+
]),
|
|
289
|
+
note('warn', 'Non è incrementale', `Inviare solo il nuovo ruolo rimuove gli altri. Invia sempre la lista completa desiderata.`),
|
|
290
|
+
],
|
|
291
|
+
},
|
|
292
|
+
'grant-direct': {
|
|
293
|
+
title: 'Grant diretti',
|
|
294
|
+
blocks: [
|
|
295
|
+
p(`Permessi assegnati direttamente all'utente, indipendenti dai ruoli. Hanno precedenza sui permessi ereditati dai ruoli per lo stesso menu.`),
|
|
296
|
+
list([
|
|
297
|
+
`Imposta il livello per concedere l'accesso.`,
|
|
298
|
+
`Scegli "nessuno" per rimuovere il grant diretto.`,
|
|
299
|
+
`Il salvataggio sostituisce l'intero set di grant diretti.`,
|
|
300
|
+
]),
|
|
301
|
+
],
|
|
302
|
+
},
|
|
303
|
+
'grant-level': {
|
|
304
|
+
title: 'Livello di grant',
|
|
305
|
+
blocks: [
|
|
306
|
+
table(['Voce', 'Valore', 'Significato'], [
|
|
307
|
+
['nessuno', '—', 'Nessun grant diretto per quel menu (il permesso può arrivare dai ruoli).'],
|
|
308
|
+
['Lettura', '10', 'Sola consultazione.'],
|
|
309
|
+
['Scrittura', '20', 'Modifica dei dati.'],
|
|
310
|
+
]),
|
|
311
|
+
p(`Il confronto è tipoAbilitazione >= soglia richiesta dalla rotta.`),
|
|
312
|
+
],
|
|
313
|
+
},
|
|
314
|
+
'user-delete': {
|
|
315
|
+
title: 'Imposta stato eliminato',
|
|
316
|
+
blocks: [
|
|
317
|
+
p(`Esegue un soft delete: imposta lo stato di registrazione a "Eliminato" (50). L'utente non può più accedere, ma i dati restano nel database.`),
|
|
318
|
+
note('info', 'Reversibile', `Non è una cancellazione fisica: puoi ripristinare l'utente cambiando lo stato di registrazione.`),
|
|
319
|
+
],
|
|
320
|
+
},
|
|
321
|
+
// ----------------------------------------------------- selezioni di menu
|
|
322
|
+
'menu-group-select': {
|
|
323
|
+
title: 'Gruppo',
|
|
324
|
+
blocks: [
|
|
325
|
+
p(`Gruppo di appartenenza del menu. Se l'elenco è vuoto, crea prima un gruppo in "Menu e gruppi → Gruppi".`),
|
|
326
|
+
],
|
|
327
|
+
},
|
|
328
|
+
'menu-type-select': {
|
|
329
|
+
title: 'Tipo menu',
|
|
330
|
+
blocks: [
|
|
331
|
+
p(`Classificazione del menu (amministrazione, operativo, ...). È facoltativa: se non serve, lascia "Nessun tipo". I tipi si gestiscono in "Menu e gruppi → Tipi menu".`),
|
|
332
|
+
],
|
|
333
|
+
},
|
|
334
|
+
// ------------------------------------------------------------------ login
|
|
335
|
+
'login-email': {
|
|
336
|
+
title: 'Email o utente',
|
|
337
|
+
blocks: [
|
|
338
|
+
p(`Indirizzo email dell'utente Accessi. Se l'account è abilitato al solo codice, dopo questo passo riceverai un codice via email invece di inserire la password.`),
|
|
339
|
+
],
|
|
340
|
+
},
|
|
341
|
+
'login-password': {
|
|
342
|
+
title: 'Password',
|
|
343
|
+
blocks: [
|
|
344
|
+
p(`Password locale dell'utente. Non serve per gli account passwordless, che accedono con il solo codice email.`),
|
|
345
|
+
],
|
|
346
|
+
},
|
|
347
|
+
};
|
|
348
|
+
//# sourceMappingURL=help.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"help.js","sourceRoot":"","sources":["../../../src/accessi-module/Console/help.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Contenuti di aiuto contestuale della console Accessi.\n *\n * Ogni voce spiega, in italiano corretto, che cosa inserire in un campo\n * tecnico e da dove prendere il valore. Sono mostrati come miniguida nel\n * tooltip aperto dall'icona \"i\" accanto al campo.\n */\nimport type { WikiBlock } from './wiki';\n\nexport interface HelpEntry {\n title: string;\n blocks: WikiBlock[];\n}\n\nconst p = (text: string): WikiBlock => ({ kind: 'p', text });\nconst list = (items: string[]): WikiBlock => ({ kind: 'list', items });\nconst code = (language: string, codeText: string, title?: string): WikiBlock => ({ kind: 'code', language, title, code: codeText });\nconst note = (tone: 'info' | 'ok' | 'warn' | 'danger', title: string, text: string): WikiBlock => ({ kind: 'callout', tone, title, text });\nconst table = (head: string[], rows: string[][]): WikiBlock => ({ kind: 'table', head, rows });\n\nexport const HELP: Record<string, HelpEntry> = {\n // ------------------------------------------------------------------ SSO\n 'sso-provider': {\n title: 'Provider SSO',\n blocks: [\n p(`La chiave del provider censito in Accessi. Deve coincidere esattamente con quella usata dal backend quando valida il login SSO e chiama FederatedAuthService.authenticate({ provider, subject }).`),\n p(`Se il backend usa la chiave azure-ad-acme-prod, qui va la stessa stringa: una differenza, anche di un carattere, fa fallire il collegamento.`),\n note('info', 'Chi crea il provider', `Prima si censisce il provider in \"SSO → Provider\" (superutente), poi lo si sceglie qui. Se l'elenco è vuoto, non ci sono provider attivi.`),\n ],\n },\n 'sso-subject': {\n title: 'ID utente del provider (subject)',\n blocks: [\n p(`È l'identificatore STABILE della persona nel provider, non l'email. Il backend lo ottiene dopo aver validato il token del provider e lo passa ad Accessi; Accessi non vede mai il token esterno.`),\n p(`Ecco il claim corretto per i provider più comuni:`),\n table(\n ['Provider', 'Claim da usare', 'Note'],\n [\n ['Azure AD / Entra ID', 'oid', 'Object ID. Non usare preferred_username né email.'],\n ['Google', 'sub', 'ID numerico di 21 cifre. Non l indirizzo email.'],\n ['Apple', 'sub', 'Identificatore stabile per la tua app; disponibile solo al primo login, va salvato subito.'],\n ['Okta', 'sub', 'Claim standard OIDC.'],\n ['Auth0', 'sub', 'Formato auth0|... oppure google-oauth2|... .'],\n ['Keycloak', 'sub', 'Claim standard OIDC.'],\n ['Microsoft personale (MSA)', 'sub', 'Account outlook/live.'],\n ['SAML 2.0', 'NameID', 'Identificatore persistente dell utente.'],\n ['OIDC generico', 'sub', 'Claim standard OIDC.'],\n ],\n ),\n note('danger', 'Mai usare l email', `L'email può cambiare e non è un identificatore stabile: usarla come subject crea duplicati e collegamenti errati.`),\n code('ts', [\n '// Nel backend, dopo aver validato il token del provider:',\n '// Azure AD / Entra ID',\n \"const subject = claims.oid;\",\n '// Google / Okta / Keycloak / OIDC generico',\n \"const subject = claims.sub;\",\n '// Apple (disponibile al primo login, salvalo subito)',\n \"const subject = claims.sub;\",\n '// SAML',\n \"const subject = assertion.nameId;\",\n ].join('\\n'), 'Come ricavare il subject'),\n ],\n },\n 'sso-note': {\n title: 'Nota',\n blocks: [\n p(`Nota interna per gli amministratori, utile a ricordare perché il collegamento esiste (per esempio \"migrato da AD il 2026-01-10\"). Non viene inviata al provider.`),\n ],\n },\n 'provider-key': {\n title: 'Chiave provider',\n blocks: [\n p(`Identificativo tecnico del provider, usato dal backend nel payload SSO. Scegli una chiave descrittiva e stabile, per esempio azure-ad-acme-prod o google-workspace-acme.`),\n note('warn', 'Immutabile', `Dopo il censimento la chiave non si modifica: identità e configurazione del backend la referenziano. Se serve cambiarla, disabilita il provider e creane uno nuovo.`),\n ],\n },\n 'provider-description': {\n title: 'Descrizione',\n blocks: [\n p(`Nome leggibile mostrato agli amministratori (per esempio \"Azure AD – Acme produzione\"). Non è la chiave tecnica: può contenere spazi.`),\n ],\n },\n 'provider-note': {\n title: 'Nota',\n blocks: [\n p(`Nota interna del catalogo. Non inserire segreti, issuer, client id o dati personali: quei valori restano nel backend.`),\n ],\n },\n 'provider-active': {\n title: 'Provider attivo',\n blocks: [\n p(`Se disattivato, il provider non accetta nuovi login e nuovi collegamenti; le identità e lo storico restano. Riattivalo quando il backend è pronto.`),\n ],\n },\n\n // --------------------------------------------------------- service token\n 'token-label': {\n title: 'Descrizione del token',\n blocks: [\n p(`Nome del token, mostrato agli amministratori (per esempio \"Integrazione IA – produzione\"). Non è un segreto.`),\n ],\n },\n 'token-scopes': {\n title: 'Scope',\n blocks: [\n p(`Etichette che il backend controlla per autorizzare le chiamate tecniche. Un token non è un superutente: abilita solo le rotte protette con ServiceTokenGuard e @RequireServiceTokenScopes.`),\n list([\n `Formato: lettere, numeri, ':', '_' o '-', massimo 40 caratteri.`,\n `Esempi: ia, chat, tools, report:read.`,\n `Separa gli scope con una virgola.`,\n ]),\n code('ts', [\n '@UseGuards(ServiceTokenGuard)',\n \"@RequireServiceTokenScopes('ia')\",\n '@Post(\"internal/ask\")',\n 'ask() { /* il token deve avere lo scope ia */ }',\n ].join('\\n'), 'Come li usa il backend'),\n note('warn', 'Scope vuoto', `Senza scope il token non soddisfa nessun @RequireServiceTokenScopes, ma passa comunque le rotte protette senza scope richiesto.`),\n ],\n },\n 'token-ttl': {\n title: 'Durata (giorni)',\n blocks: [\n p(`Giorni di validità del token. Alla scadenza il token smette di funzionare.`),\n note('danger', 'Nessuna scadenza', `Se lasci vuoto questo campo e non imposti una data, il token non scade mai: sconsigliato in produzione.`),\n ],\n },\n\n // ----------------------------------------------------------------- utenti\n 'user-email': {\n title: 'Email',\n blocks: [\n p(`Identificativo di accesso dell'utente e recapito per le email di reset o codici. Deve essere univoca.`),\n ],\n },\n 'user-name': {\n title: 'Nome e cognome',\n blocks: [\n p(`Dati anagrafici mostrati in console e restituiti nel profilo. Non incidono sull'autenticazione.`),\n ],\n },\n 'user-password-login': {\n title: 'Login con password',\n blocks: [\n p(`Se disattivato, il login con email e password viene rifiutato (PASSWORD_LOGIN_DISABLED). Restano validi i login con identità SSO attive.`),\n note('info', 'Utente solo SSO', `È l'opzione tipica per gli utenti federati: nessuna password locale, accesso solo dal provider.`),\n ],\n },\n 'user-2fa': {\n title: 'Codice via email (2FA)',\n blocks: [\n p(`Richiede un codice monouso inviato per email dopo la password o dopo il provider SSO. È per-utente e disattivata per impostazione predefinita.`),\n list([\n `Codice a 6 cifre, valido 10 minuti, 5 tentativi, massimo 3 invii.`,\n `Non sono token: fino alla verifica non esiste alcun JWT.`,\n ]),\n ],\n },\n 'user-passwordless': {\n title: 'Accesso con il solo codice email',\n blocks: [\n p(`Abilita il login senza password: si inserisce solo l'email e si usa il codice ricevuto. Richiede il codice email (2FA) attivo.`),\n note('warn', 'Non sono due fattori', `L'accesso con il solo codice è autenticazione tramite possesso della casella email: un solo fattore.`),\n ],\n },\n 'user-state': {\n title: 'Stato di registrazione',\n blocks: [\n table(\n ['Stato', 'Significato'],\n [\n ['Non definito / Inserito', 'Utente non confermato.'],\n ['Invitato (10)', 'Richiede il rinnovo della password.'],\n ['Confermato (20)', 'Utente valido, può accedere.'],\n ['Eliminato (50)', 'Soft delete: login bloccato.'],\n ['Bloccato (99)', 'Login bloccato.'],\n ],\n ),\n ],\n },\n\n // ------------------------------------------------------------------ ruoli\n 'role-description': {\n title: 'Descrizione del ruolo',\n blocks: [\n p(`Nome del ruolo (per esempio \"Gestore ordini\"). Deve avere almeno un menu selezionato: il salvataggio sostituisce integralmente i menu del ruolo.`),\n ],\n },\n 'role-level': {\n title: 'Livello di abilitazione',\n blocks: [\n table(\n ['Livello', 'Valore', 'Uso tipico'],\n [\n ['Lettura', '10', 'Sola consultazione.'],\n ['Scrittura', '20', 'Modifica dei dati.'],\n ['Legacy (30)', '30', 'Valore storico, mantenuto senza perdita.'],\n ],\n ),\n p(`Il controllo confronta tipoAbilitazione >= soglia: un livello 20 soddisfa anche una richiesta di livello 10.`),\n ],\n },\n\n // --------------------------------------------------------- catalogo menu\n 'menu-code': {\n title: 'Codice menu',\n blocks: [\n p(`Chiave tecnica del menu, stabile e senza spazi (per esempio ORDINI o MNU001). È la chiave primaria: non si modifica dopo la creazione.`),\n note('warn', 'Immutabile', `Il codice è referenziato da ruoli e grant: per cambiarlo, elimina e ricrea il menu.`),\n ],\n },\n 'menu-group-code': {\n title: 'Codice gruppo',\n blocks: [\n p(`Un solo carattere (per esempio A). Raggruppa i menu nella navigazione. Immutabile dopo la creazione.`),\n ],\n },\n 'menu-type-code': {\n title: 'Codice tipo menu',\n blocks: [\n p(`Un solo carattere (per esempio X). Classifica i menu (amministrazione, operativo, ...). Immutabile dopo la creazione.`),\n ],\n },\n 'menu-group-order': {\n title: 'Ordine del gruppo',\n blocks: [\n p(`Numero che determina l'ordine dei gruppi nella navigazione: valori più bassi compaiono prima.`),\n ],\n },\n 'menu-order': {\n title: 'Ordine del menu',\n blocks: [\n p(`Numero che determina l'ordine dei menu all'interno del gruppo: valori più bassi compaiono prima.`),\n ],\n },\n 'menu-page': {\n title: 'Pagina',\n blocks: [\n p(`Percorso o nome della pagina del frontend associata al menu (per esempio /ordini). È informativo: lo usano la UI host e i client.`),\n ],\n },\n 'menu-icon': {\n title: 'Icona',\n blocks: [\n p(`Identificatore dell'icona usato dalla UI host (per esempio fa-box o un nome concordato). Accessi non impone un set di icone.`),\n ],\n },\n 'menu-rifmenu': {\n title: 'Menu di riferimento',\n blocks: [\n p(`Codice di un altro menu che fa da padre, per costruire gerarchie di menu. Lascia vuoto per un menu di primo livello.`),\n ],\n },\n 'menu-note': {\n title: 'Nota',\n blocks: [\n p(`Nota descrittiva mostrata agli amministratori. Non incide sui permessi.`),\n ],\n },\n 'menu-enabled': {\n title: 'Menu abilitato',\n blocks: [\n p(`Se disattivato, il menu non compare nel catalogo attivo e non viene considerato nel calcolo dei grant. I collegamenti a ruoli e utenti restano.`),\n ],\n },\n 'menu-group-enabled': {\n title: 'Gruppo abilitato',\n blocks: [\n p(`Disattiva l'intero gruppo: i menu al suo interno non sono considerati attivi, ma restano configurabili per una riattivazione futura.`),\n ],\n },\n\n // ----------------------------------------------------------------- filtri\n 'filter-type-code': {\n title: 'Codice tipo filtro',\n blocks: [\n p(`Numero identificativo del tipo filtro. È la chiave primaria: non si modifica dopo la creazione.`),\n ],\n },\n 'filter-type-field': {\n title: 'Campo',\n blocks: [\n p(`Nome della colonna applicativa della tabella FILTRI a cui il tipo è associato (per esempio CODCLI). Deve esistere nello schema, altrimenti i filtri che lo usano vengono rifiutati.`),\n ],\n },\n 'filter-type-enabled': {\n title: 'Tipo filtro abilitato',\n blocks: [\n p(`Se disattivato, il tipo non è proposto ai client, ma i filtri già salvati restano nel database.`),\n ],\n },\n 'filters-json': {\n title: 'Filtro JSON',\n blocks: [\n p(`Rappresentazione JSON dei filtri applicativi dell'utente. Usa \"Carica\" per partire dalla struttura esistente, modifica i valori e poi \"Salva\".`),\n note('info', 'Campi ammessi', `Sono accettati solo i campi mappati nello schema (FILTRI_UTENTE_DB_MAPPING). Un campo non configurato viene rifiutato con un errore esplicito.`),\n ],\n },\n 'filters-user': {\n title: 'Utente',\n blocks: [\n p(`Utente a cui appartengono i filtri. Selezionalo prima di caricare o salvare: i filtri sono sempre per singolo utente.`),\n ],\n },\n\n // ------------------------------------------------------------ assegnazioni\n 'role-assignment': {\n title: 'Assegnazione dei ruoli',\n blocks: [\n p(`Il salvataggio SOSTITUISCE integralmente i ruoli dell'utente: la lista selezionata diventa l'unico set di ruoli.`),\n list([\n `Per aggiungere un ruolo, selezionalo mantenendo quelli già presenti.`,\n `Per rimuovere un ruolo, deselezionalo.`,\n `Non modificare i grant diretti: quelli si gestiscono nella scheda \"Grant diretti\".`,\n ]),\n note('warn', 'Non è incrementale', `Inviare solo il nuovo ruolo rimuove gli altri. Invia sempre la lista completa desiderata.`),\n ],\n },\n 'grant-direct': {\n title: 'Grant diretti',\n blocks: [\n p(`Permessi assegnati direttamente all'utente, indipendenti dai ruoli. Hanno precedenza sui permessi ereditati dai ruoli per lo stesso menu.`),\n list([\n `Imposta il livello per concedere l'accesso.`,\n `Scegli \"nessuno\" per rimuovere il grant diretto.`,\n `Il salvataggio sostituisce l'intero set di grant diretti.`,\n ]),\n ],\n },\n 'grant-level': {\n title: 'Livello di grant',\n blocks: [\n table(\n ['Voce', 'Valore', 'Significato'],\n [\n ['nessuno', '—', 'Nessun grant diretto per quel menu (il permesso può arrivare dai ruoli).'],\n ['Lettura', '10', 'Sola consultazione.'],\n ['Scrittura', '20', 'Modifica dei dati.'],\n ],\n ),\n p(`Il confronto è tipoAbilitazione >= soglia richiesta dalla rotta.`),\n ],\n },\n 'user-delete': {\n title: 'Imposta stato eliminato',\n blocks: [\n p(`Esegue un soft delete: imposta lo stato di registrazione a \"Eliminato\" (50). L'utente non può più accedere, ma i dati restano nel database.`),\n note('info', 'Reversibile', `Non è una cancellazione fisica: puoi ripristinare l'utente cambiando lo stato di registrazione.`),\n ],\n },\n\n // ----------------------------------------------------- selezioni di menu\n 'menu-group-select': {\n title: 'Gruppo',\n blocks: [\n p(`Gruppo di appartenenza del menu. Se l'elenco è vuoto, crea prima un gruppo in \"Menu e gruppi → Gruppi\".`),\n ],\n },\n 'menu-type-select': {\n title: 'Tipo menu',\n blocks: [\n p(`Classificazione del menu (amministrazione, operativo, ...). È facoltativa: se non serve, lascia \"Nessun tipo\". I tipi si gestiscono in \"Menu e gruppi → Tipi menu\".`),\n ],\n },\n\n // ------------------------------------------------------------------ login\n 'login-email': {\n title: 'Email o utente',\n blocks: [\n p(`Indirizzo email dell'utente Accessi. Se l'account è abilitato al solo codice, dopo questo passo riceverai un codice via email invece di inserire la password.`),\n ],\n },\n 'login-password': {\n title: 'Password',\n blocks: [\n p(`Password locale dell'utente. Non serve per gli account passwordless, che accedono con il solo codice email.`),\n ],\n },\n};\n"]}
|
|
@@ -13,45 +13,113 @@
|
|
|
13
13
|
<link rel="stylesheet" href="/api/accessi/console/assets/console.css">
|
|
14
14
|
</head>
|
|
15
15
|
<body>
|
|
16
|
-
<div id="loading-overlay"
|
|
16
|
+
<div id="loading-overlay" aria-live="polite" aria-busy="true">
|
|
17
17
|
<div class="loading-panel" role="status">
|
|
18
18
|
<span class="loading-spinner" aria-hidden="true"></span>
|
|
19
|
-
<span><strong>
|
|
19
|
+
<span><strong>Caricamento</strong><small>Verifica della sessione in corso.</small></span>
|
|
20
20
|
</div>
|
|
21
21
|
</div>
|
|
22
22
|
<main id="app">
|
|
23
|
-
<section id="login" class="card" aria-labelledby="login-title">
|
|
23
|
+
<section id="login" class="card" aria-labelledby="login-title" hidden>
|
|
24
24
|
<h1 id="login-title">Accessi Console</h1>
|
|
25
|
-
<p>Gestione
|
|
25
|
+
<p>Gestione di utenti, ruoli, grant e accessi.</p>
|
|
26
26
|
<form id="login-form" method="post" action="" novalidate>
|
|
27
|
-
<label>Email o utente<input name="email" required autocomplete="username"></label>
|
|
28
|
-
<label id="password-field" hidden>Password<input name="password" type="password" autocomplete="current-password" disabled></label>
|
|
27
|
+
<label>Email o utente <button type="button" class="help-dot" data-help="login-email" aria-label="Aiuto: Email o utente">i</button><input name="email" required autocomplete="username"></label>
|
|
28
|
+
<label id="password-field" hidden>Password <button type="button" class="help-dot" data-help="login-password" aria-label="Aiuto: Password">i</button><input name="password" type="password" autocomplete="current-password" disabled></label>
|
|
29
29
|
<button id="login-submit" type="submit">Continua</button>
|
|
30
30
|
</form>
|
|
31
31
|
<form id="two-factor-form" hidden>
|
|
32
|
-
<p>Inserisci il codice ricevuto via email
|
|
32
|
+
<p class="form-help">Inserisci il codice ricevuto via email.</p>
|
|
33
33
|
<label>Codice di accesso<input name="code" inputmode="numeric" autocomplete="one-time-code" pattern="[0-9]{6}" minlength="6" maxlength="6" required></label>
|
|
34
34
|
<p id="two-factor-status" class="form-help" role="status"></p>
|
|
35
35
|
<button type="submit">Verifica e accedi</button>
|
|
36
36
|
<button id="resend-code" type="button" class="secondary">Invia un nuovo codice</button>
|
|
37
37
|
</form>
|
|
38
|
-
<button id="restart-login" type="button" class="secondary" hidden>Ricomincia
|
|
38
|
+
<button id="restart-login" type="button" class="secondary" hidden>Ricomincia</button>
|
|
39
39
|
<p id="login-error" class="error" role="alert"></p>
|
|
40
40
|
</section>
|
|
41
|
+
|
|
41
42
|
<section id="console" hidden>
|
|
42
|
-
<
|
|
43
|
-
<div
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
<
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
43
|
+
<aside class="sidebar">
|
|
44
|
+
<div class="brand">
|
|
45
|
+
<span class="brand-mark" aria-hidden="true">A</span>
|
|
46
|
+
<span class="brand-text"><strong>Accessi</strong><small id="who"></small></span>
|
|
47
|
+
</div>
|
|
48
|
+
<nav id="nav" aria-label="Sezioni console">
|
|
49
|
+
<ul class="nav-tree">
|
|
50
|
+
<li>
|
|
51
|
+
<a data-view="users" href="./utenti">
|
|
52
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>
|
|
53
|
+
<span>Utenti</span>
|
|
54
|
+
</a>
|
|
55
|
+
</li>
|
|
56
|
+
<li>
|
|
57
|
+
<a data-view="roles" href="./ruoli-e-grant">
|
|
58
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/><path d="M9 12l2 2 4-4"/></svg>
|
|
59
|
+
<span>Ruoli e grant</span>
|
|
60
|
+
</a>
|
|
61
|
+
</li>
|
|
62
|
+
<li>
|
|
63
|
+
<details data-nav-group="menus" open>
|
|
64
|
+
<summary>
|
|
65
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polygon points="12 2 2 7 12 12 22 7 12 2"/><polyline points="2 17 12 22 22 17"/><polyline points="2 12 12 17 22 12"/></svg>
|
|
66
|
+
<span>Menu e gruppi</span>
|
|
67
|
+
<svg class="nav-chevron" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="9 6 15 12 9 18"/></svg>
|
|
68
|
+
</summary>
|
|
69
|
+
<ul>
|
|
70
|
+
<li><a data-view="menuGroups" href="./menu-e-gruppi/gruppi">Gruppi</a></li>
|
|
71
|
+
<li><a data-view="menuItems" href="./menu-e-gruppi/menu">Menu</a></li>
|
|
72
|
+
<li><a data-view="menuTypes" href="./menu-e-gruppi/tipi-menu">Tipi menu</a></li>
|
|
73
|
+
</ul>
|
|
74
|
+
</details>
|
|
75
|
+
</li>
|
|
76
|
+
<li>
|
|
77
|
+
<details data-nav-group="filters" open>
|
|
78
|
+
<summary>
|
|
79
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polygon points="22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3"/></svg>
|
|
80
|
+
<span>Filtri</span>
|
|
81
|
+
<svg class="nav-chevron" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="9 6 15 12 9 18"/></svg>
|
|
82
|
+
</summary>
|
|
83
|
+
<ul>
|
|
84
|
+
<li><a data-view="filterUser" href="./filtri/utente">Filtri utente</a></li>
|
|
85
|
+
<li><a data-view="filterTypes" href="./filtri/tipi">Tipi filtro</a></li>
|
|
86
|
+
</ul>
|
|
87
|
+
</details>
|
|
88
|
+
</li>
|
|
89
|
+
<li>
|
|
90
|
+
<a data-view="tokens" href="./token-di-servizio">
|
|
91
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 2l-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.778 7.778 5.5 5.5 0 0 1 7.777-7.777zm0 0L15.5 7.5m0 0l3 3L22 7l-3-3m-3.5 3.5L19 4"/></svg>
|
|
92
|
+
<span>Token di servizio</span>
|
|
93
|
+
</a>
|
|
94
|
+
</li>
|
|
95
|
+
<li>
|
|
96
|
+
<details id="sso-navigation" data-nav-group="sso" open hidden>
|
|
97
|
+
<summary>
|
|
98
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M10 13a5 5 0 0 0 7.07 0l3-3a5 5 0 0 0-7.07-7.07l-1.5 1.5"/><path d="M14 11a5 5 0 0 0-7.07 0l-3 3a5 5 0 0 0 7.07 7.07l1.5-1.5"/></svg>
|
|
99
|
+
<span>SSO</span>
|
|
100
|
+
<svg class="nav-chevron" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="9 6 15 12 9 18"/></svg>
|
|
101
|
+
</summary>
|
|
102
|
+
<ul>
|
|
103
|
+
<li><a data-view="ssoProviders" href="./sso/provider">Provider</a></li>
|
|
104
|
+
<li><a data-view="ssoUsers" href="./sso/utenti">Utenti e identità</a></li>
|
|
105
|
+
</ul>
|
|
106
|
+
</details>
|
|
107
|
+
</li>
|
|
108
|
+
<li>
|
|
109
|
+
<a data-view="wiki" href="./wiki">
|
|
110
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg>
|
|
111
|
+
<span>Wiki</span>
|
|
112
|
+
</a>
|
|
113
|
+
</li>
|
|
114
|
+
</ul>
|
|
115
|
+
</nav>
|
|
116
|
+
<button id="logout" class="secondary sidebar-logout" type="button">Esci</button>
|
|
117
|
+
</aside>
|
|
118
|
+
|
|
119
|
+
<div class="content">
|
|
120
|
+
<div id="notice" role="status" aria-live="polite"></div>
|
|
121
|
+
<section id="view" aria-live="polite"></section>
|
|
122
|
+
</div>
|
|
55
123
|
</section>
|
|
56
124
|
</main>
|
|
57
125
|
<script type="module" src="/api/accessi/console/assets/console.js"></script>
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Contenuto della Wiki della console Accessi.
|
|
3
|
+
*
|
|
4
|
+
* I contenuti sono dati strutturati (non HTML) così da poter essere resi in modo
|
|
5
|
+
* coerente dalla console e convertiti in un digest compatto per l'IA. Nessun
|
|
6
|
+
* segreto o dato specifico di un ambiente deve finire qui.
|
|
7
|
+
*/
|
|
8
|
+
export type WikiTone = 'info' | 'ok' | 'warn' | 'danger';
|
|
9
|
+
export type WikiBlock = {
|
|
10
|
+
kind: 'p';
|
|
11
|
+
text: string;
|
|
12
|
+
} | {
|
|
13
|
+
kind: 'h';
|
|
14
|
+
text: string;
|
|
15
|
+
} | {
|
|
16
|
+
kind: 'list';
|
|
17
|
+
items: string[];
|
|
18
|
+
ordered?: boolean;
|
|
19
|
+
} | {
|
|
20
|
+
kind: 'code';
|
|
21
|
+
language: string;
|
|
22
|
+
title?: string;
|
|
23
|
+
code: string;
|
|
24
|
+
variant?: 'good' | 'bad';
|
|
25
|
+
} | {
|
|
26
|
+
kind: 'callout';
|
|
27
|
+
tone: WikiTone;
|
|
28
|
+
title?: string;
|
|
29
|
+
text: string;
|
|
30
|
+
} | {
|
|
31
|
+
kind: 'table';
|
|
32
|
+
head: string[];
|
|
33
|
+
rows: string[][];
|
|
34
|
+
};
|
|
35
|
+
export interface WikiSection {
|
|
36
|
+
id: string;
|
|
37
|
+
group: string;
|
|
38
|
+
title: string;
|
|
39
|
+
summary: string;
|
|
40
|
+
blocks: WikiBlock[];
|
|
41
|
+
}
|
|
42
|
+
export declare const WIKI_SECTIONS: WikiSection[];
|
|
43
|
+
/** Elenco ordinato dei gruppi per l'indice. */
|
|
44
|
+
export declare function wikiGroups(): Array<{
|
|
45
|
+
group: string;
|
|
46
|
+
sections: WikiSection[];
|
|
47
|
+
}>;
|
|
48
|
+
/**
|
|
49
|
+
* Digest compatto in Markdown per l'IA che costruisce il backend integratore.
|
|
50
|
+
* Deriva dagli stessi dati della wiki, quindi resta sincronizzato.
|
|
51
|
+
*/
|
|
52
|
+
export declare function buildAiDigest(): string;
|