@astram/guard 0.13.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auth/auth.module.d.ts.map +1 -1
- package/dist/auth/auth.module.js +57 -30
- package/dist/auth/connections.d.ts +2 -2
- package/dist/auth/connections.d.ts.map +1 -1
- package/dist/auth/connections.js +4 -13
- package/dist/authentication/mariadb-api-key-store.d.ts +10 -1
- package/dist/authentication/mariadb-api-key-store.d.ts.map +1 -1
- package/dist/authentication/mariadb-api-key-store.js +20 -10
- package/dist/authentication/mariadb-credential-resolver.d.ts +8 -1
- package/dist/authentication/mariadb-credential-resolver.d.ts.map +1 -1
- package/dist/authentication/mariadb-credential-resolver.js +15 -5
- package/dist/authentication/mariadb-credential-writer.d.ts +6 -1
- package/dist/authentication/mariadb-credential-writer.d.ts.map +1 -1
- package/dist/authentication/mariadb-credential-writer.js +9 -3
- package/dist/authentication/mariadb-email-address-changer.d.ts +10 -1
- package/dist/authentication/mariadb-email-address-changer.d.ts.map +1 -1
- package/dist/authentication/mariadb-email-address-changer.js +22 -9
- package/dist/authentication/mariadb-email-change-token-store.d.ts +8 -1
- package/dist/authentication/mariadb-email-change-token-store.d.ts.map +1 -1
- package/dist/authentication/mariadb-email-change-token-store.js +18 -9
- package/dist/authentication/mariadb-mfa-device-store.d.ts +6 -1
- package/dist/authentication/mariadb-mfa-device-store.d.ts.map +1 -1
- package/dist/authentication/mariadb-mfa-device-store.js +22 -13
- package/dist/authentication/mariadb-profile-resolver.d.ts +6 -1
- package/dist/authentication/mariadb-profile-resolver.d.ts.map +1 -1
- package/dist/authentication/mariadb-profile-resolver.js +12 -6
- package/dist/authentication/mariadb-profile-writer.d.ts +6 -1
- package/dist/authentication/mariadb-profile-writer.d.ts.map +1 -1
- package/dist/authentication/mariadb-profile-writer.js +11 -4
- package/dist/authentication/mariadb-recovery-code-store.d.ts +6 -1
- package/dist/authentication/mariadb-recovery-code-store.d.ts.map +1 -1
- package/dist/authentication/mariadb-recovery-code-store.js +11 -5
- package/dist/authentication/mariadb-reset-token-store.d.ts +6 -1
- package/dist/authentication/mariadb-reset-token-store.d.ts.map +1 -1
- package/dist/authentication/mariadb-reset-token-store.js +11 -5
- package/dist/authentication/mariadb-session-sweeper.d.ts +6 -1
- package/dist/authentication/mariadb-session-sweeper.d.ts.map +1 -1
- package/dist/authentication/mariadb-session-sweeper.js +11 -5
- package/dist/authz/cross-tenant-grant-writer.d.ts.map +1 -1
- package/dist/authz/cross-tenant-grant-writer.js +4 -3
- package/dist/authz/list-scope-sql.d.ts +10 -2
- package/dist/authz/list-scope-sql.d.ts.map +1 -1
- package/dist/authz/list-scope-sql.js +4 -4
- package/dist/authz/mariadb-cross-tenant-grant-adapter.d.ts.map +1 -1
- package/dist/authz/mariadb-cross-tenant-grant-adapter.js +4 -3
- package/dist/authz/mariadb-list-scope-adapter.d.ts.map +1 -1
- package/dist/authz/mariadb-list-scope-adapter.js +4 -3
- package/dist/authz/mariadb-policy-store.d.ts.map +1 -1
- package/dist/authz/mariadb-policy-store.js +4 -3
- package/dist/authz/mariadb-record-rule-adapter.d.ts.map +1 -1
- package/dist/authz/mariadb-record-rule-adapter.js +4 -3
- package/dist/authz/mariadb-record-share-adapter.d.ts.map +1 -1
- package/dist/authz/mariadb-record-share-adapter.js +4 -3
- package/dist/authz/record-share-cascade.d.ts.map +1 -1
- package/dist/authz/record-share-cascade.js +4 -3
- package/dist/authz/record-share-writer.d.ts.map +1 -1
- package/dist/authz/record-share-writer.js +4 -3
- package/dist/authz/wire-record-authorization.d.ts +8 -0
- package/dist/authz/wire-record-authorization.d.ts.map +1 -1
- package/dist/authz/wire-record-authorization.js +14 -6
- package/dist/boot/boot-sequence.d.ts +4 -0
- package/dist/boot/boot-sequence.d.ts.map +1 -1
- package/dist/boot/boot-sequence.js +13 -1
- package/dist/boot/migration-ledger-check.d.ts +94 -0
- package/dist/boot/migration-ledger-check.d.ts.map +1 -0
- package/dist/boot/migration-ledger-check.js +280 -0
- package/dist/config/app-config.d.ts +72 -3
- package/dist/config/app-config.d.ts.map +1 -1
- package/dist/config/app-config.js +129 -7
- package/dist/config/config.module.d.ts +7 -0
- package/dist/config/config.module.d.ts.map +1 -1
- package/dist/config/config.module.js +13 -2
- package/dist/config/framework-schema-names.d.ts +29 -0
- package/dist/config/framework-schema-names.d.ts.map +1 -0
- package/dist/config/framework-schema-names.js +41 -0
- package/dist/config/loopback-host.d.ts +9 -0
- package/dist/config/loopback-host.d.ts.map +1 -0
- package/dist/config/loopback-host.js +19 -0
- package/dist/encryption/local-kek-crypto.d.ts +6 -0
- package/dist/encryption/local-kek-crypto.d.ts.map +1 -1
- package/dist/encryption/local-kek-crypto.js +8 -0
- package/dist/identity/identity-actions.d.ts +18 -7
- package/dist/identity/identity-actions.d.ts.map +1 -1
- package/dist/identity/identity-actions.js +16 -17
- package/dist/identity/module-registry.bridge.d.ts.map +1 -1
- package/dist/identity/module-registry.bridge.js +5 -3
- package/dist/identity/permission-facts.adapter.d.ts +7 -1
- package/dist/identity/permission-facts.adapter.d.ts.map +1 -1
- package/dist/identity/permission-facts.adapter.js +15 -6
- package/dist/index.d.ts +14 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +68 -22
- package/dist/module/shield-tokens.d.ts +11 -0
- package/dist/module/shield-tokens.d.ts.map +1 -1
- package/dist/module/shield-tokens.js +12 -1
- package/dist/module/shield.module.d.ts +10 -0
- package/dist/module/shield.module.d.ts.map +1 -1
- package/dist/module/shield.module.js +78 -12
- package/dist/secrets/boot-secrets.d.ts +33 -0
- package/dist/secrets/boot-secrets.d.ts.map +1 -0
- package/dist/secrets/boot-secrets.js +180 -0
- package/dist/session/mariadb-session-record-store.d.ts +8 -1
- package/dist/session/mariadb-session-record-store.d.ts.map +1 -1
- package/dist/session/mariadb-session-record-store.js +23 -13
- package/dist/session/session-restriction-store.d.ts +8 -1
- package/dist/session/session-restriction-store.d.ts.map +1 -1
- package/dist/session/session-restriction-store.js +15 -5
- package/dist/storage/file-intake.interceptor.d.ts +54 -0
- package/dist/storage/file-intake.interceptor.d.ts.map +1 -0
- package/dist/storage/file-intake.interceptor.js +223 -0
- package/dist/storage/node-sha256-digest.d.ts +6 -0
- package/dist/storage/node-sha256-digest.d.ts.map +1 -0
- package/dist/storage/node-sha256-digest.js +15 -0
- package/dist/storage/object-store-boot-check.d.ts +16 -0
- package/dist/storage/object-store-boot-check.d.ts.map +1 -0
- package/dist/storage/object-store-boot-check.js +52 -0
- package/dist/storage/optional-peer.d.ts +10 -0
- package/dist/storage/optional-peer.d.ts.map +1 -0
- package/dist/storage/optional-peer.js +26 -0
- package/dist/storage/s3-object-store.d.ts +35 -0
- package/dist/storage/s3-object-store.d.ts.map +1 -0
- package/dist/storage/s3-object-store.js +238 -0
- package/dist/storage/storage.providers.d.ts +10 -0
- package/dist/storage/storage.providers.d.ts.map +1 -0
- package/dist/storage/storage.providers.js +104 -0
- package/migrations/1710000000006-CreateAuthzSchema.cjs +15 -4
- package/migrations/1710000000007-ExtendPermissionAndRolePermission.cjs +11 -3
- package/migrations/1710000000008-CreateAccessBundleTables.cjs +14 -4
- package/migrations/1710000000009-CreateRecordPermissionRule.cjs +15 -4
- package/migrations/1710000000014-CreateRecordShare.cjs +15 -4
- package/migrations/1710000000015-CreateScopeClosure.cjs +14 -4
- package/migrations/1710000000016-AlterCompanyParentFkRestrict.cjs +20 -9
- package/migrations/1710000000017-CreateServiceAccountKey.cjs +14 -4
- package/package.json +11 -3
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import type { OnApplicationBootstrap } from '@nestjs/common';
|
|
2
|
+
import { type FrameworkSchemas, type MigrationLedgerLocation } from '@astram/core';
|
|
3
|
+
/** Runs one SELECT on the runtime pool (a mariadb `Pool.query` fits). */
|
|
4
|
+
export type LedgerQuery = (sql: string) => Promise<unknown>;
|
|
5
|
+
/** Where the boot check looks for warnings. */
|
|
6
|
+
export interface LedgerCheckLogger {
|
|
7
|
+
warn(message: string): void;
|
|
8
|
+
}
|
|
9
|
+
export type { MigrationLedgerLocation };
|
|
10
|
+
export interface FrameworkMigrationsCheckOptions extends MigrationLedgerLocation {
|
|
11
|
+
/**
|
|
12
|
+
* Further ledger locations, tried in order after `database`/`table` (G-007 QA P1). Empty or
|
|
13
|
+
* absent ⇒ `database`/`table` is read directly. Otherwise each location is probed
|
|
14
|
+
* (information_schema) and the first whose table exists is read; none ⇒ fail closed.
|
|
15
|
+
*/
|
|
16
|
+
readonly alternatives?: readonly MigrationLedgerLocation[];
|
|
17
|
+
readonly query: LedgerQuery;
|
|
18
|
+
/**
|
|
19
|
+
* Directory (or directories) of shipped `.cjs` migrations (`guardMigrationsDir`,
|
|
20
|
+
* `identityMigrationsDir`); ids of several directories are checked as one set.
|
|
21
|
+
*/
|
|
22
|
+
readonly migrationsDir: string | readonly string[];
|
|
23
|
+
/** The raw `NODE_ENV`; only `development` and `test` downgrade a failure to a warning. */
|
|
24
|
+
readonly nodeEnv: string | undefined;
|
|
25
|
+
readonly logger: LedgerCheckLogger;
|
|
26
|
+
}
|
|
27
|
+
export interface FrameworkMigrationsCheckResult {
|
|
28
|
+
/** `true` when every shipped id is in the ledger. */
|
|
29
|
+
readonly ok: boolean;
|
|
30
|
+
/** Shipped ids absent from the ledger (all of them when the ledger is missing or unreadable). */
|
|
31
|
+
readonly missing: readonly string[];
|
|
32
|
+
}
|
|
33
|
+
/** The migration ids shipped in `dir` (`.cjs` files only), ascending. */
|
|
34
|
+
export declare function frameworkMigrationIds(dir: string): string[];
|
|
35
|
+
/**
|
|
36
|
+
* The migrate CLI's ledger location rule (core `resolveMigrationLedgerLocation`: `<ns>_app` when
|
|
37
|
+
* namespaced, else `DDL_DB_NAME ?? <default app>`). The boot check itself uses
|
|
38
|
+
* {@link resolveMigrationLedgerCheck}, which also tries the runtime `APP_DB_NAME`.
|
|
39
|
+
* @throws FrameworkSchemaConfigError on a conflicting `DDL_DB_NAME` or invalid names.
|
|
40
|
+
*/
|
|
41
|
+
export declare function resolveMigrationLedger(env: NodeJS.ProcessEnv, schemas: FrameworkSchemas): MigrationLedgerLocation;
|
|
42
|
+
/** Where the boot check looks: the first candidate plus the ones tried after it. */
|
|
43
|
+
export interface MigrationLedgerCheckLocation extends MigrationLedgerLocation {
|
|
44
|
+
readonly alternatives: readonly MigrationLedgerLocation[];
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* The boot check's ledger locations for this process's env (G-007 QA P1): core
|
|
48
|
+
* `migrationLedgerCandidates`, split into the first location and its `alternatives`. Namespace
|
|
49
|
+
* set ⇒ `<ns>_app` only; default ⇒ `DDL_DB_NAME`, the runtime `APP_DB_NAME`, `shield_app`.
|
|
50
|
+
* Spread it into {@link FrameworkMigrationsCheckOptions}.
|
|
51
|
+
* @throws FrameworkSchemaConfigError on a conflicting `DDL_DB_NAME` or invalid names.
|
|
52
|
+
*/
|
|
53
|
+
export declare function resolveMigrationLedgerCheck(env: NodeJS.ProcessEnv, schemas: FrameworkSchemas): MigrationLedgerCheckLocation;
|
|
54
|
+
/**
|
|
55
|
+
* Compare the shipped migration ids in `migrationsDir` with the ledger; throw (production) or
|
|
56
|
+
* warn (development/test) when any is missing or the ledger cannot be read.
|
|
57
|
+
* @throws Error naming the database and up to 10 missing ids, outside development/test; and in
|
|
58
|
+
* every environment for an invalid ledger database or table name (checked before any query).
|
|
59
|
+
*/
|
|
60
|
+
export declare function assertFrameworkMigrationsApplied(options: FrameworkMigrationsCheckOptions): Promise<FrameworkMigrationsCheckResult>;
|
|
61
|
+
/** DI token of the per-app {@link MigrationLedgerRegistry} (provided by `ShieldModule`). */
|
|
62
|
+
export declare const SHIELD_MIGRATION_LEDGER_REGISTRY: unique symbol;
|
|
63
|
+
/** DI token of guard's own check (`AuthModule`); identity provides its check under its own token. */
|
|
64
|
+
export declare const SHIELD_GUARD_MIGRATION_LEDGER_CHECK: unique symbol;
|
|
65
|
+
/**
|
|
66
|
+
* Merges the ledger checks of one application (guard's `AuthModule` and identity) so each ledger
|
|
67
|
+
* location is read once. Hooks {@link register} at construction (all providers exist before any
|
|
68
|
+
* bootstrap hook runs); the first {@link run} for a location checks the union of every registered
|
|
69
|
+
* directory and caches that promise, so later hooks share the result, rejection included.
|
|
70
|
+
*/
|
|
71
|
+
export declare class MigrationLedgerRegistry {
|
|
72
|
+
private readonly entries;
|
|
73
|
+
/** The whole candidate list: hooks with the same list share one probe + read. */
|
|
74
|
+
private static key;
|
|
75
|
+
/** Add `options.migrationsDir` to the check of `options`' ledger location. */
|
|
76
|
+
register(options: FrameworkMigrationsCheckOptions): void;
|
|
77
|
+
/** The (shared) check of `location`'s ledger over every registered directory. */
|
|
78
|
+
run(location: MigrationLedgerLocation & {
|
|
79
|
+
alternatives?: readonly MigrationLedgerLocation[];
|
|
80
|
+
}): Promise<FrameworkMigrationsCheckResult>;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* The boot hook: runs {@link assertFrameworkMigrationsApplied} once, when Nest bootstraps the
|
|
84
|
+
* application (after module init, before the HTTP server listens). Never on a request. With a
|
|
85
|
+
* {@link MigrationLedgerRegistry}, it shares one read per ledger location with the app's other
|
|
86
|
+
* hooks; without one (`null`/absent), it checks alone.
|
|
87
|
+
*/
|
|
88
|
+
export declare class FrameworkMigrationLedgerCheck implements OnApplicationBootstrap {
|
|
89
|
+
private readonly options;
|
|
90
|
+
private readonly registry;
|
|
91
|
+
constructor(options: FrameworkMigrationsCheckOptions, registry?: MigrationLedgerRegistry | null);
|
|
92
|
+
onApplicationBootstrap(): Promise<void>;
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=migration-ledger-check.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration-ledger-check.d.ts","sourceRoot":"","sources":["../../src/boot/migration-ledger-check.ts"],"names":[],"mappings":"AAgCA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,EAKL,KAAK,gBAAgB,EACrB,KAAK,uBAAuB,EAC7B,MAAM,cAAc,CAAC;AAGtB,yEAAyE;AACzE,MAAM,MAAM,WAAW,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAE5D,+CAA+C;AAC/C,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,YAAY,EAAE,uBAAuB,EAAE,CAAC;AAExC,MAAM,WAAW,+BAAgC,SAAQ,uBAAuB;IAC9E;;;;OAIG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,uBAAuB,EAAE,CAAC;IAC3D,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAC5B;;;OAGG;IACH,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC;IACnD,0FAA0F;IAC1F,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;CACpC;AAED,MAAM,WAAW,8BAA8B;IAC7C,qDAAqD;IACrD,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;IACrB,iGAAiG;IACjG,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC;AAgBD,yEAAyE;AACzE,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAO3D;AAWD;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,MAAM,CAAC,UAAU,EACtB,OAAO,EAAE,gBAAgB,GACxB,uBAAuB,CAEzB;AAED,oFAAoF;AACpF,MAAM,WAAW,4BAA6B,SAAQ,uBAAuB;IAC3E,QAAQ,CAAC,YAAY,EAAE,SAAS,uBAAuB,EAAE,CAAC;CAC3D;AAED;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CACzC,GAAG,EAAE,MAAM,CAAC,UAAU,EACtB,OAAO,EAAE,gBAAgB,GACxB,4BAA4B,CAG9B;AA+CD;;;;;GAKG;AACH,wBAAsB,gCAAgC,CACpD,OAAO,EAAE,+BAA+B,GACvC,OAAO,CAAC,8BAA8B,CAAC,CAyFzC;AAED,4FAA4F;AAC5F,eAAO,MAAM,gCAAgC,eAA6C,CAAC;AAE3F,qGAAqG;AACrG,eAAO,MAAM,mCAAmC,eAAgD,CAAC;AAEjG;;;;;GAKG;AACH,qBAAa,uBAAuB;IAClC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAOpB;IAEJ,iFAAiF;IACjF,OAAO,CAAC,MAAM,CAAC,GAAG;IAQlB,8EAA8E;IAC9E,QAAQ,CAAC,OAAO,EAAE,+BAA+B,GAAG,IAAI;IAexD,iFAAiF;IACjF,GAAG,CACD,QAAQ,EAAE,uBAAuB,GAAG;QAAE,YAAY,CAAC,EAAE,SAAS,uBAAuB,EAAE,CAAA;KAAE,GACxF,OAAO,CAAC,8BAA8B,CAAC;CAY3C;AAED;;;;;GAKG;AACH,qBAAa,6BAA8B,YAAW,sBAAsB;IAExE,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBADR,OAAO,EAAE,+BAA+B,EACxC,QAAQ,GAAE,uBAAuB,GAAG,IAAW;IAK5D,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC;CAI9C"}
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FrameworkMigrationLedgerCheck = exports.MigrationLedgerRegistry = exports.SHIELD_GUARD_MIGRATION_LEDGER_CHECK = exports.SHIELD_MIGRATION_LEDGER_REGISTRY = void 0;
|
|
4
|
+
exports.frameworkMigrationIds = frameworkMigrationIds;
|
|
5
|
+
exports.resolveMigrationLedger = resolveMigrationLedger;
|
|
6
|
+
exports.resolveMigrationLedgerCheck = resolveMigrationLedgerCheck;
|
|
7
|
+
exports.assertFrameworkMigrationsApplied = assertFrameworkMigrationsApplied;
|
|
8
|
+
/**
|
|
9
|
+
* Boot check: every framework migration a package ships is recorded in the `@astram/migrate`
|
|
10
|
+
* ledger (configurable-framework-db spec 5.D, §13).
|
|
11
|
+
*
|
|
12
|
+
* The ledger lives where `astram-migrate` writes it (spec 5.G): `<ns>_app` when
|
|
13
|
+
* `SHIELD_DB_NAMESPACE` is set, else `DDL_DB_NAME ?? APP_DB_NAME ?? <default app database>` of
|
|
14
|
+
* the migrate job's env; the table is `APP_MIGRATION_TABLE ?? 'schema_migrations'`. With the
|
|
15
|
+
* namespace set the check reads `<ns>_app` directly. In default mode it cannot know the migrate
|
|
16
|
+
* job's env, so it probes core `migrationLedgerCandidates` in order (`DDL_DB_NAME`, the runtime
|
|
17
|
+
* `APP_DB_NAME`, `shield_app`; one information_schema probe each, at bootstrap only) and reads the
|
|
18
|
+
* first ledger table that exists (G-007 QA P1). That ledger must hold every id; none found fails
|
|
19
|
+
* closed naming every location tried.
|
|
20
|
+
*
|
|
21
|
+
* Missing ids, no ledger table, or an unreadable ledger:
|
|
22
|
+
* - outside `NODE_ENV` development/test (unset included) ⇒ throws, boot fails (Shield #1);
|
|
23
|
+
* - in development/test ⇒ one warning, boot continues.
|
|
24
|
+
* An unreadable ledger is never treated as "all applied". Messages carry the database name, the
|
|
25
|
+
* table name, migration ids and a driver error code only: never a user, host, password or the
|
|
26
|
+
* driver's message text (core 70-secrets).
|
|
27
|
+
*
|
|
28
|
+
* Runs once, at application bootstrap, never per request (Shield #12). Who checks what:
|
|
29
|
+
* - `AuthModule` (`auth: true`) checks `guardMigrationsDir` over its runtime pool;
|
|
30
|
+
* - `@astram/identity` checks `guardMigrationsDir` AND `identityMigrationsDir` over its own pool
|
|
31
|
+
* (identity reads guard's authz tables; guard never imports identity, ADR-0003);
|
|
32
|
+
* - an enforcement-only app (no `auth`, no identity) opens no DB pool and reads no framework
|
|
33
|
+
* table, so it checks nothing.
|
|
34
|
+
* When both run in one app, the per-app {@link MigrationLedgerRegistry} (provided by
|
|
35
|
+
* `ShieldModule`) merges them: every hook registers its directories when constructed, and the
|
|
36
|
+
* first hook to bootstrap runs ONE SELECT per ledger location over the union; the others await
|
|
37
|
+
* that same result (a failure fails every one of them). Without the registry each hook runs alone.
|
|
38
|
+
*/
|
|
39
|
+
const node_fs_1 = require("node:fs");
|
|
40
|
+
const core_1 = require("@astram/core");
|
|
41
|
+
const app_config_js_1 = require("../config/app-config.js");
|
|
42
|
+
/** At most this many ids are listed in the message (spec §13). */
|
|
43
|
+
const MAX_LISTED_IDS = 10;
|
|
44
|
+
/** Same id rule as `@astram/migrate`'s loader, restricted to the shipped `.cjs` files. */
|
|
45
|
+
const MIGRATION_FILE = /^(\d+)-.+\.cjs$/;
|
|
46
|
+
/** MariaDB "table doesn't exist". */
|
|
47
|
+
const ER_NO_SUCH_TABLE = 1146;
|
|
48
|
+
/** `1`, `01` and `001` are the same migration id (migrate orders ids numerically). */
|
|
49
|
+
function idKey(id) {
|
|
50
|
+
return id.replace(/^0+(?=\d)/, '');
|
|
51
|
+
}
|
|
52
|
+
/** The migration ids shipped in `dir` (`.cjs` files only), ascending. */
|
|
53
|
+
function frameworkMigrationIds(dir) {
|
|
54
|
+
const ids = [];
|
|
55
|
+
for (const file of (0, node_fs_1.readdirSync)(dir)) {
|
|
56
|
+
const m = MIGRATION_FILE.exec(file);
|
|
57
|
+
if (m)
|
|
58
|
+
ids.push(m[1]);
|
|
59
|
+
}
|
|
60
|
+
return sortIds(ids);
|
|
61
|
+
}
|
|
62
|
+
/** Ascending numeric order over decimal id strings. */
|
|
63
|
+
function sortIds(ids) {
|
|
64
|
+
return ids.sort((a, b) => {
|
|
65
|
+
const ka = idKey(a);
|
|
66
|
+
const kb = idKey(b);
|
|
67
|
+
return ka.length - kb.length || (ka < kb ? -1 : ka > kb ? 1 : 0);
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* The migrate CLI's ledger location rule (core `resolveMigrationLedgerLocation`: `<ns>_app` when
|
|
72
|
+
* namespaced, else `DDL_DB_NAME ?? <default app>`). The boot check itself uses
|
|
73
|
+
* {@link resolveMigrationLedgerCheck}, which also tries the runtime `APP_DB_NAME`.
|
|
74
|
+
* @throws FrameworkSchemaConfigError on a conflicting `DDL_DB_NAME` or invalid names.
|
|
75
|
+
*/
|
|
76
|
+
function resolveMigrationLedger(env, schemas) {
|
|
77
|
+
return (0, core_1.resolveMigrationLedgerLocation)(schemas, env);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* The boot check's ledger locations for this process's env (G-007 QA P1): core
|
|
81
|
+
* `migrationLedgerCandidates`, split into the first location and its `alternatives`. Namespace
|
|
82
|
+
* set ⇒ `<ns>_app` only; default ⇒ `DDL_DB_NAME`, the runtime `APP_DB_NAME`, `shield_app`.
|
|
83
|
+
* Spread it into {@link FrameworkMigrationsCheckOptions}.
|
|
84
|
+
* @throws FrameworkSchemaConfigError on a conflicting `DDL_DB_NAME` or invalid names.
|
|
85
|
+
*/
|
|
86
|
+
function resolveMigrationLedgerCheck(env, schemas) {
|
|
87
|
+
const [first, ...alternatives] = (0, core_1.migrationLedgerCandidates)(schemas, env);
|
|
88
|
+
return { database: first.database, table: first.table, alternatives };
|
|
89
|
+
}
|
|
90
|
+
/** The driver error code only (never its message: it can carry user@host). */
|
|
91
|
+
function errorCode(err) {
|
|
92
|
+
if (typeof err === 'object' && err !== null) {
|
|
93
|
+
const { code, errno } = err;
|
|
94
|
+
if (typeof code === 'string' && /^[A-Z0-9_]{1,64}$/.test(code))
|
|
95
|
+
return code;
|
|
96
|
+
if (typeof errno === 'number')
|
|
97
|
+
return `errno ${errno}`;
|
|
98
|
+
}
|
|
99
|
+
return 'unknown error';
|
|
100
|
+
}
|
|
101
|
+
function isNoSuchTable(err) {
|
|
102
|
+
if (typeof err !== 'object' || err === null)
|
|
103
|
+
return false;
|
|
104
|
+
const { code, errno } = err;
|
|
105
|
+
return code === 'ER_NO_SUCH_TABLE' || errno === ER_NO_SUCH_TABLE;
|
|
106
|
+
}
|
|
107
|
+
/** No candidate holds a ledger table: name every location, tell the operator what to set. */
|
|
108
|
+
function notFoundMessage(tried, unverified) {
|
|
109
|
+
const where = tried.map((l) => `${l.database}.${l.table}`).join(', ');
|
|
110
|
+
return (`Shield migration ledger not found (tried, in order: ${where}); ` +
|
|
111
|
+
`${unverified} framework migrations are unverified. Set DDL_DB_NAME to the ledger database, ` +
|
|
112
|
+
'the same value for `astram-migrate` and the server, and run `astram-migrate migrate` ' +
|
|
113
|
+
'with the deploy account before starting the server.');
|
|
114
|
+
}
|
|
115
|
+
/** One information_schema probe: does `l.database` hold the table `l.table`? Names validated. */
|
|
116
|
+
function probeSql(l) {
|
|
117
|
+
return ('SELECT 1 AS present FROM information_schema.TABLES ' +
|
|
118
|
+
`WHERE TABLE_SCHEMA = '${l.database}' AND TABLE_NAME = '${l.table}' LIMIT 1`);
|
|
119
|
+
}
|
|
120
|
+
function missingMessage(database, missing) {
|
|
121
|
+
const listed = missing.slice(0, MAX_LISTED_IDS);
|
|
122
|
+
const more = missing.length - listed.length;
|
|
123
|
+
const ids = more > 0 ? `${listed.join(', ')}, … ${more} more` : listed.join(', ');
|
|
124
|
+
return (`Shield database ${database} is missing ${missing.length} framework migrations (${ids}). ` +
|
|
125
|
+
'Run `astram-migrate migrate` with the deploy account before starting the server.');
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Compare the shipped migration ids in `migrationsDir` with the ledger; throw (production) or
|
|
129
|
+
* warn (development/test) when any is missing or the ledger cannot be read.
|
|
130
|
+
* @throws Error naming the database and up to 10 missing ids, outside development/test; and in
|
|
131
|
+
* every environment for an invalid ledger database or table name (checked before any query).
|
|
132
|
+
*/
|
|
133
|
+
async function assertFrameworkMigrationsApplied(options) {
|
|
134
|
+
// Every location is validated before any query (operator names: any plain MariaDB identifier).
|
|
135
|
+
const locations = [
|
|
136
|
+
{ database: options.database, table: options.table },
|
|
137
|
+
...(options.alternatives ?? []),
|
|
138
|
+
].map((l) => {
|
|
139
|
+
const database = (0, core_1.assertLedgerDatabaseName)(l.database, 'migration ledger database');
|
|
140
|
+
if (typeof l.table !== 'string' || !core_1.MIGRATION_LEDGER_TABLE_PATTERN.test(l.table)) {
|
|
141
|
+
throw new Error(`APP_MIGRATION_TABLE is not a valid table name; expected ${core_1.MIGRATION_LEDGER_TABLE_PATTERN.source}`);
|
|
142
|
+
}
|
|
143
|
+
return { database, table: l.table };
|
|
144
|
+
});
|
|
145
|
+
let { database, table } = locations[0];
|
|
146
|
+
const devOrTest = (0, app_config_js_1.isDevOrTestNodeEnv)(options.nodeEnv);
|
|
147
|
+
const fail = (message, missing) => {
|
|
148
|
+
if (!devOrTest)
|
|
149
|
+
throw new Error(message);
|
|
150
|
+
options.logger.warn(`${message} (NODE_ENV=${options.nodeEnv}: continuing)`);
|
|
151
|
+
return { ok: false, missing };
|
|
152
|
+
};
|
|
153
|
+
let shipped;
|
|
154
|
+
try {
|
|
155
|
+
const dirs = typeof options.migrationsDir === 'string' ? [options.migrationsDir] : options.migrationsDir;
|
|
156
|
+
shipped = sortIds([...new Set(dirs.flatMap((d) => frameworkMigrationIds(d)))]);
|
|
157
|
+
}
|
|
158
|
+
catch (err) {
|
|
159
|
+
return fail(`Shield database ${database}: cannot read the framework migrations directory ` +
|
|
160
|
+
`(${errorCode(err)}); the package install is incomplete.`, []);
|
|
161
|
+
}
|
|
162
|
+
if (shipped.length === 0)
|
|
163
|
+
return { ok: true, missing: [] };
|
|
164
|
+
// Several candidates (default namespace): use the first whose ledger table exists. A probe
|
|
165
|
+
// error is never "not here" or "all applied": it fails like an unreadable ledger.
|
|
166
|
+
if (locations.length > 1) {
|
|
167
|
+
let found;
|
|
168
|
+
for (const l of locations) {
|
|
169
|
+
let rows;
|
|
170
|
+
try {
|
|
171
|
+
rows = await options.query(probeSql(l));
|
|
172
|
+
}
|
|
173
|
+
catch (err) {
|
|
174
|
+
return fail(`Shield database ${l.database}: cannot look for the migration ledger ` +
|
|
175
|
+
`${l.database}.${l.table} (${errorCode(err)}); ${shipped.length} framework ` +
|
|
176
|
+
'migrations are unverified.', shipped);
|
|
177
|
+
}
|
|
178
|
+
if (!Array.isArray(rows)) {
|
|
179
|
+
return fail(`Shield database ${l.database}: cannot look for the migration ledger ` +
|
|
180
|
+
`${l.database}.${l.table} (UNEXPECTED_RESULT); ${shipped.length} framework ` +
|
|
181
|
+
'migrations are unverified.', shipped);
|
|
182
|
+
}
|
|
183
|
+
if (rows.length > 0) {
|
|
184
|
+
found = l;
|
|
185
|
+
break;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
if (found === undefined)
|
|
189
|
+
return fail(notFoundMessage(locations, shipped.length), shipped);
|
|
190
|
+
({ database, table } = found);
|
|
191
|
+
}
|
|
192
|
+
let applied;
|
|
193
|
+
try {
|
|
194
|
+
const rows = await options.query(`SELECT id FROM \`${database}\`.\`${table}\``);
|
|
195
|
+
if (!Array.isArray(rows))
|
|
196
|
+
throw Object.assign(new Error(), { code: 'UNEXPECTED_RESULT' });
|
|
197
|
+
applied = new Set(rows.map((r) => idKey(String(r?.id ?? ''))));
|
|
198
|
+
}
|
|
199
|
+
catch (err) {
|
|
200
|
+
// No ledger table: nothing was ever migrated here, so every shipped id is missing.
|
|
201
|
+
if (isNoSuchTable(err))
|
|
202
|
+
return fail(missingMessage(database, shipped), shipped);
|
|
203
|
+
return fail(`Shield database ${database}: cannot read the migration ledger ${database}.${table} ` +
|
|
204
|
+
`(${errorCode(err)}); ${shipped.length} framework migrations are unverified.`, shipped);
|
|
205
|
+
}
|
|
206
|
+
const missing = shipped.filter((id) => !applied.has(idKey(id)));
|
|
207
|
+
if (missing.length === 0)
|
|
208
|
+
return { ok: true, missing: [] };
|
|
209
|
+
return fail(missingMessage(database, missing), missing);
|
|
210
|
+
}
|
|
211
|
+
/** DI token of the per-app {@link MigrationLedgerRegistry} (provided by `ShieldModule`). */
|
|
212
|
+
exports.SHIELD_MIGRATION_LEDGER_REGISTRY = Symbol('SHIELD_MIGRATION_LEDGER_REGISTRY');
|
|
213
|
+
/** DI token of guard's own check (`AuthModule`); identity provides its check under its own token. */
|
|
214
|
+
exports.SHIELD_GUARD_MIGRATION_LEDGER_CHECK = Symbol('SHIELD_GUARD_MIGRATION_LEDGER_CHECK');
|
|
215
|
+
/**
|
|
216
|
+
* Merges the ledger checks of one application (guard's `AuthModule` and identity) so each ledger
|
|
217
|
+
* location is read once. Hooks {@link register} at construction (all providers exist before any
|
|
218
|
+
* bootstrap hook runs); the first {@link run} for a location checks the union of every registered
|
|
219
|
+
* directory and caches that promise, so later hooks share the result, rejection included.
|
|
220
|
+
*/
|
|
221
|
+
class MigrationLedgerRegistry {
|
|
222
|
+
entries = new Map();
|
|
223
|
+
/** The whole candidate list: hooks with the same list share one probe + read. */
|
|
224
|
+
static key(l) {
|
|
225
|
+
return [l, ...(l.alternatives ?? [])]
|
|
226
|
+
.map((x) => `${x.database}\u0000${x.table}`)
|
|
227
|
+
.join('\u0001');
|
|
228
|
+
}
|
|
229
|
+
/** Add `options.migrationsDir` to the check of `options`' ledger location. */
|
|
230
|
+
register(options) {
|
|
231
|
+
const dirs = typeof options.migrationsDir === 'string' ? [options.migrationsDir] : options.migrationsDir;
|
|
232
|
+
const key = MigrationLedgerRegistry.key(options);
|
|
233
|
+
const entry = this.entries.get(key);
|
|
234
|
+
if (entry === undefined) {
|
|
235
|
+
this.entries.set(key, { options, dirs: new Set(dirs) });
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
if (entry.result !== undefined) {
|
|
239
|
+
throw new Error('MigrationLedgerRegistry: a check registered after the ledger was read.');
|
|
240
|
+
}
|
|
241
|
+
for (const d of dirs)
|
|
242
|
+
entry.dirs.add(d);
|
|
243
|
+
}
|
|
244
|
+
/** The (shared) check of `location`'s ledger over every registered directory. */
|
|
245
|
+
run(location) {
|
|
246
|
+
const entry = this.entries.get(MigrationLedgerRegistry.key(location));
|
|
247
|
+
// Never registered: nothing to share, nothing claims "checked" (fail closed).
|
|
248
|
+
if (entry === undefined) {
|
|
249
|
+
return Promise.reject(new Error('MigrationLedgerRegistry: ledger location not registered.'));
|
|
250
|
+
}
|
|
251
|
+
entry.result ??= assertFrameworkMigrationsApplied({
|
|
252
|
+
...entry.options,
|
|
253
|
+
migrationsDir: [...entry.dirs],
|
|
254
|
+
});
|
|
255
|
+
return entry.result;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
exports.MigrationLedgerRegistry = MigrationLedgerRegistry;
|
|
259
|
+
/**
|
|
260
|
+
* The boot hook: runs {@link assertFrameworkMigrationsApplied} once, when Nest bootstraps the
|
|
261
|
+
* application (after module init, before the HTTP server listens). Never on a request. With a
|
|
262
|
+
* {@link MigrationLedgerRegistry}, it shares one read per ledger location with the app's other
|
|
263
|
+
* hooks; without one (`null`/absent), it checks alone.
|
|
264
|
+
*/
|
|
265
|
+
class FrameworkMigrationLedgerCheck {
|
|
266
|
+
options;
|
|
267
|
+
registry;
|
|
268
|
+
constructor(options, registry = null) {
|
|
269
|
+
this.options = options;
|
|
270
|
+
this.registry = registry;
|
|
271
|
+
registry?.register(options);
|
|
272
|
+
}
|
|
273
|
+
async onApplicationBootstrap() {
|
|
274
|
+
if (this.registry)
|
|
275
|
+
await this.registry.run(this.options);
|
|
276
|
+
else
|
|
277
|
+
await assertFrameworkMigrationsApplied(this.options);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
exports.FrameworkMigrationLedgerCheck = FrameworkMigrationLedgerCheck;
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
* 8 × (12 + 8 + 1) + 40 = 208 ≤ 250 ✓
|
|
24
24
|
* ─────────────────────────────────────────────────────────────────────────────
|
|
25
25
|
*/
|
|
26
|
-
import type { SecretsProvider } from '@astram/core';
|
|
26
|
+
import type { FrameworkSchemas, SecretsProvider } from '@astram/core';
|
|
27
27
|
export interface AppConfig {
|
|
28
28
|
/** HTTP port the Nest app listens on. */
|
|
29
29
|
readonly port: number;
|
|
@@ -74,7 +74,20 @@ export interface AppConfig {
|
|
|
74
74
|
* composition (boot fails loud).
|
|
75
75
|
*/
|
|
76
76
|
readonly refreshReplayWindowMs?: number;
|
|
77
|
+
/**
|
|
78
|
+
* The four framework database names (configurable-framework-db, ADR-0037), resolved once from
|
|
79
|
+
* `SHIELD_DB_NAMESPACE` by core `resolveFrameworkSchemas` (unset ⇒ the `shield_*` defaults).
|
|
80
|
+
* Optional so hand-built configs keep compiling; absent ⇒ {@link frameworkSchemasOf} resolves
|
|
81
|
+
* from `process.env` once at boot. Provided app-wide under `FRAMEWORK_SCHEMAS`.
|
|
82
|
+
*/
|
|
83
|
+
readonly schemas?: FrameworkSchemas;
|
|
77
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* The resolved framework database names for a config: `config.schemas`, else resolved from
|
|
87
|
+
* `process.env` (a hand-built config without `schemas`). Call at boot only (Shield #12).
|
|
88
|
+
* @throws FrameworkSchemaConfigError on an invalid `SHIELD_DB_NAMESPACE` (fail closed).
|
|
89
|
+
*/
|
|
90
|
+
export declare function frameworkSchemasOf(config: Pick<AppConfig, 'schemas'>): FrameworkSchemas;
|
|
78
91
|
/** The per-client-IP login failure limit (failures within `windowMs` that lock the IP). */
|
|
79
92
|
export interface LoginIpLimitConfig {
|
|
80
93
|
readonly maxAttempts: number;
|
|
@@ -205,7 +218,11 @@ export declare function isDevOrTestNodeEnv(raw: string | undefined): boolean;
|
|
|
205
218
|
* perAccountMax.shield_schema_svc ← POOL_MAX_SCHEMA_SVC
|
|
206
219
|
*/
|
|
207
220
|
export declare function loadPoolBudget(env?: NodeJS.ProcessEnv): PoolBudgetConfig;
|
|
208
|
-
/**
|
|
221
|
+
/**
|
|
222
|
+
* Documented defaults for the runtime MariaDB descriptor (local docker substrate), for the
|
|
223
|
+
* default namespace. Under `SHIELD_DB_NAMESPACE` the user and database follow the namespace
|
|
224
|
+
* (`<ns>_core`, `<ns>_identity`; see {@link loadDbConfig}).
|
|
225
|
+
*/
|
|
209
226
|
export declare const DEFAULT_DB_CONFIG: Omit<DbConfig, 'password'>;
|
|
210
227
|
/** Documented default Redis url (local docker substrate). */
|
|
211
228
|
export declare const DEFAULT_REDIS_URL = "redis://localhost:6379";
|
|
@@ -219,8 +236,17 @@ export declare const DEFAULT_REDIS_URL = "redis://localhost:6379";
|
|
|
219
236
|
* connect time (loud), which is correct for a runtime that needs real creds; the
|
|
220
237
|
* secret is deliberately NOT hard-required at config load (unlike the HMAC key,
|
|
221
238
|
* which is a fail-closed security invariant even for unit tests).
|
|
239
|
+
*
|
|
240
|
+
* Namespace (configurable-framework-db, spec 5.C): `APP_DB_USER` unset ⇒ `<ns>_core`;
|
|
241
|
+
* `APP_DB_NAME` unset ⇒ `<ns>_identity`. A set `APP_DB_NAME` must be one of the four resolved
|
|
242
|
+
* framework names, else this throws naming the variable (fail closed: an unqualified query must
|
|
243
|
+
* not reach another environment's database). An invalid `SHIELD_DB_NAMESPACE` throws too.
|
|
244
|
+
*
|
|
245
|
+
* `schemas` (optional): names the caller already resolved (e.g. `IdentityFeatureModule.forRoot
|
|
246
|
+
* ({ schemas })`). When given they replace the env namespace for the defaults and the
|
|
247
|
+
* `APP_DB_NAME` check, so the runtime database cannot drift from them (G-007 QA P2-5).
|
|
222
248
|
*/
|
|
223
|
-
export declare function loadDbConfig(env?: NodeJS.ProcessEnv): DbConfig;
|
|
249
|
+
export declare function loadDbConfig(env?: NodeJS.ProcessEnv, schemas?: FrameworkSchemas): DbConfig;
|
|
224
250
|
/**
|
|
225
251
|
* `APP_DB_TLS` = `off` (default) | `on`; `APP_DB_TLS_CA` = PEM path (only with `on`). Anything
|
|
226
252
|
* else throws at boot: a typo must not silently fall back to plaintext.
|
|
@@ -310,6 +336,49 @@ export declare function loadAppConfig(env?: NodeJS.ProcessEnv): AppConfig;
|
|
|
310
336
|
* The core resolver (`resolveSecretRefs`) does the work; this is the guard-side boot seam.
|
|
311
337
|
*/
|
|
312
338
|
export declare function loadAppConfigAsync(provider?: SecretsProvider, env?: NodeJS.ProcessEnv): Promise<AppConfig>;
|
|
339
|
+
/** The S3-compatible object store descriptor read from `OBJECT_STORAGE_*`. */
|
|
340
|
+
export interface ObjectStorageConfig {
|
|
341
|
+
/** `https:` URL (or `http:` in development/test, or to a loopback host). Never carries userinfo. */
|
|
342
|
+
readonly endpoint: string;
|
|
343
|
+
readonly bucket: string;
|
|
344
|
+
/** `OBJECT_STORAGE_REGION`, default `us-east-1`. */
|
|
345
|
+
readonly region: string;
|
|
346
|
+
readonly accessKeyId: string;
|
|
347
|
+
readonly secretAccessKey: string;
|
|
348
|
+
/** Server-side encryption mode. Only SSE-S3 (`AES256`) is accepted now. */
|
|
349
|
+
readonly sse: 'AES256';
|
|
350
|
+
/** `OBJECT_STORAGE_MAX_BYTES` (default 10 MiB), at most `FILE_MAX_BYTES_CEILING` (50 MiB). */
|
|
351
|
+
readonly maxBytes: number;
|
|
352
|
+
}
|
|
353
|
+
/** Options for {@link loadObjectStorageConfig}. */
|
|
354
|
+
export interface LoadObjectStorageConfigOptions {
|
|
355
|
+
/**
|
|
356
|
+
* Provenance check for the two credential variables outside development/test (SPEC §5 F: a
|
|
357
|
+
* literal credential there is a boot error). Returns `true` when the variable's value was
|
|
358
|
+
* resolved from a `secret-ref:` at boot (`wasResolvedFromSecretRef`). Omitted outside
|
|
359
|
+
* development/test: fail closed, every credential is treated as a literal and refused (the
|
|
360
|
+
* value alone cannot tell a literal from a resolved reference).
|
|
361
|
+
*/
|
|
362
|
+
readonly resolvedFromSecretRef?: (envKey: string, env: Readonly<Record<string, string | undefined>>) => boolean;
|
|
363
|
+
}
|
|
364
|
+
/** Default per-file cap when `OBJECT_STORAGE_MAX_BYTES` is unset (10 MiB, SPEC §10). */
|
|
365
|
+
export declare const DEFAULT_OBJECT_STORAGE_MAX_BYTES: number;
|
|
366
|
+
/**
|
|
367
|
+
* Read the object-storage config (FILE_STORAGE SPEC §5 F). Returns `undefined` when
|
|
368
|
+
* `OBJECT_STORAGE_BUCKET` is unset or blank (storage off). Otherwise every bad value is a boot
|
|
369
|
+
* error that names the variable and never its value (Shield #1, #10):
|
|
370
|
+
* - endpoint or either credential missing/blank;
|
|
371
|
+
* - endpoint not a URL, carrying userinfo, or not `https:` outside development/test unless the
|
|
372
|
+
* host is loopback (the raw `NODE_ENV`; unset is not dev);
|
|
373
|
+
* - a credential still holding an unresolved `secret-ref:` value;
|
|
374
|
+
* - outside development/test, a credential not resolved from a `secret-ref:` per
|
|
375
|
+
* `options.resolvedFromSecretRef` (`ShieldModule.forRoot({ storage: 'env' })` passes
|
|
376
|
+
* `wasResolvedFromSecretRef`); without the option every credential there is refused;
|
|
377
|
+
* - `OBJECT_STORAGE_SSE` other than `AES256`;
|
|
378
|
+
* - `OBJECT_STORAGE_MAX_BYTES` not a plain positive decimal without leading zeros, or above the
|
|
379
|
+
* 50 MiB ceiling.
|
|
380
|
+
*/
|
|
381
|
+
export declare function loadObjectStorageConfig(env?: NodeJS.ProcessEnv, options?: LoadObjectStorageConfigOptions): ObjectStorageConfig | undefined;
|
|
313
382
|
/** Result of evaluating a {@link PoolBudgetConfig} against the ADR-0018 budget. */
|
|
314
383
|
export interface PoolBudgetEvaluation {
|
|
315
384
|
/** Σ(per-account runtime pool max) for a single worker. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-config.d.ts","sourceRoot":"","sources":["../../src/config/app-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"app-config.d.ts","sourceRoot":"","sources":["../../src/config/app-config.ts"],"names":[],"mappings":"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"}
|