@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
|
@@ -1,707 +0,0 @@
|
|
|
1
|
-
import { Database } from "bun:sqlite";
|
|
2
|
-
import { HttpError } from "../lib/HttpError";
|
|
3
|
-
// ---------------------------------------------------------------------------
|
|
4
|
-
// DB singleton — call setSqliteDb(path) once at startup
|
|
5
|
-
// ---------------------------------------------------------------------------
|
|
6
|
-
let _db = null;
|
|
7
|
-
export const setSqliteDb = (path) => {
|
|
8
|
-
_db = new Database(path, { create: true });
|
|
9
|
-
_db.run("PRAGMA journal_mode = WAL");
|
|
10
|
-
_db.run("PRAGMA foreign_keys = ON");
|
|
11
|
-
initSchema(_db);
|
|
12
|
-
};
|
|
13
|
-
export function getDb() {
|
|
14
|
-
if (!_db)
|
|
15
|
-
throw new Error("SQLite not initialized — call setSqliteDb(path) before using sqliteAuthAdapter or sessionStore: 'sqlite'");
|
|
16
|
-
return _db;
|
|
17
|
-
}
|
|
18
|
-
// ---------------------------------------------------------------------------
|
|
19
|
-
// Schema
|
|
20
|
-
// ---------------------------------------------------------------------------
|
|
21
|
-
function initSchema(db) {
|
|
22
|
-
db.run(`CREATE TABLE IF NOT EXISTS users (
|
|
23
|
-
id TEXT PRIMARY KEY,
|
|
24
|
-
email TEXT UNIQUE,
|
|
25
|
-
passwordHash TEXT,
|
|
26
|
-
providerIds TEXT NOT NULL DEFAULT '[]',
|
|
27
|
-
roles TEXT NOT NULL DEFAULT '[]',
|
|
28
|
-
emailVerified INTEGER NOT NULL DEFAULT 0
|
|
29
|
-
)`);
|
|
30
|
-
// Add emailVerified to pre-existing databases that lack the column
|
|
31
|
-
try {
|
|
32
|
-
db.run("ALTER TABLE users ADD COLUMN emailVerified INTEGER NOT NULL DEFAULT 0");
|
|
33
|
-
}
|
|
34
|
-
catch { /* already exists */ }
|
|
35
|
-
// Add MFA columns to pre-existing databases
|
|
36
|
-
try {
|
|
37
|
-
db.run("ALTER TABLE users ADD COLUMN mfaSecret TEXT");
|
|
38
|
-
}
|
|
39
|
-
catch { /* already exists */ }
|
|
40
|
-
try {
|
|
41
|
-
db.run("ALTER TABLE users ADD COLUMN mfaEnabled INTEGER NOT NULL DEFAULT 0");
|
|
42
|
-
}
|
|
43
|
-
catch { /* already exists */ }
|
|
44
|
-
try {
|
|
45
|
-
db.run("ALTER TABLE users ADD COLUMN recoveryCodes TEXT NOT NULL DEFAULT '[]'");
|
|
46
|
-
}
|
|
47
|
-
catch { /* already exists */ }
|
|
48
|
-
try {
|
|
49
|
-
db.run("ALTER TABLE users ADD COLUMN mfaMethods TEXT NOT NULL DEFAULT '[]'");
|
|
50
|
-
}
|
|
51
|
-
catch { /* already exists */ }
|
|
52
|
-
// Migrate legacy sessions table (userId PK) to new multi-session schema (sessionId PK)
|
|
53
|
-
try {
|
|
54
|
-
db.run("ALTER TABLE sessions RENAME TO sessions_legacy");
|
|
55
|
-
}
|
|
56
|
-
catch { /* already migrated */ }
|
|
57
|
-
db.run(`CREATE TABLE IF NOT EXISTS sessions (
|
|
58
|
-
sessionId TEXT PRIMARY KEY,
|
|
59
|
-
userId TEXT NOT NULL,
|
|
60
|
-
token TEXT,
|
|
61
|
-
createdAt INTEGER NOT NULL,
|
|
62
|
-
lastActiveAt INTEGER NOT NULL,
|
|
63
|
-
expiresAt INTEGER NOT NULL,
|
|
64
|
-
ipAddress TEXT,
|
|
65
|
-
userAgent TEXT
|
|
66
|
-
)`);
|
|
67
|
-
db.run("CREATE INDEX IF NOT EXISTS idx_sessions_userId ON sessions(userId)");
|
|
68
|
-
// Add refresh token columns to pre-existing databases
|
|
69
|
-
try {
|
|
70
|
-
db.run("ALTER TABLE sessions ADD COLUMN refreshToken TEXT");
|
|
71
|
-
}
|
|
72
|
-
catch { /* already exists */ }
|
|
73
|
-
try {
|
|
74
|
-
db.run("ALTER TABLE sessions ADD COLUMN prevRefreshToken TEXT");
|
|
75
|
-
}
|
|
76
|
-
catch { /* already exists */ }
|
|
77
|
-
try {
|
|
78
|
-
db.run("ALTER TABLE sessions ADD COLUMN prevTokenExpiresAt INTEGER");
|
|
79
|
-
}
|
|
80
|
-
catch { /* already exists */ }
|
|
81
|
-
try {
|
|
82
|
-
db.run("ALTER TABLE sessions ADD COLUMN fingerprint TEXT");
|
|
83
|
-
}
|
|
84
|
-
catch { /* already exists */ }
|
|
85
|
-
db.run("CREATE UNIQUE INDEX IF NOT EXISTS idx_sessions_refreshToken ON sessions(refreshToken) WHERE refreshToken IS NOT NULL");
|
|
86
|
-
db.run(`CREATE TABLE IF NOT EXISTS oauth_states (
|
|
87
|
-
state TEXT PRIMARY KEY,
|
|
88
|
-
codeVerifier TEXT,
|
|
89
|
-
linkUserId TEXT,
|
|
90
|
-
expiresAt INTEGER NOT NULL
|
|
91
|
-
)`);
|
|
92
|
-
db.run(`CREATE TABLE IF NOT EXISTS cache_entries (
|
|
93
|
-
key TEXT PRIMARY KEY,
|
|
94
|
-
value TEXT NOT NULL,
|
|
95
|
-
expiresAt INTEGER -- NULL = indefinite
|
|
96
|
-
)`);
|
|
97
|
-
db.run(`CREATE TABLE IF NOT EXISTS email_verifications (
|
|
98
|
-
token TEXT PRIMARY KEY,
|
|
99
|
-
userId TEXT NOT NULL,
|
|
100
|
-
email TEXT NOT NULL,
|
|
101
|
-
expiresAt INTEGER NOT NULL
|
|
102
|
-
)`);
|
|
103
|
-
db.run(`CREATE TABLE IF NOT EXISTS password_resets (
|
|
104
|
-
token TEXT PRIMARY KEY,
|
|
105
|
-
userId TEXT NOT NULL,
|
|
106
|
-
email TEXT NOT NULL,
|
|
107
|
-
expiresAt INTEGER NOT NULL
|
|
108
|
-
)`);
|
|
109
|
-
db.run(`CREATE TABLE IF NOT EXISTS tenant_roles (
|
|
110
|
-
userId TEXT NOT NULL,
|
|
111
|
-
tenantId TEXT NOT NULL,
|
|
112
|
-
role TEXT NOT NULL,
|
|
113
|
-
PRIMARY KEY (userId, tenantId, role)
|
|
114
|
-
)`);
|
|
115
|
-
db.run("CREATE INDEX IF NOT EXISTS idx_tenant_roles_tenant ON tenant_roles(tenantId)");
|
|
116
|
-
db.run(`CREATE TABLE IF NOT EXISTS webauthn_credentials (
|
|
117
|
-
credentialId TEXT PRIMARY KEY,
|
|
118
|
-
userId TEXT NOT NULL,
|
|
119
|
-
publicKey TEXT NOT NULL,
|
|
120
|
-
signCount INTEGER NOT NULL DEFAULT 0,
|
|
121
|
-
transports TEXT NOT NULL DEFAULT '[]',
|
|
122
|
-
name TEXT,
|
|
123
|
-
createdAt INTEGER NOT NULL
|
|
124
|
-
)`);
|
|
125
|
-
db.run("CREATE INDEX IF NOT EXISTS idx_webauthn_userId ON webauthn_credentials(userId)");
|
|
126
|
-
db.run(`CREATE TABLE IF NOT EXISTS groups (
|
|
127
|
-
id TEXT PRIMARY KEY,
|
|
128
|
-
name TEXT NOT NULL,
|
|
129
|
-
displayName TEXT,
|
|
130
|
-
description TEXT,
|
|
131
|
-
roles TEXT NOT NULL DEFAULT '[]',
|
|
132
|
-
tenantId TEXT,
|
|
133
|
-
createdAt INTEGER NOT NULL,
|
|
134
|
-
updatedAt INTEGER NOT NULL
|
|
135
|
-
)`);
|
|
136
|
-
// SQLite UNIQUE treats each NULL as distinct, so we use partial indexes instead of
|
|
137
|
-
// a simple UNIQUE constraint on (name, tenantId). This correctly enforces name
|
|
138
|
-
// uniqueness within app-wide scope and within each tenant scope separately.
|
|
139
|
-
db.run("CREATE UNIQUE INDEX IF NOT EXISTS idx_groups_name_appwide ON groups(name) WHERE tenantId IS NULL");
|
|
140
|
-
db.run("CREATE UNIQUE INDEX IF NOT EXISTS idx_groups_name_tenant ON groups(name, tenantId) WHERE tenantId IS NOT NULL");
|
|
141
|
-
db.run("CREATE INDEX IF NOT EXISTS idx_groups_tenantId ON groups(tenantId)");
|
|
142
|
-
db.run(`CREATE TABLE IF NOT EXISTS group_memberships (
|
|
143
|
-
userId TEXT NOT NULL,
|
|
144
|
-
groupId TEXT NOT NULL REFERENCES groups(id) ON DELETE CASCADE,
|
|
145
|
-
roles TEXT NOT NULL DEFAULT '[]',
|
|
146
|
-
tenantId TEXT,
|
|
147
|
-
createdAt INTEGER NOT NULL,
|
|
148
|
-
PRIMARY KEY (userId, groupId)
|
|
149
|
-
)`);
|
|
150
|
-
// NOTE: PRAGMA foreign_keys = ON is set in setSqliteDb() and must run per-connection.
|
|
151
|
-
// If any code path opens SQLite without going through setSqliteDb, ON DELETE CASCADE
|
|
152
|
-
// for group_memberships will silently not fire. All SQLite access must use setSqliteDb.
|
|
153
|
-
db.run("CREATE INDEX IF NOT EXISTS idx_gm_groupId ON group_memberships(groupId)");
|
|
154
|
-
db.run("CREATE INDEX IF NOT EXISTS idx_gm_userId_tenantId ON group_memberships(userId, tenantId)");
|
|
155
|
-
db.run(`CREATE TABLE IF NOT EXISTS oauth_codes (
|
|
156
|
-
codeHash TEXT PRIMARY KEY,
|
|
157
|
-
token TEXT NOT NULL,
|
|
158
|
-
userId TEXT NOT NULL,
|
|
159
|
-
email TEXT,
|
|
160
|
-
refreshToken TEXT,
|
|
161
|
-
expiresAt INTEGER NOT NULL
|
|
162
|
-
)`);
|
|
163
|
-
db.run(`CREATE TABLE IF NOT EXISTS deletion_cancel_tokens (
|
|
164
|
-
token TEXT PRIMARY KEY,
|
|
165
|
-
userId TEXT NOT NULL,
|
|
166
|
-
jobId TEXT NOT NULL,
|
|
167
|
-
expiresAt INTEGER NOT NULL
|
|
168
|
-
)`);
|
|
169
|
-
}
|
|
170
|
-
// ---------------------------------------------------------------------------
|
|
171
|
-
// Auth adapter
|
|
172
|
-
// ---------------------------------------------------------------------------
|
|
173
|
-
export const sqliteAuthAdapter = {
|
|
174
|
-
async findByEmail(email) {
|
|
175
|
-
const row = getDb().query("SELECT id, passwordHash FROM users WHERE email = ?").get(email);
|
|
176
|
-
return row ?? null;
|
|
177
|
-
},
|
|
178
|
-
async create(email, passwordHash) {
|
|
179
|
-
const id = crypto.randomUUID();
|
|
180
|
-
try {
|
|
181
|
-
getDb().run("INSERT INTO users (id, email, passwordHash) VALUES (?, ?, ?)", [id, email, passwordHash]);
|
|
182
|
-
return { id };
|
|
183
|
-
}
|
|
184
|
-
catch (err) {
|
|
185
|
-
if (err?.code === "SQLITE_CONSTRAINT_UNIQUE")
|
|
186
|
-
throw new HttpError(409, "Email already registered");
|
|
187
|
-
throw err;
|
|
188
|
-
}
|
|
189
|
-
},
|
|
190
|
-
async setPassword(userId, passwordHash) {
|
|
191
|
-
getDb().run("UPDATE users SET passwordHash = ? WHERE id = ?", [passwordHash, userId]);
|
|
192
|
-
},
|
|
193
|
-
async findOrCreateByProvider(provider, providerId, profile) {
|
|
194
|
-
const key = `${provider}:${providerId}`;
|
|
195
|
-
const db = getDb();
|
|
196
|
-
// Find by provider key using json_each
|
|
197
|
-
const existing = db.query("SELECT u.id FROM users u, json_each(u.providerIds) p WHERE p.value = ?").get(key);
|
|
198
|
-
if (existing)
|
|
199
|
-
return { id: existing.id, created: false };
|
|
200
|
-
// Reject if email belongs to a credential account
|
|
201
|
-
if (profile.email) {
|
|
202
|
-
const emailUser = db.query("SELECT id FROM users WHERE email = ?").get(profile.email);
|
|
203
|
-
if (emailUser)
|
|
204
|
-
throw new HttpError(409, "An account with this email already exists. Sign in with your credentials, then link Google from your account settings.");
|
|
205
|
-
}
|
|
206
|
-
const id = crypto.randomUUID();
|
|
207
|
-
db.run("INSERT INTO users (id, email, providerIds) VALUES (?, ?, ?)", [id, profile.email ?? null, JSON.stringify([key])]);
|
|
208
|
-
return { id, created: true };
|
|
209
|
-
},
|
|
210
|
-
async linkProvider(userId, provider, providerId) {
|
|
211
|
-
const key = `${provider}:${providerId}`;
|
|
212
|
-
const db = getDb();
|
|
213
|
-
const row = db.query("SELECT id, providerIds FROM users WHERE id = ?").get(userId);
|
|
214
|
-
if (!row)
|
|
215
|
-
throw new HttpError(404, "User not found");
|
|
216
|
-
const ids = JSON.parse(row.providerIds);
|
|
217
|
-
if (!ids.includes(key)) {
|
|
218
|
-
db.run("UPDATE users SET providerIds = ? WHERE id = ?", [JSON.stringify([...ids, key]), userId]);
|
|
219
|
-
}
|
|
220
|
-
},
|
|
221
|
-
async getRoles(userId) {
|
|
222
|
-
const row = getDb().query("SELECT roles FROM users WHERE id = ?").get(userId);
|
|
223
|
-
return row ? JSON.parse(row.roles) : [];
|
|
224
|
-
},
|
|
225
|
-
async setRoles(userId, roles) {
|
|
226
|
-
getDb().run("UPDATE users SET roles = ? WHERE id = ?", [JSON.stringify(roles), userId]);
|
|
227
|
-
},
|
|
228
|
-
async addRole(userId, role) {
|
|
229
|
-
const db = getDb();
|
|
230
|
-
const row = db.query("SELECT roles FROM users WHERE id = ?").get(userId);
|
|
231
|
-
if (!row)
|
|
232
|
-
return;
|
|
233
|
-
const roles = JSON.parse(row.roles);
|
|
234
|
-
if (!roles.includes(role)) {
|
|
235
|
-
db.run("UPDATE users SET roles = ? WHERE id = ?", [JSON.stringify([...roles, role]), userId]);
|
|
236
|
-
}
|
|
237
|
-
},
|
|
238
|
-
async removeRole(userId, role) {
|
|
239
|
-
const db = getDb();
|
|
240
|
-
const row = db.query("SELECT roles FROM users WHERE id = ?").get(userId);
|
|
241
|
-
if (!row)
|
|
242
|
-
return;
|
|
243
|
-
const roles = JSON.parse(row.roles);
|
|
244
|
-
db.run("UPDATE users SET roles = ? WHERE id = ?", [JSON.stringify(roles.filter((r) => r !== role)), userId]);
|
|
245
|
-
},
|
|
246
|
-
async getUser(userId) {
|
|
247
|
-
const row = getDb().query("SELECT email, providerIds, emailVerified FROM users WHERE id = ?").get(userId);
|
|
248
|
-
if (!row)
|
|
249
|
-
return null;
|
|
250
|
-
return {
|
|
251
|
-
email: row.email ?? undefined,
|
|
252
|
-
providerIds: JSON.parse(row.providerIds),
|
|
253
|
-
emailVerified: row.emailVerified === 1,
|
|
254
|
-
};
|
|
255
|
-
},
|
|
256
|
-
async unlinkProvider(userId, provider) {
|
|
257
|
-
const db = getDb();
|
|
258
|
-
const row = db.query("SELECT providerIds FROM users WHERE id = ?").get(userId);
|
|
259
|
-
if (!row)
|
|
260
|
-
throw new HttpError(404, "User not found");
|
|
261
|
-
const ids = JSON.parse(row.providerIds);
|
|
262
|
-
db.run("UPDATE users SET providerIds = ? WHERE id = ?", [JSON.stringify(ids.filter((id) => !id.startsWith(`${provider}:`))), userId]);
|
|
263
|
-
},
|
|
264
|
-
async findByIdentifier(value) {
|
|
265
|
-
const row = getDb().query("SELECT id, passwordHash FROM users WHERE email = ?").get(value);
|
|
266
|
-
return row ?? null;
|
|
267
|
-
},
|
|
268
|
-
async setEmailVerified(userId, verified) {
|
|
269
|
-
getDb().run("UPDATE users SET emailVerified = ? WHERE id = ?", [verified ? 1 : 0, userId]);
|
|
270
|
-
},
|
|
271
|
-
async getEmailVerified(userId) {
|
|
272
|
-
const row = getDb().query("SELECT emailVerified FROM users WHERE id = ?").get(userId);
|
|
273
|
-
return row?.emailVerified === 1;
|
|
274
|
-
},
|
|
275
|
-
async deleteUser(userId) {
|
|
276
|
-
getDb().run("DELETE FROM users WHERE id = ?", [userId]);
|
|
277
|
-
},
|
|
278
|
-
async hasPassword(userId) {
|
|
279
|
-
const row = getDb().query("SELECT passwordHash FROM users WHERE id = ?").get(userId);
|
|
280
|
-
return !!row?.passwordHash;
|
|
281
|
-
},
|
|
282
|
-
async setMfaSecret(userId, secret) {
|
|
283
|
-
getDb().run("UPDATE users SET mfaSecret = ? WHERE id = ?", [secret, userId]);
|
|
284
|
-
},
|
|
285
|
-
async getMfaSecret(userId) {
|
|
286
|
-
const row = getDb().query("SELECT mfaSecret FROM users WHERE id = ?").get(userId);
|
|
287
|
-
return row?.mfaSecret ?? null;
|
|
288
|
-
},
|
|
289
|
-
async isMfaEnabled(userId) {
|
|
290
|
-
const row = getDb().query("SELECT mfaEnabled FROM users WHERE id = ?").get(userId);
|
|
291
|
-
return row?.mfaEnabled === 1;
|
|
292
|
-
},
|
|
293
|
-
async setMfaEnabled(userId, enabled) {
|
|
294
|
-
getDb().run("UPDATE users SET mfaEnabled = ? WHERE id = ?", [enabled ? 1 : 0, userId]);
|
|
295
|
-
},
|
|
296
|
-
async setRecoveryCodes(userId, codes) {
|
|
297
|
-
getDb().run("UPDATE users SET recoveryCodes = ? WHERE id = ?", [JSON.stringify(codes), userId]);
|
|
298
|
-
},
|
|
299
|
-
async getRecoveryCodes(userId) {
|
|
300
|
-
const row = getDb().query("SELECT recoveryCodes FROM users WHERE id = ?").get(userId);
|
|
301
|
-
return row?.recoveryCodes ? JSON.parse(row.recoveryCodes) : [];
|
|
302
|
-
},
|
|
303
|
-
async removeRecoveryCode(userId, code) {
|
|
304
|
-
const current = await sqliteAuthAdapter.getRecoveryCodes(userId);
|
|
305
|
-
const idx = current.indexOf(code);
|
|
306
|
-
if (idx !== -1) {
|
|
307
|
-
current.splice(idx, 1);
|
|
308
|
-
await sqliteAuthAdapter.setRecoveryCodes(userId, current);
|
|
309
|
-
}
|
|
310
|
-
},
|
|
311
|
-
async getMfaMethods(userId) {
|
|
312
|
-
const row = getDb().query("SELECT mfaMethods, mfaEnabled FROM users WHERE id = ?").get(userId);
|
|
313
|
-
const methods = row?.mfaMethods ? JSON.parse(row.mfaMethods) : [];
|
|
314
|
-
// Backward compat: if mfaEnabled but no methods recorded, assume TOTP
|
|
315
|
-
if (methods.length === 0 && row?.mfaEnabled === 1)
|
|
316
|
-
return ["totp"];
|
|
317
|
-
return methods;
|
|
318
|
-
},
|
|
319
|
-
async setMfaMethods(userId, methods) {
|
|
320
|
-
getDb().run("UPDATE users SET mfaMethods = ? WHERE id = ?", [JSON.stringify(methods), userId]);
|
|
321
|
-
},
|
|
322
|
-
async getWebAuthnCredentials(userId) {
|
|
323
|
-
const rows = getDb().query("SELECT credentialId, publicKey, signCount, transports, name, createdAt FROM webauthn_credentials WHERE userId = ?").all(userId);
|
|
324
|
-
return rows.map((r) => ({
|
|
325
|
-
credentialId: r.credentialId,
|
|
326
|
-
publicKey: r.publicKey,
|
|
327
|
-
signCount: r.signCount,
|
|
328
|
-
transports: JSON.parse(r.transports),
|
|
329
|
-
name: r.name ?? undefined,
|
|
330
|
-
createdAt: r.createdAt,
|
|
331
|
-
}));
|
|
332
|
-
},
|
|
333
|
-
async addWebAuthnCredential(userId, credential) {
|
|
334
|
-
getDb().run("INSERT INTO webauthn_credentials (credentialId, userId, publicKey, signCount, transports, name, createdAt) VALUES (?, ?, ?, ?, ?, ?, ?)", [credential.credentialId, userId, credential.publicKey, credential.signCount, JSON.stringify(credential.transports ?? []), credential.name ?? null, credential.createdAt]);
|
|
335
|
-
},
|
|
336
|
-
async removeWebAuthnCredential(userId, credentialId) {
|
|
337
|
-
getDb().run("DELETE FROM webauthn_credentials WHERE credentialId = ? AND userId = ?", [credentialId, userId]);
|
|
338
|
-
},
|
|
339
|
-
async updateWebAuthnCredentialSignCount(userId, credentialId, signCount) {
|
|
340
|
-
getDb().run("UPDATE webauthn_credentials SET signCount = ? WHERE credentialId = ? AND userId = ?", [signCount, credentialId, userId]);
|
|
341
|
-
},
|
|
342
|
-
async findUserByWebAuthnCredentialId(credentialId) {
|
|
343
|
-
const row = getDb().query("SELECT userId FROM webauthn_credentials WHERE credentialId = ?").get(credentialId);
|
|
344
|
-
return row?.userId ?? null;
|
|
345
|
-
},
|
|
346
|
-
async getTenantRoles(userId, tenantId) {
|
|
347
|
-
const rows = getDb().query("SELECT role FROM tenant_roles WHERE userId = ? AND tenantId = ?").all(userId, tenantId);
|
|
348
|
-
return rows.map((r) => r.role);
|
|
349
|
-
},
|
|
350
|
-
async setTenantRoles(userId, tenantId, roles) {
|
|
351
|
-
const db = getDb();
|
|
352
|
-
db.run("DELETE FROM tenant_roles WHERE userId = ? AND tenantId = ?", [userId, tenantId]);
|
|
353
|
-
const stmt = db.prepare("INSERT INTO tenant_roles (userId, tenantId, role) VALUES (?, ?, ?)");
|
|
354
|
-
for (const role of roles) {
|
|
355
|
-
stmt.run(userId, tenantId, role);
|
|
356
|
-
}
|
|
357
|
-
},
|
|
358
|
-
async addTenantRole(userId, tenantId, role) {
|
|
359
|
-
try {
|
|
360
|
-
getDb().run("INSERT INTO tenant_roles (userId, tenantId, role) VALUES (?, ?, ?)", [userId, tenantId, role]);
|
|
361
|
-
}
|
|
362
|
-
catch { /* already exists */ }
|
|
363
|
-
},
|
|
364
|
-
async removeTenantRole(userId, tenantId, role) {
|
|
365
|
-
getDb().run("DELETE FROM tenant_roles WHERE userId = ? AND tenantId = ? AND role = ?", [userId, tenantId, role]);
|
|
366
|
-
},
|
|
367
|
-
// ---------------------------------------------------------------------------
|
|
368
|
-
// Groups
|
|
369
|
-
// ---------------------------------------------------------------------------
|
|
370
|
-
async createGroup(group) {
|
|
371
|
-
const id = crypto.randomUUID();
|
|
372
|
-
const now = Date.now();
|
|
373
|
-
try {
|
|
374
|
-
getDb().run("INSERT INTO groups (id, name, displayName, description, roles, tenantId, createdAt, updatedAt) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", [id, group.name, group.displayName ?? null, group.description ?? null, JSON.stringify(group.roles ?? []), group.tenantId ?? null, now, now]);
|
|
375
|
-
}
|
|
376
|
-
catch (err) {
|
|
377
|
-
if (err?.code === "SQLITE_CONSTRAINT_UNIQUE" || err?.code === "SQLITE_CONSTRAINT_PRIMARYKEY") {
|
|
378
|
-
throw new HttpError(409, "A group with this name already exists in this scope");
|
|
379
|
-
}
|
|
380
|
-
throw err;
|
|
381
|
-
}
|
|
382
|
-
return { id };
|
|
383
|
-
},
|
|
384
|
-
async deleteGroup(groupId) {
|
|
385
|
-
// group_memberships are cascade-deleted via ON DELETE CASCADE (requires PRAGMA foreign_keys = ON)
|
|
386
|
-
getDb().run("DELETE FROM groups WHERE id = ?", [groupId]);
|
|
387
|
-
},
|
|
388
|
-
async getGroup(groupId) {
|
|
389
|
-
const row = getDb().query("SELECT id, name, displayName, description, roles, tenantId, createdAt, updatedAt FROM groups WHERE id = ?").get(groupId);
|
|
390
|
-
if (!row)
|
|
391
|
-
return null;
|
|
392
|
-
return { ...row, displayName: row.displayName ?? undefined, description: row.description ?? undefined, roles: JSON.parse(row.roles) };
|
|
393
|
-
},
|
|
394
|
-
async listGroups(tenantId, opts) {
|
|
395
|
-
const limit = Math.min(opts?.limit ?? 50, 200);
|
|
396
|
-
const offset = opts?.offset ?? 0;
|
|
397
|
-
const db = getDb();
|
|
398
|
-
const cols = "id, name, displayName, description, roles, tenantId, createdAt, updatedAt";
|
|
399
|
-
let rows;
|
|
400
|
-
let total;
|
|
401
|
-
if (tenantId === null) {
|
|
402
|
-
rows = db.query(`SELECT ${cols} FROM groups WHERE tenantId IS NULL LIMIT ? OFFSET ?`).all(limit, offset);
|
|
403
|
-
total = (db.query("SELECT COUNT(*) as c FROM groups WHERE tenantId IS NULL").get()?.c ?? 0);
|
|
404
|
-
}
|
|
405
|
-
else {
|
|
406
|
-
rows = db.query(`SELECT ${cols} FROM groups WHERE tenantId = ? LIMIT ? OFFSET ?`).all(tenantId, limit, offset);
|
|
407
|
-
total = (db.query("SELECT COUNT(*) as c FROM groups WHERE tenantId = ?").get(tenantId)?.c ?? 0);
|
|
408
|
-
}
|
|
409
|
-
const items = rows.map((r) => ({ ...r, displayName: r.displayName ?? undefined, description: r.description ?? undefined, roles: JSON.parse(r.roles) }));
|
|
410
|
-
return { items, total, limit, offset };
|
|
411
|
-
},
|
|
412
|
-
async updateGroup(groupId, updates) {
|
|
413
|
-
const db = getDb();
|
|
414
|
-
const now = Date.now();
|
|
415
|
-
const sets = ["updatedAt = ?"];
|
|
416
|
-
const params = [now];
|
|
417
|
-
if (updates.name !== undefined) {
|
|
418
|
-
sets.push("name = ?");
|
|
419
|
-
params.push(updates.name);
|
|
420
|
-
}
|
|
421
|
-
if ("displayName" in updates) {
|
|
422
|
-
sets.push("displayName = ?");
|
|
423
|
-
params.push(updates.displayName ?? null);
|
|
424
|
-
}
|
|
425
|
-
if ("description" in updates) {
|
|
426
|
-
sets.push("description = ?");
|
|
427
|
-
params.push(updates.description ?? null);
|
|
428
|
-
}
|
|
429
|
-
if (updates.roles !== undefined) {
|
|
430
|
-
sets.push("roles = ?");
|
|
431
|
-
params.push(JSON.stringify(updates.roles));
|
|
432
|
-
}
|
|
433
|
-
params.push(groupId);
|
|
434
|
-
db.run(`UPDATE groups SET ${sets.join(", ")} WHERE id = ?`, params);
|
|
435
|
-
},
|
|
436
|
-
async addGroupMember(groupId, userId, roles = []) {
|
|
437
|
-
const group = getDb().query("SELECT tenantId FROM groups WHERE id = ?").get(groupId);
|
|
438
|
-
if (!group)
|
|
439
|
-
throw new HttpError(404, "Group not found");
|
|
440
|
-
try {
|
|
441
|
-
getDb().run("INSERT INTO group_memberships (userId, groupId, roles, tenantId, createdAt) VALUES (?, ?, ?, ?, ?)", [userId, groupId, JSON.stringify(roles), group.tenantId ?? null, Date.now()]);
|
|
442
|
-
}
|
|
443
|
-
catch (err) {
|
|
444
|
-
if (err?.code === "SQLITE_CONSTRAINT_PRIMARYKEY" || err?.code === "SQLITE_CONSTRAINT_UNIQUE") {
|
|
445
|
-
throw new HttpError(409, "User is already a member of this group");
|
|
446
|
-
}
|
|
447
|
-
throw err;
|
|
448
|
-
}
|
|
449
|
-
},
|
|
450
|
-
async updateGroupMembership(groupId, userId, roles) {
|
|
451
|
-
getDb().run("UPDATE group_memberships SET roles = ? WHERE userId = ? AND groupId = ?", [JSON.stringify(roles), userId, groupId]);
|
|
452
|
-
},
|
|
453
|
-
async removeGroupMember(groupId, userId) {
|
|
454
|
-
getDb().run("DELETE FROM group_memberships WHERE userId = ? AND groupId = ?", [userId, groupId]);
|
|
455
|
-
},
|
|
456
|
-
async getGroupMembers(groupId, opts) {
|
|
457
|
-
const limit = Math.min(opts?.limit ?? 50, 200);
|
|
458
|
-
const offset = opts?.offset ?? 0;
|
|
459
|
-
const db = getDb();
|
|
460
|
-
const rows = db.query("SELECT userId, roles FROM group_memberships WHERE groupId = ? LIMIT ? OFFSET ?").all(groupId, limit, offset);
|
|
461
|
-
const total = db.query("SELECT COUNT(*) as c FROM group_memberships WHERE groupId = ?").get(groupId)?.c ?? 0;
|
|
462
|
-
return { items: rows.map((r) => ({ userId: r.userId, roles: JSON.parse(r.roles) })), total, limit, offset };
|
|
463
|
-
},
|
|
464
|
-
async getUserGroups(userId, tenantId) {
|
|
465
|
-
const db = getDb();
|
|
466
|
-
let memberRows;
|
|
467
|
-
if (tenantId === null) {
|
|
468
|
-
memberRows = db.query("SELECT groupId, roles as memberRoles FROM group_memberships WHERE userId = ? AND tenantId IS NULL").all(userId);
|
|
469
|
-
}
|
|
470
|
-
else {
|
|
471
|
-
memberRows = db.query("SELECT groupId, roles as memberRoles FROM group_memberships WHERE userId = ? AND tenantId = ?").all(userId, tenantId);
|
|
472
|
-
}
|
|
473
|
-
if (memberRows.length === 0)
|
|
474
|
-
return [];
|
|
475
|
-
const result = [];
|
|
476
|
-
for (const m of memberRows) {
|
|
477
|
-
const row = db.query("SELECT id, name, displayName, description, roles, tenantId, createdAt, updatedAt FROM groups WHERE id = ?").get(m.groupId);
|
|
478
|
-
if (row) {
|
|
479
|
-
result.push({
|
|
480
|
-
group: { ...row, displayName: row.displayName ?? undefined, description: row.description ?? undefined, roles: JSON.parse(row.roles) },
|
|
481
|
-
membershipRoles: JSON.parse(m.memberRoles),
|
|
482
|
-
});
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
return result;
|
|
486
|
-
},
|
|
487
|
-
async getEffectiveRoles(userId, tenantId) {
|
|
488
|
-
const db = getDb();
|
|
489
|
-
// Direct roles
|
|
490
|
-
let direct = [];
|
|
491
|
-
if (tenantId) {
|
|
492
|
-
const rows = db.query("SELECT role FROM tenant_roles WHERE userId = ? AND tenantId = ?").all(userId, tenantId);
|
|
493
|
-
direct = rows.map((r) => r.role);
|
|
494
|
-
}
|
|
495
|
-
else {
|
|
496
|
-
const row = db.query("SELECT roles FROM users WHERE id = ?").get(userId);
|
|
497
|
-
direct = row ? JSON.parse(row.roles) : [];
|
|
498
|
-
}
|
|
499
|
-
let memberRows;
|
|
500
|
-
if (tenantId === null) {
|
|
501
|
-
memberRows = db.query("SELECT g.roles as groupRoles, gm.roles as memberRoles FROM group_memberships gm JOIN groups g ON g.id = gm.groupId WHERE gm.userId = ? AND gm.tenantId IS NULL").all(userId);
|
|
502
|
-
}
|
|
503
|
-
else {
|
|
504
|
-
memberRows = db.query("SELECT g.roles as groupRoles, gm.roles as memberRoles FROM group_memberships gm JOIN groups g ON g.id = gm.groupId WHERE gm.userId = ? AND gm.tenantId = ?").all(userId, tenantId);
|
|
505
|
-
}
|
|
506
|
-
const groupRoles = memberRows.flatMap((r) => [...JSON.parse(r.groupRoles), ...JSON.parse(r.memberRoles)]);
|
|
507
|
-
return [...new Set([...direct, ...groupRoles])];
|
|
508
|
-
},
|
|
509
|
-
};
|
|
510
|
-
import { getPersistSessionMetadata, getIncludeInactiveSessions } from "../lib/appConfig";
|
|
511
|
-
const SESSION_TTL_MS = 60 * 60 * 24 * 7 * 1000; // 7 days
|
|
512
|
-
export const sqliteCreateSession = (userId, token, sessionId, metadata) => {
|
|
513
|
-
const now = Date.now();
|
|
514
|
-
const expiresAt = now + SESSION_TTL_MS;
|
|
515
|
-
getDb().run("INSERT INTO sessions (sessionId, userId, token, createdAt, lastActiveAt, expiresAt, ipAddress, userAgent) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", [sessionId, userId, token, now, now, expiresAt, metadata?.ipAddress ?? null, metadata?.userAgent ?? null]);
|
|
516
|
-
};
|
|
517
|
-
export const sqliteGetSession = (sessionId) => {
|
|
518
|
-
const row = getDb().query("SELECT token FROM sessions WHERE sessionId = ? AND expiresAt > ?").get(sessionId, Date.now());
|
|
519
|
-
if (!row || !row.token)
|
|
520
|
-
return null;
|
|
521
|
-
return row.token;
|
|
522
|
-
};
|
|
523
|
-
export const sqliteDeleteSession = (sessionId) => {
|
|
524
|
-
if (getPersistSessionMetadata()) {
|
|
525
|
-
getDb().run("UPDATE sessions SET token = NULL, refreshToken = NULL, prevRefreshToken = NULL, prevTokenExpiresAt = NULL WHERE sessionId = ?", [sessionId]);
|
|
526
|
-
}
|
|
527
|
-
else {
|
|
528
|
-
getDb().run("DELETE FROM sessions WHERE sessionId = ?", [sessionId]);
|
|
529
|
-
}
|
|
530
|
-
};
|
|
531
|
-
export const sqliteGetUserSessions = (userId) => {
|
|
532
|
-
const now = Date.now();
|
|
533
|
-
const rows = getDb().query("SELECT sessionId, token, createdAt, lastActiveAt, expiresAt, ipAddress, userAgent FROM sessions WHERE userId = ? ORDER BY createdAt ASC").all(userId);
|
|
534
|
-
const includeInactive = getIncludeInactiveSessions();
|
|
535
|
-
const persist = getPersistSessionMetadata();
|
|
536
|
-
const results = [];
|
|
537
|
-
for (const row of rows) {
|
|
538
|
-
const isActive = !!row.token && row.expiresAt > now;
|
|
539
|
-
if (!isActive && !persist)
|
|
540
|
-
continue;
|
|
541
|
-
if (!isActive && !includeInactive)
|
|
542
|
-
continue;
|
|
543
|
-
results.push({
|
|
544
|
-
sessionId: row.sessionId,
|
|
545
|
-
createdAt: row.createdAt,
|
|
546
|
-
lastActiveAt: row.lastActiveAt,
|
|
547
|
-
expiresAt: row.expiresAt,
|
|
548
|
-
ipAddress: row.ipAddress ?? undefined,
|
|
549
|
-
userAgent: row.userAgent ?? undefined,
|
|
550
|
-
isActive,
|
|
551
|
-
});
|
|
552
|
-
}
|
|
553
|
-
return results;
|
|
554
|
-
};
|
|
555
|
-
export const sqliteGetActiveSessionCount = (userId) => {
|
|
556
|
-
const row = getDb().query("SELECT COUNT(*) AS count FROM sessions WHERE userId = ? AND token IS NOT NULL AND expiresAt > ?").get(userId, Date.now());
|
|
557
|
-
return row?.count ?? 0;
|
|
558
|
-
};
|
|
559
|
-
export const sqliteEvictOldestSession = (userId) => {
|
|
560
|
-
const now = Date.now();
|
|
561
|
-
const oldest = getDb().query("SELECT sessionId FROM sessions WHERE userId = ? AND token IS NOT NULL AND expiresAt > ? ORDER BY createdAt ASC LIMIT 1").get(userId, now);
|
|
562
|
-
if (oldest)
|
|
563
|
-
sqliteDeleteSession(oldest.sessionId);
|
|
564
|
-
};
|
|
565
|
-
export const sqliteUpdateSessionLastActive = (sessionId) => {
|
|
566
|
-
getDb().run("UPDATE sessions SET lastActiveAt = ? WHERE sessionId = ?", [Date.now(), sessionId]);
|
|
567
|
-
};
|
|
568
|
-
import { getRotationGraceSeconds } from "../lib/appConfig";
|
|
569
|
-
export const sqliteSetRefreshToken = (sessionId, refreshToken) => {
|
|
570
|
-
getDb().run("UPDATE sessions SET refreshToken = ? WHERE sessionId = ?", [refreshToken, sessionId]);
|
|
571
|
-
};
|
|
572
|
-
export const sqliteGetSessionByRefreshToken = (refreshToken) => {
|
|
573
|
-
const db = getDb();
|
|
574
|
-
// Check current refresh token
|
|
575
|
-
let row = db.query("SELECT sessionId, userId, refreshToken FROM sessions WHERE refreshToken = ?").get(refreshToken);
|
|
576
|
-
if (row) {
|
|
577
|
-
return { sessionId: row.sessionId, userId: row.userId, newRefreshToken: refreshToken };
|
|
578
|
-
}
|
|
579
|
-
// Check previous refresh token (grace window)
|
|
580
|
-
row = db.query("SELECT sessionId, userId, refreshToken, prevTokenExpiresAt FROM sessions WHERE prevRefreshToken = ?").get(refreshToken);
|
|
581
|
-
if (!row)
|
|
582
|
-
return null;
|
|
583
|
-
const prevExpiry = row.prevTokenExpiresAt;
|
|
584
|
-
if (prevExpiry && prevExpiry > Date.now()) {
|
|
585
|
-
// Within grace window — return current refresh token
|
|
586
|
-
return { sessionId: row.sessionId, userId: row.userId, newRefreshToken: row.refreshToken };
|
|
587
|
-
}
|
|
588
|
-
// Grace window expired — theft detected, invalidate session
|
|
589
|
-
sqliteDeleteSession(row.sessionId);
|
|
590
|
-
return null;
|
|
591
|
-
};
|
|
592
|
-
export const sqliteRotateRefreshToken = (sessionId, newRefreshToken, newAccessToken) => {
|
|
593
|
-
const graceSeconds = getRotationGraceSeconds();
|
|
594
|
-
const prevTokenExpiresAt = Date.now() + graceSeconds * 1000;
|
|
595
|
-
getDb().run("UPDATE sessions SET prevRefreshToken = refreshToken, prevTokenExpiresAt = ?, refreshToken = ?, token = ? WHERE sessionId = ?", [prevTokenExpiresAt, newRefreshToken, newAccessToken, sessionId]);
|
|
596
|
-
};
|
|
597
|
-
export const sqliteGetSessionFingerprint = (sessionId) => {
|
|
598
|
-
const row = getDb().query("SELECT fingerprint FROM sessions WHERE sessionId = ?").get(sessionId);
|
|
599
|
-
return row?.fingerprint ?? null;
|
|
600
|
-
};
|
|
601
|
-
export const sqliteSetSessionFingerprint = (sessionId, fingerprint) => {
|
|
602
|
-
getDb().run("UPDATE sessions SET fingerprint = ? WHERE sessionId = ?", [fingerprint, sessionId]);
|
|
603
|
-
};
|
|
604
|
-
// ---------------------------------------------------------------------------
|
|
605
|
-
// OAuth state helpers (used by src/lib/oauth.ts)
|
|
606
|
-
// ---------------------------------------------------------------------------
|
|
607
|
-
const OAUTH_STATE_TTL_MS = 5 * 60 * 1000; // 5 minutes
|
|
608
|
-
export const sqliteStoreOAuthState = (state, codeVerifier, linkUserId) => {
|
|
609
|
-
const expiresAt = Date.now() + OAUTH_STATE_TTL_MS;
|
|
610
|
-
getDb().run("INSERT INTO oauth_states (state, codeVerifier, linkUserId, expiresAt) VALUES (?, ?, ?, ?)", [state, codeVerifier ?? null, linkUserId ?? null, expiresAt]);
|
|
611
|
-
};
|
|
612
|
-
export const sqliteConsumeOAuthState = (state) => {
|
|
613
|
-
const row = getDb().query("DELETE FROM oauth_states WHERE state = ? AND expiresAt > ? RETURNING codeVerifier, linkUserId").get(state, Date.now());
|
|
614
|
-
if (!row)
|
|
615
|
-
return null;
|
|
616
|
-
return {
|
|
617
|
-
codeVerifier: row.codeVerifier ?? undefined,
|
|
618
|
-
linkUserId: row.linkUserId ?? undefined,
|
|
619
|
-
};
|
|
620
|
-
};
|
|
621
|
-
// ---------------------------------------------------------------------------
|
|
622
|
-
// Cache helpers (used by src/middleware/cacheResponse.ts)
|
|
623
|
-
// ---------------------------------------------------------------------------
|
|
624
|
-
export const isSqliteReady = () => _db !== null;
|
|
625
|
-
export const sqliteGetCache = (key) => {
|
|
626
|
-
const row = getDb().query("SELECT value FROM cache_entries WHERE key = ? AND (expiresAt IS NULL OR expiresAt > ?)").get(key, Date.now());
|
|
627
|
-
return row?.value ?? null;
|
|
628
|
-
};
|
|
629
|
-
export const sqliteSetCache = (key, value, ttlSeconds) => {
|
|
630
|
-
const expiresAt = ttlSeconds ? Date.now() + ttlSeconds * 1000 : null;
|
|
631
|
-
getDb().run("INSERT INTO cache_entries (key, value, expiresAt) VALUES (?, ?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value, expiresAt = excluded.expiresAt", [key, value, expiresAt]);
|
|
632
|
-
};
|
|
633
|
-
export const sqliteDelCache = (key) => {
|
|
634
|
-
getDb().run("DELETE FROM cache_entries WHERE key = ?", [key]);
|
|
635
|
-
};
|
|
636
|
-
export const sqliteDelCachePattern = (pattern) => {
|
|
637
|
-
// Convert glob pattern (* wildcard) to a SQL LIKE pattern (% wildcard)
|
|
638
|
-
const likePattern = pattern.replace(/%/g, "\\%").replace(/_/g, "\\_").replace(/\*/g, "%");
|
|
639
|
-
getDb().run("DELETE FROM cache_entries WHERE key LIKE ? ESCAPE '\\'", [likePattern]);
|
|
640
|
-
};
|
|
641
|
-
// ---------------------------------------------------------------------------
|
|
642
|
-
// Email verification token helpers (used by src/lib/emailVerification.ts)
|
|
643
|
-
// ---------------------------------------------------------------------------
|
|
644
|
-
export const sqliteCreateVerificationToken = (token, userId, email, ttlSeconds) => {
|
|
645
|
-
const expiresAt = Date.now() + ttlSeconds * 1000;
|
|
646
|
-
getDb().run("INSERT INTO email_verifications (token, userId, email, expiresAt) VALUES (?, ?, ?, ?)", [token, userId, email, expiresAt]);
|
|
647
|
-
};
|
|
648
|
-
export const sqliteGetVerificationToken = (token) => {
|
|
649
|
-
const row = getDb().query("SELECT userId, email FROM email_verifications WHERE token = ? AND expiresAt > ?").get(token, Date.now());
|
|
650
|
-
return row ?? null;
|
|
651
|
-
};
|
|
652
|
-
export const sqliteDeleteVerificationToken = (token) => {
|
|
653
|
-
getDb().run("DELETE FROM email_verifications WHERE token = ?", [token]);
|
|
654
|
-
};
|
|
655
|
-
// ---------------------------------------------------------------------------
|
|
656
|
-
// Password reset token helpers (used by src/lib/resetPassword.ts)
|
|
657
|
-
// ---------------------------------------------------------------------------
|
|
658
|
-
export const sqliteCreateResetToken = (token, userId, email, ttlSeconds) => {
|
|
659
|
-
const expiresAt = Date.now() + ttlSeconds * 1000;
|
|
660
|
-
getDb().run("INSERT INTO password_resets (token, userId, email, expiresAt) VALUES (?, ?, ?, ?)", [token, userId, email, expiresAt]);
|
|
661
|
-
};
|
|
662
|
-
export const sqliteConsumeResetToken = (hash) => {
|
|
663
|
-
const row = getDb().query("DELETE FROM password_resets WHERE token = ? AND expiresAt > ? RETURNING userId, email").get(hash, Date.now());
|
|
664
|
-
return row ?? null;
|
|
665
|
-
};
|
|
666
|
-
// ---------------------------------------------------------------------------
|
|
667
|
-
// Account deletion cancel token helpers (used by src/lib/deletionCancelToken.ts)
|
|
668
|
-
// ---------------------------------------------------------------------------
|
|
669
|
-
export const sqliteCreateDeletionCancelToken = (token, userId, jobId, ttlSeconds) => {
|
|
670
|
-
const expiresAt = Date.now() + ttlSeconds * 1000;
|
|
671
|
-
getDb().run("INSERT INTO deletion_cancel_tokens (token, userId, jobId, expiresAt) VALUES (?, ?, ?, ?)", [token, userId, jobId, expiresAt]);
|
|
672
|
-
};
|
|
673
|
-
export const sqliteConsumeDeletionCancelToken = (hash) => {
|
|
674
|
-
const row = getDb().query("DELETE FROM deletion_cancel_tokens WHERE token = ? AND expiresAt > ? RETURNING userId, jobId").get(hash, Date.now());
|
|
675
|
-
return row ?? null;
|
|
676
|
-
};
|
|
677
|
-
export const sqliteStoreOAuthCode = (hash, payload, ttlSeconds) => {
|
|
678
|
-
const expiresAt = Date.now() + ttlSeconds * 1000;
|
|
679
|
-
getDb().run("INSERT INTO oauth_codes (codeHash, token, userId, email, refreshToken, expiresAt) VALUES (?, ?, ?, ?, ?, ?)", [hash, payload.token, payload.userId, payload.email ?? null, payload.refreshToken ?? null, expiresAt]);
|
|
680
|
-
};
|
|
681
|
-
export const sqliteConsumeOAuthCode = (hash) => {
|
|
682
|
-
const row = getDb().query("DELETE FROM oauth_codes WHERE codeHash = ? AND expiresAt > ? RETURNING token, userId, email, refreshToken").get(hash, Date.now());
|
|
683
|
-
if (!row)
|
|
684
|
-
return null;
|
|
685
|
-
return { token: row.token, userId: row.userId, email: row.email ?? undefined, refreshToken: row.refreshToken ?? undefined };
|
|
686
|
-
};
|
|
687
|
-
// ---------------------------------------------------------------------------
|
|
688
|
-
// Optional periodic cleanup of expired rows
|
|
689
|
-
// ---------------------------------------------------------------------------
|
|
690
|
-
export const startSqliteCleanup = (intervalMs = 3_600_000) => {
|
|
691
|
-
return setInterval(() => {
|
|
692
|
-
const db = getDb();
|
|
693
|
-
const now = Date.now();
|
|
694
|
-
if (getPersistSessionMetadata()) {
|
|
695
|
-
// Null out tokens for expired sessions but keep the metadata row
|
|
696
|
-
db.run("UPDATE sessions SET token = NULL WHERE expiresAt <= ? AND token IS NOT NULL", [now]);
|
|
697
|
-
}
|
|
698
|
-
else {
|
|
699
|
-
db.run("DELETE FROM sessions WHERE expiresAt <= ?", [now]);
|
|
700
|
-
}
|
|
701
|
-
db.run("DELETE FROM oauth_states WHERE expiresAt <= ?", [now]);
|
|
702
|
-
db.run("DELETE FROM cache_entries WHERE expiresAt IS NOT NULL AND expiresAt <= ?", [now]);
|
|
703
|
-
db.run("DELETE FROM email_verifications WHERE expiresAt <= ?", [now]);
|
|
704
|
-
db.run("DELETE FROM password_resets WHERE expiresAt <= ?", [now]);
|
|
705
|
-
db.run("DELETE FROM oauth_codes WHERE expiresAt <= ?", [now]);
|
|
706
|
-
}, intervalMs);
|
|
707
|
-
};
|