@astram/guard 0.12.1 → 0.14.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/connections.d.ts +19 -1
- package/dist/auth/connections.d.ts.map +1 -1
- package/dist/auth/connections.js +44 -1
- package/dist/config/app-config.d.ts +66 -0
- package/dist/config/app-config.d.ts.map +1 -1
- package/dist/config/app-config.js +112 -1
- package/dist/config/config.module.d.ts.map +1 -1
- package/dist/config/config.module.js +5 -1
- 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/index.d.ts +11 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +56 -21
- 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 +35 -5
- 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/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/package.json +11 -3
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AASzD,OAAO,EAAE,2BAA2B,EAAE,MAAM,sCAAsC,CAAC;AACnF,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AASzD,OAAO,EAAE,2BAA2B,EAAE,MAAM,sCAAsC,CAAC;AACnF,OAAO,EACL,UAAU,EACV,gBAAgB,EAChB,0BAA0B,EAC1B,oBAAoB,EACpB,uBAAuB,EACvB,UAAU,EACV,SAAS,GACV,MAAM,gCAAgC,CAAC;AAGxC,OAAO,EACL,YAAY,EACZ,yBAAyB,EAGzB,2BAA2B,EAC3B,KAAK,mBAAmB,EACxB,KAAK,wBAAwB,EAI7B,KAAK,yBAAyB,GAC/B,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EACL,MAAM,EACN,UAAU,EACV,uBAAuB,EACvB,yBAAyB,EACzB,uBAAuB,GACxB,MAAM,2CAA2C,CAAC;AACnD,YAAY,EAAE,cAAc,EAAE,MAAM,2CAA2C,CAAC;AAKhF,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAKpG,OAAO,EAAE,yBAAyB,EAAE,MAAM,+CAA+C,CAAC;AAC1F,OAAO,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AACjG,YAAY,EACV,YAAY,EACZ,oBAAoB,EACpB,eAAe,GAChB,MAAM,uCAAuC,CAAC;AAM/C,OAAO,EACL,2BAA2B,EAC3B,4BAA4B,GAC7B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,kBAAkB,EAAE,MAAM,wCAAwC,CAAC;AAC5E,YAAY,EACV,oBAAoB,EACpB,yBAAyB,GAC1B,MAAM,wCAAwC,CAAC;AAChD,OAAO,EACL,uBAAuB,EACvB,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,QAAQ,GACT,MAAM,qCAAqC,CAAC;AAG7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,2CAA2C,CAAC;AAS/E,OAAO,EACL,wBAAwB,EACxB,gBAAgB,EAChB,KAAK,iBAAiB,GACvB,MAAM,qCAAqC,CAAC;AAU7C,OAAO,EAAE,sBAAsB,EAAE,MAAM,2CAA2C,CAAC;AAKnF,OAAO,EACL,qBAAqB,EACrB,KAAK,MAAM,EACX,KAAK,qBAAqB,EAC1B,KAAK,YAAY,EACjB,KAAK,SAAS,GACf,MAAM,4BAA4B,CAAC;AAMpC,OAAO,EACL,sBAAsB,EACtB,sBAAsB,EACtB,sBAAsB,EACtB,KAAK,cAAc,GACpB,MAAM,8CAA8C,CAAC;AAKtD,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAKlE,OAAO,EAAE,4BAA4B,EAAE,MAAM,qCAAqC,CAAC;AAInF,OAAO,EACL,kBAAkB,EAClB,4BAA4B,EAC5B,4BAA4B,EAC5B,wBAAwB,EACxB,KAAK,yBAAyB,GAC/B,MAAM,2BAA2B,CAAC;AAKnC,OAAO,EACL,aAAa,EACb,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,GAC1B,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AAC5E,OAAO,EACL,UAAU,EACV,uBAAuB,EACvB,6BAA6B,EAC7B,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,GACtB,MAAM,sCAAsC,CAAC;AAC9C,YAAY,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAC1E,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACpF,OAAO,EACL,uBAAuB,EACvB,gCAAgC,EAChC,KAAK,mBAAmB,EACxB,KAAK,8BAA8B,GACpC,MAAM,wBAAwB,CAAC;AAOhC,OAAO,EACL,yBAAyB,EACzB,2BAA2B,EAC3B,oBAAoB,EACpB,wBAAwB,EAExB,wBAAwB,EACxB,KAAK,+BAA+B,EACpC,oBAAoB,EACpB,wBAAwB,EACxB,WAAW,EACX,4BAA4B,EAC5B,qBAAqB,EACrB,mBAAmB,EACnB,sBAAsB,EACtB,qBAAqB,EACrB,YAAY,EAEZ,6BAA6B,EAC7B,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EAEzB,wBAAwB,EACxB,eAAe,EACf,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAO5B,OAAO,EACL,kCAAkC,EAClC,uBAAuB,EACvB,KAAK,aAAa,GACnB,MAAM,wCAAwC,CAAC;AAShD,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,KAAK,aAAa,IAAI,oBAAoB,GAC3C,MAAM,iCAAiC,CAAC;AAUzC,OAAO,EACL,uBAAuB,EACvB,sBAAsB,EACtB,KAAK,kBAAkB,GACxB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,GACxB,MAAM,2BAA2B,CAAC;AAMnC,OAAO,EACL,yBAAyB,EACzB,wBAAwB,EACxB,KAAK,cAAc,GACpB,MAAM,yCAAyC,CAAC;AASjD,OAAO,EACL,iBAAiB,EACjB,0BAA0B,EAC1B,sBAAsB,EACtB,0BAA0B,EAC1B,KAAK,UAAU,EACf,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,cAAc,GACpB,MAAM,gCAAgC,CAAC;AAMxC,OAAO,EACL,sBAAsB,EACtB,KAAK,iBAAiB,EACtB,KAAK,YAAY,GAClB,MAAM,iCAAiC,CAAC;AAOzC,OAAO,EACL,8BAA8B,EAC9B,8BAA8B,EAC9B,KAAK,cAAc,GACpB,MAAM,+CAA+C,CAAC;AAWvD,OAAO,EACL,sBAAsB,EACtB,gCAAgC,EAChC,sBAAsB,EACtB,iBAAiB,EACjB,0BAA0B,EAC1B,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,GACtB,MAAM,sCAAsC,CAAC;AAQ9C,OAAO,EACL,iCAAiC,EACjC,+BAA+B,EAC/B,KAAK,sBAAsB,GAC5B,MAAM,iDAAiD,CAAC;AAYzD,OAAO,EAAE,wBAAwB,EAAE,MAAM,sCAAsC,CAAC;AAChF,OAAO,EACL,0BAA0B,EAC1B,KAAK,+BAA+B,GACrC,MAAM,sCAAsC,CAAC;AAM9C,OAAO,EACL,2BAA2B,EAC3B,6BAA6B,EAC7B,iCAAiC,EACjC,KAAK,uBAAuB,EAC5B,KAAK,0BAA0B,EAC/B,KAAK,kCAAkC,GACxC,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,+BAA+B,EAAE,MAAM,kBAAkB,CAAC;AAGnE,OAAO,EAAE,2BAA2B,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,EACL,8BAA8B,EAC9B,KAAK,uBAAuB,EAC5B,KAAK,mBAAmB,GACzB,MAAM,wCAAwC,CAAC;AAOhD,OAAO,EAAE,gBAAgB,EAAE,KAAK,WAAW,EAAE,MAAM,sCAAsC,CAAC;AAI1F,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAOzE,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EACL,aAAa,EACb,cAAc,EACd,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EACxB,KAAK,SAAS,EACd,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EAGxB,YAAY,EACZ,eAAe,EACf,oBAAoB,EACpB,kBAAkB,EAClB,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,EACjB,KAAK,QAAQ,EACb,KAAK,WAAW,EAChB,KAAK,wBAAwB,EAG7B,gBAAgB,EAChB,yBAAyB,EACzB,sBAAsB,EACtB,kBAAkB,EAClB,KAAK,kBAAkB,EAEvB,eAAe,EACf,KAAK,WAAW,GACjB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAezD,OAAO,EACL,YAAY,EACZ,0BAA0B,EAC1B,uBAAuB,EACvB,oBAAoB,EACpB,wBAAwB,EAIxB,wBAAwB,EACxB,wBAAwB,EAExB,+BAA+B,EAC/B,mBAAmB,EACnB,0BAA0B,EAC1B,qBAAqB,EACrB,sBAAsB,EAEtB,iBAAiB,EAEjB,uBAAuB,EAEvB,6BAA6B,GAC9B,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,yBAAyB,EAAE,MAAM,iDAAiD,CAAC;AAI5F,YAAY,EACV,WAAW,EACX,iBAAiB,EACjB,cAAc,EACd,YAAY,EACZ,oBAAoB,EACpB,aAAa,EACb,UAAU,EACV,WAAW,EACX,cAAc,EACd,eAAe,EACf,aAAa,EACb,SAAS,GACV,MAAM,eAAe,CAAC;AAOvB,OAAO,EAAE,UAAU,EAAE,KAAK,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAQ3E,OAAO,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAS/F,YAAY,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAQ3F,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAM9E,YAAY,EACV,eAAe,EACf,kBAAkB,EAClB,WAAW,EACX,aAAa,GACd,MAAM,4BAA4B,CAAC;AAMpC,YAAY,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAC1E,YAAY,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AACzE,YAAY,EACV,qBAAqB,EACrB,uBAAuB,EACvB,qBAAqB,GACtB,MAAM,0CAA0C,CAAC;AAGlD,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAGnF,OAAO,EAAE,0BAA0B,EAAE,MAAM,mDAAmD,CAAC;AAC/F,YAAY,EACV,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,EAClB,YAAY,EACZ,gBAAgB,GACjB,MAAM,uCAAuC,CAAC;AAC/C,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC9E,YAAY,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AAC7E,YAAY,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AACvE,YAAY,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACtE,YAAY,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;AAClF,YAAY,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAK5E,YAAY,EAAE,qBAAqB,EAAE,MAAM,yCAAyC,CAAC;AACrF,OAAO,EAAE,8BAA8B,EAAE,MAAM,kBAAkB,CAAC;AAMlE,YAAY,EAAE,oBAAoB,EAAE,MAAM,wCAAwC,CAAC;AACnF,OAAO,EAAE,6BAA6B,EAAE,MAAM,kBAAkB,CAAC;AAOjE,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EACL,eAAe,EACf,oBAAoB,EACpB,KAAK,mBAAmB,GACzB,MAAM,6BAA6B,CAAC;AAGrC,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,gBAAgB,EAChB,KAAK,SAAS,EACd,KAAK,eAAe,GACrB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,0BAA0B,GAC3B,MAAM,kBAAkB,CAAC;AAK1B,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,qBAAqB,GACtB,MAAM,2BAA2B,CAAC;AAKnC,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAEjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AAQ5E,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,uBAAuB,EACvB,KAAK,SAAS,EACd,KAAK,UAAU,GAChB,MAAM,4BAA4B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -16,10 +16,10 @@
|
|
|
16
16
|
* `@nestjs/core`, `reflect-metadata`, `rxjs` so the host owns one copy of each.
|
|
17
17
|
*/
|
|
18
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
-
exports.
|
|
20
|
-
exports.
|
|
21
|
-
exports.
|
|
22
|
-
exports.ScopeUnknownParentError = exports.ScopeDepthError = exports.ScopeCycleError = void 0;
|
|
19
|
+
exports.FileIntake = exports.ObjectStoreBootCheck = exports.NodeSha256Digest = exports.S3ObjectStore = exports.wasResolvedFromSecretRef = exports.assertNoUnresolvedSecretRefs = exports.createSecretsProviderFromEnv = exports.resolveBootSecrets = exports.EncryptedFileSecretsProvider = exports.LocalKekCrypto = exports.SHIELD_PASSWORD_HASHER = exports.argon2idHasherProvider = exports.Argon2idPasswordHasher = exports.stubDecisionAuthority = exports.GlobalEnforcementGuard = exports.NO_SESSION_FACTS = exports.SHIELD_SESSION_FACTS_ALS = exports.MariaDbApiKeyStore = exports.isApiKey = exports.extractBearerToken = exports.principalFromClaims = exports.resolveRequestAuth = exports.resolveRequestPrincipal = exports.SessionTokenBinder = exports.SHIELD_SERVICE_AUTHENTICATOR = exports.SHIELD_SESSION_TOKEN_BINDER = exports.CatalogGatabilityError = exports.CatalogReconciler = exports.OperationInventoryScanner = exports.uuidArrayField = exports.optionalUuidField = exports.uuidField = exports.UuidPipe = exports.normalizeClassification = exports.DEFAULT_CLASSIFIED_ACTION = exports.CLASSIFICATION_METADATA = exports.Classified = exports.Public = exports.SHIELD_RECORD_AUTHORIZATION = exports.SHIELD_DECISION_AUTHORITY = exports.ShieldModule = exports.actionsOf = exports.actionsFor = exports.SERVICE_ACCOUNT_ACTIONS = exports.RECORD_SHARE_ACTIONS = exports.CROSS_TENANT_GRANT_ACTIONS = exports.IDENTITY_ACTIONS = exports.MODULE_KEY = exports.buildIdentityModuleRegistry = exports.guardMigrationsDir = void 0;
|
|
20
|
+
exports.withRedisPermissionVersion = exports.buildRecordAuthorization = exports.SHIELD_OPERATION_AUTHORITY_PORT = exports.ManifestOperationAuthorityAdapter = exports.GrantStoreUnavailableError = exports.InvalidGrantError = exports.GrantNotPermittedError = exports.SHIELD_CROSS_TENANT_GRANT_WRITER = exports.CrossTenantGrantWriter = exports.SHIELD_CROSS_TENANT_GRANT_PORT = exports.MariaDbCrossTenantGrantAdapter = exports.makeShareDeleteCascade = exports.ShareStoreUnavailableError = exports.ShareNotPermittedError = exports.SHIELD_RECORD_SHARE_WRITER = exports.RecordShareWriter = exports.SHIELD_RECORD_SHARE_PORT = exports.MariaDbRecordShareAdapter = exports.UnknownScopeFieldError = exports.translateListScope = exports.SHIELD_LIST_SCOPE_PORT = exports.MariaDbListScopeAdapter = exports.SHIELD_POLICY_STORE = exports.MariaDbPolicyStore = exports.SHIELD_RECORD_RULE_PORT = exports.MariaDbRecordPermissionRuleAdapter = exports.accessBindingTtlMs = exports.ROTATE_GRACE_MS = exports.SHIELD_SESSION_LIFETIMES = exports.HotRevokingSessionRecordStore = exports.SHIELD_CLOCK = exports.SHIELD_REFRESH_HASHER = exports.SHIELD_TOKEN_GENERATOR = exports.systemClockProvider = exports.refreshHasherProvider = exports.cryptoTokenGeneratorProvider = exports.SystemClock = exports.Sha256RefreshTokenHasher = exports.CryptoTokenGenerator = exports.RedisRecentRotationStore = exports.SHIELD_HOT_SESSION_STORE = exports.RedisHotSessionStore = exports.SHIELD_SESSION_RECORD_STORE = exports.MariaDbSessionRecordStore = exports.DEFAULT_OBJECT_STORAGE_MAX_BYTES = exports.loadObjectStorageConfig = exports.SHIELD_FILE_INGEST = exports.SHIELD_OBJECT_STORE = exports.FILE_INTAKE_DEFAULT_MAX_BYTES = exports.FILE_INTAKE_REQUEST_KEY = void 0;
|
|
21
|
+
exports.isEmailShaped = exports.canonicalEmail = exports.hmacSha1 = exports.resolveTotpVerifier = exports.makeDefaultTotpVerifier = exports.AuthModule = exports.MariaDbCredentialResolver = exports.SHIELD_TOTP_VERIFIER_OVERRIDE = exports.SHIELD_MFA_DEVICE_STORE = exports.SHIELD_AUDIT_SINK = exports.SHIELD_SESSION_SWEEPER = exports.SHIELD_PROFILE_WRITER = exports.SHIELD_RECOVERY_CODE_STORE = exports.SHIELD_EMAIL_SENDER = exports.SHIELD_EMAIL_CHANGE_TOKEN_STORE = exports.SHIELD_RESET_TOKEN_STORE = exports.SHIELD_CREDENTIAL_WRITER = exports.SHIELD_SESSION_AUTHORITY = exports.SHIELD_AUTHENTICATOR = exports.SHIELD_PROFILE_RESOLVER = exports.SHIELD_CREDENTIAL_RESOLVER = exports.SHIELD_REDIS = exports.mariadbSslOption = exports.loadDbTlsConfig = exports.isDevOrTestNodeEnv = exports.DEFAULT_LOGIN_IP_LIMIT = exports.loadRefreshReplayWindowMs = exports.loadLoginIpLimit = exports.DEFAULT_REDIS_URL = exports.DEFAULT_DB_CONFIG = exports.assertRefreshHmacKey = exports.loadRefreshHmacKey = exports.loadSessionLifetimes = exports.loadRedisConfig = exports.loadDbConfig = exports.SCHEMA_SVC_POOL_HARD_CAP = exports.DEFAULT_POOL_BUDGET = exports.evaluatePoolBudget = exports.loadPoolBudget = exports.loadAppConfig = exports.APP_CONFIG = exports.assertPoolBudget = exports.BootSequence = exports.buildListScopeFn = exports.MariaDbSessionRestrictionStore = exports.SHIELD_SESSION_RESTRICTIONS = exports.SHIELD_PERMISSION_VERSION_CACHE = exports.DEFAULT_PERMISSION_VERSION_TTL_MS = exports.PERMISSION_VERSION_KEY_PREFIX = exports.RedisPermissionVersionCache = void 0;
|
|
22
|
+
exports.ScopeUnknownParentError = exports.ScopeDepthError = exports.ScopeCycleError = exports.buildClosureRows = exports.ConfirmEmailController = exports.AccountController = exports.generateRecoveryCodes = exports.buildOtpauthUri = exports.generateTotpSecret = exports.SHIELD_LOGIN_TOTP_VERIFIER = exports.SHIELD_MFA_STEP_UP = exports.SHIELD_MFA_LIMITER = exports.challengeMatches = exports.credentialFingerprint = exports.CredentialMfaStepUp = exports.RedisPendingMfaStore = exports.PendingMfaStore = exports.AuthController = exports.SHIELD_SCOPE_SUBTREE_RESOLVER = exports.SHIELD_SESSION_FACTS_PROJECTOR = exports.ProfileNameTakenError = exports.MariaDbEmailAddressChanger = exports.maskEmail = void 0;
|
|
23
23
|
// Framework authz migrations (shield_authz DDL — permission / role_permission /
|
|
24
24
|
// authz_permission_version). Absolute path a consumer's `@astram/migrate` setup merges in.
|
|
25
25
|
var migrations_dir_js_1 = require("./migrations-dir.js");
|
|
@@ -36,7 +36,11 @@ Object.defineProperty(exports, "buildIdentityModuleRegistry", { enumerable: true
|
|
|
36
36
|
var identity_actions_js_1 = require("./identity/identity-actions.js");
|
|
37
37
|
Object.defineProperty(exports, "MODULE_KEY", { enumerable: true, get: function () { return identity_actions_js_1.MODULE_KEY; } });
|
|
38
38
|
Object.defineProperty(exports, "IDENTITY_ACTIONS", { enumerable: true, get: function () { return identity_actions_js_1.IDENTITY_ACTIONS; } });
|
|
39
|
+
Object.defineProperty(exports, "CROSS_TENANT_GRANT_ACTIONS", { enumerable: true, get: function () { return identity_actions_js_1.CROSS_TENANT_GRANT_ACTIONS; } });
|
|
40
|
+
Object.defineProperty(exports, "RECORD_SHARE_ACTIONS", { enumerable: true, get: function () { return identity_actions_js_1.RECORD_SHARE_ACTIONS; } });
|
|
41
|
+
Object.defineProperty(exports, "SERVICE_ACCOUNT_ACTIONS", { enumerable: true, get: function () { return identity_actions_js_1.SERVICE_ACCOUNT_ACTIONS; } });
|
|
39
42
|
Object.defineProperty(exports, "actionsFor", { enumerable: true, get: function () { return identity_actions_js_1.actionsFor; } });
|
|
43
|
+
Object.defineProperty(exports, "actionsOf", { enumerable: true, get: function () { return identity_actions_js_1.actionsOf; } });
|
|
40
44
|
// The single registration seam.
|
|
41
45
|
var shield_module_js_1 = require("./module/shield.module.js");
|
|
42
46
|
Object.defineProperty(exports, "ShieldModule", { enumerable: true, get: function () { return shield_module_js_1.ShieldModule; } });
|
|
@@ -129,6 +133,32 @@ Object.defineProperty(exports, "LocalKekCrypto", { enumerable: true, get: functi
|
|
|
129
133
|
// real values are resolved at boot. Vault / AWS SM / GCP SM implement the same port.
|
|
130
134
|
var encrypted_file_secrets_js_1 = require("./secrets/encrypted-file-secrets.js");
|
|
131
135
|
Object.defineProperty(exports, "EncryptedFileSecretsProvider", { enumerable: true, get: function () { return encrypted_file_secrets_js_1.EncryptedFileSecretsProvider; } });
|
|
136
|
+
// Boot `secret-ref:` resolution (FILE_STORAGE SPEC §5 L-N): `resolveBootSecrets()` first in
|
|
137
|
+
// main.ts; the provider is built from `SECRETS_*`; the backstop aborts boot on a leftover reference.
|
|
138
|
+
var boot_secrets_js_1 = require("./secrets/boot-secrets.js");
|
|
139
|
+
Object.defineProperty(exports, "resolveBootSecrets", { enumerable: true, get: function () { return boot_secrets_js_1.resolveBootSecrets; } });
|
|
140
|
+
Object.defineProperty(exports, "createSecretsProviderFromEnv", { enumerable: true, get: function () { return boot_secrets_js_1.createSecretsProviderFromEnv; } });
|
|
141
|
+
Object.defineProperty(exports, "assertNoUnresolvedSecretRefs", { enumerable: true, get: function () { return boot_secrets_js_1.assertNoUnresolvedSecretRefs; } });
|
|
142
|
+
Object.defineProperty(exports, "wasResolvedFromSecretRef", { enumerable: true, get: function () { return boot_secrets_js_1.wasResolvedFromSecretRef; } });
|
|
143
|
+
// Object storage (FILE_STORAGE SPEC §5 E-H, §6): the SSE-S3 adapter, the node sha256 digest, the
|
|
144
|
+
// env loader, the boot check, the multipart intake interceptor and the two DI tokens
|
|
145
|
+
// (`ShieldModule.forRoot({ storage })` binds them).
|
|
146
|
+
var s3_object_store_js_1 = require("./storage/s3-object-store.js");
|
|
147
|
+
Object.defineProperty(exports, "S3ObjectStore", { enumerable: true, get: function () { return s3_object_store_js_1.S3ObjectStore; } });
|
|
148
|
+
var node_sha256_digest_js_1 = require("./storage/node-sha256-digest.js");
|
|
149
|
+
Object.defineProperty(exports, "NodeSha256Digest", { enumerable: true, get: function () { return node_sha256_digest_js_1.NodeSha256Digest; } });
|
|
150
|
+
var object_store_boot_check_js_1 = require("./storage/object-store-boot-check.js");
|
|
151
|
+
Object.defineProperty(exports, "ObjectStoreBootCheck", { enumerable: true, get: function () { return object_store_boot_check_js_1.ObjectStoreBootCheck; } });
|
|
152
|
+
var file_intake_interceptor_js_1 = require("./storage/file-intake.interceptor.js");
|
|
153
|
+
Object.defineProperty(exports, "FileIntake", { enumerable: true, get: function () { return file_intake_interceptor_js_1.FileIntake; } });
|
|
154
|
+
Object.defineProperty(exports, "FILE_INTAKE_REQUEST_KEY", { enumerable: true, get: function () { return file_intake_interceptor_js_1.FILE_INTAKE_REQUEST_KEY; } });
|
|
155
|
+
Object.defineProperty(exports, "FILE_INTAKE_DEFAULT_MAX_BYTES", { enumerable: true, get: function () { return file_intake_interceptor_js_1.FILE_INTAKE_DEFAULT_MAX_BYTES; } });
|
|
156
|
+
var shield_tokens_js_1 = require("./module/shield-tokens.js");
|
|
157
|
+
Object.defineProperty(exports, "SHIELD_OBJECT_STORE", { enumerable: true, get: function () { return shield_tokens_js_1.SHIELD_OBJECT_STORE; } });
|
|
158
|
+
Object.defineProperty(exports, "SHIELD_FILE_INGEST", { enumerable: true, get: function () { return shield_tokens_js_1.SHIELD_FILE_INGEST; } });
|
|
159
|
+
var app_config_js_1 = require("./config/app-config.js");
|
|
160
|
+
Object.defineProperty(exports, "loadObjectStorageConfig", { enumerable: true, get: function () { return app_config_js_1.loadObjectStorageConfig; } });
|
|
161
|
+
Object.defineProperty(exports, "DEFAULT_OBJECT_STORAGE_MAX_BYTES", { enumerable: true, get: function () { return app_config_js_1.DEFAULT_OBJECT_STORAGE_MAX_BYTES; } });
|
|
132
162
|
// The Session storage/crypto adapters (ADR-0003 / ADR-0013): the concrete durable
|
|
133
163
|
// (MariaDB) + hot (Redis) stores, the node:crypto token generator, the keyed HMAC
|
|
134
164
|
// refresh hasher, and the system clock — all implementing `@astram/core`'s Session
|
|
@@ -294,27 +324,32 @@ Object.defineProperty(exports, "assertPoolBudget", { enumerable: true, get: func
|
|
|
294
324
|
// the one seam can honor caller-supplied config.
|
|
295
325
|
var config_module_js_1 = require("./config/config.module.js");
|
|
296
326
|
Object.defineProperty(exports, "APP_CONFIG", { enumerable: true, get: function () { return config_module_js_1.APP_CONFIG; } });
|
|
297
|
-
var
|
|
298
|
-
Object.defineProperty(exports, "loadAppConfig", { enumerable: true, get: function () { return
|
|
299
|
-
Object.defineProperty(exports, "loadPoolBudget", { enumerable: true, get: function () { return
|
|
300
|
-
Object.defineProperty(exports, "evaluatePoolBudget", { enumerable: true, get: function () { return
|
|
301
|
-
Object.defineProperty(exports, "DEFAULT_POOL_BUDGET", { enumerable: true, get: function () { return
|
|
302
|
-
Object.defineProperty(exports, "SCHEMA_SVC_POOL_HARD_CAP", { enumerable: true, get: function () { return
|
|
327
|
+
var app_config_js_2 = require("./config/app-config.js");
|
|
328
|
+
Object.defineProperty(exports, "loadAppConfig", { enumerable: true, get: function () { return app_config_js_2.loadAppConfig; } });
|
|
329
|
+
Object.defineProperty(exports, "loadPoolBudget", { enumerable: true, get: function () { return app_config_js_2.loadPoolBudget; } });
|
|
330
|
+
Object.defineProperty(exports, "evaluatePoolBudget", { enumerable: true, get: function () { return app_config_js_2.evaluatePoolBudget; } });
|
|
331
|
+
Object.defineProperty(exports, "DEFAULT_POOL_BUDGET", { enumerable: true, get: function () { return app_config_js_2.DEFAULT_POOL_BUDGET; } });
|
|
332
|
+
Object.defineProperty(exports, "SCHEMA_SVC_POOL_HARD_CAP", { enumerable: true, get: function () { return app_config_js_2.SCHEMA_SVC_POOL_HARD_CAP; } });
|
|
303
333
|
// Phase 0b Auth-surface config (additive): the DB/Redis/lifetime loaders + the
|
|
304
334
|
// required-secret resolver/gate + the new config shapes.
|
|
305
|
-
Object.defineProperty(exports, "loadDbConfig", { enumerable: true, get: function () { return
|
|
306
|
-
Object.defineProperty(exports, "loadRedisConfig", { enumerable: true, get: function () { return
|
|
307
|
-
Object.defineProperty(exports, "loadSessionLifetimes", { enumerable: true, get: function () { return
|
|
308
|
-
Object.defineProperty(exports, "loadRefreshHmacKey", { enumerable: true, get: function () { return
|
|
309
|
-
Object.defineProperty(exports, "assertRefreshHmacKey", { enumerable: true, get: function () { return
|
|
310
|
-
Object.defineProperty(exports, "DEFAULT_DB_CONFIG", { enumerable: true, get: function () { return
|
|
311
|
-
Object.defineProperty(exports, "DEFAULT_REDIS_URL", { enumerable: true, get: function () { return
|
|
335
|
+
Object.defineProperty(exports, "loadDbConfig", { enumerable: true, get: function () { return app_config_js_2.loadDbConfig; } });
|
|
336
|
+
Object.defineProperty(exports, "loadRedisConfig", { enumerable: true, get: function () { return app_config_js_2.loadRedisConfig; } });
|
|
337
|
+
Object.defineProperty(exports, "loadSessionLifetimes", { enumerable: true, get: function () { return app_config_js_2.loadSessionLifetimes; } });
|
|
338
|
+
Object.defineProperty(exports, "loadRefreshHmacKey", { enumerable: true, get: function () { return app_config_js_2.loadRefreshHmacKey; } });
|
|
339
|
+
Object.defineProperty(exports, "assertRefreshHmacKey", { enumerable: true, get: function () { return app_config_js_2.assertRefreshHmacKey; } });
|
|
340
|
+
Object.defineProperty(exports, "DEFAULT_DB_CONFIG", { enumerable: true, get: function () { return app_config_js_2.DEFAULT_DB_CONFIG; } });
|
|
341
|
+
Object.defineProperty(exports, "DEFAULT_REDIS_URL", { enumerable: true, get: function () { return app_config_js_2.DEFAULT_REDIS_URL; } });
|
|
312
342
|
// Security hardening #5/#6 (additive): the per-IP login failure limit (D3) and the
|
|
313
343
|
// raw-NODE_ENV dev/test predicate that gates the dev email logger.
|
|
314
|
-
Object.defineProperty(exports, "loadLoginIpLimit", { enumerable: true, get: function () { return
|
|
315
|
-
Object.defineProperty(exports, "loadRefreshReplayWindowMs", { enumerable: true, get: function () { return
|
|
316
|
-
Object.defineProperty(exports, "DEFAULT_LOGIN_IP_LIMIT", { enumerable: true, get: function () { return
|
|
317
|
-
Object.defineProperty(exports, "isDevOrTestNodeEnv", { enumerable: true, get: function () { return
|
|
344
|
+
Object.defineProperty(exports, "loadLoginIpLimit", { enumerable: true, get: function () { return app_config_js_2.loadLoginIpLimit; } });
|
|
345
|
+
Object.defineProperty(exports, "loadRefreshReplayWindowMs", { enumerable: true, get: function () { return app_config_js_2.loadRefreshReplayWindowMs; } });
|
|
346
|
+
Object.defineProperty(exports, "DEFAULT_LOGIN_IP_LIMIT", { enumerable: true, get: function () { return app_config_js_2.DEFAULT_LOGIN_IP_LIMIT; } });
|
|
347
|
+
Object.defineProperty(exports, "isDevOrTestNodeEnv", { enumerable: true, get: function () { return app_config_js_2.isDevOrTestNodeEnv; } });
|
|
348
|
+
// Phase 16 (additive): TLS to MariaDB (APP_DB_TLS / APP_DB_TLS_CA).
|
|
349
|
+
Object.defineProperty(exports, "loadDbTlsConfig", { enumerable: true, get: function () { return app_config_js_2.loadDbTlsConfig; } });
|
|
350
|
+
// Phase 16: the driver `ssl` option every framework pool uses (identity's pools build on it).
|
|
351
|
+
var connections_js_1 = require("./auth/connections.js");
|
|
352
|
+
Object.defineProperty(exports, "mariadbSslOption", { enumerable: true, get: function () { return connections_js_1.mariadbSslOption; } });
|
|
318
353
|
// ---------------------------------------------------------------------------
|
|
319
354
|
// Phase 0b Auth surface (framework-owned login → session, spec §2/§3/§4).
|
|
320
355
|
//
|
|
@@ -29,4 +29,15 @@ export { SHIELD_DECISION_AUTHORITY } from '@astram/core';
|
|
|
29
29
|
* `ShieldModule.forRoot({ decisionAuthority })`. Two of them fail the boot.
|
|
30
30
|
*/
|
|
31
31
|
export declare const SHIELD_RECORD_AUTHORIZATION: unique symbol;
|
|
32
|
+
/**
|
|
33
|
+
* The app's `ObjectStore` (`@astram/core`; FILE_STORAGE SPEC §6), provided app-wide by
|
|
34
|
+
* `ShieldModule.forRoot({ storage })`: the given instance, an `S3ObjectStore` built from
|
|
35
|
+
* `OBJECT_STORAGE_*` (`'env'`), or `null` when storage is not configured (callers answer 501).
|
|
36
|
+
*/
|
|
37
|
+
export declare const SHIELD_OBJECT_STORE: unique symbol;
|
|
38
|
+
/**
|
|
39
|
+
* The pure file ingest check (`@astram/core` `createFileIngest` over `NodeSha256Digest`) that
|
|
40
|
+
* `FileIntake` runs after multipart parsing. Always provided by `ShieldModule`.
|
|
41
|
+
*/
|
|
42
|
+
export declare const SHIELD_FILE_INGEST: unique symbol;
|
|
32
43
|
//# sourceMappingURL=shield-tokens.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shield-tokens.d.ts","sourceRoot":"","sources":["../../src/module/shield-tokens.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;GAUG;AACH,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AAEzD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,2BAA2B,eAAwC,CAAC"}
|
|
1
|
+
{"version":3,"file":"shield-tokens.d.ts","sourceRoot":"","sources":["../../src/module/shield-tokens.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;GAUG;AACH,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AAEzD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,2BAA2B,eAAwC,CAAC;AAEjF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,eAAgC,CAAC;AAEjE;;;GAGG;AACH,eAAO,MAAM,kBAAkB,eAA+B,CAAC"}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* with no cycle. `shield.module.ts` re-exports these for the public barrel.
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.SHIELD_RECORD_AUTHORIZATION = exports.SHIELD_DECISION_AUTHORITY = void 0;
|
|
10
|
+
exports.SHIELD_FILE_INGEST = exports.SHIELD_OBJECT_STORE = exports.SHIELD_RECORD_AUTHORIZATION = exports.SHIELD_DECISION_AUTHORITY = void 0;
|
|
11
11
|
/**
|
|
12
12
|
* The Core decision authority (`@astram/core`'s `DecisionAuthority`) — the single
|
|
13
13
|
* ADR-0001 decision entry both the global enforcement guard and the engine's
|
|
@@ -33,3 +33,14 @@ Object.defineProperty(exports, "SHIELD_DECISION_AUTHORITY", { enumerable: true,
|
|
|
33
33
|
* `ShieldModule.forRoot({ decisionAuthority })`. Two of them fail the boot.
|
|
34
34
|
*/
|
|
35
35
|
exports.SHIELD_RECORD_AUTHORIZATION = Symbol('SHIELD_RECORD_AUTHORIZATION');
|
|
36
|
+
/**
|
|
37
|
+
* The app's `ObjectStore` (`@astram/core`; FILE_STORAGE SPEC §6), provided app-wide by
|
|
38
|
+
* `ShieldModule.forRoot({ storage })`: the given instance, an `S3ObjectStore` built from
|
|
39
|
+
* `OBJECT_STORAGE_*` (`'env'`), or `null` when storage is not configured (callers answer 501).
|
|
40
|
+
*/
|
|
41
|
+
exports.SHIELD_OBJECT_STORE = Symbol('SHIELD_OBJECT_STORE');
|
|
42
|
+
/**
|
|
43
|
+
* The pure file ingest check (`@astram/core` `createFileIngest` over `NodeSha256Digest`) that
|
|
44
|
+
* `FileIntake` runs after multipart parsing. Always provided by `ShieldModule`.
|
|
45
|
+
*/
|
|
46
|
+
exports.SHIELD_FILE_INGEST = Symbol('SHIELD_FILE_INGEST');
|
|
@@ -17,6 +17,7 @@ import type { CoreDecisionAuthority } from '../enforcement/core-seam.js';
|
|
|
17
17
|
import { type AppConfig } from '../config/app-config.js';
|
|
18
18
|
import { SHIELD_DECISION_AUTHORITY, SHIELD_RECORD_AUTHORIZATION } from './shield-tokens.js';
|
|
19
19
|
export { SHIELD_DECISION_AUTHORITY, SHIELD_RECORD_AUTHORIZATION };
|
|
20
|
+
import { type ShieldStorageOption } from '../storage/storage.providers.js';
|
|
20
21
|
export type { RecordAuthorizationInputs } from '../authz/wire-record-authorization.js';
|
|
21
22
|
/**
|
|
22
23
|
* Options for {@link ShieldModule.forRoot}. Intentionally minimal (ADR-0023 §7 —
|
|
@@ -196,6 +197,13 @@ export interface ShieldModuleOptions {
|
|
|
196
197
|
* loopback (`localhost`, `127.0.0.1`, `::1`, `0.0.0.0`), unless `emailSender: 'disabled'`.
|
|
197
198
|
*/
|
|
198
199
|
readonly emailChangeLinkBaseUrl?: string;
|
|
200
|
+
/**
|
|
201
|
+
* OPTIONAL object storage (FILE_STORAGE SPEC §6): an `ObjectStore` instance, or `'env'` to build
|
|
202
|
+
* an `S3ObjectStore` from `OBJECT_STORAGE_*` (`loadObjectStorageConfig`; storage stays off when
|
|
203
|
+
* `OBJECT_STORAGE_BUCKET` is unset). Bound under `SHIELD_OBJECT_STORE` (`null` when absent) and
|
|
204
|
+
* pinged at boot (fail closed). `SHIELD_FILE_INGEST` (used by `FileIntake`) is always bound.
|
|
205
|
+
*/
|
|
206
|
+
readonly storage?: ShieldStorageOption;
|
|
199
207
|
}
|
|
200
208
|
/** Async variant of {@link ShieldModuleOptions} (DI-computed config). */
|
|
201
209
|
export interface ShieldModuleAsyncOptions {
|
|
@@ -303,6 +311,8 @@ export interface ShieldModuleAsyncOptions {
|
|
|
303
311
|
readonly membershipChecker?: MembershipChecker;
|
|
304
312
|
/** See {@link ShieldModuleOptions.emailChangeLinkBaseUrl}. STATIC here (registration-time). */
|
|
305
313
|
readonly emailChangeLinkBaseUrl?: string;
|
|
314
|
+
/** See {@link ShieldModuleOptions.storage}. STATIC here (registration-time, like `auth`). */
|
|
315
|
+
readonly storage?: ShieldStorageOption;
|
|
306
316
|
}
|
|
307
317
|
/**
|
|
308
318
|
* `ShieldModule` — the SINGLE registration seam (ADR-0023 §4).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shield.module.d.ts","sourceRoot":"","sources":["../../src/module/shield.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,aAAa,EAAiB,MAAM,gBAAgB,CAAC;AAOnF,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAQvE,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,uCAAuC,CAAC;AACvF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAC3E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAC1E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AAC9E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AACvE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,0CAA0C,CAAC;AACtF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yCAAyC,CAAC;AACpF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AAC7E,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AAKzE,OAAO,EAAiB,KAAK,SAAS,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"shield.module.d.ts","sourceRoot":"","sources":["../../src/module/shield.module.ts"],"names":[],"mappings":"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"}
|
|
@@ -48,6 +48,7 @@ const enforcement_module_js_1 = require("../enforcement/enforcement.module.js");
|
|
|
48
48
|
const boot_module_js_1 = require("../boot/boot.module.js");
|
|
49
49
|
const config_module_js_1 = require("../config/config.module.js");
|
|
50
50
|
const app_config_js_1 = require("../config/app-config.js");
|
|
51
|
+
const boot_secrets_js_1 = require("../secrets/boot-secrets.js");
|
|
51
52
|
// Static import is SAFE: auth.module.ts top-level-imports @astram/core as TYPES
|
|
52
53
|
// only (it loads core's ESM factory VALUES lazily inside its async provider
|
|
53
54
|
// factories — see auth.module.ts loadCore()). So pulling AuthModule here does NOT
|
|
@@ -64,6 +65,8 @@ const tokens_js_1 = require("../auth/tokens.js");
|
|
|
64
65
|
const shield_tokens_js_1 = require("./shield-tokens.js");
|
|
65
66
|
Object.defineProperty(exports, "SHIELD_DECISION_AUTHORITY", { enumerable: true, get: function () { return shield_tokens_js_1.SHIELD_DECISION_AUTHORITY; } });
|
|
66
67
|
Object.defineProperty(exports, "SHIELD_RECORD_AUTHORIZATION", { enumerable: true, get: function () { return shield_tokens_js_1.SHIELD_RECORD_AUTHORIZATION; } });
|
|
68
|
+
// FILE_STORAGE SPEC §6: the `storage` option (S3 adapter loaded lazily inside the provider).
|
|
69
|
+
const storage_providers_js_1 = require("../storage/storage.providers.js");
|
|
67
70
|
/**
|
|
68
71
|
* A `Function`-wrapped dynamic `import()` that survives the CommonJS **build** — the same
|
|
69
72
|
* shim as auth.module.ts's `evalImport`. Under `module: commonjs`, `tsc` would rewrite a
|
|
@@ -165,6 +168,15 @@ const OPTIONAL_RECORD_AUTHORIZATION = {
|
|
|
165
168
|
token: shield_tokens_js_1.SHIELD_RECORD_AUTHORIZATION,
|
|
166
169
|
optional: true,
|
|
167
170
|
};
|
|
171
|
+
/**
|
|
172
|
+
* Config read straight from `process.env`: refuse to boot while a `secret-ref:` is still unresolved
|
|
173
|
+
* there. A caller-supplied `config` (e.g. from `loadAppConfigAsync`) is already resolved and is not
|
|
174
|
+
* re-checked against the raw env.
|
|
175
|
+
*/
|
|
176
|
+
function loadEnvAppConfig() {
|
|
177
|
+
(0, boot_secrets_js_1.assertNoUnresolvedSecretRefs)(process.env);
|
|
178
|
+
return (0, app_config_js_1.loadAppConfig)();
|
|
179
|
+
}
|
|
168
180
|
/**
|
|
169
181
|
* `ShieldModule` — the SINGLE registration seam (ADR-0023 §4).
|
|
170
182
|
*
|
|
@@ -192,7 +204,7 @@ const OPTIONAL_RECORD_AUTHORIZATION = {
|
|
|
192
204
|
let ShieldModule = ShieldModule_1 = class ShieldModule {
|
|
193
205
|
/** Register Shield with static options (the common path). */
|
|
194
206
|
static forRoot(options = {}) {
|
|
195
|
-
const config = options.config ?? (
|
|
207
|
+
const config = options.config ?? loadEnvAppConfig();
|
|
196
208
|
// ADR-0035: with auth on and no explicit projector, sessions cache the facts the framework-built
|
|
197
209
|
// authority decides on (attached when the authority is built; inactive until then).
|
|
198
210
|
const defaultProjector = defaultProjectorFor(options.auth, options.sessionFactsProjector);
|
|
@@ -274,11 +286,17 @@ let ShieldModule = ShieldModule_1 = class ShieldModule {
|
|
|
274
286
|
// Phase 9 #7: the record authorization a feature module provides (IdentityFeatureModule).
|
|
275
287
|
inject: [OPTIONAL_VERSION_CACHE, OPTIONAL_RECORD_AUTHORIZATION],
|
|
276
288
|
},
|
|
289
|
+
...(0, storage_providers_js_1.storageProviders)(options.storage),
|
|
277
290
|
],
|
|
278
291
|
// Re-export the composed AuthModule app-wide ONLY when auth is opted in — its
|
|
279
292
|
// own `exports` (SHIELD_AUTHENTICATOR / SHIELD_SESSION_AUTHORITY) then become
|
|
280
293
|
// visible to a consumer's controllers/services via the @Global seam.
|
|
281
|
-
exports: [
|
|
294
|
+
exports: [
|
|
295
|
+
config_module_js_1.APP_CONFIG,
|
|
296
|
+
shield_tokens_js_1.SHIELD_DECISION_AUTHORITY,
|
|
297
|
+
...storage_providers_js_1.STORAGE_EXPORTS,
|
|
298
|
+
...(authModule ? [authModule] : []),
|
|
299
|
+
],
|
|
282
300
|
};
|
|
283
301
|
}
|
|
284
302
|
/**
|
|
@@ -300,7 +318,9 @@ let ShieldModule = ShieldModule_1 = class ShieldModule {
|
|
|
300
318
|
};
|
|
301
319
|
const configProvider = {
|
|
302
320
|
provide: config_module_js_1.APP_CONFIG,
|
|
303
|
-
useFactory: (opts) =>
|
|
321
|
+
useFactory: (opts) => {
|
|
322
|
+
return opts.config ?? loadEnvAppConfig();
|
|
323
|
+
},
|
|
304
324
|
inject: [optionsToken],
|
|
305
325
|
};
|
|
306
326
|
// ADR-0035: the deferred default projector (auth on, no explicit projector), attached when the
|
|
@@ -375,8 +395,18 @@ let ShieldModule = ShieldModule_1 = class ShieldModule {
|
|
|
375
395
|
...(authModule ? [authModule] : []),
|
|
376
396
|
...(options.imports ?? []),
|
|
377
397
|
],
|
|
378
|
-
providers: [
|
|
379
|
-
|
|
398
|
+
providers: [
|
|
399
|
+
asyncOptionsProvider,
|
|
400
|
+
configProvider,
|
|
401
|
+
authorityProvider,
|
|
402
|
+
...(0, storage_providers_js_1.storageProviders)(options.storage),
|
|
403
|
+
],
|
|
404
|
+
exports: [
|
|
405
|
+
config_module_js_1.APP_CONFIG,
|
|
406
|
+
shield_tokens_js_1.SHIELD_DECISION_AUTHORITY,
|
|
407
|
+
...storage_providers_js_1.STORAGE_EXPORTS,
|
|
408
|
+
...(authModule ? [authModule] : []),
|
|
409
|
+
],
|
|
380
410
|
};
|
|
381
411
|
}
|
|
382
412
|
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { type SecretsProvider } from '@astram/core';
|
|
2
|
+
type EnvBag = Readonly<Record<string, string | undefined>>;
|
|
3
|
+
export interface ResolveBootSecretsOptions {
|
|
4
|
+
/** Use this provider instead of building one from the `SECRETS_*` variables. */
|
|
5
|
+
provider?: SecretsProvider;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Resolve every `secret-ref:` value in `process.env` in place. No references and no provider
|
|
9
|
+
* configured: no-op. Idempotent (a second call finds no references).
|
|
10
|
+
*/
|
|
11
|
+
export declare function resolveBootSecrets(options?: ResolveBootSecretsOptions): Promise<void>;
|
|
12
|
+
/**
|
|
13
|
+
* `true` when `key`'s CURRENT value in `env` (default `process.env`) is the value
|
|
14
|
+
* {@link resolveBootSecrets} resolved from a `secret-ref:` at boot (FILE_STORAGE SPEC §5 F:
|
|
15
|
+
* credentials outside development/test must be references, never literals). A value changed
|
|
16
|
+
* after resolution (e.g. a literal written over it) is `false`. No value is kept, only a keyed
|
|
17
|
+
* fingerprint.
|
|
18
|
+
*/
|
|
19
|
+
export declare function wasResolvedFromSecretRef(key: string, env?: EnvBag): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Build the {@link SecretsProvider} named by `SECRETS_PROVIDER`. Returns `undefined` for `none`
|
|
22
|
+
* or unset. Throws (naming the variable only) on an unknown value, `vault`, an unset, missing or
|
|
23
|
+
* unreadable file, a corrupt store, a KEK that is not 32 bytes, or a DEK that does not unwrap
|
|
24
|
+
* under the KEK.
|
|
25
|
+
*/
|
|
26
|
+
export declare function createSecretsProviderFromEnv(env: EnvBag): SecretsProvider | undefined;
|
|
27
|
+
/**
|
|
28
|
+
* Synchronous backstop: throws if any env value still starts with `secret-ref:` (the app did not
|
|
29
|
+
* call {@link resolveBootSecrets} before building modules). Lists env key names only.
|
|
30
|
+
*/
|
|
31
|
+
export declare function assertNoUnresolvedSecretRefs(env: EnvBag): void;
|
|
32
|
+
export {};
|
|
33
|
+
//# sourceMappingURL=boot-secrets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"boot-secrets.d.ts","sourceRoot":"","sources":["../../src/secrets/boot-secrets.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAkC,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAQpF,KAAK,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;AAE3D,MAAM,WAAW,yBAAyB;IACxC,gFAAgF;IAChF,QAAQ,CAAC,EAAE,eAAe,CAAC;CAC5B;AAOD;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,GAAE,yBAA8B,GAAG,OAAO,CAAC,IAAI,CAAC,CAmB/F;AAcD;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,GAAE,MAAoB,GAAG,OAAO,CAKxF;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS,CAqCrF;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAO9D"}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveBootSecrets = resolveBootSecrets;
|
|
4
|
+
exports.wasResolvedFromSecretRef = wasResolvedFromSecretRef;
|
|
5
|
+
exports.createSecretsProviderFromEnv = createSecretsProviderFromEnv;
|
|
6
|
+
exports.assertNoUnresolvedSecretRefs = assertNoUnresolvedSecretRefs;
|
|
7
|
+
/**
|
|
8
|
+
* Boot-time `secret-ref:` resolution (ADR-0032; FILE_STORAGE SPEC §5 L-N, §13).
|
|
9
|
+
*
|
|
10
|
+
* - {@link resolveBootSecrets}: called first in the app's `main.ts`, before `AppModule` is loaded,
|
|
11
|
+
* so every `forRoot` and direct env reader sees resolved values. Resolves every `secret-ref:` env
|
|
12
|
+
* value via core `resolveSecretRefs` and writes the results back into `process.env` for those
|
|
13
|
+
* keys only, and only once every reference has resolved (no partial write-back).
|
|
14
|
+
* - {@link createSecretsProviderFromEnv}: builds the configured {@link SecretsProvider} from the
|
|
15
|
+
* `SECRETS_*` variables (`none` | `encrypted-file`; `vault` reserved).
|
|
16
|
+
* - {@link assertNoUnresolvedSecretRefs}: synchronous backstop at every `loadAppConfig()` call site.
|
|
17
|
+
*
|
|
18
|
+
* SECURITY (Shield #1, #10): fail closed on every bad variable, file, key or reference. Errors name
|
|
19
|
+
* env variable names (and, for a failed resolution, the reference path); never a value, a key
|
|
20
|
+
* byte or file contents. Nothing is logged.
|
|
21
|
+
*/
|
|
22
|
+
const node_crypto_1 = require("node:crypto");
|
|
23
|
+
const node_fs_1 = require("node:fs");
|
|
24
|
+
const core_1 = require("@astram/core");
|
|
25
|
+
const local_kek_crypto_js_1 = require("../encryption/local-kek-crypto.js");
|
|
26
|
+
const encrypted_file_secrets_js_1 = require("./encrypted-file-secrets.js");
|
|
27
|
+
/** AEAD additional data the secrets DEK is wrapped under. */
|
|
28
|
+
const SECRETS_DEK_AAD = 'shield:secrets';
|
|
29
|
+
const KEK_BYTES = 32;
|
|
30
|
+
/** Env keys whose value is still a `secret-ref:` reference. */
|
|
31
|
+
function refKeys(env) {
|
|
32
|
+
return Object.keys(env).filter((k) => (0, core_1.isSecretRef)(env[k]));
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Resolve every `secret-ref:` value in `process.env` in place. No references and no provider
|
|
36
|
+
* configured: no-op. Idempotent (a second call finds no references).
|
|
37
|
+
*/
|
|
38
|
+
async function resolveBootSecrets(options = {}) {
|
|
39
|
+
const env = process.env;
|
|
40
|
+
const provider = options.provider ?? createSecretsProviderFromEnv(env);
|
|
41
|
+
const keys = refKeys(env);
|
|
42
|
+
if (keys.length === 0)
|
|
43
|
+
return;
|
|
44
|
+
if (!provider) {
|
|
45
|
+
throw new Error(`secret-ref: values are set but no secrets provider is configured ` +
|
|
46
|
+
`(SECRETS_PROVIDER is unset or 'none'); env keys: ${keys.join(', ')}`);
|
|
47
|
+
}
|
|
48
|
+
// Core resolves into a NEW bag and throws on the first failure (key + path, never a value),
|
|
49
|
+
// so process.env is only touched once every reference has resolved.
|
|
50
|
+
const resolved = await (0, core_1.resolveSecretRefs)(env, provider);
|
|
51
|
+
for (const key of keys) {
|
|
52
|
+
const value = resolved[key];
|
|
53
|
+
env[key] = value;
|
|
54
|
+
if (value !== undefined)
|
|
55
|
+
resolvedFromRef.set(key, fingerprint(value));
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Env key -> keyed fingerprint of the value {@link resolveBootSecrets} wrote for it. The value
|
|
60
|
+
* itself is never kept: an HMAC-SHA256 under a random per-process key (so the fingerprint cannot
|
|
61
|
+
* be checked against guesses outside this process).
|
|
62
|
+
*/
|
|
63
|
+
const resolvedFromRef = new Map();
|
|
64
|
+
const FINGERPRINT_KEY = (0, node_crypto_1.randomBytes)(32);
|
|
65
|
+
function fingerprint(value) {
|
|
66
|
+
return (0, node_crypto_1.createHmac)('sha256', FINGERPRINT_KEY).update(value, 'utf8').digest('hex');
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* `true` when `key`'s CURRENT value in `env` (default `process.env`) is the value
|
|
70
|
+
* {@link resolveBootSecrets} resolved from a `secret-ref:` at boot (FILE_STORAGE SPEC §5 F:
|
|
71
|
+
* credentials outside development/test must be references, never literals). A value changed
|
|
72
|
+
* after resolution (e.g. a literal written over it) is `false`. No value is kept, only a keyed
|
|
73
|
+
* fingerprint.
|
|
74
|
+
*/
|
|
75
|
+
function wasResolvedFromSecretRef(key, env = process.env) {
|
|
76
|
+
const recorded = resolvedFromRef.get(key);
|
|
77
|
+
const current = env[key];
|
|
78
|
+
if (recorded === undefined || typeof current !== 'string')
|
|
79
|
+
return false;
|
|
80
|
+
return (0, node_crypto_1.timingSafeEqual)(Buffer.from(recorded, 'hex'), Buffer.from(fingerprint(current), 'hex'));
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Build the {@link SecretsProvider} named by `SECRETS_PROVIDER`. Returns `undefined` for `none`
|
|
84
|
+
* or unset. Throws (naming the variable only) on an unknown value, `vault`, an unset, missing or
|
|
85
|
+
* unreadable file, a corrupt store, a KEK that is not 32 bytes, or a DEK that does not unwrap
|
|
86
|
+
* under the KEK.
|
|
87
|
+
*/
|
|
88
|
+
function createSecretsProviderFromEnv(env) {
|
|
89
|
+
const kind = (env.SECRETS_PROVIDER ?? '').trim();
|
|
90
|
+
if (kind === '' || kind === 'none')
|
|
91
|
+
return undefined;
|
|
92
|
+
if (kind === 'vault') {
|
|
93
|
+
throw new Error(`SECRETS_PROVIDER 'vault' is not supported yet (use 'none' or 'encrypted-file')`);
|
|
94
|
+
}
|
|
95
|
+
if (kind !== 'encrypted-file') {
|
|
96
|
+
throw new Error(`SECRETS_PROVIDER has an unknown value (expected 'none' or 'encrypted-file')`);
|
|
97
|
+
}
|
|
98
|
+
const storeFile = requirePath(env, 'SECRETS_FILE');
|
|
99
|
+
const kekFile = requirePath(env, 'SECRETS_KEK_FILE');
|
|
100
|
+
const dekFile = requirePath(env, 'SECRETS_DEK_FILE');
|
|
101
|
+
// SPEC §13: a missing, unreadable or corrupt store aborts boot naming SECRETS_FILE, even when
|
|
102
|
+
// no env value references it yet (a misconfigured provider is never silently empty).
|
|
103
|
+
checkStoreFile(storeFile);
|
|
104
|
+
const kek = readKeyFile(kekFile, 'SECRETS_KEK_FILE');
|
|
105
|
+
if (kek.length !== KEK_BYTES) {
|
|
106
|
+
throw new Error(`SECRETS_KEK_FILE must hold exactly ${KEK_BYTES} raw bytes`);
|
|
107
|
+
}
|
|
108
|
+
const crypto = new local_kek_crypto_js_1.LocalKekCrypto(new Uint8Array(kek));
|
|
109
|
+
kek.fill(0);
|
|
110
|
+
const wrapped = readKeyFile(dekFile, 'SECRETS_DEK_FILE');
|
|
111
|
+
let dek;
|
|
112
|
+
try {
|
|
113
|
+
dek = crypto.unwrapDekSync(new Uint8Array(wrapped), SECRETS_DEK_AAD);
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
throw new Error(`SECRETS_DEK_FILE could not be unwrapped with the key in SECRETS_KEK_FILE ` +
|
|
117
|
+
`(wrong KEK, wrong wrap context or a corrupt file)`);
|
|
118
|
+
}
|
|
119
|
+
return new encrypted_file_secrets_js_1.EncryptedFileSecretsProvider(storeFile, crypto, dek);
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Synchronous backstop: throws if any env value still starts with `secret-ref:` (the app did not
|
|
123
|
+
* call {@link resolveBootSecrets} before building modules). Lists env key names only.
|
|
124
|
+
*/
|
|
125
|
+
function assertNoUnresolvedSecretRefs(env) {
|
|
126
|
+
const keys = refKeys(env);
|
|
127
|
+
if (keys.length === 0)
|
|
128
|
+
return;
|
|
129
|
+
throw new Error(`unresolved secret references in env keys: ${keys.join(', ')}. ` +
|
|
130
|
+
`Call resolveBootSecrets() in main.ts before loading AppModule.`);
|
|
131
|
+
}
|
|
132
|
+
function requirePath(env, name) {
|
|
133
|
+
const value = env[name]?.trim();
|
|
134
|
+
if (!value)
|
|
135
|
+
throw new Error(`${name} must be set when SECRETS_PROVIDER is 'encrypted-file'`);
|
|
136
|
+
return value;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* The store must exist, be readable and hold a JSON object of `{ version, ciphertext }` entries
|
|
140
|
+
* (an empty file is an empty store). Errors name `SECRETS_FILE` and an errno code only, never
|
|
141
|
+
* the path's contents.
|
|
142
|
+
*/
|
|
143
|
+
function checkStoreFile(path) {
|
|
144
|
+
let raw;
|
|
145
|
+
try {
|
|
146
|
+
raw = (0, node_fs_1.readFileSync)(path, 'utf8');
|
|
147
|
+
}
|
|
148
|
+
catch (e) {
|
|
149
|
+
const code = e.code;
|
|
150
|
+
throw new Error(`SECRETS_FILE could not be read${code ? ` (${code})` : ''}`);
|
|
151
|
+
}
|
|
152
|
+
if (raw.trim() === '')
|
|
153
|
+
return;
|
|
154
|
+
let parsed;
|
|
155
|
+
try {
|
|
156
|
+
parsed = JSON.parse(raw);
|
|
157
|
+
}
|
|
158
|
+
catch {
|
|
159
|
+
parsed = undefined;
|
|
160
|
+
}
|
|
161
|
+
const isEntry = (v) => typeof v === 'object' &&
|
|
162
|
+
v !== null &&
|
|
163
|
+
Number.isInteger(v.version) &&
|
|
164
|
+
typeof v.ciphertext === 'string';
|
|
165
|
+
if (typeof parsed !== 'object' ||
|
|
166
|
+
parsed === null ||
|
|
167
|
+
Array.isArray(parsed) ||
|
|
168
|
+
!Object.values(parsed).every(isEntry)) {
|
|
169
|
+
throw new Error('SECRETS_FILE is not a valid secrets store (corrupt or wrong format)');
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
function readKeyFile(path, name) {
|
|
173
|
+
try {
|
|
174
|
+
return (0, node_fs_1.readFileSync)(path);
|
|
175
|
+
}
|
|
176
|
+
catch (e) {
|
|
177
|
+
const code = e.code;
|
|
178
|
+
throw new Error(`${name} could not be read${code ? ` (${code})` : ''}`);
|
|
179
|
+
}
|
|
180
|
+
}
|