@lastshotlabs/bunshot 0.0.25 → 0.0.28
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/.oclif.manifest.json +39 -0
- package/README.md +8282 -2147
- package/dist/cli/commands/init.js +690 -0
- package/dist/cli/index.js +6 -0
- package/dist/cli.js +4 -4
- package/dist/packages/bunshot-admin/src/index.d.ts +15 -0
- package/dist/packages/bunshot-admin/src/index.js +11 -0
- package/dist/packages/bunshot-admin/src/lib/resourceTypes.d.ts +8 -0
- package/dist/packages/bunshot-admin/src/lib/resourceTypes.js +33 -0
- package/dist/packages/bunshot-admin/src/lib/typedRoute.d.ts +14 -0
- package/dist/packages/bunshot-admin/src/lib/typedRoute.js +17 -0
- package/dist/packages/bunshot-admin/src/plugin.d.ts +4 -0
- package/dist/packages/bunshot-admin/src/plugin.js +46 -0
- package/dist/packages/bunshot-admin/src/providers/auth0Access.d.ts +6 -0
- package/dist/packages/bunshot-admin/src/providers/auth0Access.js +32 -0
- package/dist/packages/bunshot-admin/src/routes/admin.d.ts +10 -0
- package/dist/packages/bunshot-admin/src/routes/admin.js +923 -0
- package/dist/packages/bunshot-admin/src/routes/mail.d.ts +6 -0
- package/dist/packages/bunshot-admin/src/routes/mail.js +114 -0
- package/dist/packages/bunshot-admin/src/routes/permissions.d.ts +8 -0
- package/dist/packages/bunshot-admin/src/routes/permissions.js +315 -0
- package/dist/packages/bunshot-admin/src/types/config.d.ts +16 -0
- package/dist/packages/bunshot-admin/src/types/config.js +37 -0
- package/dist/packages/bunshot-admin/src/types/env.d.ts +14 -0
- package/dist/packages/bunshot-admin/src/types/provider.d.ts +1 -0
- package/dist/packages/bunshot-admin/src/types/provider.js +4 -0
- package/dist/packages/bunshot-auth/src/adapters/memoryAuth.d.ts +66 -0
- package/dist/packages/bunshot-auth/src/adapters/memoryAuth.js +1063 -0
- package/dist/packages/bunshot-auth/src/adapters/mongoAuth.d.ts +2 -0
- package/dist/packages/bunshot-auth/src/adapters/mongoAuth.js +536 -0
- package/dist/packages/bunshot-auth/src/adapters/sqliteAuth.d.ts +88 -0
- package/dist/packages/bunshot-auth/src/adapters/sqliteAuth.js +1366 -0
- package/dist/packages/bunshot-auth/src/admin/bunshotAccess.d.ts +2 -0
- package/dist/packages/bunshot-auth/src/admin/bunshotAccess.js +23 -0
- package/dist/packages/bunshot-auth/src/admin/bunshotUsers.d.ts +5 -0
- package/dist/packages/bunshot-auth/src/admin/bunshotUsers.js +131 -0
- package/dist/packages/bunshot-auth/src/bootstrap.d.ts +38 -0
- package/dist/packages/bunshot-auth/src/bootstrap.js +384 -0
- package/dist/packages/bunshot-auth/src/config/appConfig.d.ts +3 -0
- package/dist/packages/bunshot-auth/src/config/appConfig.js +4 -0
- package/dist/packages/bunshot-auth/src/config/authConfig.d.ts +478 -0
- package/dist/packages/bunshot-auth/src/config/authConfig.js +46 -0
- package/dist/packages/bunshot-auth/src/config/configLock.d.ts +2 -0
- package/dist/packages/bunshot-auth/src/config/configLock.js +10 -0
- package/dist/packages/bunshot-auth/src/index.d.ts +25 -0
- package/dist/packages/bunshot-auth/src/index.js +23 -0
- package/dist/packages/bunshot-auth/src/infra/mongo.d.ts +15 -0
- package/dist/packages/bunshot-auth/src/infra/mongo.js +44 -0
- package/dist/packages/bunshot-auth/src/infra/queue.d.ts +14 -0
- package/dist/packages/bunshot-auth/src/infra/queue.js +27 -0
- package/dist/packages/bunshot-auth/src/infra/redis.d.ts +5 -0
- package/dist/packages/bunshot-auth/src/infra/redis.js +15 -0
- package/dist/packages/bunshot-auth/src/infra/signing.d.ts +7 -0
- package/dist/packages/bunshot-auth/src/infra/signing.js +8 -0
- package/dist/packages/bunshot-auth/src/lib/accountLockout.d.ts +34 -0
- package/dist/packages/bunshot-auth/src/lib/accountLockout.js +244 -0
- package/dist/packages/bunshot-auth/src/lib/adapterTiers.d.ts +1 -0
- package/dist/packages/bunshot-auth/src/lib/adapterTiers.js +1 -0
- package/dist/packages/bunshot-auth/src/lib/authAdapter.d.ts +1 -0
- package/dist/packages/bunshot-auth/src/lib/authAdapter.js +1 -0
- package/dist/packages/bunshot-auth/src/lib/authContext.d.ts +15 -0
- package/dist/packages/bunshot-auth/src/lib/authContext.js +1 -0
- package/dist/packages/bunshot-auth/src/lib/authEventBus.d.ts +4 -0
- package/dist/packages/bunshot-auth/src/lib/authEventBus.js +15 -0
- package/dist/packages/bunshot-auth/src/lib/authRateLimit.d.ts +28 -0
- package/dist/packages/bunshot-auth/src/lib/authRateLimit.js +205 -0
- package/dist/packages/bunshot-auth/src/lib/breachedPassword.d.ts +19 -0
- package/dist/packages/bunshot-auth/src/lib/breachedPassword.js +61 -0
- package/dist/packages/bunshot-auth/src/lib/cache.d.ts +12 -0
- package/dist/packages/bunshot-auth/src/lib/cache.js +120 -0
- package/dist/packages/bunshot-auth/src/lib/clientIp.d.ts +4 -0
- package/dist/{lib → packages/bunshot-auth/src/lib}/clientIp.js +14 -7
- package/dist/packages/bunshot-auth/src/lib/cookieOptions.d.ts +27 -0
- package/dist/packages/bunshot-auth/src/lib/cookieOptions.js +33 -0
- package/dist/packages/bunshot-auth/src/lib/credentialStuffing.d.ts +40 -0
- package/dist/packages/bunshot-auth/src/lib/credentialStuffing.js +221 -0
- package/dist/packages/bunshot-auth/src/lib/deletionCancelToken.d.ts +19 -0
- package/dist/packages/bunshot-auth/src/lib/deletionCancelToken.js +148 -0
- package/dist/packages/bunshot-auth/src/lib/emailTemplates.d.ts +23 -0
- package/dist/packages/bunshot-auth/src/lib/emailTemplates.js +265 -0
- package/dist/packages/bunshot-auth/src/lib/emailVerification.d.ts +30 -0
- package/dist/packages/bunshot-auth/src/lib/emailVerification.js +200 -0
- package/dist/packages/bunshot-auth/src/lib/env.d.ts +1 -0
- package/dist/packages/bunshot-auth/src/lib/env.js +3 -0
- package/dist/packages/bunshot-auth/src/lib/fingerprint.js +36 -0
- package/dist/{lib → packages/bunshot-auth/src/lib}/groups.d.ts +15 -16
- package/dist/{lib → packages/bunshot-auth/src/lib}/groups.js +22 -34
- package/dist/packages/bunshot-auth/src/lib/jwks.d.ts +28 -0
- package/dist/packages/bunshot-auth/src/lib/jwks.js +79 -0
- package/dist/packages/bunshot-auth/src/lib/jwt.d.ts +12 -0
- package/dist/packages/bunshot-auth/src/lib/jwt.js +86 -0
- package/dist/packages/bunshot-auth/src/lib/logger.d.ts +3 -0
- package/dist/packages/bunshot-auth/src/lib/logger.js +13 -0
- package/dist/packages/bunshot-auth/src/lib/m2m.d.ts +30 -0
- package/dist/packages/bunshot-auth/src/lib/m2m.js +44 -0
- package/dist/packages/bunshot-auth/src/lib/magicLink.d.ts +13 -0
- package/dist/packages/bunshot-auth/src/lib/magicLink.js +145 -0
- package/dist/packages/bunshot-auth/src/lib/mfaChallenge.d.ts +60 -0
- package/dist/packages/bunshot-auth/src/lib/mfaChallenge.js +419 -0
- package/dist/packages/bunshot-auth/src/lib/oauth.d.ts +82 -0
- package/dist/packages/bunshot-auth/src/lib/oauth.js +177 -0
- package/dist/packages/bunshot-auth/src/lib/oauthCode.d.ts +19 -0
- package/dist/packages/bunshot-auth/src/lib/oauthCode.js +182 -0
- package/dist/packages/bunshot-auth/src/lib/oauthReauth.d.ts +19 -0
- package/dist/packages/bunshot-auth/src/lib/oauthReauth.js +255 -0
- package/dist/packages/bunshot-auth/src/lib/organization.d.ts +66 -0
- package/dist/packages/bunshot-auth/src/lib/organization.js +225 -0
- package/dist/packages/bunshot-auth/src/lib/passwordHistory.d.ts +12 -0
- package/dist/packages/bunshot-auth/src/lib/passwordHistory.js +31 -0
- package/dist/packages/bunshot-auth/src/lib/resetPassword.d.ts +20 -0
- package/dist/packages/bunshot-auth/src/lib/resetPassword.js +148 -0
- package/dist/packages/bunshot-auth/src/lib/roles.d.ts +9 -0
- package/dist/packages/bunshot-auth/src/lib/roles.js +93 -0
- package/dist/packages/bunshot-auth/src/lib/saml.d.ts +29 -0
- package/dist/packages/bunshot-auth/src/lib/saml.js +73 -0
- package/dist/packages/bunshot-auth/src/lib/samlRequestId.d.ts +13 -0
- package/dist/packages/bunshot-auth/src/lib/samlRequestId.js +129 -0
- package/dist/packages/bunshot-auth/src/lib/scim.d.ts +44 -0
- package/dist/packages/bunshot-auth/src/lib/scim.js +56 -0
- package/dist/packages/bunshot-auth/src/lib/securityEventWiring.d.ts +22 -0
- package/dist/packages/bunshot-auth/src/lib/securityEventWiring.js +65 -0
- package/dist/packages/bunshot-auth/src/lib/session.d.ts +45 -0
- package/dist/packages/bunshot-auth/src/lib/session.js +1211 -0
- package/dist/packages/bunshot-auth/src/lib/storeInfra.d.ts +26 -0
- package/dist/packages/bunshot-auth/src/lib/storeInfra.js +18 -0
- package/dist/packages/bunshot-auth/src/lib/suspension.d.ts +14 -0
- package/dist/packages/bunshot-auth/src/lib/suspension.js +20 -0
- package/dist/packages/bunshot-auth/src/lib/validateAdapter.d.ts +16 -0
- package/dist/packages/bunshot-auth/src/lib/validateAdapter.js +161 -0
- package/dist/packages/bunshot-auth/src/middleware/bearerAuth.d.ts +13 -0
- package/dist/packages/bunshot-auth/src/middleware/bearerAuth.js +58 -0
- package/dist/{middleware → packages/bunshot-auth/src/middleware}/csrf.d.ts +5 -4
- package/dist/packages/bunshot-auth/src/middleware/csrf.js +138 -0
- package/dist/packages/bunshot-auth/src/middleware/identify.d.ts +4 -0
- package/dist/packages/bunshot-auth/src/middleware/identify.js +124 -0
- package/dist/{middleware → packages/bunshot-auth/src/middleware}/requireMfaSetup.d.ts +2 -2
- package/dist/{middleware → packages/bunshot-auth/src/middleware}/requireMfaSetup.js +10 -7
- package/dist/{middleware → packages/bunshot-auth/src/middleware}/requireRole.d.ts +2 -2
- package/dist/{middleware → packages/bunshot-auth/src/middleware}/requireRole.js +20 -16
- package/dist/packages/bunshot-auth/src/middleware/requireScope.d.ts +10 -0
- package/dist/packages/bunshot-auth/src/middleware/requireScope.js +25 -0
- package/dist/packages/bunshot-auth/src/middleware/requireStepUp.d.ts +18 -0
- package/dist/packages/bunshot-auth/src/middleware/requireStepUp.js +30 -0
- package/dist/{middleware → packages/bunshot-auth/src/middleware}/requireVerifiedEmail.d.ts +2 -2
- package/dist/{middleware → packages/bunshot-auth/src/middleware}/requireVerifiedEmail.js +7 -6
- package/dist/packages/bunshot-auth/src/middleware/scimAuth.d.ts +8 -0
- package/dist/packages/bunshot-auth/src/middleware/scimAuth.js +29 -0
- package/dist/packages/bunshot-auth/src/middleware/userAuth.d.ts +3 -0
- package/dist/packages/bunshot-auth/src/middleware/userAuth.js +6 -0
- package/dist/{models → packages/bunshot-auth/src/models}/AuthUser.d.ts +19 -8
- package/dist/packages/bunshot-auth/src/models/AuthUser.js +53 -0
- package/dist/packages/bunshot-auth/src/models/Group.d.ts +19 -0
- package/dist/packages/bunshot-auth/src/models/Group.js +22 -0
- package/dist/{models → packages/bunshot-auth/src/models}/GroupMembership.d.ts +6 -8
- package/dist/packages/bunshot-auth/src/models/GroupMembership.js +19 -0
- package/dist/packages/bunshot-auth/src/models/M2MClient.d.ts +18 -0
- package/dist/packages/bunshot-auth/src/models/M2MClient.js +18 -0
- package/dist/packages/bunshot-auth/src/models/TenantRole.d.ts +13 -0
- package/dist/packages/bunshot-auth/src/models/TenantRole.js +17 -0
- package/dist/packages/bunshot-auth/src/plugin.d.ts +4 -0
- package/dist/packages/bunshot-auth/src/plugin.js +274 -0
- package/dist/packages/bunshot-auth/src/routes/auth.d.ts +15 -0
- package/dist/packages/bunshot-auth/src/routes/auth.js +1624 -0
- package/dist/packages/bunshot-auth/src/routes/groups.d.ts +4 -0
- package/dist/packages/bunshot-auth/src/routes/groups.js +481 -0
- package/dist/packages/bunshot-auth/src/routes/m2m.d.ts +2 -0
- package/dist/packages/bunshot-auth/src/routes/m2m.js +145 -0
- package/dist/packages/bunshot-auth/src/routes/mfa.d.ts +6 -0
- package/dist/packages/bunshot-auth/src/routes/mfa.js +991 -0
- package/dist/packages/bunshot-auth/src/routes/oauth.d.ts +3 -0
- package/dist/packages/bunshot-auth/src/routes/oauth.js +1727 -0
- package/dist/packages/bunshot-auth/src/routes/oidc.d.ts +2 -0
- package/dist/packages/bunshot-auth/src/routes/oidc.js +84 -0
- package/dist/packages/bunshot-auth/src/routes/organizations.d.ts +3 -0
- package/dist/packages/bunshot-auth/src/routes/organizations.js +741 -0
- package/dist/packages/bunshot-auth/src/routes/passkey.d.ts +2 -0
- package/dist/packages/bunshot-auth/src/routes/passkey.js +199 -0
- package/dist/packages/bunshot-auth/src/routes/saml.d.ts +2 -0
- package/dist/packages/bunshot-auth/src/routes/saml.js +226 -0
- package/dist/packages/bunshot-auth/src/routes/scim.d.ts +3 -0
- package/dist/packages/bunshot-auth/src/routes/scim.js +588 -0
- package/dist/packages/bunshot-auth/src/runtime.d.ts +52 -0
- package/dist/packages/bunshot-auth/src/runtime.js +11 -0
- package/dist/{schemas → packages/bunshot-auth/src/schemas}/auth.d.ts +4 -5
- package/dist/packages/bunshot-auth/src/schemas/auth.js +24 -0
- package/dist/packages/bunshot-auth/src/schemas/error.d.ts +10 -0
- package/dist/packages/bunshot-auth/src/schemas/error.js +10 -0
- package/dist/packages/bunshot-auth/src/schemas/success.d.ts +10 -0
- package/dist/packages/bunshot-auth/src/schemas/success.js +10 -0
- package/dist/packages/bunshot-auth/src/services/auth.d.ts +39 -0
- package/dist/packages/bunshot-auth/src/services/auth.js +378 -0
- package/dist/{services → packages/bunshot-auth/src/services}/mfa.d.ts +41 -17
- package/dist/{services → packages/bunshot-auth/src/services}/mfa.js +259 -183
- package/dist/packages/bunshot-auth/src/testing.d.ts +31 -0
- package/dist/packages/bunshot-auth/src/testing.js +23 -0
- package/dist/packages/bunshot-auth/src/types/adapter.d.ts +1 -0
- package/dist/packages/bunshot-auth/src/types/adapter.js +1 -0
- package/dist/packages/bunshot-auth/src/types/config.d.ts +152 -0
- package/dist/packages/bunshot-auth/src/types/config.js +179 -0
- package/dist/{routes → packages/bunshot-auth/src/types}/groups.d.ts +2 -3
- package/dist/packages/bunshot-auth/src/types/groups.js +1 -0
- package/dist/packages/bunshot-auth/src/types/oauthCode.d.ts +6 -0
- package/dist/packages/bunshot-auth/src/types/oauthCode.js +1 -0
- package/dist/packages/bunshot-auth/src/types/oauthReauth.d.ts +13 -0
- package/dist/packages/bunshot-auth/src/types/oauthReauth.js +1 -0
- package/dist/packages/bunshot-auth/src/types/redis.d.ts +1 -0
- package/dist/packages/bunshot-auth/src/types/redis.js +1 -0
- package/dist/packages/bunshot-auth/src/types/saml.d.ts +10 -0
- package/dist/packages/bunshot-auth/src/types/saml.js +1 -0
- package/dist/packages/bunshot-auth/src/types/session.d.ts +18 -0
- package/dist/packages/bunshot-auth/src/types/session.js +1 -0
- package/dist/packages/bunshot-auth/src/types/store.d.ts +1 -0
- package/dist/packages/bunshot-auth/src/types/store.js +1 -0
- package/dist/packages/bunshot-core/src/adminProvider.d.ts +95 -0
- package/dist/packages/bunshot-core/src/adminProvider.js +1 -0
- package/dist/packages/bunshot-core/src/auditLog.d.ts +34 -0
- package/dist/packages/bunshot-core/src/auditLog.js +1 -0
- package/dist/packages/bunshot-core/src/auth-adapter.d.ts +227 -0
- package/dist/packages/bunshot-core/src/auth-adapter.js +4 -0
- package/dist/packages/bunshot-core/src/authVariables.d.ts +14 -0
- package/dist/packages/bunshot-core/src/authVariables.js +4 -0
- package/dist/packages/bunshot-core/src/cache.d.ts +12 -0
- package/dist/packages/bunshot-core/src/cache.js +21 -0
- package/dist/packages/bunshot-core/src/captcha.d.ts +16 -0
- package/dist/packages/bunshot-core/src/captcha.js +1 -0
- package/dist/packages/bunshot-core/src/clearRegistry.d.ts +6 -0
- package/dist/packages/bunshot-core/src/clearRegistry.js +17 -0
- package/dist/packages/bunshot-core/src/clientIp.d.ts +3 -0
- package/dist/packages/bunshot-core/src/clientIp.js +45 -0
- package/dist/packages/bunshot-core/src/configLock.d.ts +4 -0
- package/dist/packages/bunshot-core/src/configLock.js +7 -0
- package/dist/packages/bunshot-core/src/configValidation.d.ts +22 -0
- package/dist/packages/bunshot-core/src/configValidation.js +39 -0
- package/dist/packages/bunshot-core/src/constants.js +10 -0
- package/dist/packages/bunshot-core/src/context/bunshotContext.d.ts +232 -0
- package/dist/packages/bunshot-core/src/context/bunshotContext.js +1 -0
- package/dist/packages/bunshot-core/src/context/contextAccess.d.ts +3 -0
- package/dist/packages/bunshot-core/src/context/contextAccess.js +16 -0
- package/dist/packages/bunshot-core/src/context/contextStore.d.ts +16 -0
- package/dist/packages/bunshot-core/src/context/contextStore.js +31 -0
- package/dist/packages/bunshot-core/src/context/frameworkConfig.d.ts +38 -0
- package/dist/packages/bunshot-core/src/context/frameworkConfig.js +1 -0
- package/dist/packages/bunshot-core/src/context/index.d.ts +4 -0
- package/dist/packages/bunshot-core/src/context/index.js +2 -0
- package/dist/packages/bunshot-core/src/context.d.ts +40 -0
- package/dist/packages/bunshot-core/src/context.js +35 -0
- package/dist/packages/bunshot-core/src/coreContracts.d.ts +47 -0
- package/dist/packages/bunshot-core/src/coreContracts.js +1 -0
- package/dist/packages/bunshot-core/src/coreRegistrar.d.ts +6 -0
- package/dist/packages/bunshot-core/src/coreRegistrar.js +42 -0
- package/dist/{lib → packages/bunshot-core/src}/createRoute.d.ts +4 -30
- package/dist/{lib → packages/bunshot-core/src}/createRoute.js +39 -88
- package/dist/packages/bunshot-core/src/cronRegistry.d.ts +11 -0
- package/dist/packages/bunshot-core/src/cronRegistry.js +1 -0
- package/dist/packages/bunshot-core/src/crypto.d.ts +43 -0
- package/dist/packages/bunshot-core/src/crypto.js +74 -0
- package/dist/packages/bunshot-core/src/csrf.d.ts +8 -0
- package/dist/packages/bunshot-core/src/csrf.js +1 -0
- package/dist/packages/bunshot-core/src/defaults/defaultFingerprint.d.ts +7 -0
- package/dist/packages/bunshot-core/src/defaults/defaultFingerprint.js +19 -0
- package/dist/packages/bunshot-core/src/defaults/memoryCacheAdapter.d.ts +6 -0
- package/dist/packages/bunshot-core/src/defaults/memoryCacheAdapter.js +40 -0
- package/dist/packages/bunshot-core/src/defaults/memoryRateLimit.d.ts +6 -0
- package/dist/packages/bunshot-core/src/defaults/memoryRateLimit.js +24 -0
- package/dist/packages/bunshot-core/src/emailTemplates.d.ts +5 -0
- package/dist/packages/bunshot-core/src/emailTemplates.js +10 -0
- package/dist/packages/bunshot-core/src/errors.d.ts +13 -0
- package/dist/packages/bunshot-core/src/errors.js +22 -0
- package/dist/packages/bunshot-core/src/eventBus.d.ts +270 -0
- package/dist/packages/bunshot-core/src/eventBus.js +143 -0
- package/dist/packages/bunshot-core/src/idempotency.d.ts +18 -0
- package/dist/packages/bunshot-core/src/idempotency.js +1 -0
- package/dist/packages/bunshot-core/src/index.d.ts +60 -0
- package/dist/packages/bunshot-core/src/index.js +34 -0
- package/dist/packages/bunshot-core/src/mail.d.ts +14 -0
- package/dist/packages/bunshot-core/src/mail.js +8 -0
- package/dist/packages/bunshot-core/src/memoryEviction.d.ts +24 -0
- package/dist/packages/bunshot-core/src/memoryEviction.js +52 -0
- package/dist/packages/bunshot-core/src/pagination.d.ts +45 -0
- package/dist/packages/bunshot-core/src/pagination.js +61 -0
- package/dist/packages/bunshot-core/src/permissions.d.ts +64 -0
- package/dist/packages/bunshot-core/src/permissions.js +27 -0
- package/dist/packages/bunshot-core/src/plugin.d.ts +44 -0
- package/dist/packages/bunshot-core/src/plugin.js +1 -0
- package/dist/packages/bunshot-core/src/rateLimit.d.ts +5 -0
- package/dist/packages/bunshot-core/src/rateLimit.js +18 -0
- package/dist/packages/bunshot-core/src/redis.d.ts +21 -0
- package/dist/packages/bunshot-core/src/redis.js +1 -0
- package/dist/packages/bunshot-core/src/routeAuth.d.ts +5 -0
- package/dist/packages/bunshot-core/src/routeAuth.js +11 -0
- package/dist/packages/bunshot-core/src/routeOverrides.d.ts +24 -0
- package/dist/packages/bunshot-core/src/routeOverrides.js +25 -0
- package/dist/packages/bunshot-core/src/routerAdapter.d.ts +6 -0
- package/dist/packages/bunshot-core/src/routerAdapter.js +56 -0
- package/dist/packages/bunshot-core/src/secrets.d.ts +48 -0
- package/dist/packages/bunshot-core/src/secrets.js +8 -0
- package/dist/packages/bunshot-core/src/signing.d.ts +41 -0
- package/dist/packages/bunshot-core/src/signing.js +1 -0
- package/dist/packages/bunshot-core/src/sse.d.ts +36 -0
- package/dist/packages/bunshot-core/src/sse.js +1 -0
- package/dist/packages/bunshot-core/src/storageAdapter.js +1 -0
- package/dist/packages/bunshot-core/src/storeInfra.d.ts +44 -0
- package/dist/packages/bunshot-core/src/storeInfra.js +18 -0
- package/dist/packages/bunshot-core/src/storeType.d.ts +7 -0
- package/dist/packages/bunshot-core/src/storeType.js +1 -0
- package/dist/packages/bunshot-core/src/testing.d.ts +1 -0
- package/dist/packages/bunshot-core/src/testing.js +1 -0
- package/dist/packages/bunshot-core/src/uploadRegistry.d.ts +23 -0
- package/dist/packages/bunshot-core/src/uploadRegistry.js +4 -0
- package/dist/packages/bunshot-core/src/userResolver.d.ts +5 -0
- package/dist/packages/bunshot-core/src/userResolver.js +14 -0
- package/dist/packages/bunshot-core/src/wsMessages.d.ts +42 -0
- package/dist/packages/bunshot-core/src/wsMessages.js +4 -0
- package/dist/packages/bunshot-permissions/src/adapters/memory.d.ts +7 -0
- package/dist/packages/bunshot-permissions/src/adapters/memory.js +73 -0
- package/dist/packages/bunshot-permissions/src/index.d.ts +10 -0
- package/dist/packages/bunshot-permissions/src/index.js +5 -0
- package/dist/packages/bunshot-permissions/src/lib/bootstrap.d.ts +7 -0
- package/dist/packages/bunshot-permissions/src/lib/bootstrap.js +12 -0
- package/dist/packages/bunshot-permissions/src/lib/evaluator.d.ts +10 -0
- package/dist/packages/bunshot-permissions/src/lib/evaluator.js +165 -0
- package/dist/packages/bunshot-permissions/src/lib/registry.d.ts +2 -0
- package/dist/packages/bunshot-permissions/src/lib/registry.js +31 -0
- package/dist/packages/bunshot-permissions/src/lib/validation.d.ts +1 -0
- package/dist/packages/bunshot-permissions/src/lib/validation.js +1 -0
- package/dist/packages/bunshot-permissions/src/types/adapter.d.ts +1 -0
- package/dist/packages/bunshot-permissions/src/types/adapter.js +1 -0
- package/dist/packages/bunshot-permissions/src/types/evaluator.d.ts +1 -0
- package/dist/packages/bunshot-permissions/src/types/evaluator.js +1 -0
- package/dist/packages/bunshot-permissions/src/types/models.d.ts +1 -0
- package/dist/packages/bunshot-permissions/src/types/models.js +1 -0
- package/dist/packages/bunshot-permissions/src/types/registry.d.ts +1 -0
- package/dist/packages/bunshot-permissions/src/types/registry.js +1 -0
- package/dist/packages/bunshot-postgres/src/adapter.d.ts +6 -0
- package/dist/packages/bunshot-postgres/src/adapter.js +794 -0
- package/dist/packages/bunshot-postgres/src/connection.d.ts +15 -0
- package/dist/packages/bunshot-postgres/src/connection.js +16 -0
- package/dist/packages/bunshot-postgres/src/index.d.ts +4 -0
- package/dist/packages/bunshot-postgres/src/index.js +2 -0
- package/dist/packages/bunshot-postgres/src/schema.d.ts +997 -0
- package/dist/packages/bunshot-postgres/src/schema.js +105 -0
- package/dist/src/app.d.ts +230 -0
- package/dist/src/app.js +182 -0
- package/dist/src/cli/commands/init.d.ts +10 -0
- package/dist/src/cli/commands/init.js +709 -0
- package/dist/src/cli/index.d.ts +1 -0
- package/dist/src/cli/index.js +3 -0
- package/dist/src/entrypoints/mongo.d.ts +6 -0
- package/dist/src/entrypoints/mongo.js +4 -0
- package/dist/src/entrypoints/queue.d.ts +2 -0
- package/dist/src/entrypoints/queue.js +1 -0
- package/dist/src/entrypoints/redis.d.ts +1 -0
- package/dist/src/entrypoints/redis.js +1 -0
- package/dist/{adapters → src/framework/adapters}/localStorage.d.ts +1 -1
- package/dist/{adapters → src/framework/adapters}/localStorage.js +23 -8
- package/dist/src/framework/adapters/memoryStorage.d.ts +2 -0
- package/dist/src/framework/adapters/memoryStorage.js +45 -0
- package/dist/{adapters → src/framework/adapters}/s3Storage.d.ts +1 -1
- package/dist/{adapters → src/framework/adapters}/s3Storage.js +12 -12
- package/dist/src/framework/admin/bunshotAccess.d.ts +2 -0
- package/dist/src/framework/admin/bunshotAccess.js +23 -0
- package/dist/src/framework/admin/bunshotUsers.d.ts +2 -0
- package/dist/src/framework/admin/bunshotUsers.js +103 -0
- package/dist/src/framework/admin/index.d.ts +7 -0
- package/dist/src/framework/admin/index.js +21 -0
- package/dist/src/framework/boundaryAdapters/cacheFactories.d.ts +13 -0
- package/dist/src/framework/boundaryAdapters/cacheFactories.js +86 -0
- package/dist/src/framework/boundaryAdapters/index.d.ts +2 -0
- package/dist/src/framework/boundaryAdapters/index.js +1 -0
- package/dist/src/framework/boundaryAdapters.d.ts +17 -0
- package/dist/src/framework/boundaryAdapters.js +62 -0
- package/dist/src/framework/buildContext.d.ts +33 -0
- package/dist/src/framework/buildContext.js +119 -0
- package/dist/src/framework/config/schema.d.ts +447 -0
- package/dist/src/framework/config/schema.js +528 -0
- package/dist/src/framework/createInfrastructure.d.ts +76 -0
- package/dist/src/framework/createInfrastructure.js +221 -0
- package/dist/src/framework/lib/auditLog.d.ts +23 -0
- package/dist/src/framework/lib/auditLog.js +416 -0
- package/dist/src/framework/lib/captcha.d.ts +11 -0
- package/dist/src/framework/lib/captcha.js +40 -0
- package/dist/{lib → src/framework/lib}/createDtoMapper.js +4 -4
- package/dist/src/framework/lib/createRoute.d.ts +1 -0
- package/dist/src/framework/lib/createRoute.js +2 -0
- package/dist/{lib → src/framework/lib}/idempotency.d.ts +2 -6
- package/dist/src/framework/lib/idempotency.js +74 -0
- package/dist/src/framework/lib/logger.d.ts +3 -0
- package/dist/src/framework/lib/logger.js +14 -0
- package/dist/src/framework/lib/metrics.d.ts +34 -0
- package/dist/{lib → src/framework/lib}/metrics.js +49 -57
- package/dist/src/framework/lib/pagination.d.ts +42 -0
- package/dist/src/framework/lib/pagination.js +51 -0
- package/dist/src/framework/lib/redisTransport.d.ts +38 -0
- package/dist/src/framework/lib/redisTransport.js +107 -0
- package/dist/src/framework/lib/resolveUserId.d.ts +2 -0
- package/dist/src/framework/lib/resolveUserId.js +5 -0
- package/dist/src/framework/lib/sseCollision.d.ts +6 -0
- package/dist/src/framework/lib/sseCollision.js +26 -0
- package/dist/src/framework/lib/storageAdapter.d.ts +1 -0
- package/dist/src/framework/lib/storageAdapter.js +1 -0
- package/dist/{lib → src/framework/lib}/stripUnreferencedSchemas.js +4 -4
- package/dist/src/framework/lib/tenant.d.ts +21 -0
- package/dist/src/framework/lib/tenant.js +70 -0
- package/dist/{lib → src/framework/lib}/upload.d.ts +14 -9
- package/dist/src/framework/lib/upload.js +132 -0
- package/dist/src/framework/lib/uploadRegistry.d.ts +23 -0
- package/dist/src/framework/lib/uploadRegistry.js +34 -0
- package/dist/{lib → src/framework/lib}/validate.d.ts +1 -1
- package/dist/{lib → src/framework/lib}/validate.js +2 -2
- package/dist/src/framework/lib/ws.d.ts +19 -0
- package/dist/src/framework/lib/ws.js +130 -0
- package/dist/src/framework/lib/wsHeartbeat.d.ts +12 -0
- package/dist/src/framework/lib/wsHeartbeat.js +53 -0
- package/dist/src/framework/lib/wsMessages.d.ts +25 -0
- package/dist/src/framework/lib/wsMessages.js +45 -0
- package/dist/src/framework/lib/wsNamespace.d.ts +17 -0
- package/dist/src/framework/lib/wsNamespace.js +19 -0
- package/dist/src/framework/lib/wsPresence.d.ts +17 -0
- package/dist/src/framework/lib/wsPresence.js +84 -0
- package/dist/src/framework/lib/wsTransport.d.ts +38 -0
- package/dist/src/framework/lib/wsTransport.js +9 -0
- package/dist/{lib → src/framework/lib}/zodToMongoose.d.ts +1 -1
- package/dist/{lib → src/framework/lib}/zodToMongoose.js +11 -11
- package/dist/{middleware → src/framework/middleware}/auditLog.d.ts +4 -3
- package/dist/src/framework/middleware/auditLog.js +42 -0
- package/dist/{middleware → src/framework/middleware}/botProtection.d.ts +2 -2
- package/dist/{middleware → src/framework/middleware}/botProtection.js +8 -9
- package/dist/src/framework/middleware/cacheResponse.d.ts +35 -0
- package/dist/src/framework/middleware/cacheResponse.js +126 -0
- package/dist/src/framework/middleware/captcha.d.ts +9 -0
- package/dist/src/framework/middleware/captcha.js +37 -0
- package/dist/{middleware → src/framework/middleware}/errorHandler.d.ts +1 -1
- package/dist/src/framework/middleware/errorHandler.js +16 -0
- package/dist/src/framework/middleware/index.js +1 -0
- package/dist/{middleware → src/framework/middleware}/logger.d.ts +1 -1
- package/dist/src/framework/middleware/metrics.d.ts +12 -0
- package/dist/src/framework/middleware/metrics.js +26 -0
- package/dist/{middleware → src/framework/middleware}/rateLimit.d.ts +2 -2
- package/dist/src/framework/middleware/rateLimit.js +22 -0
- package/dist/src/framework/middleware/requestId.d.ts +3 -0
- package/dist/{middleware → src/framework/middleware}/requestId.js +2 -2
- package/dist/{middleware → src/framework/middleware}/requestLogger.d.ts +3 -3
- package/dist/{middleware → src/framework/middleware}/requestLogger.js +17 -12
- package/dist/{middleware → src/framework/middleware}/requestSigning.d.ts +2 -2
- package/dist/{middleware → src/framework/middleware}/requestSigning.js +18 -19
- package/dist/src/framework/middleware/tenant.d.ts +14 -0
- package/dist/{middleware → src/framework/middleware}/tenant.js +31 -27
- package/dist/src/framework/middleware/upload.d.ts +5 -0
- package/dist/{middleware → src/framework/middleware}/upload.js +4 -4
- package/dist/{middleware → src/framework/middleware}/webhookAuth.d.ts +3 -3
- package/dist/{middleware → src/framework/middleware}/webhookAuth.js +11 -11
- package/dist/src/framework/models/AuditLog.d.ts +21 -0
- package/dist/src/framework/models/AuditLog.js +31 -0
- package/dist/src/framework/mountMiddleware.d.ts +91 -0
- package/dist/src/framework/mountMiddleware.js +128 -0
- package/dist/src/framework/mountOptionalEndpoints.d.ts +103 -0
- package/dist/src/framework/mountOptionalEndpoints.js +47 -0
- package/dist/src/framework/mountRoutes.d.ts +21 -0
- package/dist/src/framework/mountRoutes.js +144 -0
- package/dist/src/framework/persistence/cronRegistry.d.ts +28 -0
- package/dist/src/framework/persistence/cronRegistry.js +139 -0
- package/dist/src/framework/persistence/idempotency.d.ts +26 -0
- package/dist/src/framework/persistence/idempotency.js +178 -0
- package/dist/src/framework/persistence/index.d.ts +6 -0
- package/dist/src/framework/persistence/index.js +8 -0
- package/dist/src/framework/persistence/storeInfra.d.ts +9 -0
- package/dist/src/framework/persistence/storeInfra.js +1 -0
- package/dist/src/framework/persistence/uploadRegistry.d.ts +35 -0
- package/dist/src/framework/persistence/uploadRegistry.js +235 -0
- package/dist/src/framework/persistence/wsMessages.d.ts +22 -0
- package/dist/src/framework/persistence/wsMessages.js +296 -0
- package/dist/src/framework/preloadSchemas.d.ts +24 -0
- package/dist/src/framework/preloadSchemas.js +42 -0
- package/dist/src/framework/registerBoundaryAdapters.d.ts +23 -0
- package/dist/src/framework/registerBoundaryAdapters.js +46 -0
- package/dist/src/framework/routes/admin.d.ts +9 -0
- package/dist/src/framework/routes/admin.js +361 -0
- package/dist/src/framework/routes/health.d.ts +1 -0
- package/dist/src/framework/routes/health.js +21 -0
- package/dist/src/framework/routes/home.d.ts +1 -0
- package/dist/src/framework/routes/home.js +18 -0
- package/dist/src/framework/routes/jobs.d.ts +3 -0
- package/dist/src/framework/routes/jobs.js +315 -0
- package/dist/src/framework/routes/metrics.d.ts +10 -0
- package/dist/src/framework/routes/metrics.js +57 -0
- package/dist/src/framework/routes/uploads.d.ts +14 -0
- package/dist/src/framework/routes/uploads.js +262 -0
- package/dist/src/framework/runPluginLifecycle.d.ts +27 -0
- package/dist/src/framework/runPluginLifecycle.js +121 -0
- package/dist/src/framework/secrets/frameworkSecretSchema.d.ts +58 -0
- package/dist/src/framework/secrets/frameworkSecretSchema.js +20 -0
- package/dist/src/framework/secrets/index.d.ts +9 -0
- package/dist/src/framework/secrets/index.js +7 -0
- package/dist/src/framework/secrets/providers/envProvider.d.ts +15 -0
- package/dist/src/framework/secrets/providers/envProvider.js +18 -0
- package/dist/src/framework/secrets/providers/fileProvider.d.ts +8 -0
- package/dist/src/framework/secrets/providers/fileProvider.js +82 -0
- package/dist/src/framework/secrets/providers/ssmProvider.d.ts +20 -0
- package/dist/src/framework/secrets/providers/ssmProvider.js +127 -0
- package/dist/src/framework/secrets/resolveSecretBundle.d.ts +53 -0
- package/dist/src/framework/secrets/resolveSecretBundle.js +84 -0
- package/dist/src/framework/secrets/resolveSecrets.d.ts +18 -0
- package/dist/src/framework/secrets/resolveSecrets.js +34 -0
- package/dist/src/framework/sse/index.d.ts +21 -0
- package/dist/src/framework/sse/index.js +109 -0
- package/dist/src/framework/ws/index.d.ts +11 -0
- package/dist/src/framework/ws/index.js +8 -0
- package/dist/src/index.d.ts +87 -0
- package/dist/src/index.js +58 -0
- package/dist/src/lib/appConfig.d.ts +7 -0
- package/dist/src/lib/appConfig.js +27 -0
- package/dist/src/lib/appMeta.d.ts +7 -0
- package/dist/src/lib/appMeta.js +3 -0
- package/dist/src/lib/authConfig.d.ts +532 -0
- package/dist/src/lib/authConfig.js +179 -0
- package/dist/{lib → src/lib}/context.d.ts +6 -7
- package/dist/{lib → src/lib}/context.js +5 -5
- package/dist/src/lib/logger.d.ts +1 -0
- package/dist/src/lib/logger.js +1 -0
- package/dist/src/lib/mongo.d.ts +58 -0
- package/dist/src/lib/mongo.js +96 -0
- package/dist/src/lib/queue.d.ts +72 -0
- package/dist/src/lib/queue.js +152 -0
- package/dist/src/lib/redis.d.ts +28 -0
- package/dist/src/lib/redis.js +72 -0
- package/dist/{lib → src/lib}/signing.d.ts +2 -2
- package/dist/src/lib/signing.js +210 -0
- package/dist/src/lib/signingConfig.d.ts +40 -0
- package/dist/src/lib/signingConfig.js +28 -0
- package/dist/src/server.d.ts +146 -0
- package/dist/src/server.js +469 -0
- package/dist/src/shared/lib/HttpError.d.ts +1 -0
- package/dist/src/shared/lib/HttpError.js +2 -0
- package/dist/src/shared/lib/constants.d.ts +10 -0
- package/dist/src/shared/lib/crypto.d.ts +43 -0
- package/dist/src/shared/lib/crypto.js +74 -0
- package/dist/src/shared/lib/signing.d.ts +52 -0
- package/dist/{lib → src/shared/lib}/signing.js +40 -10
- package/dist/src/testing.d.ts +34 -0
- package/dist/src/testing.js +93 -0
- package/package.json +62 -25
- package/dist/adapters/memoryAuth.d.ts +0 -46
- package/dist/adapters/memoryAuth.js +0 -634
- package/dist/adapters/memoryStorage.d.ts +0 -3
- package/dist/adapters/memoryStorage.js +0 -44
- package/dist/adapters/mongoAuth.d.ts +0 -2
- package/dist/adapters/mongoAuth.js +0 -307
- package/dist/adapters/sqliteAuth.d.ts +0 -49
- package/dist/adapters/sqliteAuth.js +0 -707
- package/dist/app.d.ts +0 -456
- package/dist/app.js +0 -548
- package/dist/entrypoints/mongo.d.ts +0 -5
- package/dist/entrypoints/mongo.js +0 -4
- package/dist/entrypoints/queue.d.ts +0 -2
- package/dist/entrypoints/queue.js +0 -1
- package/dist/entrypoints/redis.d.ts +0 -1
- package/dist/entrypoints/redis.js +0 -1
- package/dist/index.d.ts +0 -98
- package/dist/index.js +0 -77
- package/dist/lib/HttpError.d.ts +0 -9
- package/dist/lib/HttpError.js +0 -14
- package/dist/lib/appConfig.d.ts +0 -162
- package/dist/lib/appConfig.js +0 -83
- package/dist/lib/auditLog.d.ts +0 -52
- package/dist/lib/auditLog.js +0 -201
- package/dist/lib/authAdapter.d.ts +0 -176
- package/dist/lib/authAdapter.js +0 -7
- package/dist/lib/authRateLimit.d.ts +0 -13
- package/dist/lib/authRateLimit.js +0 -81
- package/dist/lib/clientIp.d.ts +0 -14
- package/dist/lib/crypto.d.ts +0 -11
- package/dist/lib/crypto.js +0 -22
- package/dist/lib/deletionCancelToken.d.ts +0 -12
- package/dist/lib/deletionCancelToken.js +0 -88
- package/dist/lib/emailVerification.d.ts +0 -13
- package/dist/lib/emailVerification.js +0 -86
- package/dist/lib/fingerprint.js +0 -36
- package/dist/lib/idempotency.js +0 -182
- package/dist/lib/jwt.d.ts +0 -2
- package/dist/lib/jwt.js +0 -24
- package/dist/lib/logger.d.ts +0 -1
- package/dist/lib/logger.js +0 -7
- package/dist/lib/metrics.d.ts +0 -14
- package/dist/lib/mfaChallenge.d.ts +0 -42
- package/dist/lib/mfaChallenge.js +0 -293
- package/dist/lib/mongo.d.ts +0 -39
- package/dist/lib/mongo.js +0 -124
- package/dist/lib/oauth.d.ts +0 -40
- package/dist/lib/oauth.js +0 -101
- package/dist/lib/oauthCode.d.ts +0 -15
- package/dist/lib/oauthCode.js +0 -90
- package/dist/lib/pagination.d.ts +0 -119
- package/dist/lib/pagination.js +0 -166
- package/dist/lib/queue.d.ts +0 -37
- package/dist/lib/queue.js +0 -117
- package/dist/lib/redis.d.ts +0 -9
- package/dist/lib/redis.js +0 -61
- package/dist/lib/resetPassword.d.ts +0 -12
- package/dist/lib/resetPassword.js +0 -91
- package/dist/lib/roles.d.ts +0 -7
- package/dist/lib/roles.js +0 -49
- package/dist/lib/session.d.ts +0 -39
- package/dist/lib/session.js +0 -535
- package/dist/lib/tenant.d.ts +0 -15
- package/dist/lib/tenant.js +0 -65
- package/dist/lib/upload.js +0 -87
- package/dist/lib/ws.d.ts +0 -22
- package/dist/lib/ws.js +0 -89
- package/dist/lib/wsHeartbeat.d.ts +0 -12
- package/dist/lib/wsHeartbeat.js +0 -57
- package/dist/lib/wsMessages.d.ts +0 -40
- package/dist/lib/wsMessages.js +0 -330
- package/dist/lib/wsPresence.d.ts +0 -25
- package/dist/lib/wsPresence.js +0 -99
- package/dist/middleware/auditLog.js +0 -39
- package/dist/middleware/bearerAuth.d.ts +0 -2
- package/dist/middleware/bearerAuth.js +0 -11
- package/dist/middleware/cacheResponse.d.ts +0 -15
- package/dist/middleware/cacheResponse.js +0 -178
- package/dist/middleware/csrf.js +0 -125
- package/dist/middleware/errorHandler.js +0 -13
- package/dist/middleware/identify.d.ts +0 -3
- package/dist/middleware/identify.js +0 -95
- package/dist/middleware/index.js +0 -1
- package/dist/middleware/metrics.d.ts +0 -9
- package/dist/middleware/metrics.js +0 -26
- package/dist/middleware/rateLimit.js +0 -22
- package/dist/middleware/requestId.d.ts +0 -3
- package/dist/middleware/tenant.d.ts +0 -5
- package/dist/middleware/upload.d.ts +0 -5
- package/dist/middleware/userAuth.d.ts +0 -3
- package/dist/middleware/userAuth.js +0 -6
- package/dist/models/AuditLog.d.ts +0 -30
- package/dist/models/AuditLog.js +0 -39
- package/dist/models/AuthUser.js +0 -48
- package/dist/models/Group.d.ts +0 -21
- package/dist/models/Group.js +0 -28
- package/dist/models/GroupMembership.js +0 -25
- package/dist/models/TenantRole.d.ts +0 -15
- package/dist/models/TenantRole.js +0 -23
- package/dist/routes/auth.d.ts +0 -11
- package/dist/routes/auth.js +0 -605
- package/dist/routes/groups.js +0 -346
- package/dist/routes/health.d.ts +0 -1
- package/dist/routes/health.js +0 -22
- package/dist/routes/home.d.ts +0 -1
- package/dist/routes/home.js +0 -16
- package/dist/routes/jobs.d.ts +0 -2
- package/dist/routes/jobs.js +0 -272
- package/dist/routes/metrics.d.ts +0 -7
- package/dist/routes/metrics.js +0 -52
- package/dist/routes/mfa.d.ts +0 -5
- package/dist/routes/mfa.js +0 -620
- package/dist/routes/oauth.d.ts +0 -2
- package/dist/routes/oauth.js +0 -514
- package/dist/routes/uploads.d.ts +0 -2
- package/dist/routes/uploads.js +0 -135
- package/dist/schemas/auth.js +0 -30
- package/dist/server.d.ts +0 -57
- package/dist/server.js +0 -112
- package/dist/services/auth.d.ts +0 -27
- package/dist/services/auth.js +0 -159
- package/dist/ws/index.d.ts +0 -10
- package/dist/ws/index.js +0 -38
- package/docs/sections/adding-middleware/full.md +0 -35
- package/docs/sections/adding-models/full.md +0 -125
- package/docs/sections/adding-models/overview.md +0 -13
- package/docs/sections/adding-routes/full.md +0 -182
- package/docs/sections/adding-routes/overview.md +0 -23
- package/docs/sections/auth-flow/full.md +0 -779
- package/docs/sections/auth-flow/overview.md +0 -10
- package/docs/sections/auth-security-examples/full.md +0 -365
- package/docs/sections/authentication/full.md +0 -130
- package/docs/sections/authentication/overview.md +0 -5
- package/docs/sections/cli/full.md +0 -42
- package/docs/sections/configuration/full.md +0 -172
- package/docs/sections/configuration/overview.md +0 -18
- package/docs/sections/configuration-example/full.md +0 -117
- package/docs/sections/configuration-example/overview.md +0 -30
- package/docs/sections/documentation/full.md +0 -171
- package/docs/sections/environment-variables/full.md +0 -55
- package/docs/sections/exports/full.md +0 -123
- package/docs/sections/extending-context/full.md +0 -59
- package/docs/sections/header.md +0 -3
- package/docs/sections/installation/full.md +0 -6
- package/docs/sections/jobs/full.md +0 -140
- package/docs/sections/jobs/overview.md +0 -15
- package/docs/sections/logging/full.md +0 -83
- package/docs/sections/metrics/full.md +0 -127
- package/docs/sections/mongodb-connections/full.md +0 -45
- package/docs/sections/mongodb-connections/overview.md +0 -7
- package/docs/sections/multi-tenancy/full.md +0 -66
- package/docs/sections/multi-tenancy/overview.md +0 -15
- package/docs/sections/oauth/full.md +0 -189
- package/docs/sections/oauth/overview.md +0 -16
- package/docs/sections/package-development/full.md +0 -7
- package/docs/sections/pagination/full.md +0 -93
- package/docs/sections/peer-dependencies/full.md +0 -47
- package/docs/sections/quick-start/full.md +0 -43
- package/docs/sections/response-caching/full.md +0 -117
- package/docs/sections/response-caching/overview.md +0 -13
- package/docs/sections/roles/full.md +0 -225
- package/docs/sections/roles/overview.md +0 -14
- package/docs/sections/running-without-redis/full.md +0 -16
- package/docs/sections/running-without-redis-or-mongodb/full.md +0 -60
- package/docs/sections/signing/full.md +0 -203
- package/docs/sections/stack/full.md +0 -10
- package/docs/sections/uploads/full.md +0 -199
- package/docs/sections/versioning/full.md +0 -85
- package/docs/sections/webhook-auth/full.md +0 -100
- package/docs/sections/websocket/full.md +0 -184
- package/docs/sections/websocket/overview.md +0 -5
- package/docs/sections/websocket-rooms/full.md +0 -102
- package/docs/sections/websocket-rooms/overview.md +0 -5
- /package/dist/{lib/storageAdapter.js → packages/bunshot-admin/src/types/env.js} +0 -0
- /package/dist/{lib → packages/bunshot-auth/src/lib}/fingerprint.d.ts +0 -0
- /package/dist/{lib → packages/bunshot-core/src}/constants.d.ts +0 -0
- /package/dist/{lib → packages/bunshot-core/src}/storageAdapter.d.ts +0 -0
- /package/dist/{lib → src/framework/lib}/createDtoMapper.d.ts +0 -0
- /package/dist/{lib → src/framework/lib}/stripUnreferencedSchemas.d.ts +0 -0
- /package/dist/{middleware → src/framework/middleware}/cors.d.ts +0 -0
- /package/dist/{middleware → src/framework/middleware}/cors.js +0 -0
- /package/dist/{middleware → src/framework/middleware}/index.d.ts +0 -0
- /package/dist/{middleware → src/framework/middleware}/logger.js +0 -0
- /package/dist/{lib → src/shared/lib}/constants.js +0 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check whether a password has appeared in a data breach using the
|
|
3
|
+
* HaveIBeenPwned k-Anonymity API.
|
|
4
|
+
*
|
|
5
|
+
* Sends only the first 5 hex chars of the SHA-1 hash — the full hash
|
|
6
|
+
* never leaves the server.
|
|
7
|
+
*/
|
|
8
|
+
export async function checkBreachedPassword(password, config, context, eventBus) {
|
|
9
|
+
const timeout = config?.timeout ?? 3000;
|
|
10
|
+
const minCount = config?.minBreachCount ?? 1;
|
|
11
|
+
// SHA-1 the password
|
|
12
|
+
const encoder = new TextEncoder();
|
|
13
|
+
const data = encoder.encode(password);
|
|
14
|
+
const hashBuffer = await crypto.subtle.digest('SHA-1', data);
|
|
15
|
+
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
16
|
+
const hashHex = hashArray
|
|
17
|
+
.map(b => b.toString(16).padStart(2, '0'))
|
|
18
|
+
.join('')
|
|
19
|
+
.toUpperCase();
|
|
20
|
+
const prefix = hashHex.slice(0, 5);
|
|
21
|
+
const suffix = hashHex.slice(5);
|
|
22
|
+
let responseText;
|
|
23
|
+
try {
|
|
24
|
+
const controller = new AbortController();
|
|
25
|
+
const timer = setTimeout(() => controller.abort(), timeout);
|
|
26
|
+
const res = await fetch(`https://api.pwnedpasswords.com/range/${prefix}`, {
|
|
27
|
+
signal: controller.signal,
|
|
28
|
+
headers: { 'Add-Padding': 'true' },
|
|
29
|
+
});
|
|
30
|
+
clearTimeout(timer);
|
|
31
|
+
if (!res.ok)
|
|
32
|
+
throw new Error(`HIBP API returned ${res.status}`);
|
|
33
|
+
responseText = await res.text();
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
// API failure — emit an observable event regardless of which policy applies,
|
|
37
|
+
// then apply onApiFailure policy (default: 'allow', i.e. fail-open).
|
|
38
|
+
eventBus?.emit('security.breached_password.api_failure', {
|
|
39
|
+
meta: { userId: context?.userId, ip: context?.ip },
|
|
40
|
+
});
|
|
41
|
+
if (config?.onApiFailure === 'block') {
|
|
42
|
+
return { breached: true, count: -1 };
|
|
43
|
+
}
|
|
44
|
+
return { breached: false, count: 0 };
|
|
45
|
+
}
|
|
46
|
+
// Parse response: each line is "SUFFIX:COUNT"
|
|
47
|
+
for (const line of responseText.split('\n')) {
|
|
48
|
+
const [lineSuffix, countStr] = line.trim().split(':');
|
|
49
|
+
if (lineSuffix === suffix) {
|
|
50
|
+
const count = parseInt(countStr, 10);
|
|
51
|
+
const breached = count >= minCount;
|
|
52
|
+
if (breached) {
|
|
53
|
+
eventBus?.emit('security.breached_password.detected', {
|
|
54
|
+
meta: { count, userId: context?.userId },
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
return { breached, count };
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return { breached: false, count: 0 };
|
|
61
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { RedisLike } from '../types/redis';
|
|
2
|
+
export interface ICacheAdapter {
|
|
3
|
+
name: string;
|
|
4
|
+
get(key: string): Promise<string | null>;
|
|
5
|
+
set(key: string, value: string, ttl?: number): Promise<void>;
|
|
6
|
+
del(key: string): Promise<void>;
|
|
7
|
+
delPattern(pattern: string): Promise<void>;
|
|
8
|
+
isReady(): boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare function createMemoryCacheAdapter(): ICacheAdapter;
|
|
11
|
+
export declare function createSqliteCacheAdapter(db: import('bun:sqlite').Database): ICacheAdapter;
|
|
12
|
+
export declare function createRedisCacheAdapter(getRedis: () => RedisLike, appName: string): ICacheAdapter;
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { DEFAULT_MAX_ENTRIES, evictOldest } from '../../../bunshot-core/src/index.js';
|
|
2
|
+
export function createMemoryCacheAdapter() {
|
|
3
|
+
const store = new Map();
|
|
4
|
+
return {
|
|
5
|
+
name: 'memory',
|
|
6
|
+
async get(key) {
|
|
7
|
+
const entry = store.get(key);
|
|
8
|
+
if (!entry)
|
|
9
|
+
return null;
|
|
10
|
+
if (entry.expiresAt > 0 && entry.expiresAt <= Date.now()) {
|
|
11
|
+
store.delete(key);
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
return entry.value;
|
|
15
|
+
},
|
|
16
|
+
async set(key, value, ttl) {
|
|
17
|
+
evictOldest(store, DEFAULT_MAX_ENTRIES);
|
|
18
|
+
const expiresAt = ttl ? Date.now() + ttl * 1000 : 0;
|
|
19
|
+
store.set(key, { value, expiresAt });
|
|
20
|
+
},
|
|
21
|
+
async del(key) {
|
|
22
|
+
store.delete(key);
|
|
23
|
+
},
|
|
24
|
+
async delPattern(pattern) {
|
|
25
|
+
const regex = new RegExp('^' + pattern.replace(/\*/g, '.*') + '$');
|
|
26
|
+
for (const key of store.keys()) {
|
|
27
|
+
if (regex.test(key))
|
|
28
|
+
store.delete(key);
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
isReady() {
|
|
32
|
+
return true;
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
// ---------------------------------------------------------------------------
|
|
37
|
+
// SQLite cache factory
|
|
38
|
+
// ---------------------------------------------------------------------------
|
|
39
|
+
export function createSqliteCacheAdapter(db) {
|
|
40
|
+
let initialized = false;
|
|
41
|
+
function init() {
|
|
42
|
+
if (initialized)
|
|
43
|
+
return;
|
|
44
|
+
db.run(`CREATE TABLE IF NOT EXISTS auth_cache (
|
|
45
|
+
key TEXT PRIMARY KEY,
|
|
46
|
+
value TEXT NOT NULL,
|
|
47
|
+
expiresAt INTEGER NOT NULL
|
|
48
|
+
)`);
|
|
49
|
+
db.run('CREATE INDEX IF NOT EXISTS idx_auth_cache_expiresAt ON auth_cache(expiresAt)');
|
|
50
|
+
initialized = true;
|
|
51
|
+
}
|
|
52
|
+
return {
|
|
53
|
+
name: 'sqlite',
|
|
54
|
+
async get(key) {
|
|
55
|
+
init();
|
|
56
|
+
const now = Date.now();
|
|
57
|
+
const row = db
|
|
58
|
+
.query('SELECT value FROM auth_cache WHERE key = ? AND (expiresAt = 0 OR expiresAt > ?)')
|
|
59
|
+
.get(key, now);
|
|
60
|
+
return row?.value ?? null;
|
|
61
|
+
},
|
|
62
|
+
async set(key, value, ttl) {
|
|
63
|
+
init();
|
|
64
|
+
const expiresAt = ttl ? Date.now() + ttl * 1000 : 0;
|
|
65
|
+
db.run(`INSERT INTO auth_cache (key, value, expiresAt)
|
|
66
|
+
VALUES (?, ?, ?)
|
|
67
|
+
ON CONFLICT(key) DO UPDATE SET value = excluded.value, expiresAt = excluded.expiresAt`, [key, value, expiresAt]);
|
|
68
|
+
},
|
|
69
|
+
async del(key) {
|
|
70
|
+
init();
|
|
71
|
+
db.run('DELETE FROM auth_cache WHERE key = ?', [key]);
|
|
72
|
+
},
|
|
73
|
+
async delPattern(pattern) {
|
|
74
|
+
init();
|
|
75
|
+
const likePattern = pattern.replace(/\*/g, '%');
|
|
76
|
+
db.run('DELETE FROM auth_cache WHERE key LIKE ?', [likePattern]);
|
|
77
|
+
},
|
|
78
|
+
isReady() {
|
|
79
|
+
return true;
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
// ---------------------------------------------------------------------------
|
|
84
|
+
// Redis cache factory
|
|
85
|
+
// ---------------------------------------------------------------------------
|
|
86
|
+
export function createRedisCacheAdapter(getRedis, appName) {
|
|
87
|
+
return {
|
|
88
|
+
name: 'redis',
|
|
89
|
+
async get(key) {
|
|
90
|
+
return getRedis().get(`cache:${appName}:${key}`);
|
|
91
|
+
},
|
|
92
|
+
async set(key, value, ttl) {
|
|
93
|
+
if (ttl) {
|
|
94
|
+
await getRedis().set(`cache:${appName}:${key}`, value, 'EX', ttl);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
await getRedis().set(`cache:${appName}:${key}`, value);
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
async del(key) {
|
|
101
|
+
await getRedis().del(`cache:${appName}:${key}`);
|
|
102
|
+
},
|
|
103
|
+
async delPattern(pattern) {
|
|
104
|
+
const redis = getRedis();
|
|
105
|
+
const fullPattern = `cache:${appName}:${pattern.replace(/\*/g, '*')}`;
|
|
106
|
+
const keys = await redis.keys(fullPattern);
|
|
107
|
+
if (keys.length > 0)
|
|
108
|
+
await redis.del(...keys);
|
|
109
|
+
},
|
|
110
|
+
isReady() {
|
|
111
|
+
try {
|
|
112
|
+
getRedis();
|
|
113
|
+
return true;
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
}
|
|
@@ -2,9 +2,12 @@
|
|
|
2
2
|
// Trust-proxy configuration (set once at startup via setTrustProxy)
|
|
3
3
|
// ---------------------------------------------------------------------------
|
|
4
4
|
let _trustProxy = false;
|
|
5
|
+
let _trustProxyConfigured = false;
|
|
5
6
|
export const setTrustProxy = (value) => {
|
|
6
7
|
_trustProxy = value;
|
|
8
|
+
_trustProxyConfigured = true;
|
|
7
9
|
};
|
|
10
|
+
export const isTrustProxyConfigured = () => _trustProxyConfigured;
|
|
8
11
|
// ---------------------------------------------------------------------------
|
|
9
12
|
// Centralized client IP extraction
|
|
10
13
|
// ---------------------------------------------------------------------------
|
|
@@ -19,6 +22,8 @@ export const setTrustProxy = (value) => {
|
|
|
19
22
|
*
|
|
20
23
|
* Returns `"unknown"` if no IP can be determined.
|
|
21
24
|
*/
|
|
25
|
+
/** Strip the IPv4-mapped IPv6 prefix added by Node.js/Bun (e.g. "::ffff:127.0.0.1" → "127.0.0.1"). */
|
|
26
|
+
const normalizeIp = (ip) => ip.startsWith("::ffff:") ? ip.slice(7) : ip;
|
|
22
27
|
export const getClientIp = (c) => {
|
|
23
28
|
// Socket-level IP via Bun's server (passed as c.env by Bun.serve)
|
|
24
29
|
let socketIp;
|
|
@@ -32,7 +37,7 @@ export const getClientIp = (c) => {
|
|
|
32
37
|
}
|
|
33
38
|
catch { /* not running under Bun.serve — e.g. test environment */ }
|
|
34
39
|
if (_trustProxy === false) {
|
|
35
|
-
return socketIp ?? "unknown";
|
|
40
|
+
return normalizeIp(socketIp ?? "unknown");
|
|
36
41
|
}
|
|
37
42
|
// Trust N proxy hops: take the Nth-from-right in XFF
|
|
38
43
|
const xff = c.req.header("x-forwarded-for");
|
|
@@ -41,12 +46,14 @@ export const getClientIp = (c) => {
|
|
|
41
46
|
// Index from the right: trustProxy=1 means 1 proxy, so take ips[length - 2]
|
|
42
47
|
const idx = ips.length - _trustProxy - 1;
|
|
43
48
|
if (idx >= 0 && ips[idx]) {
|
|
44
|
-
return ips[idx];
|
|
49
|
+
return normalizeIp(ips[idx]);
|
|
45
50
|
}
|
|
46
|
-
// If fewer entries than expected, fall back to
|
|
47
|
-
|
|
48
|
-
return ips[0];
|
|
51
|
+
// If fewer entries than expected, fall back to socket IP (not leftmost/attacker-controlled)
|
|
52
|
+
return normalizeIp(socketIp ?? "unknown");
|
|
49
53
|
}
|
|
50
|
-
// Fallback: X-Real-IP header, then socket IP
|
|
51
|
-
|
|
54
|
+
// Fallback: X-Real-IP header (only when proxies are configured), then socket IP
|
|
55
|
+
// At this point _trustProxy is narrowed to number (not false, since we returned early above)
|
|
56
|
+
const realIp = c.req.header("x-real-ip");
|
|
57
|
+
const ip = realIp ?? socketIp ?? "unknown";
|
|
58
|
+
return normalizeIp(ip);
|
|
52
59
|
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { AuthResolvedConfig } from '../config/authConfig';
|
|
2
|
+
/**
|
|
3
|
+
* Returns cookie options for the HttpOnly session/auth cookie.
|
|
4
|
+
* httpOnly is always true — not configurable.
|
|
5
|
+
* Defaults match the previously hardcoded values in each route file.
|
|
6
|
+
*/
|
|
7
|
+
export declare function getAuthCookieOptions(isProduction: boolean, config: AuthResolvedConfig, maxAge?: number): {
|
|
8
|
+
httpOnly: true;
|
|
9
|
+
secure: boolean;
|
|
10
|
+
sameSite: "Strict" | "Lax" | "None";
|
|
11
|
+
path: string;
|
|
12
|
+
domain: string | undefined;
|
|
13
|
+
maxAge: number;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Returns cookie options for the CSRF double-submit cookie.
|
|
17
|
+
* httpOnly is always false — JS must read it to set the x-csrf-token header.
|
|
18
|
+
* Defaults match the previously hardcoded values in csrf.ts.
|
|
19
|
+
*/
|
|
20
|
+
export declare function getCsrfCookieOptions(isProduction: boolean, config: AuthResolvedConfig): {
|
|
21
|
+
httpOnly: false;
|
|
22
|
+
secure: boolean;
|
|
23
|
+
sameSite: "Strict" | "Lax" | "None";
|
|
24
|
+
path: string;
|
|
25
|
+
domain: string | undefined;
|
|
26
|
+
maxAge: number;
|
|
27
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
const DEFAULT_SESSION_TTL_SECONDS = 60 * 60 * 24 * 7; // 7 days
|
|
2
|
+
/**
|
|
3
|
+
* Returns cookie options for the HttpOnly session/auth cookie.
|
|
4
|
+
* httpOnly is always true — not configurable.
|
|
5
|
+
* Defaults match the previously hardcoded values in each route file.
|
|
6
|
+
*/
|
|
7
|
+
export function getAuthCookieOptions(isProduction, config, maxAge) {
|
|
8
|
+
const c = config.authCookie;
|
|
9
|
+
return {
|
|
10
|
+
httpOnly: true, // always true for auth cookies
|
|
11
|
+
secure: c.secure ?? isProduction,
|
|
12
|
+
sameSite: (c.sameSite ?? 'Lax'),
|
|
13
|
+
path: c.path ?? '/',
|
|
14
|
+
domain: c.domain,
|
|
15
|
+
maxAge: maxAge ?? c.maxAge ?? DEFAULT_SESSION_TTL_SECONDS,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Returns cookie options for the CSRF double-submit cookie.
|
|
20
|
+
* httpOnly is always false — JS must read it to set the x-csrf-token header.
|
|
21
|
+
* Defaults match the previously hardcoded values in csrf.ts.
|
|
22
|
+
*/
|
|
23
|
+
export function getCsrfCookieOptions(isProduction, config) {
|
|
24
|
+
const c = config.csrfCookie;
|
|
25
|
+
return {
|
|
26
|
+
httpOnly: false, // always false — JS must read it
|
|
27
|
+
secure: c.secure ?? isProduction,
|
|
28
|
+
sameSite: (c.sameSite ?? 'Lax'),
|
|
29
|
+
path: c.path ?? '/',
|
|
30
|
+
domain: c.domain,
|
|
31
|
+
maxAge: c.maxAge ?? 60 * 60 * 24 * 365, // 1 year — tied to browser, not session
|
|
32
|
+
};
|
|
33
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { RepoFactories } from '../../../bunshot-core/src/index.js';
|
|
2
|
+
import type { RedisLike } from '../types/redis';
|
|
3
|
+
export interface CredentialStuffingConfig {
|
|
4
|
+
/** Block when an IP attempts login against this many distinct accounts. Default: 5 per 15 min. */
|
|
5
|
+
maxAccountsPerIp?: {
|
|
6
|
+
count: number;
|
|
7
|
+
windowMs: number;
|
|
8
|
+
};
|
|
9
|
+
/** Block when an account is attempted from this many distinct IPs. Default: 10 per 15 min. */
|
|
10
|
+
maxIpsPerAccount?: {
|
|
11
|
+
count: number;
|
|
12
|
+
windowMs: number;
|
|
13
|
+
};
|
|
14
|
+
/** Called when stuffing is detected. Non-blocking, errors swallowed. */
|
|
15
|
+
onDetected?: (signal: {
|
|
16
|
+
type: 'ip' | 'account';
|
|
17
|
+
key: string;
|
|
18
|
+
count: number;
|
|
19
|
+
}) => void;
|
|
20
|
+
}
|
|
21
|
+
export interface CredentialStuffingService {
|
|
22
|
+
/**
|
|
23
|
+
* Records a failed login attempt and checks whether the thresholds are now
|
|
24
|
+
* exceeded. Returns `true` if the IP or account is now blocked so callers
|
|
25
|
+
* can gate the response immediately — treat the return value as a blocking
|
|
26
|
+
* decision, not a fire-and-forget side-effect.
|
|
27
|
+
*/
|
|
28
|
+
trackFailedLogin(ip: string, identifier: string): Promise<boolean>;
|
|
29
|
+
isStuffingBlocked(ip: string, identifier: string): Promise<boolean>;
|
|
30
|
+
}
|
|
31
|
+
export interface ICredentialStuffingRepository {
|
|
32
|
+
addToSet(key: string, member: string, windowMs: number): Promise<number>;
|
|
33
|
+
getSetSize(key: string, windowMs: number): Promise<number>;
|
|
34
|
+
}
|
|
35
|
+
export declare function createMemoryCredentialStuffingRepository(): ICredentialStuffingRepository;
|
|
36
|
+
export declare function createSqliteCredentialStuffingRepository(db: import('bun:sqlite').Database): ICredentialStuffingRepository;
|
|
37
|
+
export declare function createRedisCredentialStuffingRepository(getRedis: () => RedisLike, appName: string): ICredentialStuffingRepository;
|
|
38
|
+
export declare function createMongoCredentialStuffingRepository(conn: import('mongoose').Connection, mg: typeof import('mongoose')): ICredentialStuffingRepository;
|
|
39
|
+
export declare const credentialStuffingFactories: RepoFactories<ICredentialStuffingRepository>;
|
|
40
|
+
export declare function createCredentialStuffingService(config: CredentialStuffingConfig, repo: ICredentialStuffingRepository): CredentialStuffingService;
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import { DEFAULT_MAX_ENTRIES, evictOldest } from '../../../bunshot-core/src/index.js';
|
|
2
|
+
// ---------------------------------------------------------------------------
|
|
3
|
+
// Redis scripts
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
const REDIS_ADD_TO_SET_LUA = `
|
|
6
|
+
local key = KEYS[1]
|
|
7
|
+
local member = ARGV[1]
|
|
8
|
+
local now = tonumber(ARGV[2])
|
|
9
|
+
local windowStart = tonumber(ARGV[3])
|
|
10
|
+
local windowMs = tonumber(ARGV[4])
|
|
11
|
+
redis.call('ZADD', key, now, member)
|
|
12
|
+
redis.call('ZREMRANGEBYSCORE', key, '-inf', windowStart)
|
|
13
|
+
redis.call('PEXPIRE', key, windowMs)
|
|
14
|
+
return redis.call('ZCARD', key)
|
|
15
|
+
`;
|
|
16
|
+
const REDIS_GET_SET_SIZE_LUA = `
|
|
17
|
+
local key = KEYS[1]
|
|
18
|
+
local windowStart = tonumber(ARGV[1])
|
|
19
|
+
redis.call('ZREMRANGEBYSCORE', key, '-inf', windowStart)
|
|
20
|
+
return redis.call('ZCARD', key)
|
|
21
|
+
`;
|
|
22
|
+
export function createMemoryCredentialStuffingRepository() {
|
|
23
|
+
const store = new Map();
|
|
24
|
+
function cleanExpired() {
|
|
25
|
+
const now = Date.now();
|
|
26
|
+
for (const [key, entry] of store.entries()) {
|
|
27
|
+
if (entry.expiresAt < now)
|
|
28
|
+
store.delete(key);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return {
|
|
32
|
+
async addToSet(key, member, windowMs) {
|
|
33
|
+
cleanExpired();
|
|
34
|
+
const now = Date.now();
|
|
35
|
+
let entry = store.get(key);
|
|
36
|
+
if (!entry || entry.expiresAt < now) {
|
|
37
|
+
entry = { members: new Set(), expiresAt: now + windowMs };
|
|
38
|
+
evictOldest(store, DEFAULT_MAX_ENTRIES);
|
|
39
|
+
store.set(key, entry);
|
|
40
|
+
}
|
|
41
|
+
entry.members.add(member);
|
|
42
|
+
return entry.members.size;
|
|
43
|
+
},
|
|
44
|
+
async getSetSize(key) {
|
|
45
|
+
cleanExpired();
|
|
46
|
+
const now = Date.now();
|
|
47
|
+
const entry = store.get(key);
|
|
48
|
+
if (!entry || entry.expiresAt < now)
|
|
49
|
+
return 0;
|
|
50
|
+
return entry.members.size;
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
// ---------------------------------------------------------------------------
|
|
55
|
+
// SQLite repository factory
|
|
56
|
+
// ---------------------------------------------------------------------------
|
|
57
|
+
export function createSqliteCredentialStuffingRepository(db) {
|
|
58
|
+
let initialized = false;
|
|
59
|
+
function init() {
|
|
60
|
+
if (initialized)
|
|
61
|
+
return;
|
|
62
|
+
db.run(`CREATE TABLE IF NOT EXISTS auth_credential_stuffing (
|
|
63
|
+
bucketKey TEXT NOT NULL,
|
|
64
|
+
member TEXT NOT NULL,
|
|
65
|
+
expiresAt INTEGER NOT NULL,
|
|
66
|
+
PRIMARY KEY (bucketKey, member)
|
|
67
|
+
)`);
|
|
68
|
+
db.run('CREATE INDEX IF NOT EXISTS idx_auth_credential_stuffing_expiresAt ON auth_credential_stuffing(expiresAt)');
|
|
69
|
+
db.run('CREATE INDEX IF NOT EXISTS idx_auth_credential_stuffing_bucketKey ON auth_credential_stuffing(bucketKey)');
|
|
70
|
+
initialized = true;
|
|
71
|
+
}
|
|
72
|
+
return {
|
|
73
|
+
async addToSet(key, member, windowMs) {
|
|
74
|
+
init();
|
|
75
|
+
const now = Date.now();
|
|
76
|
+
const expiresAt = now + windowMs;
|
|
77
|
+
db.run('DELETE FROM auth_credential_stuffing WHERE bucketKey = ? AND expiresAt <= ?', [
|
|
78
|
+
key,
|
|
79
|
+
now,
|
|
80
|
+
]);
|
|
81
|
+
db.run(`INSERT INTO auth_credential_stuffing (bucketKey, member, expiresAt)
|
|
82
|
+
VALUES (?, ?, ?)
|
|
83
|
+
ON CONFLICT(bucketKey, member) DO UPDATE SET expiresAt = excluded.expiresAt`, [key, member, expiresAt]);
|
|
84
|
+
const row = db
|
|
85
|
+
.query('SELECT COUNT(*) AS count FROM auth_credential_stuffing WHERE bucketKey = ? AND expiresAt > ?')
|
|
86
|
+
.get(key, now);
|
|
87
|
+
return row?.count ?? 0;
|
|
88
|
+
},
|
|
89
|
+
async getSetSize(key) {
|
|
90
|
+
init();
|
|
91
|
+
const now = Date.now();
|
|
92
|
+
db.run('DELETE FROM auth_credential_stuffing WHERE bucketKey = ? AND expiresAt <= ?', [
|
|
93
|
+
key,
|
|
94
|
+
now,
|
|
95
|
+
]);
|
|
96
|
+
const row = db
|
|
97
|
+
.query('SELECT COUNT(*) AS count FROM auth_credential_stuffing WHERE bucketKey = ? AND expiresAt > ?')
|
|
98
|
+
.get(key, now);
|
|
99
|
+
return row?.count ?? 0;
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
// ---------------------------------------------------------------------------
|
|
104
|
+
// Redis repository factory
|
|
105
|
+
// ---------------------------------------------------------------------------
|
|
106
|
+
export function createRedisCredentialStuffingRepository(getRedis, appName) {
|
|
107
|
+
const redis = getRedis();
|
|
108
|
+
return {
|
|
109
|
+
async addToSet(key, member, windowMs) {
|
|
110
|
+
const now = Date.now();
|
|
111
|
+
const windowStart = now - windowMs;
|
|
112
|
+
const fullKey = `credstuffing:${appName}:${key}`;
|
|
113
|
+
return redis.eval(REDIS_ADD_TO_SET_LUA, 1, fullKey, member, now, windowStart, windowMs);
|
|
114
|
+
},
|
|
115
|
+
async getSetSize(key, windowMs) {
|
|
116
|
+
const now = Date.now();
|
|
117
|
+
const windowStart = now - windowMs;
|
|
118
|
+
const fullKey = `credstuffing:${appName}:${key}`;
|
|
119
|
+
return redis.eval(REDIS_GET_SET_SIZE_LUA, 1, fullKey, windowStart);
|
|
120
|
+
},
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
export function createMongoCredentialStuffingRepository(conn, mg) {
|
|
124
|
+
function getModel() {
|
|
125
|
+
if (conn.models['CredentialStuffing']) {
|
|
126
|
+
return conn.models['CredentialStuffing'];
|
|
127
|
+
}
|
|
128
|
+
const { Schema } = mg;
|
|
129
|
+
const schema = new Schema({
|
|
130
|
+
bucketKey: { type: String, required: true, index: true },
|
|
131
|
+
member: { type: String, required: true },
|
|
132
|
+
expiresAt: { type: Date, required: true, index: { expireAfterSeconds: 0 } },
|
|
133
|
+
}, { collection: 'credential_stuffing' });
|
|
134
|
+
schema.index({ bucketKey: 1, member: 1 }, { unique: true });
|
|
135
|
+
return conn.model('CredentialStuffing', schema);
|
|
136
|
+
}
|
|
137
|
+
return {
|
|
138
|
+
async addToSet(key, member, windowMs) {
|
|
139
|
+
const expiresAt = new Date(Date.now() + windowMs);
|
|
140
|
+
await getModel().updateOne({ bucketKey: key, member }, { $set: { expiresAt } }, { upsert: true });
|
|
141
|
+
return getModel().countDocuments({
|
|
142
|
+
bucketKey: key,
|
|
143
|
+
expiresAt: { $gt: new Date() },
|
|
144
|
+
});
|
|
145
|
+
},
|
|
146
|
+
async getSetSize(key) {
|
|
147
|
+
return getModel().countDocuments({
|
|
148
|
+
bucketKey: key,
|
|
149
|
+
expiresAt: { $gt: new Date() },
|
|
150
|
+
});
|
|
151
|
+
},
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
// ---------------------------------------------------------------------------
|
|
155
|
+
// Factory map
|
|
156
|
+
// ---------------------------------------------------------------------------
|
|
157
|
+
export const credentialStuffingFactories = {
|
|
158
|
+
memory: () => createMemoryCredentialStuffingRepository(),
|
|
159
|
+
sqlite: infra => createSqliteCredentialStuffingRepository(infra.getSqliteDb()),
|
|
160
|
+
redis: infra => createRedisCredentialStuffingRepository(infra.getRedis, infra.appName),
|
|
161
|
+
mongo: infra => {
|
|
162
|
+
const { conn, mg } = infra.getMongo();
|
|
163
|
+
return createMongoCredentialStuffingRepository(conn, mg);
|
|
164
|
+
},
|
|
165
|
+
postgres: () => {
|
|
166
|
+
throw new Error('[bunshot-auth] postgres store is not yet supported for credentialStuffing repository');
|
|
167
|
+
},
|
|
168
|
+
};
|
|
169
|
+
// ---------------------------------------------------------------------------
|
|
170
|
+
// Service factory
|
|
171
|
+
// ---------------------------------------------------------------------------
|
|
172
|
+
export function createCredentialStuffingService(config, repo) {
|
|
173
|
+
return {
|
|
174
|
+
async trackFailedLogin(ip, identifier) {
|
|
175
|
+
const ipMax = config.maxAccountsPerIp?.count ?? 5;
|
|
176
|
+
const accountMax = config.maxIpsPerAccount?.count ?? 10;
|
|
177
|
+
const ipWindowMs = config.maxAccountsPerIp?.windowMs ?? 15 * 60 * 1000;
|
|
178
|
+
const accountWindowMs = config.maxIpsPerAccount?.windowMs ?? 15 * 60 * 1000;
|
|
179
|
+
const ipCount = await repo.addToSet(`ip:${ip}`, identifier, ipWindowMs);
|
|
180
|
+
if (ipCount >= ipMax) {
|
|
181
|
+
try {
|
|
182
|
+
config.onDetected?.({ type: 'ip', key: ip, count: ipCount });
|
|
183
|
+
}
|
|
184
|
+
catch { }
|
|
185
|
+
return true;
|
|
186
|
+
}
|
|
187
|
+
const accountCount = await repo.addToSet(`account:${identifier}`, ip, accountWindowMs);
|
|
188
|
+
if (accountCount >= accountMax) {
|
|
189
|
+
try {
|
|
190
|
+
config.onDetected?.({ type: 'account', key: identifier, count: accountCount });
|
|
191
|
+
}
|
|
192
|
+
catch { }
|
|
193
|
+
return true;
|
|
194
|
+
}
|
|
195
|
+
return false;
|
|
196
|
+
},
|
|
197
|
+
async isStuffingBlocked(ip, identifier) {
|
|
198
|
+
const ipMax = config.maxAccountsPerIp?.count ?? 5;
|
|
199
|
+
const accountMax = config.maxIpsPerAccount?.count ?? 10;
|
|
200
|
+
const ipWindowMs = config.maxAccountsPerIp?.windowMs ?? 15 * 60 * 1000;
|
|
201
|
+
const accountWindowMs = config.maxIpsPerAccount?.windowMs ?? 15 * 60 * 1000;
|
|
202
|
+
const ipCount = await repo.getSetSize(`ip:${ip}`, ipWindowMs);
|
|
203
|
+
if (ipCount >= ipMax) {
|
|
204
|
+
try {
|
|
205
|
+
config.onDetected?.({ type: 'ip', key: ip, count: ipCount });
|
|
206
|
+
}
|
|
207
|
+
catch { }
|
|
208
|
+
return true;
|
|
209
|
+
}
|
|
210
|
+
const accountCount = await repo.getSetSize(`account:${identifier}`, accountWindowMs);
|
|
211
|
+
if (accountCount >= accountMax) {
|
|
212
|
+
try {
|
|
213
|
+
config.onDetected?.({ type: 'account', key: identifier, count: accountCount });
|
|
214
|
+
}
|
|
215
|
+
catch { }
|
|
216
|
+
return true;
|
|
217
|
+
}
|
|
218
|
+
return false;
|
|
219
|
+
},
|
|
220
|
+
};
|
|
221
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { RepoFactories } from '../../../bunshot-core/src/index.js';
|
|
2
|
+
import type { RedisLike } from '../types/redis';
|
|
3
|
+
export interface IDeletionCancelTokenRepository {
|
|
4
|
+
store(hash: string, userId: string, jobId: string, ttl: number): Promise<void>;
|
|
5
|
+
consume(hash: string): Promise<{
|
|
6
|
+
userId: string;
|
|
7
|
+
jobId: string;
|
|
8
|
+
} | null>;
|
|
9
|
+
}
|
|
10
|
+
export declare function createMemoryDeletionCancelTokenRepository(): IDeletionCancelTokenRepository;
|
|
11
|
+
export declare function createSqliteDeletionCancelTokenRepository(db: import('bun:sqlite').Database): IDeletionCancelTokenRepository;
|
|
12
|
+
export declare function createRedisDeletionCancelTokenRepository(getRedis: () => RedisLike, appName: string): IDeletionCancelTokenRepository;
|
|
13
|
+
export declare function createMongoDeletionCancelTokenRepository(conn: import('mongoose').Connection, mg: typeof import('mongoose')): IDeletionCancelTokenRepository;
|
|
14
|
+
export declare const deletionCancelTokenFactories: RepoFactories<IDeletionCancelTokenRepository>;
|
|
15
|
+
export declare const createDeletionCancelToken: (repo: IDeletionCancelTokenRepository, userId: string, jobId: string, gracePeriodSeconds: number) => Promise<string>;
|
|
16
|
+
export declare const consumeDeletionCancelToken: (repo: IDeletionCancelTokenRepository, token: string) => Promise<{
|
|
17
|
+
userId: string;
|
|
18
|
+
jobId: string;
|
|
19
|
+
} | null>;
|