emilsoftware-utilities 2.0.0-dev.72 → 2.0.0-dev.74
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 +44 -0
- package/dist/accessi/server/standalone.d.ts +2 -4
- package/dist/accessi/server/standalone.js +4 -79
- package/dist/accessi/server/standalone.js.map +1 -1
- package/dist/accessi-module/Console/console.js +4 -1
- package/dist/accessi-module/Console/wiki.js +4 -1
- package/dist/accessi-module/Console/wiki.js.map +1 -1
- package/dist/accessi-module/health/nest.d.ts +31 -0
- package/dist/accessi-module/health/nest.js +89 -0
- package/dist/accessi-module/health/nest.js.map +1 -0
- package/dist/accessi-module/health/readiness.d.ts +53 -0
- package/dist/accessi-module/health/readiness.js +110 -0
- package/dist/accessi-module/health/readiness.js.map +1 -0
- package/dist/accessi-module/index.d.ts +4 -0
- package/dist/accessi-module/index.js +9 -1
- package/dist/accessi-module/index.js.map +1 -1
- package/dist/emilsoftware-utilities-2.0.0-dev.74.tgz +0 -0
- package/docs/accessi-openapi-baseline.json +4500 -0
- package/docs/accessi-openapi-breaking-allowlist.json +1 -0
- package/docs/adr/0001-split-package.md +79 -0
- package/docs/proxy-ip.md +99 -0
- package/docs/standalone-service.md +25 -0
- package/package.json +20 -4
- package/dist/emilsoftware-utilities-2.0.0-dev.72.tgz +0 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { AccessiOptions } from '../AccessiModule';
|
|
2
|
+
/**
|
|
3
|
+
* Health e readiness riutilizzabili.
|
|
4
|
+
*
|
|
5
|
+
* Lo stesso contratto e usato da `createAccessiService` (servizio standalone) e
|
|
6
|
+
* da `createAccessiHealthModule` (host Nest con `AccessiModule.forRoot`):
|
|
7
|
+
* `/health/live` risponde sempre se il processo e vivo, `/health/ready` verifica
|
|
8
|
+
* bootstrap, schema del database, store condivisi e check applicativi.
|
|
9
|
+
*/
|
|
10
|
+
export interface AccessiReadinessCheck {
|
|
11
|
+
name: string;
|
|
12
|
+
check: () => boolean | Promise<boolean>;
|
|
13
|
+
}
|
|
14
|
+
export interface AccessiHealthCheckResult {
|
|
15
|
+
ok: boolean;
|
|
16
|
+
detail?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface AccessiReadinessReport {
|
|
19
|
+
status: 'ok' | 'error';
|
|
20
|
+
checks: Record<string, AccessiHealthCheckResult>;
|
|
21
|
+
timestamp: string;
|
|
22
|
+
}
|
|
23
|
+
export interface AccessiLiveReport {
|
|
24
|
+
status: 'ok';
|
|
25
|
+
uptimeSeconds: number;
|
|
26
|
+
}
|
|
27
|
+
/** Store condivisi con health check, senza duplicati. */
|
|
28
|
+
export interface AccessiHealthStore {
|
|
29
|
+
name: string;
|
|
30
|
+
store: {
|
|
31
|
+
healthCheck?: () => Promise<boolean>;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
export interface AccessiReadinessDependencies {
|
|
35
|
+
/** Override del check database (usato dai test o da host con pool esterni). */
|
|
36
|
+
databaseVersion?: (options: AccessiOptions) => Promise<string | null | undefined>;
|
|
37
|
+
}
|
|
38
|
+
/** Stato liveness: il processo risponde, nessun accesso a DB o store. */
|
|
39
|
+
export declare function createAccessiLiveReport(): AccessiLiveReport;
|
|
40
|
+
/** Store con health check configurati nelle opzioni Accessi. */
|
|
41
|
+
export declare function collectAccessiHealthStores(options: AccessiOptions): AccessiHealthStore[];
|
|
42
|
+
/** Verifica che lo schema Accessi sia inizializzato e alla versione attesa. */
|
|
43
|
+
export declare function checkAccessiDatabase(options: AccessiOptions, resolveVersion?: AccessiReadinessDependencies['databaseVersion']): Promise<AccessiHealthCheckResult>;
|
|
44
|
+
/**
|
|
45
|
+
* Report di readiness con lo stesso formato del servizio standalone.
|
|
46
|
+
*
|
|
47
|
+
* `bootstrap` e considerato completato: chi chiama questa funzione ha gia
|
|
48
|
+
* inizializzato il modulo. Il servizio standalone mantiene il proprio stato di
|
|
49
|
+
* bootstrap prima di delegare qui.
|
|
50
|
+
*/
|
|
51
|
+
export declare function checkAccessiReadiness(options: AccessiOptions, readinessChecks?: AccessiReadinessCheck[], dependencies?: AccessiReadinessDependencies): Promise<AccessiReadinessReport>;
|
|
52
|
+
/** Status HTTP da usare per un report di readiness: 200 o 503. */
|
|
53
|
+
export declare function readinessHttpStatus(report: AccessiReadinessReport): 200 | 503;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.createAccessiLiveReport = createAccessiLiveReport;
|
|
13
|
+
exports.collectAccessiHealthStores = collectAccessiHealthStores;
|
|
14
|
+
exports.checkAccessiDatabase = checkAccessiDatabase;
|
|
15
|
+
exports.checkAccessiReadiness = checkAccessiReadiness;
|
|
16
|
+
exports.readinessHttpStatus = readinessHttpStatus;
|
|
17
|
+
const accessiSchema_1 = require("../database-updates/accessiSchema");
|
|
18
|
+
const AccessiDatabaseUpdater_1 = require("../database-updates/AccessiDatabaseUpdater");
|
|
19
|
+
/** Stato liveness: il processo risponde, nessun accesso a DB o store. */
|
|
20
|
+
function createAccessiLiveReport() {
|
|
21
|
+
return { status: 'ok', uptimeSeconds: Math.floor(process.uptime()) };
|
|
22
|
+
}
|
|
23
|
+
/** Store con health check configurati nelle opzioni Accessi. */
|
|
24
|
+
function collectAccessiHealthStores(options) {
|
|
25
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
26
|
+
const stores = [];
|
|
27
|
+
const seen = new Set();
|
|
28
|
+
const add = (name, store) => {
|
|
29
|
+
if (!store || seen.has(store) || typeof store.healthCheck !== 'function')
|
|
30
|
+
return;
|
|
31
|
+
seen.add(store);
|
|
32
|
+
stores.push({ name, store });
|
|
33
|
+
};
|
|
34
|
+
add('publicAuthRateLimit', (_a = options.publicAuthRateLimit) === null || _a === void 0 ? void 0 : _a.store);
|
|
35
|
+
add('serviceTokenRateLimit', (_b = options.serviceTokens) === null || _b === void 0 ? void 0 : _b.rateLimitStore);
|
|
36
|
+
add('consoleEntry', (_c = options.consoleEntry) === null || _c === void 0 ? void 0 : _c.store);
|
|
37
|
+
add('edgeRateLimit', (_d = options.edgeRateLimit) === null || _d === void 0 ? void 0 : _d.store);
|
|
38
|
+
add('sessionRevocation', (_e = options.sessionRevocation) === null || _e === void 0 ? void 0 : _e.store);
|
|
39
|
+
add('accessTokenRevocation', (_f = options.accessTokenRevocation) === null || _f === void 0 ? void 0 : _f.store);
|
|
40
|
+
add('refreshTokenRotation', (_g = options.refreshTokenRotation) === null || _g === void 0 ? void 0 : _g.store);
|
|
41
|
+
return stores;
|
|
42
|
+
}
|
|
43
|
+
/** Verifica che lo schema Accessi sia inizializzato e alla versione attesa. */
|
|
44
|
+
function checkAccessiDatabase(options_1) {
|
|
45
|
+
return __awaiter(this, arguments, void 0, function* (options, resolveVersion = (value) => AccessiDatabaseUpdater_1.AccessiDatabaseUpdater.getCurrentVersion(value)) {
|
|
46
|
+
try {
|
|
47
|
+
const version = yield resolveVersion(options);
|
|
48
|
+
if (!version) {
|
|
49
|
+
return { ok: false, detail: 'schema Accessi non inizializzato' };
|
|
50
|
+
}
|
|
51
|
+
return {
|
|
52
|
+
ok: true,
|
|
53
|
+
detail: version === accessiSchema_1.ACCESSI_SCHEMA_VERSION ? version : `${version} (atteso ${accessiSchema_1.ACCESSI_SCHEMA_VERSION})`,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
return { ok: false, detail: error instanceof Error ? error.message : String(error) };
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Report di readiness con lo stesso formato del servizio standalone.
|
|
63
|
+
*
|
|
64
|
+
* `bootstrap` e considerato completato: chi chiama questa funzione ha gia
|
|
65
|
+
* inizializzato il modulo. Il servizio standalone mantiene il proprio stato di
|
|
66
|
+
* bootstrap prima di delegare qui.
|
|
67
|
+
*/
|
|
68
|
+
function checkAccessiReadiness(options_1) {
|
|
69
|
+
return __awaiter(this, arguments, void 0, function* (options, readinessChecks = [], dependencies = {}) {
|
|
70
|
+
const checks = {
|
|
71
|
+
bootstrap: { ok: true },
|
|
72
|
+
database: yield checkAccessiDatabase(options, dependencies.databaseVersion),
|
|
73
|
+
};
|
|
74
|
+
const stores = collectAccessiHealthStores(options);
|
|
75
|
+
yield Promise.all(stores.map((_a) => __awaiter(this, [_a], void 0, function* ({ name, store }) {
|
|
76
|
+
var _b;
|
|
77
|
+
try {
|
|
78
|
+
checks[name] = { ok: Boolean(yield ((_b = store.healthCheck) === null || _b === void 0 ? void 0 : _b.call(store))) };
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
checks[name] = {
|
|
82
|
+
ok: false,
|
|
83
|
+
detail: error instanceof Error ? error.message : String(error),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
})));
|
|
87
|
+
for (const check of readinessChecks) {
|
|
88
|
+
try {
|
|
89
|
+
checks[check.name] = { ok: Boolean(yield check.check()) };
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
checks[check.name] = {
|
|
93
|
+
ok: false,
|
|
94
|
+
detail: error instanceof Error ? error.message : String(error),
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
const ok = Object.values(checks).every((check) => check.ok);
|
|
99
|
+
return {
|
|
100
|
+
status: ok ? 'ok' : 'error',
|
|
101
|
+
checks,
|
|
102
|
+
timestamp: new Date().toISOString(),
|
|
103
|
+
};
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
/** Status HTTP da usare per un report di readiness: 200 o 503. */
|
|
107
|
+
function readinessHttpStatus(report) {
|
|
108
|
+
return report.status === 'ok' ? 200 : 503;
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=readiness.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"readiness.js","sourceRoot":"","sources":["../../../src/accessi-module/health/readiness.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AccessiOptions } from '../AccessiModule';\nimport { ACCESSI_SCHEMA_VERSION } from '../database-updates/accessiSchema';\nimport { AccessiDatabaseUpdater } from '../database-updates/AccessiDatabaseUpdater';\n\n/**\n * Health e readiness riutilizzabili.\n *\n * Lo stesso contratto e usato da `createAccessiService` (servizio standalone) e\n * da `createAccessiHealthModule` (host Nest con `AccessiModule.forRoot`):\n * `/health/live` risponde sempre se il processo e vivo, `/health/ready` verifica\n * bootstrap, schema del database, store condivisi e check applicativi.\n */\nexport interface AccessiReadinessCheck {\n name: string;\n check: () => boolean | Promise<boolean>;\n}\n\nexport interface AccessiHealthCheckResult {\n ok: boolean;\n detail?: string;\n}\n\nexport interface AccessiReadinessReport {\n status: 'ok' | 'error';\n checks: Record<string, AccessiHealthCheckResult>;\n timestamp: string;\n}\n\nexport interface AccessiLiveReport {\n status: 'ok';\n uptimeSeconds: number;\n}\n\n/** Store condivisi con health check, senza duplicati. */\nexport interface AccessiHealthStore {\n name: string;\n store: { healthCheck?: () => Promise<boolean> };\n}\n\nexport interface AccessiReadinessDependencies {\n /** Override del check database (usato dai test o da host con pool esterni). */\n databaseVersion?: (options: AccessiOptions) => Promise<string | null | undefined>;\n}\n\n/** Stato liveness: il processo risponde, nessun accesso a DB o store. */\nexport function createAccessiLiveReport(): AccessiLiveReport {\n return { status: 'ok', uptimeSeconds: Math.floor(process.uptime()) };\n}\n\n/** Store con health check configurati nelle opzioni Accessi. */\nexport function collectAccessiHealthStores(options: AccessiOptions): AccessiHealthStore[] {\n const stores: AccessiHealthStore[] = [];\n const seen = new Set<unknown>();\n\n const add = (name: string, store: { healthCheck?: () => Promise<boolean> } | undefined): void => {\n if (!store || seen.has(store) || typeof store.healthCheck !== 'function') return;\n seen.add(store);\n stores.push({ name, store });\n };\n\n add('publicAuthRateLimit', options.publicAuthRateLimit?.store);\n add('serviceTokenRateLimit', options.serviceTokens?.rateLimitStore);\n add('consoleEntry', options.consoleEntry?.store);\n add('edgeRateLimit', options.edgeRateLimit?.store);\n add('sessionRevocation', options.sessionRevocation?.store);\n add('accessTokenRevocation', options.accessTokenRevocation?.store);\n add('refreshTokenRotation', options.refreshTokenRotation?.store);\n return stores;\n}\n\n/** Verifica che lo schema Accessi sia inizializzato e alla versione attesa. */\nexport async function checkAccessiDatabase(\n options: AccessiOptions,\n resolveVersion: AccessiReadinessDependencies['databaseVersion'] = (value) =>\n AccessiDatabaseUpdater.getCurrentVersion(value),\n): Promise<AccessiHealthCheckResult> {\n try {\n const version = await resolveVersion(options);\n if (!version) {\n return { ok: false, detail: 'schema Accessi non inizializzato' };\n }\n return {\n ok: true,\n detail: version === ACCESSI_SCHEMA_VERSION ? version : `${version} (atteso ${ACCESSI_SCHEMA_VERSION})`,\n };\n } catch (error) {\n return { ok: false, detail: error instanceof Error ? error.message : String(error) };\n }\n}\n\n/**\n * Report di readiness con lo stesso formato del servizio standalone.\n *\n * `bootstrap` e considerato completato: chi chiama questa funzione ha gia\n * inizializzato il modulo. Il servizio standalone mantiene il proprio stato di\n * bootstrap prima di delegare qui.\n */\nexport async function checkAccessiReadiness(\n options: AccessiOptions,\n readinessChecks: AccessiReadinessCheck[] = [],\n dependencies: AccessiReadinessDependencies = {},\n): Promise<AccessiReadinessReport> {\n const checks: Record<string, AccessiHealthCheckResult> = {\n bootstrap: { ok: true },\n database: await checkAccessiDatabase(options, dependencies.databaseVersion),\n };\n\n const stores = collectAccessiHealthStores(options);\n await Promise.all(stores.map(async ({ name, store }) => {\n try {\n checks[name] = { ok: Boolean(await store.healthCheck?.()) };\n } catch (error) {\n checks[name] = {\n ok: false,\n detail: error instanceof Error ? error.message : String(error),\n };\n }\n }));\n\n for (const check of readinessChecks) {\n try {\n checks[check.name] = { ok: Boolean(await check.check()) };\n } catch (error) {\n checks[check.name] = {\n ok: false,\n detail: error instanceof Error ? error.message : String(error),\n };\n }\n }\n\n const ok = Object.values(checks).every((check) => check.ok);\n return {\n status: ok ? 'ok' : 'error',\n checks,\n timestamp: new Date().toISOString(),\n };\n}\n\n/** Status HTTP da usare per un report di readiness: 200 o 503. */\nexport function readinessHttpStatus(report: AccessiReadinessReport): 200 | 503 {\n return report.status === 'ok' ? 200 : 503;\n}\n"]}
|
|
@@ -68,3 +68,7 @@ export { accessiRequirement } from "./middleware/accessiRequirements";
|
|
|
68
68
|
export { registerAccessiModuleServices, getAccessiModuleServices, ACCESSI_MODULE_SERVICES_LOCALS_KEY } from "./accessiRuntime";
|
|
69
69
|
export type { AccessiModuleServices } from "./accessiRuntime";
|
|
70
70
|
export type { AccessiAuthorizationOptions, AccessiRequirementNode, AccessiCustomRequirementContext, AccessiCustomRequirementHandler } from "./middleware/accessiRequirements";
|
|
71
|
+
export { checkAccessiReadiness, checkAccessiDatabase, collectAccessiHealthStores, createAccessiLiveReport, readinessHttpStatus } from './health/readiness';
|
|
72
|
+
export type { AccessiHealthCheckResult, AccessiHealthStore, AccessiLiveReport, AccessiReadinessCheck, AccessiReadinessDependencies, AccessiReadinessReport } from './health/readiness';
|
|
73
|
+
export { createAccessiHealthModule } from './health/nest';
|
|
74
|
+
export type { AccessiHealthModuleOptions } from './health/nest';
|
|
@@ -27,7 +27,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
27
27
|
};
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
29
|
exports.getAccessiServiceToken = exports.RequireServiceTokenScopes = exports.ServiceTokenGuard = exports.isValidAdminBootstrapToken = exports.clearAdminBootstrapToken = exports.getAdminBootstrapToken = exports.getOrCreateAdminBootstrapToken = exports.AdminBootstrapService = exports.SchemaExportService = exports.ServiceTokenService = exports.discoverCatalogScripts = exports.computeCatalogScriptChecksum = exports.leadingStatementKeyword = exports.analyzeCatalogScript = exports.splitSqlStatements = exports.listPendingCatalogScripts = exports.applyCatalogScripts = exports.AccessiCatalogMigrator = exports.revokeAccessiAccessTokenIfConfigured = exports.revokeAccessiAccessToken = exports.isAccessiAccessTokenRevoked = exports.getAccessTokenRevocationStore = exports.createRedisAccessTokenRevocationStore = exports.createMemoryAccessTokenRevocationStore = exports.revokeRefreshTokenFamily = exports.isRefreshTokenFamilyRevoked = exports.getRefreshTokenRotationStore = exports.consumeRefreshToken = exports.createRedisRefreshTokenRotationStore = exports.createMemoryRefreshTokenRotationStore = exports.getSessionRevocationStore = exports.isAccessiTokenRevoked = exports.revokeAccessiUserSessionsIfConfigured = exports.revokeAccessiUserSessions = exports.createRedisSessionRevocationStore = exports.createMemorySessionRevocationStore = exports.auditAccessi = exports.validateAccessiOptions = exports.assertValidAccessiOptions = exports.createAccessiEdgeRateLimitMiddleware = exports.getDefaultRateLimitStore = exports.createRedisRateLimitStore = exports.createMemoryRateLimitStore = exports.getDefaultConsoleEntryStore = exports.createRedisConsoleEntryStore = exports.createMemoryConsoleEntryStore = exports.AccessiDatabaseUpdater = exports.FederatedAuthExchangeController = exports.AccessiIntrospectionController = exports.AccessiModule = void 0;
|
|
30
|
-
exports.ACCESSI_MODULE_SERVICES_LOCALS_KEY = exports.getAccessiModuleServices = exports.registerAccessiModuleServices = exports.accessiRequirement = exports.authenticateGen = exports.authorizeAccessi = exports.FederatedAuthService = exports.setupAccessiJwks = exports.getAccessiJwksPath = exports.createAccessiJwksHandler = exports.buildAccessiJwks = exports.LOGIN_AS_QUERY_PARAM = exports.buildLoginAsUrl = exports.ACCESSI_EMAIL_NOT_CONFIGURED = exports.AccessiEmailNotConfiguredError = exports.isEmailConfigured = exports.assertEmailConfigured = void 0;
|
|
30
|
+
exports.createAccessiHealthModule = exports.readinessHttpStatus = exports.createAccessiLiveReport = exports.collectAccessiHealthStores = exports.checkAccessiDatabase = exports.checkAccessiReadiness = exports.ACCESSI_MODULE_SERVICES_LOCALS_KEY = exports.getAccessiModuleServices = exports.registerAccessiModuleServices = exports.accessiRequirement = exports.authenticateGen = exports.authorizeAccessi = exports.FederatedAuthService = exports.setupAccessiJwks = exports.getAccessiJwksPath = exports.createAccessiJwksHandler = exports.buildAccessiJwks = exports.LOGIN_AS_QUERY_PARAM = exports.buildLoginAsUrl = exports.ACCESSI_EMAIL_NOT_CONFIGURED = exports.AccessiEmailNotConfiguredError = exports.isEmailConfigured = exports.assertEmailConfigured = void 0;
|
|
31
31
|
exports.initializeAccessiModule = initializeAccessiModule;
|
|
32
32
|
const express_1 = __importDefault(require("express"));
|
|
33
33
|
const core_1 = require("@nestjs/core");
|
|
@@ -244,4 +244,12 @@ var accessiRuntime_2 = require("./accessiRuntime");
|
|
|
244
244
|
Object.defineProperty(exports, "registerAccessiModuleServices", { enumerable: true, get: function () { return accessiRuntime_2.registerAccessiModuleServices; } });
|
|
245
245
|
Object.defineProperty(exports, "getAccessiModuleServices", { enumerable: true, get: function () { return accessiRuntime_2.getAccessiModuleServices; } });
|
|
246
246
|
Object.defineProperty(exports, "ACCESSI_MODULE_SERVICES_LOCALS_KEY", { enumerable: true, get: function () { return accessiRuntime_2.ACCESSI_MODULE_SERVICES_LOCALS_KEY; } });
|
|
247
|
+
var readiness_1 = require("./health/readiness");
|
|
248
|
+
Object.defineProperty(exports, "checkAccessiReadiness", { enumerable: true, get: function () { return readiness_1.checkAccessiReadiness; } });
|
|
249
|
+
Object.defineProperty(exports, "checkAccessiDatabase", { enumerable: true, get: function () { return readiness_1.checkAccessiDatabase; } });
|
|
250
|
+
Object.defineProperty(exports, "collectAccessiHealthStores", { enumerable: true, get: function () { return readiness_1.collectAccessiHealthStores; } });
|
|
251
|
+
Object.defineProperty(exports, "createAccessiLiveReport", { enumerable: true, get: function () { return readiness_1.createAccessiLiveReport; } });
|
|
252
|
+
Object.defineProperty(exports, "readinessHttpStatus", { enumerable: true, get: function () { return readiness_1.readinessHttpStatus; } });
|
|
253
|
+
var nest_1 = require("./health/nest");
|
|
254
|
+
Object.defineProperty(exports, "createAccessiHealthModule", { enumerable: true, get: function () { return nest_1.createAccessiHealthModule; } });
|
|
247
255
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/accessi-module/index.ts"],"names":[],"mappings":"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","sourcesContent":["import express, { Application, Request } from \"express\";\nimport { NestFactory } from \"@nestjs/core\";\nimport { ExpressAdapter } from \"@nestjs/platform-express\";\nimport type { INestApplication } from \"@nestjs/common\";\nimport type { OpenAPIObject } from \"@nestjs/swagger\";\nimport { AccessiModule, AccessiOptions } from \"./AccessiModule\";\nimport { Logger } from \"../Logger\";\nimport { AuthService } from \"./Services/AuthService/AuthService\";\nimport {\n buildOpenApiExcludePaths,\n isOpenApiRequestPath,\n resolveAccessiOpenApiOptions,\n setupOpenApi\n} from \"../openapi/OpenApiConfig\";\nimport {\n beginAccessiAuthInitialization,\n failAccessiAuthInitialization,\n setAccessiAuthService\n} from \"./middleware/authenticateGen\";\nimport { registerAccessiModuleServices } from \"./accessiRuntime\";\nimport { logAccessiStartup } from \"./startupLog\";\nimport { createAccessiValidationPipe } from './security/accessiValidation';\nimport { AccessiHttpExceptionFilter } from './security/AccessiHttpExceptionFilter';\nimport { assertEmailConfigured } from './security/emailConfiguration';\nimport { getAccessiJwksPath, setupAccessiJwks } from './security/jwks';\nimport { createAccessiEdgeRateLimitMiddleware } from './security/edgeRateLimit';\n\n/** Esito del bootstrap Express di Accessi. */\nexport interface AccessiModuleInitializationResult {\n /** Sotto-app Nest che serve `/api/accessi/*` e la documentazione. */\n nestApp: INestApplication;\n /** Documento OpenAPI generato, mergiabile nel documento unico dell'host. */\n document: OpenAPIObject;\n}\n\nfunction describeDatabaseTarget(options: AccessiOptions): string {\n const dbOptions = options.databaseOptions as {\n host?: string;\n port?: number;\n database?: string;\n user?: string;\n };\n\n return `${dbOptions.host ?? \"?\"}:${dbOptions.port ?? \"?\"} -> ${dbOptions.database ?? \"?\"} as ${dbOptions.user ?? \"?\"}`;\n}\n\n/**\n * Monta il modulo Accessi in un'applicazione Express gia esistente.\n *\n * Il bootstrap crea un host Nest isolato per le rotte `/api/accessi`, inizializza la\n * documentazione OpenAPI, validazione ed error handler, quindi rende disponibile\n * `authorizeAccessi` al resto dell'app.\n * Attendere questa Promise prima di aprire la porta HTTP: durante il bootstrap il middleware\n * restituisce `ACCESSI_AUTH_INITIALIZING` invece di autorizzare richieste parzialmente inizializzate.\n *\n * @param app Applicazione Express ospitante. Non viene sostituita ne vengono intercettate rotte estranee ad Accessi.\n * @param options Configurazione riservata del modulo; proviene normalmente da variabili d'ambiente o secret manager.\n * @returns Il sotto-app Nest e il documento OpenAPI generato (utile per il merge nell'host).\n */\nexport async function initializeAccessiModule(\n app: Application,\n options: AccessiOptions\n): Promise<AccessiModuleInitializationResult> {\n // Il servizio email e obbligatorio: reset password, 2FA e creazione utente ne dipendono.\n assertEmailConfigured(options);\n const logger: Logger = new Logger(\"initializeAccessiModule\");\n beginAccessiAuthInitialization();\n const startedAt = performance.now();\n const resolvedOpenApi = resolveAccessiOpenApiOptions(options.openapi);\n\n try {\n logger.info(\"Inizializzazione modulo accessi avviata.\");\n logger.info(`Target database accessi: ${describeDatabaseTarget(options)}`);\n logger.info(\n `Configurazione accessi: autoUpdateDatabase=${options.autoUpdateDatabase !== false}, legacyPasswordMigrationOnStartup=${options.legacyPasswordMigrationOnStartup !== false}`\n );\n const nestHostApp = express();\n if (options.http?.trustProxy !== undefined) {\n app.set('trust proxy', options.http.trustProxy);\n nestHostApp.set('trust proxy', options.http.trustProxy);\n }\n const jwksPath = getAccessiJwksPath(options);\n const isAccessiRoute = (path: string) =>\n path === \"/api/accessi\" ||\n path.startsWith(\"/api/accessi/\") ||\n isOpenApiRequestPath(path, resolvedOpenApi) ||\n (jwksPath !== undefined && path === jwksPath);\n const edgeRateLimit = options.edgeRateLimit\n ? createAccessiEdgeRateLimitMiddleware({\n ...options.edgeRateLimit,\n match: options.edgeRateLimit.match ?? ((path) => isAccessiRoute(path)),\n })\n : undefined;\n if (edgeRateLimit) {\n app.use(edgeRateLimit);\n }\n if (options.http?.securityHeaders !== false) {\n app.use((req: Request, res, next) => {\n if (!isAccessiRoute(req.path)) {\n return next();\n }\n res.setHeader('X-Content-Type-Options', 'nosniff');\n res.setHeader('X-Frame-Options', 'SAMEORIGIN');\n res.setHeader('Referrer-Policy', 'no-referrer');\n res.setHeader('Permissions-Policy', 'camera=(), microphone=(), geolocation=()');\n return next();\n });\n }\n\n app.use((req: Request, res, next) => {\n if (!isAccessiRoute(req.path)) {\n return next();\n }\n\n return nestHostApp(req, res, next);\n });\n\n setupAccessiJwks(app, options);\n if (jwksPath) {\n logger.info(`JWKS accessi disponibile su: ${jwksPath}`);\n }\n\n const nestExpressInstance = new ExpressAdapter(nestHostApp);\n\n const nestApp = await NestFactory.create(AccessiModule.forRoot(options), nestExpressInstance, {\n bufferLogs: options.bufferLogs !== false,\n ...(options.logger ? { logger: options.logger } : {})\n });\n logger.info(\"Applicazione Nest accessi creata.\");\n\n if (options.http?.cors !== false) {\n nestApp.enableCors(options.http?.cors ?? { exposedHeaders: ['X-Total-Count'] });\n }\n nestApp.useGlobalPipes(createAccessiValidationPipe());\n nestApp.useGlobalFilters(new AccessiHttpExceptionFilter());\n\n nestApp.setGlobalPrefix('api', {\n exclude: buildOpenApiExcludePaths(resolvedOpenApi)\n });\n\n const document = setupOpenApi(nestApp, resolvedOpenApi);\n logger.info(\"Avvio init del modulo accessi.\");\n await nestApp.init();\n logger.info(\"Init del modulo accessi completata.\");\n if (options.legacyPasswordMigrationOnStartup !== false) {\n logger.info(\"Avvio migrazione password legacy accessi.\");\n const passwordMigrationService = nestApp.get(AuthService);\n await passwordMigrationService.migrateLegacyEncryptedPasswords();\n logger.info(\"Migrazione password legacy accessi completata.\");\n }\n\n const accessiServices = registerAccessiModuleServices(app, nestApp);\n app.locals.accessiAuthService = accessiServices.authenticateGenService;\n setAccessiAuthService(accessiServices.authenticateGenService);\n logAccessiStartup(options, resolvedOpenApi);\n const elapsedMs = performance.now() - startedAt;\n logger.info(`Accessi initialized. Tempo totale bootstrap: ${elapsedMs.toFixed(2)} ms`);\n\n return { nestApp, document };\n } catch (error) {\n failAccessiAuthInitialization(error);\n logger.error(\n \"Errore in initialize AccessiModule:\",\n error instanceof Error\n ? { name: error.name, message: error.message, stack: error.stack }\n : { error: String(error) }\n );\n throw error;\n }\n}\n\nexport { AccessiModule } from \"./AccessiModule\";\nexport { AccessiIntrospectionController } from \"./Controllers/AccessiIntrospectionController\";\nexport { FederatedAuthExchangeController } from \"./federated-auth/FederatedAuthExchangeController\";\nexport type { AccessiTokenIntrospectionResult } from \"./Services/AuthService/AuthService\";\nexport { AccessiDatabaseUpdater } from \"./database-updates/AccessiDatabaseUpdater\";\nexport type { AccessiOptions, EmailOptions, JwtOptions, ExtensionFieldsOptions, PublicAuthRateLimitOptions, PublicAuthRateLimitRuleOptions } from \"./AccessiModule\";\nexport type { PublicRegistrationOptions, FederatedAuthenticationOptions, ServiceTokenOptions } from \"./AccessiModule\";\nexport type { CatalogScriptsOptions, CatalogScriptChecksumPolicy, ConsoleEntryOptions } from \"./AccessiModule\";\nexport {\n createMemoryConsoleEntryStore,\n createRedisConsoleEntryStore,\n getDefaultConsoleEntryStore\n} from './security/consoleEntry';\nexport type {\n ConsoleEntryRedisClient,\n ConsoleEntryRecord,\n ConsoleEntryStore,\n ConsoleEntryTicket,\n MemoryConsoleEntryStore,\n RedisConsoleEntryStoreOptions\n} from './security/consoleEntry';\nexport {\n createMemoryRateLimitStore,\n createRedisRateLimitStore,\n getDefaultRateLimitStore\n} from './security/rateLimitStore';\nexport type {\n MemoryRateLimitStore,\n RateLimitDecision,\n RateLimitRedisClient,\n RateLimitStore,\n RedisRateLimitStoreOptions\n} from './security/rateLimitStore';\nexport { createAccessiEdgeRateLimitMiddleware } from './security/edgeRateLimit';\nexport type {\n AccessiEdgeRateLimitMiddleware,\n AccessiEdgeRateLimitOptions\n} from './security/edgeRateLimit';\nexport {\n assertValidAccessiOptions,\n validateAccessiOptions\n} from './security/validateOptions';\nexport { auditAccessi } from './security/audit';\nexport {\n createMemorySessionRevocationStore,\n createRedisSessionRevocationStore,\n revokeAccessiUserSessions,\n revokeAccessiUserSessionsIfConfigured,\n isAccessiTokenRevoked,\n getSessionRevocationStore\n} from './security/sessionRevocation';\nexport type {\n MemorySessionRevocationStore,\n RedisSessionRevocationStoreOptions,\n SessionRevocationOptions,\n SessionRevocationRedisClient,\n SessionRevocationStore\n} from './security/sessionRevocation';\nexport {\n createMemoryRefreshTokenRotationStore,\n createRedisRefreshTokenRotationStore,\n consumeRefreshToken,\n getRefreshTokenRotationStore,\n isRefreshTokenFamilyRevoked,\n revokeRefreshTokenFamily\n} from './security/refreshTokenRotation';\nexport type {\n MemoryRefreshTokenRotationStore,\n RedisRefreshTokenRotationStoreOptions,\n RefreshTokenConsumeResult,\n RefreshTokenRotationOptions,\n RefreshTokenRotationRedisClient,\n RefreshTokenRotationStore\n} from './security/refreshTokenRotation';\nexport {\n createMemoryAccessTokenRevocationStore,\n createRedisAccessTokenRevocationStore,\n getAccessTokenRevocationStore,\n isAccessiAccessTokenRevoked,\n revokeAccessiAccessToken,\n revokeAccessiAccessTokenIfConfigured\n} from './security/accessTokenRevocation';\nexport type {\n AccessTokenRevocationOptions,\n AccessTokenRevocationRedisClient,\n AccessTokenRevocationStore,\n MemoryAccessTokenRevocationStore,\n RedisAccessTokenRevocationStoreOptions\n} from './security/accessTokenRevocation';\nexport type {\n AccessiOptionsValidationIssue,\n AccessiOptionsValidationResult\n} from './security/validateOptions';\nexport {\n AccessiCatalogMigrator,\n applyCatalogScripts,\n listPendingCatalogScripts,\n splitSqlStatements,\n analyzeCatalogScript,\n leadingStatementKeyword,\n computeCatalogScriptChecksum,\n discoverCatalogScripts\n} from \"./database-updates/AccessiCatalogMigrator\";\nexport type { CatalogMigrationReport, CatalogScriptMigration } from \"./database-updates/AccessiCatalogMigrator\";\nexport { ServiceTokenService } from './Services/ServiceTokenService/ServiceTokenService';\nexport type {\n ServiceTokenMetadata,\n IssuedServiceToken,\n VerifiedServiceToken,\n IssueServiceTokenInput\n} from './Services/ServiceTokenService/ServiceTokenService';\nexport { SchemaExportService } from './Services/SchemaExportService/SchemaExportService';\nexport type { SchemaDdlResult, SchemaDdlSection, SchemaEntitiesResult } from './Services/SchemaExportService/SchemaExportService';\nexport { AdminBootstrapService } from './Services/AdminBootstrapService/AdminBootstrapService';\nexport type { BootstrapAdminResult } from './Services/AdminBootstrapService/AdminBootstrapService';\nexport {\n getOrCreateAdminBootstrapToken,\n getAdminBootstrapToken,\n clearAdminBootstrapToken,\n isValidAdminBootstrapToken\n} from './security/adminBootstrap';\nexport { ServiceTokenGuard, RequireServiceTokenScopes, getAccessiServiceToken } from './security/serviceTokenGuard';\nexport { assertEmailConfigured, isEmailConfigured, AccessiEmailNotConfiguredError, ACCESSI_EMAIL_NOT_CONFIGURED } from './security/emailConfiguration';\nexport { buildLoginAsUrl, LOGIN_AS_QUERY_PARAM } from './security/loginAs';\nexport {\n buildAccessiJwks,\n createAccessiJwksHandler,\n getAccessiJwksPath,\n setupAccessiJwks\n} from './security/jwks';\nexport type { AccessiJwksDocument, AccessiJwksKey } from './security/jwks';\nexport { FederatedAuthService } from './federated-auth/FederatedAuthService';\nexport type { FederatedAuthenticationResult, FederatedIdentity, FederatedProvider, VerifiedFederatedIdentity } from './federated-auth/FederatedAuthTypes';\nexport * from \"./Dtos\";\nexport {\n authorizeAccessi,\n authenticateGen\n} from \"./middleware/authenticateGen\";\nexport { accessiRequirement } from \"./middleware/accessiRequirements\";\nexport {\n registerAccessiModuleServices,\n getAccessiModuleServices,\n ACCESSI_MODULE_SERVICES_LOCALS_KEY\n} from \"./accessiRuntime\";\nexport type { AccessiModuleServices } from \"./accessiRuntime\";\nexport type {\n AccessiAuthorizationOptions,\n AccessiRequirementNode,\n AccessiCustomRequirementContext,\n AccessiCustomRequirementHandler\n} from \"./middleware/accessiRequirements\";\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/accessi-module/index.ts"],"names":[],"mappings":"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","sourcesContent":["import express, { Application, Request } from \"express\";\nimport { NestFactory } from \"@nestjs/core\";\nimport { ExpressAdapter } from \"@nestjs/platform-express\";\nimport type { INestApplication } from \"@nestjs/common\";\nimport type { OpenAPIObject } from \"@nestjs/swagger\";\nimport { AccessiModule, AccessiOptions } from \"./AccessiModule\";\nimport { Logger } from \"../Logger\";\nimport { AuthService } from \"./Services/AuthService/AuthService\";\nimport {\n buildOpenApiExcludePaths,\n isOpenApiRequestPath,\n resolveAccessiOpenApiOptions,\n setupOpenApi\n} from \"../openapi/OpenApiConfig\";\nimport {\n beginAccessiAuthInitialization,\n failAccessiAuthInitialization,\n setAccessiAuthService\n} from \"./middleware/authenticateGen\";\nimport { registerAccessiModuleServices } from \"./accessiRuntime\";\nimport { logAccessiStartup } from \"./startupLog\";\nimport { createAccessiValidationPipe } from './security/accessiValidation';\nimport { AccessiHttpExceptionFilter } from './security/AccessiHttpExceptionFilter';\nimport { assertEmailConfigured } from './security/emailConfiguration';\nimport { getAccessiJwksPath, setupAccessiJwks } from './security/jwks';\nimport { createAccessiEdgeRateLimitMiddleware } from './security/edgeRateLimit';\n\n/** Esito del bootstrap Express di Accessi. */\nexport interface AccessiModuleInitializationResult {\n /** Sotto-app Nest che serve `/api/accessi/*` e la documentazione. */\n nestApp: INestApplication;\n /** Documento OpenAPI generato, mergiabile nel documento unico dell'host. */\n document: OpenAPIObject;\n}\n\nfunction describeDatabaseTarget(options: AccessiOptions): string {\n const dbOptions = options.databaseOptions as {\n host?: string;\n port?: number;\n database?: string;\n user?: string;\n };\n\n return `${dbOptions.host ?? \"?\"}:${dbOptions.port ?? \"?\"} -> ${dbOptions.database ?? \"?\"} as ${dbOptions.user ?? \"?\"}`;\n}\n\n/**\n * Monta il modulo Accessi in un'applicazione Express gia esistente.\n *\n * Il bootstrap crea un host Nest isolato per le rotte `/api/accessi`, inizializza la\n * documentazione OpenAPI, validazione ed error handler, quindi rende disponibile\n * `authorizeAccessi` al resto dell'app.\n * Attendere questa Promise prima di aprire la porta HTTP: durante il bootstrap il middleware\n * restituisce `ACCESSI_AUTH_INITIALIZING` invece di autorizzare richieste parzialmente inizializzate.\n *\n * @param app Applicazione Express ospitante. Non viene sostituita ne vengono intercettate rotte estranee ad Accessi.\n * @param options Configurazione riservata del modulo; proviene normalmente da variabili d'ambiente o secret manager.\n * @returns Il sotto-app Nest e il documento OpenAPI generato (utile per il merge nell'host).\n */\nexport async function initializeAccessiModule(\n app: Application,\n options: AccessiOptions\n): Promise<AccessiModuleInitializationResult> {\n // Il servizio email e obbligatorio: reset password, 2FA e creazione utente ne dipendono.\n assertEmailConfigured(options);\n const logger: Logger = new Logger(\"initializeAccessiModule\");\n beginAccessiAuthInitialization();\n const startedAt = performance.now();\n const resolvedOpenApi = resolveAccessiOpenApiOptions(options.openapi);\n\n try {\n logger.info(\"Inizializzazione modulo accessi avviata.\");\n logger.info(`Target database accessi: ${describeDatabaseTarget(options)}`);\n logger.info(\n `Configurazione accessi: autoUpdateDatabase=${options.autoUpdateDatabase !== false}, legacyPasswordMigrationOnStartup=${options.legacyPasswordMigrationOnStartup !== false}`\n );\n const nestHostApp = express();\n if (options.http?.trustProxy !== undefined) {\n app.set('trust proxy', options.http.trustProxy);\n nestHostApp.set('trust proxy', options.http.trustProxy);\n }\n const jwksPath = getAccessiJwksPath(options);\n const isAccessiRoute = (path: string) =>\n path === \"/api/accessi\" ||\n path.startsWith(\"/api/accessi/\") ||\n isOpenApiRequestPath(path, resolvedOpenApi) ||\n (jwksPath !== undefined && path === jwksPath);\n const edgeRateLimit = options.edgeRateLimit\n ? createAccessiEdgeRateLimitMiddleware({\n ...options.edgeRateLimit,\n match: options.edgeRateLimit.match ?? ((path) => isAccessiRoute(path)),\n })\n : undefined;\n if (edgeRateLimit) {\n app.use(edgeRateLimit);\n }\n if (options.http?.securityHeaders !== false) {\n app.use((req: Request, res, next) => {\n if (!isAccessiRoute(req.path)) {\n return next();\n }\n res.setHeader('X-Content-Type-Options', 'nosniff');\n res.setHeader('X-Frame-Options', 'SAMEORIGIN');\n res.setHeader('Referrer-Policy', 'no-referrer');\n res.setHeader('Permissions-Policy', 'camera=(), microphone=(), geolocation=()');\n return next();\n });\n }\n\n app.use((req: Request, res, next) => {\n if (!isAccessiRoute(req.path)) {\n return next();\n }\n\n return nestHostApp(req, res, next);\n });\n\n setupAccessiJwks(app, options);\n if (jwksPath) {\n logger.info(`JWKS accessi disponibile su: ${jwksPath}`);\n }\n\n const nestExpressInstance = new ExpressAdapter(nestHostApp);\n\n const nestApp = await NestFactory.create(AccessiModule.forRoot(options), nestExpressInstance, {\n bufferLogs: options.bufferLogs !== false,\n ...(options.logger ? { logger: options.logger } : {})\n });\n logger.info(\"Applicazione Nest accessi creata.\");\n\n if (options.http?.cors !== false) {\n nestApp.enableCors(options.http?.cors ?? { exposedHeaders: ['X-Total-Count'] });\n }\n nestApp.useGlobalPipes(createAccessiValidationPipe());\n nestApp.useGlobalFilters(new AccessiHttpExceptionFilter());\n\n nestApp.setGlobalPrefix('api', {\n exclude: buildOpenApiExcludePaths(resolvedOpenApi)\n });\n\n const document = setupOpenApi(nestApp, resolvedOpenApi);\n logger.info(\"Avvio init del modulo accessi.\");\n await nestApp.init();\n logger.info(\"Init del modulo accessi completata.\");\n if (options.legacyPasswordMigrationOnStartup !== false) {\n logger.info(\"Avvio migrazione password legacy accessi.\");\n const passwordMigrationService = nestApp.get(AuthService);\n await passwordMigrationService.migrateLegacyEncryptedPasswords();\n logger.info(\"Migrazione password legacy accessi completata.\");\n }\n\n const accessiServices = registerAccessiModuleServices(app, nestApp);\n app.locals.accessiAuthService = accessiServices.authenticateGenService;\n setAccessiAuthService(accessiServices.authenticateGenService);\n logAccessiStartup(options, resolvedOpenApi);\n const elapsedMs = performance.now() - startedAt;\n logger.info(`Accessi initialized. Tempo totale bootstrap: ${elapsedMs.toFixed(2)} ms`);\n\n return { nestApp, document };\n } catch (error) {\n failAccessiAuthInitialization(error);\n logger.error(\n \"Errore in initialize AccessiModule:\",\n error instanceof Error\n ? { name: error.name, message: error.message, stack: error.stack }\n : { error: String(error) }\n );\n throw error;\n }\n}\n\nexport { AccessiModule } from \"./AccessiModule\";\nexport { AccessiIntrospectionController } from \"./Controllers/AccessiIntrospectionController\";\nexport { FederatedAuthExchangeController } from \"./federated-auth/FederatedAuthExchangeController\";\nexport type { AccessiTokenIntrospectionResult } from \"./Services/AuthService/AuthService\";\nexport { AccessiDatabaseUpdater } from \"./database-updates/AccessiDatabaseUpdater\";\nexport type { AccessiOptions, EmailOptions, JwtOptions, ExtensionFieldsOptions, PublicAuthRateLimitOptions, PublicAuthRateLimitRuleOptions } from \"./AccessiModule\";\nexport type { PublicRegistrationOptions, FederatedAuthenticationOptions, ServiceTokenOptions } from \"./AccessiModule\";\nexport type { CatalogScriptsOptions, CatalogScriptChecksumPolicy, ConsoleEntryOptions } from \"./AccessiModule\";\nexport {\n createMemoryConsoleEntryStore,\n createRedisConsoleEntryStore,\n getDefaultConsoleEntryStore\n} from './security/consoleEntry';\nexport type {\n ConsoleEntryRedisClient,\n ConsoleEntryRecord,\n ConsoleEntryStore,\n ConsoleEntryTicket,\n MemoryConsoleEntryStore,\n RedisConsoleEntryStoreOptions\n} from './security/consoleEntry';\nexport {\n createMemoryRateLimitStore,\n createRedisRateLimitStore,\n getDefaultRateLimitStore\n} from './security/rateLimitStore';\nexport type {\n MemoryRateLimitStore,\n RateLimitDecision,\n RateLimitRedisClient,\n RateLimitStore,\n RedisRateLimitStoreOptions\n} from './security/rateLimitStore';\nexport { createAccessiEdgeRateLimitMiddleware } from './security/edgeRateLimit';\nexport type {\n AccessiEdgeRateLimitMiddleware,\n AccessiEdgeRateLimitOptions\n} from './security/edgeRateLimit';\nexport {\n assertValidAccessiOptions,\n validateAccessiOptions\n} from './security/validateOptions';\nexport { auditAccessi } from './security/audit';\nexport {\n createMemorySessionRevocationStore,\n createRedisSessionRevocationStore,\n revokeAccessiUserSessions,\n revokeAccessiUserSessionsIfConfigured,\n isAccessiTokenRevoked,\n getSessionRevocationStore\n} from './security/sessionRevocation';\nexport type {\n MemorySessionRevocationStore,\n RedisSessionRevocationStoreOptions,\n SessionRevocationOptions,\n SessionRevocationRedisClient,\n SessionRevocationStore\n} from './security/sessionRevocation';\nexport {\n createMemoryRefreshTokenRotationStore,\n createRedisRefreshTokenRotationStore,\n consumeRefreshToken,\n getRefreshTokenRotationStore,\n isRefreshTokenFamilyRevoked,\n revokeRefreshTokenFamily\n} from './security/refreshTokenRotation';\nexport type {\n MemoryRefreshTokenRotationStore,\n RedisRefreshTokenRotationStoreOptions,\n RefreshTokenConsumeResult,\n RefreshTokenRotationOptions,\n RefreshTokenRotationRedisClient,\n RefreshTokenRotationStore\n} from './security/refreshTokenRotation';\nexport {\n createMemoryAccessTokenRevocationStore,\n createRedisAccessTokenRevocationStore,\n getAccessTokenRevocationStore,\n isAccessiAccessTokenRevoked,\n revokeAccessiAccessToken,\n revokeAccessiAccessTokenIfConfigured\n} from './security/accessTokenRevocation';\nexport type {\n AccessTokenRevocationOptions,\n AccessTokenRevocationRedisClient,\n AccessTokenRevocationStore,\n MemoryAccessTokenRevocationStore,\n RedisAccessTokenRevocationStoreOptions\n} from './security/accessTokenRevocation';\nexport type {\n AccessiOptionsValidationIssue,\n AccessiOptionsValidationResult\n} from './security/validateOptions';\nexport {\n AccessiCatalogMigrator,\n applyCatalogScripts,\n listPendingCatalogScripts,\n splitSqlStatements,\n analyzeCatalogScript,\n leadingStatementKeyword,\n computeCatalogScriptChecksum,\n discoverCatalogScripts\n} from \"./database-updates/AccessiCatalogMigrator\";\nexport type { CatalogMigrationReport, CatalogScriptMigration } from \"./database-updates/AccessiCatalogMigrator\";\nexport { ServiceTokenService } from './Services/ServiceTokenService/ServiceTokenService';\nexport type {\n ServiceTokenMetadata,\n IssuedServiceToken,\n VerifiedServiceToken,\n IssueServiceTokenInput\n} from './Services/ServiceTokenService/ServiceTokenService';\nexport { SchemaExportService } from './Services/SchemaExportService/SchemaExportService';\nexport type { SchemaDdlResult, SchemaDdlSection, SchemaEntitiesResult } from './Services/SchemaExportService/SchemaExportService';\nexport { AdminBootstrapService } from './Services/AdminBootstrapService/AdminBootstrapService';\nexport type { BootstrapAdminResult } from './Services/AdminBootstrapService/AdminBootstrapService';\nexport {\n getOrCreateAdminBootstrapToken,\n getAdminBootstrapToken,\n clearAdminBootstrapToken,\n isValidAdminBootstrapToken\n} from './security/adminBootstrap';\nexport { ServiceTokenGuard, RequireServiceTokenScopes, getAccessiServiceToken } from './security/serviceTokenGuard';\nexport { assertEmailConfigured, isEmailConfigured, AccessiEmailNotConfiguredError, ACCESSI_EMAIL_NOT_CONFIGURED } from './security/emailConfiguration';\nexport { buildLoginAsUrl, LOGIN_AS_QUERY_PARAM } from './security/loginAs';\nexport {\n buildAccessiJwks,\n createAccessiJwksHandler,\n getAccessiJwksPath,\n setupAccessiJwks\n} from './security/jwks';\nexport type { AccessiJwksDocument, AccessiJwksKey } from './security/jwks';\nexport { FederatedAuthService } from './federated-auth/FederatedAuthService';\nexport type { FederatedAuthenticationResult, FederatedIdentity, FederatedProvider, VerifiedFederatedIdentity } from './federated-auth/FederatedAuthTypes';\nexport * from \"./Dtos\";\nexport {\n authorizeAccessi,\n authenticateGen\n} from \"./middleware/authenticateGen\";\nexport { accessiRequirement } from \"./middleware/accessiRequirements\";\nexport {\n registerAccessiModuleServices,\n getAccessiModuleServices,\n ACCESSI_MODULE_SERVICES_LOCALS_KEY\n} from \"./accessiRuntime\";\nexport type { AccessiModuleServices } from \"./accessiRuntime\";\nexport type {\n AccessiAuthorizationOptions,\n AccessiRequirementNode,\n AccessiCustomRequirementContext,\n AccessiCustomRequirementHandler\n} from \"./middleware/accessiRequirements\";\n\nexport {\n checkAccessiReadiness,\n checkAccessiDatabase,\n collectAccessiHealthStores,\n createAccessiLiveReport,\n readinessHttpStatus\n} from './health/readiness';\nexport type {\n AccessiHealthCheckResult,\n AccessiHealthStore,\n AccessiLiveReport,\n AccessiReadinessCheck,\n AccessiReadinessDependencies,\n AccessiReadinessReport\n} from './health/readiness';\nexport { createAccessiHealthModule } from './health/nest';\nexport type { AccessiHealthModuleOptions } from './health/nest';\n\n"]}
|
|
Binary file
|