@lastshotlabs/bunshot 0.0.27 → 0.1.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/.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/{lib → packages/bunshot-auth/src/lib}/breachedPassword.d.ts +8 -2
- package/dist/{lib → packages/bunshot-auth/src/lib}/breachedPassword.js +22 -9
- 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 +211 -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/{lib → packages/bunshot-auth/src/lib}/logger.js +3 -3
- package/dist/{lib → packages/bunshot-auth/src/lib}/m2m.d.ts +5 -4
- package/dist/{lib → packages/bunshot-auth/src/lib}/m2m.js +6 -10
- 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/{lib → packages/bunshot-auth/src/lib}/scim.d.ts +7 -7
- package/dist/{lib → packages/bunshot-auth/src/lib}/scim.js +15 -13
- 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/{lib → packages/bunshot-auth/src/lib}/suspension.d.ts +3 -2
- package/dist/{lib → packages/bunshot-auth/src/lib}/suspension.js +2 -5
- 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 -8
- 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/{middleware → packages/bunshot-auth/src/middleware}/requireScope.d.ts +2 -2
- package/dist/{middleware → packages/bunshot-auth/src/middleware}/requireScope.js +6 -6
- package/dist/{middleware → packages/bunshot-auth/src/middleware}/requireStepUp.d.ts +2 -2
- package/dist/{middleware → packages/bunshot-auth/src/middleware}/requireStepUp.js +8 -7
- 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 +12 -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/{models → packages/bunshot-auth/src/models}/M2MClient.d.ts +1 -1
- package/dist/{models → packages/bunshot-auth/src/models}/M2MClient.js +5 -5
- 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 +277 -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/{lib → packages/bunshot-core/src}/captcha.d.ts +1 -10
- 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/{lib/HttpError.d.ts → packages/bunshot-core/src/errors.d.ts} +4 -1
- package/dist/{lib/HttpError.js → packages/bunshot-core/src/errors.js} +7 -1
- 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 +10 -10
- 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/{lib → src/framework/lib}/captcha.js +13 -10
- 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 +11 -10
- 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/{middleware → src/framework/middleware}/captcha.d.ts +2 -3
- package/dist/src/framework/middleware/captcha.js +37 -0
- package/dist/{middleware → src/framework/middleware}/errorHandler.d.ts +1 -1
- package/dist/{middleware → src/framework/middleware}/errorHandler.js +2 -2
- 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 -20
- 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 -12
- 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 +64 -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/{routes → src/framework/routes}/jobs.js +128 -103
- package/dist/src/framework/routes/metrics.d.ts +10 -0
- package/dist/src/framework/routes/metrics.js +57 -0
- package/dist/{routes → src/framework/routes}/uploads.d.ts +3 -3
- 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/{lib/appConfig.js → src/lib/authConfig.js} +75 -17
- package/dist/{lib → src/lib}/context.d.ts +6 -12
- 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 +35 -8
- package/dist/src/testing.d.ts +34 -0
- package/dist/src/testing.js +93 -0
- package/package.json +100 -26
- package/dist/adapters/memoryAuth.d.ts +0 -52
- package/dist/adapters/memoryAuth.js +0 -749
- 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 -403
- package/dist/adapters/sqliteAuth.d.ts +0 -72
- package/dist/adapters/sqliteAuth.js +0 -858
- package/dist/app.d.ts +0 -559
- package/dist/app.js +0 -651
- 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 -117
- package/dist/index.js +0 -88
- package/dist/lib/appConfig.d.ts +0 -275
- package/dist/lib/auditLog.d.ts +0 -58
- package/dist/lib/auditLog.js +0 -218
- package/dist/lib/authAdapter.d.ts +0 -246
- package/dist/lib/authAdapter.js +0 -7
- package/dist/lib/authRateLimit.d.ts +0 -13
- package/dist/lib/authRateLimit.js +0 -117
- package/dist/lib/clientIp.d.ts +0 -14
- package/dist/lib/credentialStuffing.d.ts +0 -31
- package/dist/lib/credentialStuffing.js +0 -77
- 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 -19
- package/dist/lib/emailVerification.js +0 -129
- package/dist/lib/fingerprint.js +0 -36
- package/dist/lib/idempotency.js +0 -182
- package/dist/lib/jwks.d.ts +0 -25
- package/dist/lib/jwks.js +0 -51
- package/dist/lib/jwt.d.ts +0 -15
- package/dist/lib/jwt.js +0 -111
- package/dist/lib/metrics.d.ts +0 -14
- package/dist/lib/mfaChallenge.d.ts +0 -55
- package/dist/lib/mfaChallenge.js +0 -398
- 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 -95
- 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 -93
- package/dist/lib/roles.d.ts +0 -7
- package/dist/lib/roles.js +0 -49
- package/dist/lib/saml.d.ts +0 -25
- package/dist/lib/saml.js +0 -64
- package/dist/lib/securityEvents.d.ts +0 -28
- package/dist/lib/securityEvents.js +0 -26
- package/dist/lib/session.d.ts +0 -49
- package/dist/lib/session.js +0 -597
- package/dist/lib/tenant.d.ts +0 -15
- package/dist/lib/tenant.js +0 -65
- package/dist/lib/upload.js +0 -112
- package/dist/lib/uploadRegistry.d.ts +0 -18
- package/dist/lib/uploadRegistry.js +0 -83
- package/dist/lib/ws.d.ts +0 -22
- package/dist/lib/ws.js +0 -96
- 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/captcha.js +0 -36
- package/dist/middleware/csrf.js +0 -129
- package/dist/middleware/identify.d.ts +0 -3
- package/dist/middleware/identify.js +0 -122
- 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/scimAuth.d.ts +0 -8
- package/dist/middleware/scimAuth.js +0 -29
- 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 -55
- 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 -12
- package/dist/routes/auth.js +0 -744
- 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/m2m.d.ts +0 -2
- package/dist/routes/m2m.js +0 -72
- package/dist/routes/metrics.d.ts +0 -8
- package/dist/routes/metrics.js +0 -55
- package/dist/routes/mfa.d.ts +0 -5
- package/dist/routes/mfa.js +0 -628
- package/dist/routes/oauth.d.ts +0 -2
- package/dist/routes/oauth.js +0 -520
- package/dist/routes/oidc.d.ts +0 -2
- package/dist/routes/oidc.js +0 -29
- package/dist/routes/passkey.d.ts +0 -1
- package/dist/routes/passkey.js +0 -157
- package/dist/routes/saml.d.ts +0 -2
- package/dist/routes/saml.js +0 -86
- package/dist/routes/scim.d.ts +0 -2
- package/dist/routes/scim.js +0 -255
- package/dist/routes/uploads.js +0 -227
- 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 -29
- package/dist/services/auth.js +0 -238
- package/dist/ws/index.d.ts +0 -10
- package/dist/ws/index.js +0 -39
- 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 -790
- package/docs/sections/auth-flow/overview.md +0 -10
- package/docs/sections/auth-security-examples/full.md +0 -388
- 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 -131
- 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/passkey-login/full.md +0 -90
- package/docs/sections/passkey-login/overview.md +0 -1
- 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 -208
- package/docs/sections/versioning/full.md +0 -85
- package/docs/sections/webhook-auth/full.md +0 -100
- package/docs/sections/websocket/full.md +0 -196
- 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-auth/src/lib}/logger.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,469 @@
|
|
|
1
|
+
import { validateServerConfig } from './framework/config/schema';
|
|
2
|
+
import { log } from './framework/lib/logger';
|
|
3
|
+
import { routePatternCanMatchLiteral } from './framework/lib/sseCollision';
|
|
4
|
+
import { cleanupSocket, handleRoomActions } from './framework/lib/ws';
|
|
5
|
+
import { deregisterSocket, handlePong, registerSocket, startHeartbeat, stopHeartbeat, } from './framework/lib/wsHeartbeat';
|
|
6
|
+
import { wsEndpointKey } from './framework/lib/wsNamespace';
|
|
7
|
+
import { trackSocket, untrackSocket } from './framework/lib/wsPresence';
|
|
8
|
+
// ensureClientSafeEventKey is now an instance method on BunshotEventBus
|
|
9
|
+
import { createSseRegistry, createSseUpgradeHandler } from './framework/sse/index';
|
|
10
|
+
import { createWsUpgradeHandler } from './framework/ws/index';
|
|
11
|
+
import { disconnectMongo } from './lib/mongo';
|
|
12
|
+
import { disconnectRedis } from './lib/redis';
|
|
13
|
+
import { createApp } from './app';
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
// Server → Context mapping (for testing / tooling access)
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
const SERVER_CONTEXT_SYMBOL = Symbol.for('bunshot.serverContext');
|
|
18
|
+
const DEFAULT_SHUTDOWN_TIMEOUT_MS = 30_000;
|
|
19
|
+
const SHUTDOWN_REGISTRY_SYMBOL = Symbol.for('bunshot.shutdownRegistry');
|
|
20
|
+
function getShutdownRegistry() {
|
|
21
|
+
const proc = process;
|
|
22
|
+
let registry = proc[SHUTDOWN_REGISTRY_SYMBOL];
|
|
23
|
+
if (!registry) {
|
|
24
|
+
registry = { callbacks: new Map(), listeners: null };
|
|
25
|
+
proc[SHUTDOWN_REGISTRY_SYMBOL] = registry;
|
|
26
|
+
}
|
|
27
|
+
return registry;
|
|
28
|
+
}
|
|
29
|
+
function ensureProcessShutdownListeners() {
|
|
30
|
+
const registry = getShutdownRegistry();
|
|
31
|
+
if (registry.listeners)
|
|
32
|
+
return;
|
|
33
|
+
let dispatching = false;
|
|
34
|
+
const dispatch = (signal) => {
|
|
35
|
+
if (dispatching)
|
|
36
|
+
return;
|
|
37
|
+
dispatching = true;
|
|
38
|
+
const forceExit = setTimeout(() => {
|
|
39
|
+
console.error(`[shutdown] Timed out after ${DEFAULT_SHUTDOWN_TIMEOUT_MS}ms during ${signal}; forcing exit`);
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}, DEFAULT_SHUTDOWN_TIMEOUT_MS);
|
|
42
|
+
forceExit.unref?.();
|
|
43
|
+
const cbs = [...registry.callbacks.values()];
|
|
44
|
+
void Promise.allSettled(cbs.map(cb => cb(signal))).then(results => {
|
|
45
|
+
clearTimeout(forceExit);
|
|
46
|
+
const exitCode = results.some(r => r.status === 'rejected' || (r.status === 'fulfilled' && r.value !== 0))
|
|
47
|
+
? 1
|
|
48
|
+
: 0;
|
|
49
|
+
console.log(`[shutdown] All servers completed with exit code ${exitCode}`);
|
|
50
|
+
process.exit(exitCode);
|
|
51
|
+
});
|
|
52
|
+
};
|
|
53
|
+
const sigterm = () => dispatch('SIGTERM');
|
|
54
|
+
const sigint = () => dispatch('SIGINT');
|
|
55
|
+
process.on('SIGTERM', sigterm);
|
|
56
|
+
process.on('SIGINT', sigint);
|
|
57
|
+
registry.listeners = { sigterm, sigint };
|
|
58
|
+
}
|
|
59
|
+
function removeProcessShutdownListeners() {
|
|
60
|
+
const registry = getShutdownRegistry();
|
|
61
|
+
const { listeners } = registry;
|
|
62
|
+
if (!listeners)
|
|
63
|
+
return;
|
|
64
|
+
process.off('SIGTERM', listeners.sigterm);
|
|
65
|
+
process.off('SIGINT', listeners.sigint);
|
|
66
|
+
registry.listeners = null;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Retrieve the BunshotContext associated with a server.
|
|
70
|
+
* Available after createServer() completes. Used by test helpers.
|
|
71
|
+
*/
|
|
72
|
+
export function getServerContext(server) {
|
|
73
|
+
return (server[SERVER_CONTEXT_SYMBOL] ?? null);
|
|
74
|
+
}
|
|
75
|
+
// ---------------------------------------------------------------------------
|
|
76
|
+
// createServer
|
|
77
|
+
// ---------------------------------------------------------------------------
|
|
78
|
+
export const createServer = async (config) => {
|
|
79
|
+
const serverOwnerId = crypto.randomUUID();
|
|
80
|
+
// Validate the full server config shape — catches typos and type errors.
|
|
81
|
+
// createApp separately validates its own subset (app-level keys only).
|
|
82
|
+
const { warnings } = validateServerConfig(config);
|
|
83
|
+
for (const w of warnings)
|
|
84
|
+
console.warn(w);
|
|
85
|
+
// Startup validation — unix is mutually exclusive with port/hostname/tls
|
|
86
|
+
if (config.unix && config.port !== undefined)
|
|
87
|
+
throw new Error('[bunshot] unix and port are mutually exclusive');
|
|
88
|
+
if (config.unix && config.hostname)
|
|
89
|
+
throw new Error('[bunshot] unix and hostname are mutually exclusive');
|
|
90
|
+
if (config.unix && config.tls)
|
|
91
|
+
throw new Error('[bunshot] unix sockets do not support TLS');
|
|
92
|
+
// Extract only app-level config keys — createApp validates its own shape and
|
|
93
|
+
// will warn about unknown keys. Passing the full CreateServerConfig would
|
|
94
|
+
// trigger false warnings for server-only keys like port, sse, ws, etc.
|
|
95
|
+
const { port: _port, hostname: _hostname, unix: _unix, tls: _tls, workersDir: _workersDir, enableWorkers: _enableWorkers, ws: _ws, sse: _sse, maxRequestBodySize: _maxRequestBodySize, ...appConfig } = config;
|
|
96
|
+
const { app, ctx } = await createApp(appConfig);
|
|
97
|
+
const port = Number(process.env.PORT ?? config.port ?? 3000);
|
|
98
|
+
const { workersDir, enableWorkers = true, ws: wsConfig } = config;
|
|
99
|
+
const sseRegistry = createSseRegistry();
|
|
100
|
+
const sseBusListeners = [];
|
|
101
|
+
if (config.sse) {
|
|
102
|
+
// Read bus from context (replaces appMeta WeakMap)
|
|
103
|
+
const bus = ctx.bus;
|
|
104
|
+
const { endpoints: sseEndpoints } = config.sse;
|
|
105
|
+
const wsEndpointPaths = new Set(Object.keys(config.ws?.endpoints ?? {}));
|
|
106
|
+
const honoGetPatterns = app.routes
|
|
107
|
+
.filter(r => r.method === 'GET')
|
|
108
|
+
.map(r => r.path);
|
|
109
|
+
for (const [ssePath, epConfig] of Object.entries(sseEndpoints)) {
|
|
110
|
+
// 1. Literal path — no :params or wildcards in sse.endpoints keys
|
|
111
|
+
if (ssePath.includes(':') || ssePath.includes('*'))
|
|
112
|
+
throw new Error(`[sse] "${ssePath}" must be a literal path — no :params or * wildcards`);
|
|
113
|
+
// 2. Prefix enforcement
|
|
114
|
+
if (!ssePath.startsWith('/__sse/'))
|
|
115
|
+
throw new Error(`[sse] "${ssePath}" must be under the /__sse/ prefix`);
|
|
116
|
+
// 3. WS path collision
|
|
117
|
+
if (wsEndpointPaths.has(ssePath))
|
|
118
|
+
throw new Error(`[sse] "${ssePath}" collides with an existing WS endpoint`);
|
|
119
|
+
// 4. Hono GET route collision (pattern-aware — existing routes may use :param or *)
|
|
120
|
+
for (const pattern of honoGetPatterns) {
|
|
121
|
+
if (routePatternCanMatchLiteral(pattern, ssePath))
|
|
122
|
+
throw new Error(`[sse] "${ssePath}" collides with Hono GET route "${pattern}"`);
|
|
123
|
+
}
|
|
124
|
+
// 5. Per-endpoint bus subscriptions (once per event key, not per client)
|
|
125
|
+
const heartbeatMs = epConfig.heartbeat === undefined ? 30_000 : epConfig.heartbeat;
|
|
126
|
+
const upgradeHandler = epConfig.upgrade ?? createSseUpgradeHandler(ssePath, ctx.userResolver);
|
|
127
|
+
for (const rawKey of epConfig.events) {
|
|
128
|
+
const key = bus.ensureClientSafeEventKey(rawKey, `sse.endpoints["${ssePath}"].events`);
|
|
129
|
+
const listener = (payload) => {
|
|
130
|
+
sseRegistry.fanout(ssePath, key, payload, epConfig.filter);
|
|
131
|
+
};
|
|
132
|
+
bus.on(key, listener);
|
|
133
|
+
sseBusListeners.push({ key, listener });
|
|
134
|
+
}
|
|
135
|
+
// 6. Mount Hono GET route
|
|
136
|
+
app.get(ssePath, async (c) => {
|
|
137
|
+
const result = await upgradeHandler(c.req.raw);
|
|
138
|
+
if (result instanceof Response)
|
|
139
|
+
return result;
|
|
140
|
+
const stream = sseRegistry.createClientStream(ssePath, result, heartbeatMs);
|
|
141
|
+
c.header('Content-Type', 'text/event-stream');
|
|
142
|
+
c.header('Cache-Control', 'no-cache');
|
|
143
|
+
c.header('Connection', 'keep-alive');
|
|
144
|
+
c.header('X-Accel-Buffering', 'no');
|
|
145
|
+
return c.newResponse(stream);
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
// Compute maxRequestBodySize: explicit config wins, else derive from upload config
|
|
150
|
+
let maxRequestBodySize = config.maxRequestBodySize;
|
|
151
|
+
if (maxRequestBodySize === undefined && config.upload) {
|
|
152
|
+
const maxFileSize = config.upload.maxFileSize ?? 10 * 1024 * 1024;
|
|
153
|
+
const maxFiles = config.upload.maxFiles ?? 10;
|
|
154
|
+
maxRequestBodySize = maxFileSize * maxFiles;
|
|
155
|
+
}
|
|
156
|
+
let server;
|
|
157
|
+
if (wsConfig) {
|
|
158
|
+
const { endpoints, transport: wsTransport, idleTimeout, backpressureLimit, closeOnBackpressureLimit, perMessageDeflate, publishToSelf, } = wsConfig;
|
|
159
|
+
// Compute presence flag once — true if any endpoint enables presence
|
|
160
|
+
const presenceEnabled = Object.values(endpoints).some(ep => !!ep.presence);
|
|
161
|
+
const wsState = {
|
|
162
|
+
server: null,
|
|
163
|
+
transport: wsTransport ?? null,
|
|
164
|
+
instanceId: crypto.randomUUID(),
|
|
165
|
+
presenceEnabled,
|
|
166
|
+
roomRegistry: new Map(),
|
|
167
|
+
heartbeatSockets: new Map(),
|
|
168
|
+
heartbeatEndpointConfigs: new Map(),
|
|
169
|
+
heartbeatTimer: null,
|
|
170
|
+
socketUsers: new Map(),
|
|
171
|
+
roomPresence: new Map(),
|
|
172
|
+
};
|
|
173
|
+
// Configure per-endpoint side effects
|
|
174
|
+
for (const [, ep] of Object.entries(endpoints)) {
|
|
175
|
+
if (ep.persistence?.defaults) {
|
|
176
|
+
ctx.persistence.setDefaults(ep.persistence.defaults);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
const wsHandler = {
|
|
180
|
+
async open(socket) {
|
|
181
|
+
const ep = endpoints[socket.data.endpoint];
|
|
182
|
+
if (ep?.heartbeat)
|
|
183
|
+
registerSocket(wsState, socket, socket.data.id, socket.data.endpoint);
|
|
184
|
+
if (ep?.presence)
|
|
185
|
+
trackSocket(wsState, socket.data.id, socket.data.userId);
|
|
186
|
+
socket.send(JSON.stringify({ event: 'connected', id: socket.data.id }));
|
|
187
|
+
if (ep?.on?.open) {
|
|
188
|
+
try {
|
|
189
|
+
await ep.on.open(socket);
|
|
190
|
+
}
|
|
191
|
+
catch (e) {
|
|
192
|
+
console.error(`[ws:hook] ${socket.data.endpoint} open error`, e);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
async message(socket, message) {
|
|
197
|
+
const ep = endpoints[socket.data.endpoint];
|
|
198
|
+
const maxSize = ep?.maxMessageSize ?? 65_536;
|
|
199
|
+
const size = typeof message === 'string' ? message.length : message.byteLength;
|
|
200
|
+
if (size > maxSize) {
|
|
201
|
+
socket.close(1009, 'Message too large');
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
if (!(await handleRoomActions(wsState, socket, message, ep?.onRoomSubscribe))) {
|
|
205
|
+
if (ep?.on?.message) {
|
|
206
|
+
try {
|
|
207
|
+
await ep.on.message(socket, message);
|
|
208
|
+
}
|
|
209
|
+
catch (e) {
|
|
210
|
+
console.error(`[ws:hook] ${socket.data.endpoint} message error`, e);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
},
|
|
215
|
+
async close(socket, code, reason) {
|
|
216
|
+
const ep = endpoints[socket.data.endpoint];
|
|
217
|
+
if (ep?.heartbeat)
|
|
218
|
+
deregisterSocket(wsState, socket.data.id);
|
|
219
|
+
if (ep?.presence)
|
|
220
|
+
untrackSocket(wsState, socket.data.id);
|
|
221
|
+
cleanupSocket(wsState, socket);
|
|
222
|
+
if (ep?.on?.close) {
|
|
223
|
+
try {
|
|
224
|
+
await ep.on.close(socket, code, reason);
|
|
225
|
+
}
|
|
226
|
+
catch (e) {
|
|
227
|
+
console.error(`[ws:hook] ${socket.data.endpoint} close error`, e);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
},
|
|
231
|
+
pong(socket) {
|
|
232
|
+
handlePong(wsState, socket.data.id);
|
|
233
|
+
},
|
|
234
|
+
drain(socket) {
|
|
235
|
+
void endpoints[socket.data.endpoint]?.on?.drain?.(socket);
|
|
236
|
+
},
|
|
237
|
+
};
|
|
238
|
+
// One upgrade route per endpoint
|
|
239
|
+
const routes = Object.fromEntries(Object.entries(endpoints).map(([path, ep]) => [
|
|
240
|
+
path,
|
|
241
|
+
(req) => ep.upgrade
|
|
242
|
+
? ep.upgrade(req, server)
|
|
243
|
+
: createWsUpgradeHandler(server, path, ctx.userResolver)(req),
|
|
244
|
+
]));
|
|
245
|
+
server = Bun.serve({
|
|
246
|
+
...(config.unix
|
|
247
|
+
? { unix: config.unix }
|
|
248
|
+
: { port, ...(config.hostname ? { hostname: config.hostname } : {}) }),
|
|
249
|
+
...(config.tls ? { tls: config.tls } : {}),
|
|
250
|
+
...(maxRequestBodySize !== undefined ? { maxRequestBodySize } : {}),
|
|
251
|
+
routes,
|
|
252
|
+
fetch: app.fetch,
|
|
253
|
+
websocket: {
|
|
254
|
+
...wsHandler,
|
|
255
|
+
...(idleTimeout !== undefined ? { idleTimeout } : {}),
|
|
256
|
+
...(backpressureLimit !== undefined ? { backpressureLimit } : {}),
|
|
257
|
+
...(closeOnBackpressureLimit !== undefined ? { closeOnBackpressureLimit } : {}),
|
|
258
|
+
...(perMessageDeflate !== undefined ? { perMessageDeflate } : {}),
|
|
259
|
+
...(publishToSelf !== undefined ? { publishToSelf } : {}),
|
|
260
|
+
},
|
|
261
|
+
error(err) {
|
|
262
|
+
console.error(err);
|
|
263
|
+
return Response.json({ error: 'Internal Server Error' }, { status: 500 });
|
|
264
|
+
},
|
|
265
|
+
});
|
|
266
|
+
wsState.server = server;
|
|
267
|
+
// Connect cross-instance transport
|
|
268
|
+
if (wsTransport) {
|
|
269
|
+
const localId = wsState.instanceId;
|
|
270
|
+
await wsTransport.connect((endpoint, room, msg, origin) => {
|
|
271
|
+
if (origin === localId)
|
|
272
|
+
return;
|
|
273
|
+
server.publish(wsEndpointKey(endpoint, room), msg);
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
// Heartbeat — collect per-endpoint configs
|
|
277
|
+
const heartbeatConfigs = {};
|
|
278
|
+
for (const [path, ep] of Object.entries(endpoints)) {
|
|
279
|
+
if (ep.heartbeat)
|
|
280
|
+
heartbeatConfigs[path] = ep.heartbeat;
|
|
281
|
+
}
|
|
282
|
+
if (Object.keys(heartbeatConfigs).length > 0) {
|
|
283
|
+
startHeartbeat(wsState, heartbeatConfigs);
|
|
284
|
+
}
|
|
285
|
+
// Populate WS state on the BunshotContext so instance-scoped consumers
|
|
286
|
+
// can read it via getContext(app).ws instead of module-level singletons.
|
|
287
|
+
// presenceEnabled already computed above
|
|
288
|
+
ctx.ws = wsState;
|
|
289
|
+
}
|
|
290
|
+
else {
|
|
291
|
+
// No WS config — plain HTTP server
|
|
292
|
+
server = Bun.serve({
|
|
293
|
+
...(config.unix
|
|
294
|
+
? { unix: config.unix }
|
|
295
|
+
: { port, ...(config.hostname ? { hostname: config.hostname } : {}) }),
|
|
296
|
+
...(config.tls ? { tls: config.tls } : {}),
|
|
297
|
+
...(maxRequestBodySize !== undefined ? { maxRequestBodySize } : {}),
|
|
298
|
+
fetch: app.fetch,
|
|
299
|
+
error(err) {
|
|
300
|
+
console.error(err);
|
|
301
|
+
return Response.json({ error: 'Internal Server Error' }, { status: 500 });
|
|
302
|
+
},
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
const releaseProcessShutdownOwnership = () => {
|
|
306
|
+
const registry = getShutdownRegistry();
|
|
307
|
+
registry.callbacks.delete(serverOwnerId);
|
|
308
|
+
if (registry.callbacks.size === 0) {
|
|
309
|
+
removeProcessShutdownListeners();
|
|
310
|
+
}
|
|
311
|
+
};
|
|
312
|
+
const originalStop = server.stop.bind(server);
|
|
313
|
+
server.stop = (async (...args) => {
|
|
314
|
+
releaseProcessShutdownOwnership();
|
|
315
|
+
return originalStop(...args);
|
|
316
|
+
});
|
|
317
|
+
// Graceful shutdown — stop accepting new work, then tear down plugins/bus/db.
|
|
318
|
+
// Returns an exit code (0 = clean, 1 = errors). process.exit() is called by
|
|
319
|
+
// the dispatch layer after all registered servers have finished shutting down.
|
|
320
|
+
let shutdownPromise = null;
|
|
321
|
+
const gracefulShutdown = (signal) => {
|
|
322
|
+
if (shutdownPromise) {
|
|
323
|
+
console.warn(`[shutdown] ${signal} received while shutdown is already in progress`);
|
|
324
|
+
return shutdownPromise;
|
|
325
|
+
}
|
|
326
|
+
shutdownPromise = (async () => {
|
|
327
|
+
console.log(`[shutdown] Received ${signal}; starting graceful shutdown`);
|
|
328
|
+
let exitCode = 0;
|
|
329
|
+
try {
|
|
330
|
+
await server.stop();
|
|
331
|
+
if (ctx.ws)
|
|
332
|
+
stopHeartbeat(ctx.ws);
|
|
333
|
+
// Plugin teardown runs BEFORE WS transport disconnect so plugins can
|
|
334
|
+
// still publish to rooms (e.g. "user X disconnected" broadcasts).
|
|
335
|
+
const bunshotPlugins = [...ctx.plugins];
|
|
336
|
+
const bunshotBus = ctx.bus;
|
|
337
|
+
bunshotBus.emit('app:shutdown', { signal });
|
|
338
|
+
const teardownResults = await Promise.allSettled(bunshotPlugins.map(p => p.teardown?.()));
|
|
339
|
+
for (const [i, result] of teardownResults.entries()) {
|
|
340
|
+
if (result.status === 'rejected') {
|
|
341
|
+
console.error(`[shutdown] Plugin teardown error (plugin index ${i}):`, result.reason);
|
|
342
|
+
exitCode = 1;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
// SSE teardown — unsubscribe listeners and close streams BEFORE the bus
|
|
346
|
+
// shuts down, so cleanup runs against a live bus.
|
|
347
|
+
for (const { key, listener } of sseBusListeners)
|
|
348
|
+
bunshotBus.off(key, listener);
|
|
349
|
+
sseRegistry.closeAll();
|
|
350
|
+
await bunshotBus.shutdown?.();
|
|
351
|
+
// WS transport disconnect — after plugins and SSE are torn down,
|
|
352
|
+
// no more consumers need the transport.
|
|
353
|
+
const wsTransport = wsConfig?.transport;
|
|
354
|
+
if (wsTransport) {
|
|
355
|
+
try {
|
|
356
|
+
await wsTransport.disconnect();
|
|
357
|
+
}
|
|
358
|
+
catch (e) {
|
|
359
|
+
console.error('[ws-transport] disconnect error:', e);
|
|
360
|
+
exitCode = 1;
|
|
361
|
+
}
|
|
362
|
+
if (ctx.ws)
|
|
363
|
+
ctx.ws.transport = null;
|
|
364
|
+
}
|
|
365
|
+
// Database disconnects — close persistent connections last, after all consumers are torn down
|
|
366
|
+
const dbConfig = config.db ?? {};
|
|
367
|
+
const enableRedis = dbConfig.redis ?? true;
|
|
368
|
+
const mongoMode = dbConfig.mongo ?? 'single';
|
|
369
|
+
if (enableRedis && ctx.redis) {
|
|
370
|
+
try {
|
|
371
|
+
await disconnectRedis(ctx.redis);
|
|
372
|
+
}
|
|
373
|
+
catch (e) {
|
|
374
|
+
console.error('[shutdown] Redis disconnect error:', e);
|
|
375
|
+
exitCode = 1;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
if (mongoMode !== false && ctx.mongo) {
|
|
379
|
+
try {
|
|
380
|
+
await disconnectMongo(ctx.mongo.auth, ctx.mongo.app);
|
|
381
|
+
}
|
|
382
|
+
catch (e) {
|
|
383
|
+
console.error('[shutdown] MongoDB disconnect error:', e);
|
|
384
|
+
exitCode = 1;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
catch (e) {
|
|
389
|
+
console.error(`[shutdown] Unhandled shutdown error during ${signal}:`, e);
|
|
390
|
+
exitCode = 1;
|
|
391
|
+
}
|
|
392
|
+
console.log(`[shutdown] Server ${serverOwnerId.slice(0, 8)} completed with exit code ${exitCode}`);
|
|
393
|
+
return exitCode;
|
|
394
|
+
})();
|
|
395
|
+
return shutdownPromise;
|
|
396
|
+
};
|
|
397
|
+
// Register this server's shutdown callback. Multiple concurrent servers are
|
|
398
|
+
// supported — each gets its own entry, all invoked in parallel on signal.
|
|
399
|
+
getShutdownRegistry().callbacks.set(serverOwnerId, signal => gracefulShutdown(signal));
|
|
400
|
+
ensureProcessShutdownListeners();
|
|
401
|
+
if (enableWorkers && workersDir) {
|
|
402
|
+
const glob = new Bun.Glob('**/*.ts');
|
|
403
|
+
const currentNames = new Set();
|
|
404
|
+
// Build a QueueFactory from resolved secrets so worker files receive
|
|
405
|
+
// properly-credentialed infrastructure rather than reading process.env.
|
|
406
|
+
let queueFactory = null;
|
|
407
|
+
const redisHost = ctx.resolvedSecrets.redisHost;
|
|
408
|
+
if (redisHost) {
|
|
409
|
+
try {
|
|
410
|
+
const { createQueueFactory } = await import('./lib/queue');
|
|
411
|
+
queueFactory = createQueueFactory({
|
|
412
|
+
host: redisHost,
|
|
413
|
+
user: ctx.resolvedSecrets.redisUser,
|
|
414
|
+
password: ctx.resolvedSecrets.redisPassword,
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
catch {
|
|
418
|
+
/* bullmq not installed — queue workers will fail at import time */
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
// Load scheduler names saved by the previous deployment before importing
|
|
422
|
+
// workers, so we can diff current vs. previous after discovery.
|
|
423
|
+
const previousNames = await ctx.persistence.cronRegistry.getAll();
|
|
424
|
+
for await (const file of glob.scan({ cwd: workersDir })) {
|
|
425
|
+
const mod = await import(`${workersDir}/${file}`);
|
|
426
|
+
if (typeof mod.default === 'function' && queueFactory) {
|
|
427
|
+
try {
|
|
428
|
+
const names = await mod.default(queueFactory);
|
|
429
|
+
if (Array.isArray(names)) {
|
|
430
|
+
for (const name of names)
|
|
431
|
+
currentNames.add(name);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
catch (e) {
|
|
435
|
+
console.error(`[workers] error initialising worker ${file}:`, e);
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
// Persist current names for the next deployment's cleanup pass.
|
|
440
|
+
await ctx.persistence.cronRegistry.save(currentNames);
|
|
441
|
+
// Remove schedulers present in the previous deployment but absent from
|
|
442
|
+
// the current one. knownNames is the union so cleanupStaleSchedulers
|
|
443
|
+
// iterates everything it might need to remove.
|
|
444
|
+
if (queueFactory) {
|
|
445
|
+
const knownNames = new Set([...previousNames, ...currentNames]);
|
|
446
|
+
try {
|
|
447
|
+
await queueFactory.cleanupStaleSchedulers([...currentNames], knownNames);
|
|
448
|
+
}
|
|
449
|
+
catch {
|
|
450
|
+
/* best-effort — bullmq not installed or Redis unavailable */
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
// Store context on server for test/tooling access
|
|
455
|
+
Object.defineProperty(server, SERVER_CONTEXT_SYMBOL, {
|
|
456
|
+
configurable: true,
|
|
457
|
+
enumerable: false,
|
|
458
|
+
writable: true,
|
|
459
|
+
value: ctx,
|
|
460
|
+
});
|
|
461
|
+
if (!config.unix) {
|
|
462
|
+
log(`[server] running at http://localhost:${server.port}`);
|
|
463
|
+
log(`[server] API docs at http://localhost:${server.port}/docs`);
|
|
464
|
+
}
|
|
465
|
+
else {
|
|
466
|
+
log(`[server] running at unix:${config.unix}`);
|
|
467
|
+
}
|
|
468
|
+
return server;
|
|
469
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { HttpError, ValidationError } from '../../../packages/bunshot-core/src/index.js';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare const COOKIE_TOKEN = "token";
|
|
2
|
+
export declare const HEADER_USER_TOKEN = "x-user-token";
|
|
3
|
+
export declare const COOKIE_REFRESH_TOKEN = "refresh_token";
|
|
4
|
+
export declare const HEADER_REFRESH_TOKEN = "x-refresh-token";
|
|
5
|
+
export declare const COOKIE_CSRF_TOKEN = "csrf_token";
|
|
6
|
+
export declare const HEADER_CSRF_TOKEN = "x-csrf-token";
|
|
7
|
+
export declare const HEADER_REQUEST_ID = "x-request-id";
|
|
8
|
+
export declare const HEADER_IDEMPOTENCY_KEY = "idempotency-key";
|
|
9
|
+
export declare const HEADER_SIGNATURE = "x-signature";
|
|
10
|
+
export declare const HEADER_TIMESTAMP = "x-timestamp";
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Constant-time string comparison to prevent timing attacks.
|
|
3
|
+
* Returns true if both strings are equal, false otherwise.
|
|
4
|
+
* Always compares the full length even on mismatch.
|
|
5
|
+
*/
|
|
6
|
+
export declare function timingSafeEqual(a: string, b: string): boolean;
|
|
7
|
+
/**
|
|
8
|
+
* SHA-256 hash a string and return the hex digest.
|
|
9
|
+
* Centralized to avoid duplicate implementations across modules.
|
|
10
|
+
*/
|
|
11
|
+
export declare function sha256(input: string): string;
|
|
12
|
+
/**
|
|
13
|
+
* Named alias for sha256 — use when hashing tokens for storage.
|
|
14
|
+
* The plaintext token is what gets sent to the client;
|
|
15
|
+
* the hash is what gets stored.
|
|
16
|
+
*/
|
|
17
|
+
export declare function hashToken(token: string): string;
|
|
18
|
+
/**
|
|
19
|
+
* A data encryption key entry.
|
|
20
|
+
* keyId: short identifier used in the ciphertext envelope (e.g. "v1")
|
|
21
|
+
* key: 32-byte AES-256 key
|
|
22
|
+
*/
|
|
23
|
+
export interface DataEncryptionKey {
|
|
24
|
+
keyId: string;
|
|
25
|
+
key: Buffer;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Encrypt a plaintext value with AES-256-GCM.
|
|
29
|
+
* keyConfig: first entry is the active key, rest are for decryption-only rotation.
|
|
30
|
+
* Returns: "keyId.base64url(iv).base64url(ciphertext).base64url(tag)"
|
|
31
|
+
*/
|
|
32
|
+
export declare function encryptField(plaintext: string, keyConfig: DataEncryptionKey[]): Promise<string>;
|
|
33
|
+
/**
|
|
34
|
+
* Decrypt a value encrypted by encryptField.
|
|
35
|
+
* keyConfig: all available keys (current + rotated).
|
|
36
|
+
* Returns: plaintext string, or throws if no matching key found.
|
|
37
|
+
*/
|
|
38
|
+
export declare function decryptField(ciphertext: string, keyConfig: DataEncryptionKey[]): Promise<string>;
|
|
39
|
+
/**
|
|
40
|
+
* Detect whether a stored value looks like an encrypted ciphertext produced by encryptField.
|
|
41
|
+
* Format: "keyId.base64url(iv).base64url(ct).base64url(tag)" — exactly 4 dot-separated parts.
|
|
42
|
+
*/
|
|
43
|
+
export declare function isEncryptedField(value: string): boolean;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { createHash, timingSafeEqual as nodeTimingSafeEqual, createCipheriv, createDecipheriv, randomBytes } from "crypto";
|
|
2
|
+
/**
|
|
3
|
+
* Constant-time string comparison to prevent timing attacks.
|
|
4
|
+
* Returns true if both strings are equal, false otherwise.
|
|
5
|
+
* Always compares the full length even on mismatch.
|
|
6
|
+
*/
|
|
7
|
+
export function timingSafeEqual(a, b) {
|
|
8
|
+
if (a.length !== b.length) {
|
|
9
|
+
// Compare against self to burn the same time, then return false
|
|
10
|
+
const buf = Buffer.from(a, "utf-8");
|
|
11
|
+
nodeTimingSafeEqual(buf, buf);
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
return nodeTimingSafeEqual(Buffer.from(a, "utf-8"), Buffer.from(b, "utf-8"));
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* SHA-256 hash a string and return the hex digest.
|
|
18
|
+
* Centralized to avoid duplicate implementations across modules.
|
|
19
|
+
*/
|
|
20
|
+
export function sha256(input) {
|
|
21
|
+
return createHash("sha256").update(input).digest("hex");
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Named alias for sha256 — use when hashing tokens for storage.
|
|
25
|
+
* The plaintext token is what gets sent to the client;
|
|
26
|
+
* the hash is what gets stored.
|
|
27
|
+
*/
|
|
28
|
+
export function hashToken(token) {
|
|
29
|
+
return sha256(token);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Encrypt a plaintext value with AES-256-GCM.
|
|
33
|
+
* keyConfig: first entry is the active key, rest are for decryption-only rotation.
|
|
34
|
+
* Returns: "keyId.base64url(iv).base64url(ciphertext).base64url(tag)"
|
|
35
|
+
*/
|
|
36
|
+
export async function encryptField(plaintext, keyConfig) {
|
|
37
|
+
if (keyConfig.length === 0)
|
|
38
|
+
throw new Error("encryptField: no encryption keys configured");
|
|
39
|
+
const { keyId, key } = keyConfig[0];
|
|
40
|
+
const iv = randomBytes(12); // 96-bit IV for AES-GCM
|
|
41
|
+
const cipher = createCipheriv("aes-256-gcm", key, iv);
|
|
42
|
+
const encrypted = Buffer.concat([cipher.update(plaintext, "utf8"), cipher.final()]);
|
|
43
|
+
const tag = cipher.getAuthTag();
|
|
44
|
+
const encode = (buf) => buf.toString("base64url");
|
|
45
|
+
return `${keyId}.${encode(iv)}.${encode(encrypted)}.${encode(tag)}`;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Decrypt a value encrypted by encryptField.
|
|
49
|
+
* keyConfig: all available keys (current + rotated).
|
|
50
|
+
* Returns: plaintext string, or throws if no matching key found.
|
|
51
|
+
*/
|
|
52
|
+
export async function decryptField(ciphertext, keyConfig) {
|
|
53
|
+
const parts = ciphertext.split(".");
|
|
54
|
+
if (parts.length !== 4)
|
|
55
|
+
throw new Error("decryptField: invalid ciphertext format");
|
|
56
|
+
const [keyId, ivB64, ctB64, tagB64] = parts;
|
|
57
|
+
const keyEntry = keyConfig.find((k) => k.keyId === keyId);
|
|
58
|
+
if (!keyEntry)
|
|
59
|
+
throw new Error(`decryptField: no key found for keyId "${keyId}"`);
|
|
60
|
+
const iv = Buffer.from(ivB64, "base64url");
|
|
61
|
+
const ct = Buffer.from(ctB64, "base64url");
|
|
62
|
+
const tag = Buffer.from(tagB64, "base64url");
|
|
63
|
+
const decipher = createDecipheriv("aes-256-gcm", keyEntry.key, iv);
|
|
64
|
+
decipher.setAuthTag(tag);
|
|
65
|
+
const decrypted = Buffer.concat([decipher.update(ct), decipher.final()]);
|
|
66
|
+
return decrypted.toString("utf8");
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Detect whether a stored value looks like an encrypted ciphertext produced by encryptField.
|
|
70
|
+
* Format: "keyId.base64url(iv).base64url(ct).base64url(tag)" — exactly 4 dot-separated parts.
|
|
71
|
+
*/
|
|
72
|
+
export function isEncryptedField(value) {
|
|
73
|
+
return value.split(".").length === 4;
|
|
74
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sign `data` with the active key (first element of `secret`).
|
|
3
|
+
* Normalizes string | string[] so that an array is never passed directly to
|
|
4
|
+
* createHmac() — which would silently call .toString() and produce
|
|
5
|
+
* "[object Array]" as the key.
|
|
6
|
+
*/
|
|
7
|
+
export declare function hmacSign(data: string, secret: string | string[]): string;
|
|
8
|
+
/**
|
|
9
|
+
* Verify `sig` against `data` using one of the provided keys.
|
|
10
|
+
* Keys are tried newest-first (index 0 is the active signing key).
|
|
11
|
+
*
|
|
12
|
+
* Key ordering convention: put the current (newest) key first; rotated keys
|
|
13
|
+
* after. The common case (valid current-key signature) succeeds on the first
|
|
14
|
+
* comparison; old rotated keys only matter for in-flight tokens.
|
|
15
|
+
*
|
|
16
|
+
* MUST use timingSafeEqual — never === — to prevent timing side-channel leaks.
|
|
17
|
+
* This is the most common HMAC implementation mistake.
|
|
18
|
+
*/
|
|
19
|
+
export declare function hmacVerify(data: string, sig: string, secret: string | string[]): boolean;
|
|
20
|
+
/** Returns `"base64url(value).hmac"`. */
|
|
21
|
+
export declare function signCookieValue(value: string, secret: string | string[]): string;
|
|
22
|
+
/** Returns the original value or `null` if the signature is invalid. */
|
|
23
|
+
export declare function verifyCookieValue(signed: string, secret: string | string[]): string | null;
|
|
24
|
+
/** Returns `"base64url(payload).hmac"`. */
|
|
25
|
+
export declare function signCursor(payload: string, secret: string | string[]): string;
|
|
26
|
+
/** Returns the original payload or `null` if the signature is invalid. */
|
|
27
|
+
export declare function verifyCursor(cursor: string, secret: string | string[]): string | null;
|
|
28
|
+
/**
|
|
29
|
+
* Create a stateless HMAC-signed URL. The signature covers the HTTP method,
|
|
30
|
+
* storage key, expiry timestamp, and any extra query params so that:
|
|
31
|
+
* - Expired URLs are rejected (replay prevention)
|
|
32
|
+
* - URLs are method-bound (a GET URL can't be replayed as a PUT)
|
|
33
|
+
* - Tampering with the key, expiry, or any extra param invalidates the signature
|
|
34
|
+
*
|
|
35
|
+
* @param base Base URL string (e.g. "https://api.example.com/uploads/presign")
|
|
36
|
+
* @param key Storage object key
|
|
37
|
+
* @param opts Method, expiry in seconds from now, optional extra query params
|
|
38
|
+
* @param secret HMAC secret (supports key rotation via string[])
|
|
39
|
+
*/
|
|
40
|
+
export declare function createPresignedUrl(base: string, key: string, opts: {
|
|
41
|
+
method: string;
|
|
42
|
+
expiry: number;
|
|
43
|
+
extra?: Record<string, string>;
|
|
44
|
+
}, secret: string | string[]): string;
|
|
45
|
+
/**
|
|
46
|
+
* Verify an HMAC-signed URL. Returns the key and any extra params, or null
|
|
47
|
+
* if the URL is expired, tampered, or method-mismatched.
|
|
48
|
+
*/
|
|
49
|
+
export declare function verifyPresignedUrl(url: string, method: string, secret: string | string[]): {
|
|
50
|
+
key: string;
|
|
51
|
+
extra?: Record<string, string>;
|
|
52
|
+
} | null;
|