@astram/guard 0.9.0 → 0.10.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/account.controller.d.ts +21 -13
- package/dist/auth/account.controller.d.ts.map +1 -1
- package/dist/auth/account.controller.js +91 -38
- package/dist/auth/auth.controller.d.ts +6 -5
- package/dist/auth/auth.controller.d.ts.map +1 -1
- package/dist/auth/auth.controller.js +127 -75
- package/dist/auth/auth.module.d.ts.map +1 -1
- package/dist/auth/auth.module.js +10 -7
- package/dist/auth/connections.d.ts.map +1 -1
- package/dist/auth/connections.js +3 -1
- package/dist/auth/rate-limit/attempt-limiter.d.ts +59 -1
- package/dist/auth/rate-limit/attempt-limiter.d.ts.map +1 -1
- package/dist/auth/rate-limit/attempt-limiter.js +85 -2
- package/dist/auth/tokens.d.ts +13 -10
- package/dist/auth/tokens.d.ts.map +1 -1
- package/dist/auth/tokens.js +13 -10
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -3
- package/dist/module/shield-tokens.d.ts +12 -0
- package/dist/module/shield-tokens.d.ts.map +1 -1
- package/dist/module/shield-tokens.js +13 -1
- package/dist/module/shield.module.d.ts +6 -2
- package/dist/module/shield.module.d.ts.map +1 -1
- package/dist/module/shield.module.js +40 -18
- package/package.json +3 -3
package/dist/auth/tokens.d.ts
CHANGED
|
@@ -216,9 +216,11 @@ export declare const SHIELD_MEMBERSHIP_CHECKER: unique symbol;
|
|
|
216
216
|
* typed hint (the DB collation decides which spellings are one account), else
|
|
217
217
|
* `login:<sha256(canonical hint)>` for an unknown hint — no PII in the key; see
|
|
218
218
|
* `rate-limit/canonical-hint.ts`. Default 10 failures / 15-min window.
|
|
219
|
-
*
|
|
220
|
-
*
|
|
221
|
-
*
|
|
219
|
+
* Phase 9 #10: every attempt is counted at the TOP of `POST /auth/login` (`consume`, atomic
|
|
220
|
+
* increment-first → generic 401 when over budget, 503 when Redis cannot answer); a rejected
|
|
221
|
+
* wrong-password stays counted, `authenticated` → `reset`, `mfa_required` or a transient
|
|
222
|
+
* outage → `refund` (a correct password that merely needs MFA is NOT a failure, nor a
|
|
223
|
+
* success until `/auth/mfa` completes). Shared with `POST /account/change-password`.
|
|
222
224
|
*/
|
|
223
225
|
export declare const SHIELD_LOGIN_LIMITER: unique symbol;
|
|
224
226
|
/**
|
|
@@ -227,8 +229,8 @@ export declare const SHIELD_LOGIN_LIMITER: unique symbol;
|
|
|
227
229
|
* `LOGIN_IP_MAX_FAILURES` / `LOGIN_IP_WINDOW_MS`, see `AppConfig.loginIpLimit`). Caps
|
|
228
230
|
* password spraying across MANY distinct hints from one client. Counts wrong-password
|
|
229
231
|
* FAILURES only and is NEVER reset by a success (an attacker's own valid login must not
|
|
230
|
-
* wipe the budget).
|
|
231
|
-
*
|
|
232
|
+
* wipe the budget; a non-failure gives its attempt back). Counted before the account lookup
|
|
233
|
+
* and the authenticator (Phase 9 #10); fails closed (503) on a Redis error. ENFORCED ONLY when the app set Express
|
|
232
234
|
* `trust proxy` explicitly (0 = no proxy, else the hop count): otherwise every client
|
|
233
235
|
* behind a proxy shares one `req.ip`, so the limiter is switched OFF at boot with a
|
|
234
236
|
* warning (`TrustProxyBootCheck`) rather than becoming a global login DoS.
|
|
@@ -237,16 +239,17 @@ export declare const SHIELD_LOGIN_IP_LIMITER: unique symbol;
|
|
|
237
239
|
/**
|
|
238
240
|
* The recovery-code {@link AttemptLimiter} (spec §5) — keyed `recovery:<principalId>`,
|
|
239
241
|
* default 5 failures / 15-min window (recovery codes are higher-value than a rotating
|
|
240
|
-
* 30-s TOTP). Consumed in the `/auth/mfa` recovery branch:
|
|
241
|
-
* (
|
|
242
|
-
* code, `reset` on success.
|
|
242
|
+
* 30-s TOTP). Consumed in the `/auth/mfa` recovery branch: the attempt is counted
|
|
243
|
+
* (`consume`, Phase 9 #10) BEFORE the store is consulted (over budget → generic 401;
|
|
244
|
+
* Redis error → 503), a wrong code stays counted, `reset` on success.
|
|
243
245
|
*/
|
|
244
246
|
export declare const SHIELD_RECOVERY_LIMITER: unique symbol;
|
|
245
247
|
/**
|
|
246
248
|
* The TOTP-step {@link AttemptLimiter} (security hardening #9) — keyed per account,
|
|
247
249
|
* `mfa:pid:<principalId>`, default 5 failures / 15-min window. Consumed in the `/auth/mfa`
|
|
248
|
-
* TOTP branch
|
|
249
|
-
*
|
|
250
|
+
* TOTP branch and the code-gated `/account/mfa/*` routes: the attempt is counted
|
|
251
|
+
* (`consume`, Phase 9 #10) BEFORE the factor is verified (over budget → generic 401 /
|
|
252
|
+
* 429; Redis error → 503), a rejected factor stays counted (the threshold edge audits
|
|
250
253
|
* `auth.mfa.locked` once), `reset` on success.
|
|
251
254
|
*/
|
|
252
255
|
export declare const SHIELD_MFA_LIMITER: unique symbol;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../../src/auth/tokens.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,+CAA+C,CAAC;AAEvF;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,eAA2B,CAAC;AAEvD;;;;GAIG;AACH,eAAO,MAAM,YAAY,eAAyB,CAAC;AAEnD;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B,eAAuC,CAAC;AAE/E;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,eAAoC,CAAC;AAEzE;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,eAAiC,CAAC;AAEnE;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB,eAAqC,CAAC;AAW3E;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB,eAAqC,CAAC;AAE3E;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,eAAqC,CAAC;AAE3E;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,eAAgC,CAAC;AAEjE;;;GAGG;AACH,eAAO,MAAM,0BAA0B,eAAuC,CAAC;AAE/E;;;GAGG;AACH,eAAO,MAAM,qBAAqB,eAAkC,CAAC;AAErE;;;;;;;;GAQG;AACH,eAAO,MAAM,iBAAiB,eAA8B,CAAC;AAE7D;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,eAAoC,CAAC;AAEzE;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,eAAmC,CAAC;AAEvE;;;;;;;GAOG;AACH,eAAO,MAAM,0BAA0B,eAAuC,CAAC;AAE/E;;;;;;;;;;GAUG;AACH,eAAO,MAAM,oBAAoB,eAAiC,CAAC;AAEnE;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,6BAA6B,eAA0C,CAAC;AAErF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,eAAe,eAA4B,CAAC;AAEzD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,8BAA8B,eAA2C,CAAC;AAEvF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,6BAA6B,eAA0C,CAAC;AAErF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,yBAAyB,eAAsC,CAAC;AAU7E
|
|
1
|
+
{"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../../src/auth/tokens.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,+CAA+C,CAAC;AAEvF;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,eAA2B,CAAC;AAEvD;;;;GAIG;AACH,eAAO,MAAM,YAAY,eAAyB,CAAC;AAEnD;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B,eAAuC,CAAC;AAE/E;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,eAAoC,CAAC;AAEzE;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,eAAiC,CAAC;AAEnE;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB,eAAqC,CAAC;AAW3E;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB,eAAqC,CAAC;AAE3E;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,eAAqC,CAAC;AAE3E;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,eAAgC,CAAC;AAEjE;;;GAGG;AACH,eAAO,MAAM,0BAA0B,eAAuC,CAAC;AAE/E;;;GAGG;AACH,eAAO,MAAM,qBAAqB,eAAkC,CAAC;AAErE;;;;;;;;GAQG;AACH,eAAO,MAAM,iBAAiB,eAA8B,CAAC;AAE7D;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,eAAoC,CAAC;AAEzE;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,eAAmC,CAAC;AAEvE;;;;;;;GAOG;AACH,eAAO,MAAM,0BAA0B,eAAuC,CAAC;AAE/E;;;;;;;;;;GAUG;AACH,eAAO,MAAM,oBAAoB,eAAiC,CAAC;AAEnE;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,6BAA6B,eAA0C,CAAC;AAErF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,eAAe,eAA4B,CAAC;AAEzD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,8BAA8B,eAA2C,CAAC;AAEvF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,6BAA6B,eAA0C,CAAC;AAErF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,yBAAyB,eAAsC,CAAC;AAU7E;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,oBAAoB,eAAiC,CAAC;AAEnE;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,uBAAuB,eAAoC,CAAC;AAEzE;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,eAAoC,CAAC;AAEzE;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,eAA+B,CAAC;AAE/D;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,eAA+B,CAAC;AAE/D;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B,eAAuC,CAAC;AAE/E;;;;;;;;;;GAUG;AACH,eAAO,MAAM,qBAAqB,eAAkC,CAAC;AAErE;;;;;;;;;GASG;AACH,eAAO,MAAM,0BAA0B,eAAuC,CAAC;AAE/E;;;;;;;;;;GAUG;AACH,eAAO,MAAM,oBAAoB,eAAiC,CAAC;AAEnE;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,eAAoC,CAAC;AAEzE;;;;;;;GAOG;AACH,eAAO,MAAM,+BAA+B,eAA4C,CAAC;AAEzF;;;;;;GAMG;AACH,eAAO,MAAM,2BAA2B,eAAwC,CAAC"}
|
package/dist/auth/tokens.js
CHANGED
|
@@ -235,9 +235,11 @@ exports.SHIELD_MEMBERSHIP_CHECKER = Symbol('SHIELD_MEMBERSHIP_CHECKER');
|
|
|
235
235
|
* typed hint (the DB collation decides which spellings are one account), else
|
|
236
236
|
* `login:<sha256(canonical hint)>` for an unknown hint — no PII in the key; see
|
|
237
237
|
* `rate-limit/canonical-hint.ts`. Default 10 failures / 15-min window.
|
|
238
|
-
*
|
|
239
|
-
*
|
|
240
|
-
*
|
|
238
|
+
* Phase 9 #10: every attempt is counted at the TOP of `POST /auth/login` (`consume`, atomic
|
|
239
|
+
* increment-first → generic 401 when over budget, 503 when Redis cannot answer); a rejected
|
|
240
|
+
* wrong-password stays counted, `authenticated` → `reset`, `mfa_required` or a transient
|
|
241
|
+
* outage → `refund` (a correct password that merely needs MFA is NOT a failure, nor a
|
|
242
|
+
* success until `/auth/mfa` completes). Shared with `POST /account/change-password`.
|
|
241
243
|
*/
|
|
242
244
|
exports.SHIELD_LOGIN_LIMITER = Symbol('SHIELD_LOGIN_LIMITER');
|
|
243
245
|
/**
|
|
@@ -246,8 +248,8 @@ exports.SHIELD_LOGIN_LIMITER = Symbol('SHIELD_LOGIN_LIMITER');
|
|
|
246
248
|
* `LOGIN_IP_MAX_FAILURES` / `LOGIN_IP_WINDOW_MS`, see `AppConfig.loginIpLimit`). Caps
|
|
247
249
|
* password spraying across MANY distinct hints from one client. Counts wrong-password
|
|
248
250
|
* FAILURES only and is NEVER reset by a success (an attacker's own valid login must not
|
|
249
|
-
* wipe the budget).
|
|
250
|
-
*
|
|
251
|
+
* wipe the budget; a non-failure gives its attempt back). Counted before the account lookup
|
|
252
|
+
* and the authenticator (Phase 9 #10); fails closed (503) on a Redis error. ENFORCED ONLY when the app set Express
|
|
251
253
|
* `trust proxy` explicitly (0 = no proxy, else the hop count): otherwise every client
|
|
252
254
|
* behind a proxy shares one `req.ip`, so the limiter is switched OFF at boot with a
|
|
253
255
|
* warning (`TrustProxyBootCheck`) rather than becoming a global login DoS.
|
|
@@ -256,16 +258,17 @@ exports.SHIELD_LOGIN_IP_LIMITER = Symbol('SHIELD_LOGIN_IP_LIMITER');
|
|
|
256
258
|
/**
|
|
257
259
|
* The recovery-code {@link AttemptLimiter} (spec §5) — keyed `recovery:<principalId>`,
|
|
258
260
|
* default 5 failures / 15-min window (recovery codes are higher-value than a rotating
|
|
259
|
-
* 30-s TOTP). Consumed in the `/auth/mfa` recovery branch:
|
|
260
|
-
* (
|
|
261
|
-
* code, `reset` on success.
|
|
261
|
+
* 30-s TOTP). Consumed in the `/auth/mfa` recovery branch: the attempt is counted
|
|
262
|
+
* (`consume`, Phase 9 #10) BEFORE the store is consulted (over budget → generic 401;
|
|
263
|
+
* Redis error → 503), a wrong code stays counted, `reset` on success.
|
|
262
264
|
*/
|
|
263
265
|
exports.SHIELD_RECOVERY_LIMITER = Symbol('SHIELD_RECOVERY_LIMITER');
|
|
264
266
|
/**
|
|
265
267
|
* The TOTP-step {@link AttemptLimiter} (security hardening #9) — keyed per account,
|
|
266
268
|
* `mfa:pid:<principalId>`, default 5 failures / 15-min window. Consumed in the `/auth/mfa`
|
|
267
|
-
* TOTP branch
|
|
268
|
-
*
|
|
269
|
+
* TOTP branch and the code-gated `/account/mfa/*` routes: the attempt is counted
|
|
270
|
+
* (`consume`, Phase 9 #10) BEFORE the factor is verified (over budget → generic 401 /
|
|
271
|
+
* 429; Redis error → 503), a rejected factor stays counted (the threshold edge audits
|
|
269
272
|
* `auth.mfa.locked` once), `reset` on success.
|
|
270
273
|
*/
|
|
271
274
|
exports.SHIELD_MFA_LIMITER = Symbol('SHIELD_MFA_LIMITER');
|
package/dist/index.d.ts
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
export { guardMigrationsDir } from './migrations-dir.js';
|
|
18
18
|
export { buildIdentityModuleRegistry } from './identity/module-registry.bridge.js';
|
|
19
19
|
export { MODULE_KEY, IDENTITY_ACTIONS, actionsFor } from './identity/identity-actions.js';
|
|
20
|
-
export { ShieldModule, SHIELD_DECISION_AUTHORITY, type ShieldModuleOptions, type ShieldModuleAsyncOptions, type RecordAuthorizationInputs, } from './module/shield.module.js';
|
|
20
|
+
export { ShieldModule, SHIELD_DECISION_AUTHORITY, SHIELD_RECORD_AUTHORIZATION, type ShieldModuleOptions, type ShieldModuleAsyncOptions, type RecordAuthorizationInputs, } from './module/shield.module.js';
|
|
21
21
|
export { Public, Classified, CLASSIFICATION_METADATA, DEFAULT_CLASSIFIED_ACTION, normalizeClassification, } from './enforcement/classification.decorator.js';
|
|
22
22
|
export type { Classification } from './enforcement/classification.decorator.js';
|
|
23
23
|
export { OperationInventoryScanner } from './completeness/operation-inventory-scanner.js';
|
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,EAAE,UAAU,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAG1F,OAAO,EACL,YAAY,EACZ,yBAAyB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -16,9 +16,9 @@
|
|
|
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.ScopeUnknownParentError = exports.ScopeDepthError = exports.ScopeCycleError = exports.buildClosureRows = 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.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_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.isDevOrTestNodeEnv = void 0;
|
|
19
|
+
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.SHIELD_HOT_SESSION_STORE = exports.RedisHotSessionStore = exports.SHIELD_SESSION_RECORD_STORE = exports.MariaDbSessionRecordStore = 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.normalizeClassification = exports.DEFAULT_CLASSIFIED_ACTION = exports.CLASSIFICATION_METADATA = exports.Classified = exports.Public = exports.SHIELD_RECORD_AUTHORIZATION = exports.SHIELD_DECISION_AUTHORITY = exports.ShieldModule = exports.actionsFor = exports.IDENTITY_ACTIONS = exports.MODULE_KEY = exports.buildIdentityModuleRegistry = exports.guardMigrationsDir = void 0;
|
|
20
|
+
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 = 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 = void 0;
|
|
21
|
+
exports.ScopeUnknownParentError = exports.ScopeDepthError = exports.ScopeCycleError = exports.buildClosureRows = 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.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_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.isDevOrTestNodeEnv = exports.DEFAULT_LOGIN_IP_LIMIT = void 0;
|
|
22
22
|
// Framework authz migrations (shield_authz DDL — permission / role_permission /
|
|
23
23
|
// authz_permission_version). Absolute path a consumer's `@astram/migrate` setup merges in.
|
|
24
24
|
var migrations_dir_js_1 = require("./migrations-dir.js");
|
|
@@ -40,6 +40,9 @@ Object.defineProperty(exports, "actionsFor", { enumerable: true, get: function (
|
|
|
40
40
|
var shield_module_js_1 = require("./module/shield.module.js");
|
|
41
41
|
Object.defineProperty(exports, "ShieldModule", { enumerable: true, get: function () { return shield_module_js_1.ShieldModule; } });
|
|
42
42
|
Object.defineProperty(exports, "SHIELD_DECISION_AUTHORITY", { enumerable: true, get: function () { return shield_module_js_1.SHIELD_DECISION_AUTHORITY; } });
|
|
43
|
+
// Phase 9 #7: the record-authorization inputs a feature module (IdentityFeatureModule)
|
|
44
|
+
// provides for ShieldModule to build the request-path authority from (one source).
|
|
45
|
+
Object.defineProperty(exports, "SHIELD_RECORD_AUTHORIZATION", { enumerable: true, get: function () { return shield_module_js_1.SHIELD_RECORD_AUTHORIZATION; } });
|
|
43
46
|
// Route classification (the consumer authors these on its controllers).
|
|
44
47
|
var classification_decorator_js_1 = require("./enforcement/classification.decorator.js");
|
|
45
48
|
Object.defineProperty(exports, "Public", { enumerable: true, get: function () { return classification_decorator_js_1.Public; } });
|
|
@@ -17,4 +17,16 @@
|
|
|
17
17
|
* now import the ONE symbol from core, so it stays a single DI identity across the app.
|
|
18
18
|
*/
|
|
19
19
|
export { SHIELD_DECISION_AUTHORITY } from '@astram/core';
|
|
20
|
+
/**
|
|
21
|
+
* The record-authorization inputs (`RecordAuthorizationInputs`: pool + app ports + registry) that
|
|
22
|
+
* a FEATURE module provides app-wide for `ShieldModule` to build the request-path decision
|
|
23
|
+
* authority from (security hardening Phase 9 #7). `@astram/identity`'s `IdentityFeatureModule`
|
|
24
|
+
* provides it, built from the same `extraObjects` as its own authorities, so the request path and
|
|
25
|
+
* the identity module can never judge with different registries. Guard never imports identity:
|
|
26
|
+
* this token is the seam.
|
|
27
|
+
*
|
|
28
|
+
* Exactly one source per app: this token, `ShieldModule.forRoot({ recordAuthorization })` or
|
|
29
|
+
* `ShieldModule.forRoot({ decisionAuthority })`. Two of them fail the boot.
|
|
30
|
+
*/
|
|
31
|
+
export declare const SHIELD_RECORD_AUTHORIZATION: unique symbol;
|
|
20
32
|
//# 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"}
|
|
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"}
|
|
@@ -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_DECISION_AUTHORITY = void 0;
|
|
10
|
+
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
|
|
@@ -21,3 +21,15 @@ exports.SHIELD_DECISION_AUTHORITY = void 0;
|
|
|
21
21
|
*/
|
|
22
22
|
var core_1 = require("@astram/core");
|
|
23
23
|
Object.defineProperty(exports, "SHIELD_DECISION_AUTHORITY", { enumerable: true, get: function () { return core_1.SHIELD_DECISION_AUTHORITY; } });
|
|
24
|
+
/**
|
|
25
|
+
* The record-authorization inputs (`RecordAuthorizationInputs`: pool + app ports + registry) that
|
|
26
|
+
* a FEATURE module provides app-wide for `ShieldModule` to build the request-path decision
|
|
27
|
+
* authority from (security hardening Phase 9 #7). `@astram/identity`'s `IdentityFeatureModule`
|
|
28
|
+
* provides it, built from the same `extraObjects` as its own authorities, so the request path and
|
|
29
|
+
* the identity module can never judge with different registries. Guard never imports identity:
|
|
30
|
+
* this token is the seam.
|
|
31
|
+
*
|
|
32
|
+
* Exactly one source per app: this token, `ShieldModule.forRoot({ recordAuthorization })` or
|
|
33
|
+
* `ShieldModule.forRoot({ decisionAuthority })`. Two of them fail the boot.
|
|
34
|
+
*/
|
|
35
|
+
exports.SHIELD_RECORD_AUTHORIZATION = Symbol('SHIELD_RECORD_AUTHORIZATION');
|
|
@@ -15,8 +15,8 @@ import type { ScopeSubtreeResolver } from '../auth/ports/scope-subtree-resolver.
|
|
|
15
15
|
import type { MembershipChecker } from '../auth/ports/membership-checker.js';
|
|
16
16
|
import type { CoreDecisionAuthority } from '../enforcement/core-seam.js';
|
|
17
17
|
import { type AppConfig } from '../config/app-config.js';
|
|
18
|
-
import { SHIELD_DECISION_AUTHORITY } from './shield-tokens.js';
|
|
19
|
-
export { SHIELD_DECISION_AUTHORITY };
|
|
18
|
+
import { SHIELD_DECISION_AUTHORITY, SHIELD_RECORD_AUTHORIZATION } from './shield-tokens.js';
|
|
19
|
+
export { SHIELD_DECISION_AUTHORITY, SHIELD_RECORD_AUTHORIZATION };
|
|
20
20
|
export type { RecordAuthorizationInputs } from '../authz/wire-record-authorization.js';
|
|
21
21
|
/**
|
|
22
22
|
* Options for {@link ShieldModule.forRoot}. Intentionally minimal (ADR-0023 §7 —
|
|
@@ -49,6 +49,10 @@ export interface ShieldModuleOptions {
|
|
|
49
49
|
*
|
|
50
50
|
* MUTUALLY EXCLUSIVE with {@link decisionAuthority} — supplying BOTH is a misconfig and
|
|
51
51
|
* throws at registration. Supplying NEITHER binds the fail-closed stub (unchanged).
|
|
52
|
+
*
|
|
53
|
+
* An app that imports `IdentityFeatureModule` (`@astram/identity` ≥ 0.7) passes NEITHER: the
|
|
54
|
+
* identity module provides the inputs under {@link SHIELD_RECORD_AUTHORIZATION} (Phase 9 #7),
|
|
55
|
+
* and this option next to it fails the boot (one source of `extraObjects`).
|
|
52
56
|
*/
|
|
53
57
|
readonly recordAuthorization?: RecordAuthorizationInputs;
|
|
54
58
|
/**
|
|
@@ -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;AAgBxE,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"shield.module.d.ts","sourceRoot":"","sources":["../../src/module/shield.module.ts"],"names":[],"mappings":"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"}
|
|
@@ -40,7 +40,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
40
40
|
})();
|
|
41
41
|
var ShieldModule_1;
|
|
42
42
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
|
-
exports.ShieldModule = exports.SHIELD_DECISION_AUTHORITY = void 0;
|
|
43
|
+
exports.ShieldModule = exports.SHIELD_RECORD_AUTHORIZATION = exports.SHIELD_DECISION_AUTHORITY = void 0;
|
|
44
44
|
const common_1 = require("@nestjs/common");
|
|
45
45
|
const node_url_1 = require("node:url");
|
|
46
46
|
const core_seam_js_1 = require("../enforcement/core-seam.js");
|
|
@@ -63,6 +63,7 @@ const tokens_js_1 = require("../auth/tokens.js");
|
|
|
63
63
|
// EnforcementModule → guard). Re-exported here to keep the public import path stable.
|
|
64
64
|
const shield_tokens_js_1 = require("./shield-tokens.js");
|
|
65
65
|
Object.defineProperty(exports, "SHIELD_DECISION_AUTHORITY", { enumerable: true, get: function () { return shield_tokens_js_1.SHIELD_DECISION_AUTHORITY; } });
|
|
66
|
+
Object.defineProperty(exports, "SHIELD_RECORD_AUTHORIZATION", { enumerable: true, get: function () { return shield_tokens_js_1.SHIELD_RECORD_AUTHORIZATION; } });
|
|
66
67
|
/**
|
|
67
68
|
* A `Function`-wrapped dynamic `import()` that survives the CommonJS **build** — the same
|
|
68
69
|
* shim as auth.module.ts's `evalImport`. Under `module: commonjs`, `tsc` would rewrite a
|
|
@@ -105,33 +106,45 @@ async function loadBuildRecordAuthorization() {
|
|
|
105
106
|
}
|
|
106
107
|
/**
|
|
107
108
|
* Resolve the `SHIELD_DECISION_AUTHORITY` VALUE from the caller's options (the ONE seam,
|
|
108
|
-
* ADR-0023 — only how its value is PRODUCED changes here).
|
|
109
|
+
* ADR-0023 — only how its value is PRODUCED changes here). Exactly ONE source, else boot fails:
|
|
109
110
|
*
|
|
110
|
-
* -
|
|
111
|
-
*
|
|
112
|
-
* Phase
|
|
111
|
+
* - {@link SHIELD_RECORD_AUTHORIZATION} PROVIDED (by a feature module — `IdentityFeatureModule`
|
|
112
|
+
* from `@astram/identity`, built from its own `extraObjects`) → the framework builds the REAL
|
|
113
|
+
* wired authority from those inputs (Phase 9 #7: one registry for the request path and the
|
|
114
|
+
* identity module's own authorities).
|
|
115
|
+
* - `recordAuthorization` PRESENT → the same, from inputs the app passes (an app without the
|
|
116
|
+
* identity module). The four record-tier adapters are constructed inside guard either way,
|
|
117
|
+
* un-overridable.
|
|
113
118
|
* - `decisionAuthority` PRESENT (legacy passthrough) → bind the caller's pre-built
|
|
114
119
|
* authority verbatim (kept for other consumers / back-compat).
|
|
115
|
-
* -
|
|
116
|
-
* -
|
|
120
|
+
* - MORE THAN ONE → MISCONFIG: throw a clear error (two sources could disagree).
|
|
121
|
+
* - NONE → the fail-closed {@link stubDecisionAuthority} (enforcement-only apps).
|
|
117
122
|
*
|
|
118
|
-
* Async because the
|
|
123
|
+
* Async because the record-authorization path lazy-loads the (core-touching) builder.
|
|
119
124
|
*/
|
|
120
125
|
async function resolveDecisionAuthority(options, extras = {}) {
|
|
126
|
+
const provided = extras.providedRecordAuthorization ?? undefined;
|
|
127
|
+
if (provided && (options.recordAuthorization || options.decisionAuthority)) {
|
|
128
|
+
throw new Error('ShieldModule: a record authorization is already provided under SHIELD_RECORD_AUTHORIZATION ' +
|
|
129
|
+
'(IdentityFeatureModule.forRoot builds it from its own extraObjects), so ShieldModule.forRoot ' +
|
|
130
|
+
'must not also receive `recordAuthorization` or `decisionAuthority`. Remove that option ' +
|
|
131
|
+
'(since @astram/identity 0.7 the identity module is the one source).');
|
|
132
|
+
}
|
|
121
133
|
if (options.recordAuthorization && options.decisionAuthority) {
|
|
122
134
|
throw new Error('ShieldModule: `recordAuthorization` and `decisionAuthority` are mutually exclusive — ' +
|
|
123
135
|
'supply the record-authorization inputs (pool + app ports + registry) so the framework ' +
|
|
124
136
|
'builds the decision authority, OR a pre-built `decisionAuthority`, but not both.');
|
|
125
137
|
}
|
|
126
|
-
|
|
138
|
+
const recordAuthorization = provided ?? options.recordAuthorization;
|
|
139
|
+
if (recordAuthorization) {
|
|
127
140
|
const api = await loadBuildRecordAuthorization();
|
|
128
141
|
const versionCache = extras.versionCache ?? undefined;
|
|
129
142
|
// ADR-0035 default projector: cache the SAME facts the authority decides on (version-cache
|
|
130
143
|
// wrapped, so a login projection also warms the Redis version).
|
|
131
144
|
extras.defaultProjector?.attach(versionCache !== undefined
|
|
132
|
-
? api.withRedisPermissionVersion(
|
|
133
|
-
:
|
|
134
|
-
return api.buildRecordAuthorization(
|
|
145
|
+
? api.withRedisPermissionVersion(recordAuthorization.permissionFacts, versionCache)
|
|
146
|
+
: recordAuthorization.permissionFacts);
|
|
147
|
+
return api.buildRecordAuthorization(recordAuthorization, versionCache !== undefined ? { versionCache } : {});
|
|
135
148
|
}
|
|
136
149
|
return options.decisionAuthority ?? core_seam_js_1.stubDecisionAuthority;
|
|
137
150
|
}
|
|
@@ -144,6 +157,14 @@ function defaultProjectorFor(auth, explicit) {
|
|
|
144
157
|
}
|
|
145
158
|
/** Inject the Redis version cache when AuthModule provides it (`auth: true`); absent otherwise. */
|
|
146
159
|
const OPTIONAL_VERSION_CACHE = { token: tokens_js_1.SHIELD_PERMISSION_VERSION_CACHE, optional: true };
|
|
160
|
+
/**
|
|
161
|
+
* Phase 9 #7: the record-authorization inputs a feature module provides app-wide (global), e.g.
|
|
162
|
+
* `IdentityFeatureModule`. Optional: an enforcement-only app provides none.
|
|
163
|
+
*/
|
|
164
|
+
const OPTIONAL_RECORD_AUTHORIZATION = {
|
|
165
|
+
token: shield_tokens_js_1.SHIELD_RECORD_AUTHORIZATION,
|
|
166
|
+
optional: true,
|
|
167
|
+
};
|
|
147
168
|
/**
|
|
148
169
|
* `ShieldModule` — the SINGLE registration seam (ADR-0023 §4).
|
|
149
170
|
*
|
|
@@ -238,16 +259,17 @@ let ShieldModule = ShieldModule_1 = class ShieldModule {
|
|
|
238
259
|
// stub paths resolve synchronously but flow through the same one seam. Both
|
|
239
260
|
// supplied → throws (mutual exclusion).
|
|
240
261
|
provide: shield_tokens_js_1.SHIELD_DECISION_AUTHORITY,
|
|
241
|
-
useFactory: (versionCache) => resolveDecisionAuthority({
|
|
262
|
+
useFactory: (versionCache, providedRecordAuthorization) => resolveDecisionAuthority({
|
|
242
263
|
...(options.recordAuthorization
|
|
243
264
|
? { recordAuthorization: options.recordAuthorization }
|
|
244
265
|
: {}),
|
|
245
266
|
...(options.decisionAuthority
|
|
246
267
|
? { decisionAuthority: options.decisionAuthority }
|
|
247
268
|
: {}),
|
|
248
|
-
}, { versionCache, defaultProjector }),
|
|
269
|
+
}, { versionCache, defaultProjector, providedRecordAuthorization }),
|
|
249
270
|
// ADR-0035: the Redis version cache AuthModule provides under `auth: true`.
|
|
250
|
-
|
|
271
|
+
// Phase 9 #7: the record authorization a feature module provides (IdentityFeatureModule).
|
|
272
|
+
inject: [OPTIONAL_VERSION_CACHE, OPTIONAL_RECORD_AUTHORIZATION],
|
|
251
273
|
},
|
|
252
274
|
],
|
|
253
275
|
// Re-export the composed AuthModule app-wide ONLY when auth is opted in — its
|
|
@@ -289,11 +311,11 @@ let ShieldModule = ShieldModule_1 = class ShieldModule {
|
|
|
289
311
|
// in its useFactory from the injected registrations) has the framework build the
|
|
290
312
|
// real wired authority; `decisionAuthority` is the legacy passthrough; both →
|
|
291
313
|
// throws; neither → stub. Async because the record path lazy-loads the builder.
|
|
292
|
-
useFactory: (opts, versionCache) => resolveDecisionAuthority({
|
|
314
|
+
useFactory: (opts, versionCache, providedRecordAuthorization) => resolveDecisionAuthority({
|
|
293
315
|
...(opts.recordAuthorization ? { recordAuthorization: opts.recordAuthorization } : {}),
|
|
294
316
|
...(opts.decisionAuthority ? { decisionAuthority: opts.decisionAuthority } : {}),
|
|
295
|
-
}, { versionCache, defaultProjector }),
|
|
296
|
-
inject: [optionsToken, OPTIONAL_VERSION_CACHE],
|
|
317
|
+
}, { versionCache, defaultProjector, providedRecordAuthorization }),
|
|
318
|
+
inject: [optionsToken, OPTIONAL_VERSION_CACHE, OPTIONAL_RECORD_AUTHORIZATION],
|
|
297
319
|
};
|
|
298
320
|
// Same one-instance opt-in AuthModule as forRoot (imported + re-exported).
|
|
299
321
|
// `credentialResolver` is STATIC on the async options (like `auth`) — a
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astram/guard",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Astram framework — the enforcement guard + real-world adapters (the 'hands'). One global deny-by-default gate every request passes through (ADR-0002), classification decorators, boot-pool assertion (ADR-0018), the forRoot() registration seam, and the DB/Redis/crypto adapters that connect the sealed core to a real backend. Depends on @astram/core (ADR-0003, ADR-0023).",
|
|
6
6
|
"type": "commonjs",
|
|
@@ -34,9 +34,9 @@
|
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"argon2": "^0.41.1",
|
|
36
36
|
"ioredis": "^5.4.1",
|
|
37
|
-
"mariadb": "^3.4
|
|
37
|
+
"mariadb": "^3.5.4",
|
|
38
38
|
"@astram/core": "1.4.0",
|
|
39
|
-
"@astram/engine": "0.5.
|
|
39
|
+
"@astram/engine": "0.5.1"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
42
|
"@nestjs/common": "^11",
|