@sixthsummit/ship-api 0.0.0-stage → 4.1.1
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/CHANGELOG.md +605 -0
- package/LICENSE +202 -0
- package/NOTICE +4 -0
- package/README.md +58 -2
- package/cli/commands/add.js +537 -0
- package/cli/commands/contract.js +2 -0
- package/cli/commands/create.js +250 -0
- package/cli/commands/dev.js +227 -0
- package/cli/commands/doctor.js +286 -0
- package/cli/commands/generate.js +937 -0
- package/cli/commands/graph.js +2 -0
- package/cli/commands/migrate-orm.js +1171 -0
- package/cli/commands/update.js +37 -0
- package/cli/ship-api.js +285 -0
- package/lib/app/auth/AuthProvider.d.ts +91 -0
- package/lib/app/auth/AuthProvider.d.ts.map +1 -0
- package/lib/app/auth/AuthProvider.js +13 -0
- package/lib/app/auth/AuthProvider.js.map +1 -0
- package/lib/app/auth/adapters/firebase.d.ts +79 -0
- package/lib/app/auth/adapters/firebase.d.ts.map +1 -0
- package/lib/app/auth/adapters/firebase.js +122 -0
- package/lib/app/auth/adapters/firebase.js.map +1 -0
- package/lib/app/auth/adapters/jwtCookie.d.ts +55 -0
- package/lib/app/auth/adapters/jwtCookie.d.ts.map +1 -0
- package/lib/app/auth/adapters/jwtCookie.js +120 -0
- package/lib/app/auth/adapters/jwtCookie.js.map +1 -0
- package/lib/app/auth/index.d.ts +8 -0
- package/lib/app/auth/index.d.ts.map +1 -0
- package/lib/app/auth/index.js +7 -0
- package/lib/app/auth/index.js.map +1 -0
- package/lib/app/auth/jwt/AuthFlow.d.ts +94 -0
- package/lib/app/auth/jwt/AuthFlow.d.ts.map +1 -0
- package/lib/app/auth/jwt/AuthFlow.js +127 -0
- package/lib/app/auth/jwt/AuthFlow.js.map +1 -0
- package/lib/app/auth/jwt/DrizzleRefreshTokenStore.d.ts +80 -0
- package/lib/app/auth/jwt/DrizzleRefreshTokenStore.d.ts.map +1 -0
- package/lib/app/auth/jwt/DrizzleRefreshTokenStore.js +134 -0
- package/lib/app/auth/jwt/DrizzleRefreshTokenStore.js.map +1 -0
- package/lib/app/auth/jwt/JwtSigner.d.ts +123 -0
- package/lib/app/auth/jwt/JwtSigner.d.ts.map +1 -0
- package/lib/app/auth/jwt/JwtSigner.js +118 -0
- package/lib/app/auth/jwt/JwtSigner.js.map +1 -0
- package/lib/app/auth/jwt/RefreshTokenStore.d.ts +97 -0
- package/lib/app/auth/jwt/RefreshTokenStore.d.ts.map +1 -0
- package/lib/app/auth/jwt/RefreshTokenStore.js +122 -0
- package/lib/app/auth/jwt/RefreshTokenStore.js.map +1 -0
- package/lib/app/auth/permissionDefinition.d.ts +20 -0
- package/lib/app/auth/permissionDefinition.d.ts.map +1 -0
- package/lib/app/auth/permissionDefinition.js +2 -0
- package/lib/app/auth/permissionDefinition.js.map +1 -0
- package/lib/app/context/RequestContext.d.ts +59 -0
- package/lib/app/context/RequestContext.d.ts.map +1 -0
- package/lib/app/context/RequestContext.js +25 -0
- package/lib/app/context/RequestContext.js.map +1 -0
- package/lib/app/db/QueryOptions.d.ts +82 -0
- package/lib/app/db/QueryOptions.d.ts.map +1 -0
- package/lib/app/db/QueryOptions.js +37 -0
- package/lib/app/db/QueryOptions.js.map +1 -0
- package/lib/app/db/baseFields.d.ts +60 -0
- package/lib/app/db/baseFields.d.ts.map +1 -0
- package/lib/app/db/baseFields.js +54 -0
- package/lib/app/db/baseFields.js.map +1 -0
- package/lib/app/db/buildWhere.d.ts +22 -0
- package/lib/app/db/buildWhere.d.ts.map +1 -0
- package/lib/app/db/buildWhere.js +75 -0
- package/lib/app/db/buildWhere.js.map +1 -0
- package/lib/app/db/client.d.ts +111 -0
- package/lib/app/db/client.d.ts.map +1 -0
- package/lib/app/db/client.js +99 -0
- package/lib/app/db/client.js.map +1 -0
- package/lib/app/db/tenantScoped.d.ts +59 -0
- package/lib/app/db/tenantScoped.d.ts.map +1 -0
- package/lib/app/db/tenantScoped.js +54 -0
- package/lib/app/db/tenantScoped.js.map +1 -0
- package/lib/app/db/transaction.d.ts +58 -0
- package/lib/app/db/transaction.d.ts.map +1 -0
- package/lib/app/db/transaction.js +106 -0
- package/lib/app/db/transaction.js.map +1 -0
- package/lib/app/health/HealthCheck.d.ts +121 -0
- package/lib/app/health/HealthCheck.d.ts.map +1 -0
- package/lib/app/health/HealthCheck.js +151 -0
- package/lib/app/health/HealthCheck.js.map +1 -0
- package/lib/app/health/redisHealthCheck.d.ts +14 -0
- package/lib/app/health/redisHealthCheck.d.ts.map +1 -0
- package/lib/app/health/redisHealthCheck.js +21 -0
- package/lib/app/health/redisHealthCheck.js.map +1 -0
- package/lib/app/lifecycle/Bootstrapper.d.ts +92 -0
- package/lib/app/lifecycle/Bootstrapper.d.ts.map +1 -0
- package/lib/app/lifecycle/Bootstrapper.js +99 -0
- package/lib/app/lifecycle/Bootstrapper.js.map +1 -0
- package/lib/app/registry/routes.d.ts +89 -0
- package/lib/app/registry/routes.d.ts.map +1 -0
- package/lib/app/registry/routes.js +72 -0
- package/lib/app/registry/routes.js.map +1 -0
- package/lib/app/services/DrizzleEntityService.d.ts +123 -0
- package/lib/app/services/DrizzleEntityService.d.ts.map +1 -0
- package/lib/app/services/DrizzleEntityService.js +342 -0
- package/lib/app/services/DrizzleEntityService.js.map +1 -0
- package/lib/app/services/RedisProvider.d.ts +52 -0
- package/lib/app/services/RedisProvider.d.ts.map +1 -0
- package/lib/app/services/RedisProvider.js +75 -0
- package/lib/app/services/RedisProvider.js.map +1 -0
- package/lib/app/services/cache/Cache.d.ts +70 -0
- package/lib/app/services/cache/Cache.d.ts.map +1 -0
- package/lib/app/services/cache/Cache.js +18 -0
- package/lib/app/services/cache/Cache.js.map +1 -0
- package/lib/app/services/cache/InMemoryCache.d.ts +35 -0
- package/lib/app/services/cache/InMemoryCache.d.ts.map +1 -0
- package/lib/app/services/cache/InMemoryCache.js +76 -0
- package/lib/app/services/cache/InMemoryCache.js.map +1 -0
- package/lib/app/services/cache/RedisCache.d.ts +99 -0
- package/lib/app/services/cache/RedisCache.d.ts.map +1 -0
- package/lib/app/services/cache/RedisCache.js +150 -0
- package/lib/app/services/cache/RedisCache.js.map +1 -0
- package/lib/app/services/cache/cached.d.ts +30 -0
- package/lib/app/services/cache/cached.d.ts.map +1 -0
- package/lib/app/services/cache/cached.js +38 -0
- package/lib/app/services/cache/cached.js.map +1 -0
- package/lib/app/services/cache/index.d.ts +5 -0
- package/lib/app/services/cache/index.d.ts.map +1 -0
- package/lib/app/services/cache/index.js +4 -0
- package/lib/app/services/cache/index.js.map +1 -0
- package/lib/app/services/cron/defineCron.d.ts +57 -0
- package/lib/app/services/cron/defineCron.d.ts.map +1 -0
- package/lib/app/services/cron/defineCron.js +15 -0
- package/lib/app/services/cron/defineCron.js.map +1 -0
- package/lib/app/services/cron/index.d.ts +2 -0
- package/lib/app/services/cron/index.d.ts.map +1 -0
- package/lib/app/services/cron/index.js +2 -0
- package/lib/app/services/cron/index.js.map +1 -0
- package/lib/app/services/hooks/LifecycleHooks.d.ts +61 -0
- package/lib/app/services/hooks/LifecycleHooks.d.ts.map +1 -0
- package/lib/app/services/hooks/LifecycleHooks.js +85 -0
- package/lib/app/services/hooks/LifecycleHooks.js.map +1 -0
- package/lib/app/services/jobs/JobsManager.d.ts +67 -0
- package/lib/app/services/jobs/JobsManager.d.ts.map +1 -0
- package/lib/app/services/jobs/JobsManager.js +121 -0
- package/lib/app/services/jobs/JobsManager.js.map +1 -0
- package/lib/app/services/jobs/bullBoard.d.ts +72 -0
- package/lib/app/services/jobs/bullBoard.d.ts.map +1 -0
- package/lib/app/services/jobs/bullBoard.js +96 -0
- package/lib/app/services/jobs/bullBoard.js.map +1 -0
- package/lib/app/services/jobs/defineJob.d.ts +81 -0
- package/lib/app/services/jobs/defineJob.d.ts.map +1 -0
- package/lib/app/services/jobs/defineJob.js +49 -0
- package/lib/app/services/jobs/defineJob.js.map +1 -0
- package/lib/app/services/jobs/index.d.ts +4 -0
- package/lib/app/services/jobs/index.d.ts.map +1 -0
- package/lib/app/services/jobs/index.js +4 -0
- package/lib/app/services/jobs/index.js.map +1 -0
- package/lib/app/services/rateLimit/InMemorySlidingWindowBackend.d.ts +23 -0
- package/lib/app/services/rateLimit/InMemorySlidingWindowBackend.d.ts.map +1 -0
- package/lib/app/services/rateLimit/InMemorySlidingWindowBackend.js +51 -0
- package/lib/app/services/rateLimit/InMemorySlidingWindowBackend.js.map +1 -0
- package/lib/app/services/rateLimit/RateLimitBackend.d.ts +41 -0
- package/lib/app/services/rateLimit/RateLimitBackend.d.ts.map +1 -0
- package/lib/app/services/rateLimit/RateLimitBackend.js +19 -0
- package/lib/app/services/rateLimit/RateLimitBackend.js.map +1 -0
- package/lib/app/services/rateLimit/RedisSlidingWindowBackend.d.ts +16 -0
- package/lib/app/services/rateLimit/RedisSlidingWindowBackend.d.ts.map +1 -0
- package/lib/app/services/rateLimit/RedisSlidingWindowBackend.js +80 -0
- package/lib/app/services/rateLimit/RedisSlidingWindowBackend.js.map +1 -0
- package/lib/app/services/rateLimit/index.d.ts +4 -0
- package/lib/app/services/rateLimit/index.d.ts.map +1 -0
- package/lib/app/services/rateLimit/index.js +3 -0
- package/lib/app/services/rateLimit/index.js.map +1 -0
- package/lib/app/services/storage/DiskStorageAdapter.d.ts +62 -0
- package/lib/app/services/storage/DiskStorageAdapter.d.ts.map +1 -0
- package/lib/app/services/storage/DiskStorageAdapter.js +295 -0
- package/lib/app/services/storage/DiskStorageAdapter.js.map +1 -0
- package/lib/app/services/storage/GCSStorageAdapter.d.ts +44 -0
- package/lib/app/services/storage/GCSStorageAdapter.d.ts.map +1 -0
- package/lib/app/services/storage/GCSStorageAdapter.js +133 -0
- package/lib/app/services/storage/GCSStorageAdapter.js.map +1 -0
- package/lib/app/services/storage/S3StorageAdapter.d.ts +57 -0
- package/lib/app/services/storage/S3StorageAdapter.d.ts.map +1 -0
- package/lib/app/services/storage/S3StorageAdapter.js +162 -0
- package/lib/app/services/storage/S3StorageAdapter.js.map +1 -0
- package/lib/app/services/storage/StorageService.d.ts +88 -0
- package/lib/app/services/storage/StorageService.d.ts.map +1 -0
- package/lib/app/services/storage/StorageService.js +18 -0
- package/lib/app/services/storage/StorageService.js.map +1 -0
- package/lib/app/services/storage/index.d.ts +5 -0
- package/lib/app/services/storage/index.d.ts.map +1 -0
- package/lib/app/services/storage/index.js +4 -0
- package/lib/app/services/storage/index.js.map +1 -0
- package/lib/app/utils/ContextValidators.d.ts +46 -0
- package/lib/app/utils/ContextValidators.d.ts.map +1 -0
- package/lib/app/utils/ContextValidators.js +81 -0
- package/lib/app/utils/ContextValidators.js.map +1 -0
- package/lib/app/utils/defineEnv.d.ts +80 -0
- package/lib/app/utils/defineEnv.d.ts.map +1 -0
- package/lib/app/utils/defineEnv.js +95 -0
- package/lib/app/utils/defineEnv.js.map +1 -0
- package/lib/client.d.ts +139 -0
- package/lib/client.d.ts.map +1 -0
- package/lib/client.js +98 -0
- package/lib/client.js.map +1 -0
- package/lib/contract/application.d.ts +3 -0
- package/lib/contract/application.d.ts.map +1 -0
- package/lib/contract/application.js +2 -0
- package/lib/contract/application.js.map +1 -0
- package/lib/contract/client.d.ts +3 -0
- package/lib/contract/client.d.ts.map +1 -0
- package/lib/contract/client.js +3 -0
- package/lib/contract/client.js.map +1 -0
- package/lib/contract/index.d.ts +3 -0
- package/lib/contract/index.d.ts.map +1 -0
- package/lib/contract/index.js +3 -0
- package/lib/contract/index.js.map +1 -0
- package/lib/contract/manifest.d.ts +3 -0
- package/lib/contract/manifest.d.ts.map +1 -0
- package/lib/contract/manifest.js +2 -0
- package/lib/contract/manifest.js.map +1 -0
- package/lib/contract/openapi.d.ts +3 -0
- package/lib/contract/openapi.d.ts.map +1 -0
- package/lib/contract/openapi.js +3 -0
- package/lib/contract/openapi.js.map +1 -0
- package/lib/contract/project.d.ts +3 -0
- package/lib/contract/project.d.ts.map +1 -0
- package/lib/contract/project.js +3 -0
- package/lib/contract/project.js.map +1 -0
- package/lib/contract/schema.d.ts +3 -0
- package/lib/contract/schema.d.ts.map +1 -0
- package/lib/contract/schema.js +3 -0
- package/lib/contract/schema.js.map +1 -0
- package/lib/drizzle/index.d.ts +3 -0
- package/lib/drizzle/index.d.ts.map +1 -0
- package/lib/drizzle/index.js +3 -0
- package/lib/drizzle/index.js.map +1 -0
- package/lib/hono/auth.d.ts +6 -0
- package/lib/hono/auth.d.ts.map +1 -0
- package/lib/hono/auth.js +54 -0
- package/lib/hono/auth.js.map +1 -0
- package/lib/hono/index.d.ts +4 -0
- package/lib/hono/index.d.ts.map +1 -0
- package/lib/hono/index.js +4 -0
- package/lib/hono/index.js.map +1 -0
- package/lib/http/app/createApp.d.ts +132 -0
- package/lib/http/app/createApp.d.ts.map +1 -0
- package/lib/http/app/createApp.js +215 -0
- package/lib/http/app/createApp.js.map +1 -0
- package/lib/http/app/devRoutes.d.ts +31 -0
- package/lib/http/app/devRoutes.d.ts.map +1 -0
- package/lib/http/app/devRoutes.js +145 -0
- package/lib/http/app/devRoutes.js.map +1 -0
- package/lib/http/app/errors.d.ts +45 -0
- package/lib/http/app/errors.d.ts.map +1 -0
- package/lib/http/app/errors.js +93 -0
- package/lib/http/app/errors.js.map +1 -0
- package/lib/http/app/health.d.ts +66 -0
- package/lib/http/app/health.d.ts.map +1 -0
- package/lib/http/app/health.js +104 -0
- package/lib/http/app/health.js.map +1 -0
- package/lib/http/errors/AppError.d.ts +10 -0
- package/lib/http/errors/AppError.d.ts.map +1 -0
- package/lib/http/errors/AppError.js +19 -0
- package/lib/http/errors/AppError.js.map +1 -0
- package/lib/http/errors/AuthenticationError.d.ts +8 -0
- package/lib/http/errors/AuthenticationError.d.ts.map +1 -0
- package/lib/http/errors/AuthenticationError.js +10 -0
- package/lib/http/errors/AuthenticationError.js.map +1 -0
- package/lib/http/errors/AuthorizationError.d.ts +8 -0
- package/lib/http/errors/AuthorizationError.d.ts.map +1 -0
- package/lib/http/errors/AuthorizationError.js +10 -0
- package/lib/http/errors/AuthorizationError.js.map +1 -0
- package/lib/http/errors/BadRequestError.d.ts +8 -0
- package/lib/http/errors/BadRequestError.d.ts.map +1 -0
- package/lib/http/errors/BadRequestError.js +10 -0
- package/lib/http/errors/BadRequestError.js.map +1 -0
- package/lib/http/errors/ConflictError.d.ts +8 -0
- package/lib/http/errors/ConflictError.d.ts.map +1 -0
- package/lib/http/errors/ConflictError.js +10 -0
- package/lib/http/errors/ConflictError.js.map +1 -0
- package/lib/http/errors/InternalServerError.d.ts +8 -0
- package/lib/http/errors/InternalServerError.d.ts.map +1 -0
- package/lib/http/errors/InternalServerError.js +10 -0
- package/lib/http/errors/InternalServerError.js.map +1 -0
- package/lib/http/errors/NotFoundError.d.ts +8 -0
- package/lib/http/errors/NotFoundError.d.ts.map +1 -0
- package/lib/http/errors/NotFoundError.js +10 -0
- package/lib/http/errors/NotFoundError.js.map +1 -0
- package/lib/http/errors/RateLimitError.d.ts +13 -0
- package/lib/http/errors/RateLimitError.d.ts.map +1 -0
- package/lib/http/errors/RateLimitError.js +16 -0
- package/lib/http/errors/RateLimitError.js.map +1 -0
- package/lib/http/errors/ServiceUnavailableError.d.ts +8 -0
- package/lib/http/errors/ServiceUnavailableError.d.ts.map +1 -0
- package/lib/http/errors/ServiceUnavailableError.js +10 -0
- package/lib/http/errors/ServiceUnavailableError.js.map +1 -0
- package/lib/http/errors/ValidationError.d.ts +9 -0
- package/lib/http/errors/ValidationError.d.ts.map +1 -0
- package/lib/http/errors/ValidationError.js +12 -0
- package/lib/http/errors/ValidationError.js.map +1 -0
- package/lib/http/errors/index.d.ts +11 -0
- package/lib/http/errors/index.d.ts.map +1 -0
- package/lib/http/errors/index.js +12 -0
- package/lib/http/errors/index.js.map +1 -0
- package/lib/http/middleware/apiKey.d.ts +9 -0
- package/lib/http/middleware/apiKey.d.ts.map +1 -0
- package/lib/http/middleware/apiKey.js +71 -0
- package/lib/http/middleware/apiKey.js.map +1 -0
- package/lib/http/middleware/csrf.d.ts +63 -0
- package/lib/http/middleware/csrf.d.ts.map +1 -0
- package/lib/http/middleware/csrf.js +169 -0
- package/lib/http/middleware/csrf.js.map +1 -0
- package/lib/http/middleware/httpLogger.d.ts +39 -0
- package/lib/http/middleware/httpLogger.d.ts.map +1 -0
- package/lib/http/middleware/httpLogger.js +118 -0
- package/lib/http/middleware/httpLogger.js.map +1 -0
- package/lib/http/middleware/idempotency.d.ts +48 -0
- package/lib/http/middleware/idempotency.d.ts.map +1 -0
- package/lib/http/middleware/idempotency.js +180 -0
- package/lib/http/middleware/idempotency.js.map +1 -0
- package/lib/http/middleware/rateLimit.d.ts +105 -0
- package/lib/http/middleware/rateLimit.d.ts.map +1 -0
- package/lib/http/middleware/rateLimit.js +84 -0
- package/lib/http/middleware/rateLimit.js.map +1 -0
- package/lib/http/middleware/requireAuth.d.ts +58 -0
- package/lib/http/middleware/requireAuth.d.ts.map +1 -0
- package/lib/http/middleware/requireAuth.js +63 -0
- package/lib/http/middleware/requireAuth.js.map +1 -0
- package/lib/http/middleware/requirePermission.d.ts +23 -0
- package/lib/http/middleware/requirePermission.d.ts.map +1 -0
- package/lib/http/middleware/requirePermission.js +50 -0
- package/lib/http/middleware/requirePermission.js.map +1 -0
- package/lib/http/middleware/resolveTenant.d.ts +41 -0
- package/lib/http/middleware/resolveTenant.d.ts.map +1 -0
- package/lib/http/middleware/resolveTenant.js +17 -0
- package/lib/http/middleware/resolveTenant.js.map +1 -0
- package/lib/http/streaming/sse.d.ts +31 -0
- package/lib/http/streaming/sse.d.ts.map +1 -0
- package/lib/http/streaming/sse.js +11 -0
- package/lib/http/streaming/sse.js.map +1 -0
- package/lib/http/streaming/streamLLM.d.ts +94 -0
- package/lib/http/streaming/streamLLM.d.ts.map +1 -0
- package/lib/http/streaming/streamLLM.js +94 -0
- package/lib/http/streaming/streamLLM.js.map +1 -0
- package/lib/http/utils/authCookies.d.ts +74 -0
- package/lib/http/utils/authCookies.d.ts.map +1 -0
- package/lib/http/utils/authCookies.js +102 -0
- package/lib/http/utils/authCookies.js.map +1 -0
- package/lib/http/utils/clientIp.d.ts +85 -0
- package/lib/http/utils/clientIp.d.ts.map +1 -0
- package/lib/http/utils/clientIp.js +249 -0
- package/lib/http/utils/clientIp.js.map +1 -0
- package/lib/http/utils/index.d.ts +4 -0
- package/lib/http/utils/index.d.ts.map +1 -0
- package/lib/http/utils/index.js +5 -0
- package/lib/http/utils/index.js.map +1 -0
- package/lib/http/utils/metaTags.d.ts +49 -0
- package/lib/http/utils/metaTags.d.ts.map +1 -0
- package/lib/http/utils/metaTags.js +32 -0
- package/lib/http/utils/metaTags.js.map +1 -0
- package/lib/http/utils/publicSuffix.d.ts +34 -0
- package/lib/http/utils/publicSuffix.d.ts.map +1 -0
- package/lib/http/utils/publicSuffix.js +276 -0
- package/lib/http/utils/publicSuffix.js.map +1 -0
- package/lib/http/utils/uploads.d.ts +92 -0
- package/lib/http/utils/uploads.d.ts.map +1 -0
- package/lib/http/utils/uploads.js +126 -0
- package/lib/http/utils/uploads.js.map +1 -0
- package/lib/http/utils/validate.d.ts +41 -0
- package/lib/http/utils/validate.d.ts.map +1 -0
- package/lib/http/utils/validate.js +55 -0
- package/lib/http/utils/validate.js.map +1 -0
- package/lib/http/utils/webhooks.d.ts +63 -0
- package/lib/http/utils/webhooks.d.ts.map +1 -0
- package/lib/http/utils/webhooks.js +133 -0
- package/lib/http/utils/webhooks.js.map +1 -0
- package/lib/http/ws/auth.d.ts +46 -0
- package/lib/http/ws/auth.d.ts.map +1 -0
- package/lib/http/ws/auth.js +123 -0
- package/lib/http/ws/auth.js.map +1 -0
- package/lib/index.d.ts +80 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +61 -0
- package/lib/index.js.map +1 -0
- package/lib/kernel/index.d.ts +3 -0
- package/lib/kernel/index.d.ts.map +1 -0
- package/lib/kernel/index.js +3 -0
- package/lib/kernel/index.js.map +1 -0
- package/lib/libraries/.gitkeep +0 -0
- package/lib/libraries/ai/CHANGELOG.md +17 -0
- package/lib/libraries/ai/README.md +164 -0
- package/lib/libraries/ai/adapters/AnthropicAdapter.ts +382 -0
- package/lib/libraries/ai/adapters/LLMProvider.ts +76 -0
- package/lib/libraries/ai/adapters/OpenAIAdapter.ts +466 -0
- package/lib/libraries/ai/experimental/index.ts +20 -0
- package/lib/libraries/ai/index.ts +128 -0
- package/lib/libraries/ai/library.json +19 -0
- package/lib/libraries/ai/loop/agentLoop.ts +377 -0
- package/lib/libraries/ai/prompts/definePrompt.ts +0 -0
- package/lib/libraries/ai/rag/retrieveAndAnswer.ts +177 -0
- package/lib/libraries/ai/streaming/streamLLM.ts +94 -0
- package/lib/libraries/ai/structured/completeStructured.ts +143 -0
- package/lib/libraries/ai/tokens/Tokenizer.ts +216 -0
- package/lib/libraries/ai/tools/defineTool.ts +208 -0
- package/lib/libraries/ai/types.ts +260 -0
- package/lib/libraries/chunking/ChunkingService.ts +103 -0
- package/lib/libraries/chunking/README.md +104 -0
- package/lib/libraries/chunking/docs/api-reference.md +549 -0
- package/lib/libraries/chunking/docs/best-practices.md +321 -0
- package/lib/libraries/chunking/docs/code-organization.md +538 -0
- package/lib/libraries/chunking/docs/configuration.md +418 -0
- package/lib/libraries/chunking/docs/index.md +236 -0
- package/lib/libraries/chunking/docs/quick-start.md +298 -0
- package/lib/libraries/chunking/docs/strategies.md +407 -0
- package/lib/libraries/chunking/docs/summary.md +258 -0
- package/lib/libraries/chunking/docs/troubleshooting.md +527 -0
- package/lib/libraries/chunking/index.ts +17 -0
- package/lib/libraries/chunking/library.json +16 -0
- package/lib/libraries/chunking/strategies/ChunkingStrategy.ts +13 -0
- package/lib/libraries/chunking/strategies/FixedLengthChunkingStrategy.ts +88 -0
- package/lib/libraries/chunking/strategies/SemanticChunkingStrategy.ts +389 -0
- package/lib/libraries/chunking/strategies/SlidingWindowChunkingStrategy.ts +258 -0
- package/lib/libraries/chunking/types/index.ts +63 -0
- package/lib/libraries/email/EmailService.ts +591 -0
- package/lib/libraries/email/README.md +777 -0
- package/lib/libraries/email/TemplateRegistry.ts +148 -0
- package/lib/libraries/email/TemplateRenderer.ts +273 -0
- package/lib/libraries/email/index.ts +4 -0
- package/lib/libraries/email/initializeEmailService.ts +60 -0
- package/lib/libraries/email/library.json +12 -0
- package/lib/libraries/email/types/EmailAddress.ts +4 -0
- package/lib/libraries/email/types/EmailAttachment.ts +11 -0
- package/lib/libraries/email/types/EmailTag.ts +9 -0
- package/lib/libraries/email/types/EmailTemplate.ts +124 -0
- package/lib/libraries/email/types/SendBatchEmailsOptions.ts +9 -0
- package/lib/libraries/email/types/SendBatchEmailsResult.ts +9 -0
- package/lib/libraries/email/types/SendEmailOptions.ts +33 -0
- package/lib/libraries/email/types/SendEmailResult.ts +9 -0
- package/lib/libraries/email/types/index.ts +8 -0
- package/lib/libraries/weaviate/QueryBuilder.ts +292 -0
- package/lib/libraries/weaviate/README.md +284 -0
- package/lib/libraries/weaviate/Weaviate.ts +1419 -0
- package/lib/libraries/weaviate/WeaviateConfig.ts +268 -0
- package/lib/libraries/weaviate/docs/.gitkeep +1 -0
- package/lib/libraries/weaviate/docs/API_REFERENCE.md +1067 -0
- package/lib/libraries/weaviate/docs/CONFIGURATION.md +320 -0
- package/lib/libraries/weaviate/docs/ERROR_HANDLING.md +271 -0
- package/lib/libraries/weaviate/docs/MULTI_TENANCY.md +348 -0
- package/lib/libraries/weaviate/docs/PERFORMANCE.md +602 -0
- package/lib/libraries/weaviate/docs/PLUGIN_DEVELOPMENT.md +547 -0
- package/lib/libraries/weaviate/docs/QUICK_START.md +443 -0
- package/lib/libraries/weaviate/docs/README.md +269 -0
- package/lib/libraries/weaviate/docs/SCHEMA_GUIDE.md +630 -0
- package/lib/libraries/weaviate/docs/WEAVIATE_README.md +520 -0
- package/lib/libraries/weaviate/errors/WeaviateError.ts +92 -0
- package/lib/libraries/weaviate/errors/index.ts +1 -0
- package/lib/libraries/weaviate/index.ts +35 -0
- package/lib/libraries/weaviate/library.json +26 -0
- package/lib/libraries/weaviate/plugins/index.ts +2 -0
- package/lib/libraries/weaviate/schemas/SchemaRegistry.ts +284 -0
- package/lib/libraries/weaviate/schemas/index.ts +2 -0
- package/lib/libraries/weaviate/types/BM25SearchOptions.ts +9 -0
- package/lib/libraries/weaviate/types/ExtendedWeaviateClient.ts +7 -0
- package/lib/libraries/weaviate/types/HybridSearchOptions.ts +11 -0
- package/lib/libraries/weaviate/types/MultiTenancy.ts +81 -0
- package/lib/libraries/weaviate/types/Plugin.ts +17 -0
- package/lib/libraries/weaviate/types/SchemaConfig.ts +25 -0
- package/lib/libraries/weaviate/types/SearchMethod.ts +8 -0
- package/lib/libraries/weaviate/types/SearchOptions.ts +16 -0
- package/lib/libraries/weaviate/types/SearchRequest.ts +19 -0
- package/lib/libraries/weaviate/types/SearchResult.ts +16 -0
- package/lib/libraries/weaviate/types/SearchableField.ts +87 -0
- package/lib/libraries/weaviate/types/VectorIndexConfig.ts +19 -0
- package/lib/libraries/weaviate/types/VectorSearchOptions.ts +18 -0
- package/lib/libraries/weaviate/types/VectorizerConfig.ts +8 -0
- package/lib/libraries/weaviate/types/index.ts +29 -0
- package/lib/libraries/weaviate/utils/TenantContextManager.ts +94 -0
- package/lib/modules/accounts/index.ts +47 -0
- package/lib/modules/accounts/module.json +15 -0
- package/lib/modules/accounts/permissions.ts +33 -0
- package/lib/modules/accounts/routes.ts +200 -0
- package/lib/modules/accounts/schema.ts +219 -0
- package/lib/modules/accounts/services/AccountService.ts +44 -0
- package/lib/modules/accounts/validation/schemas.ts +70 -0
- package/lib/modules/oauth/adapters/GmailOAuthAdapter.ts +35 -0
- package/lib/modules/oauth/adapters/GoogleOAuthAdapter.ts +278 -0
- package/lib/modules/oauth/adapters/MicrosoftOAuthAdapter.ts +269 -0
- package/lib/modules/oauth/adapters/MockOAuthAdapter.ts +138 -0
- package/lib/modules/oauth/adapters/OAuthAdapter.ts +211 -0
- package/lib/modules/oauth/adapters/OAuthAdapterRegistry.ts +77 -0
- package/lib/modules/oauth/adapters/OutlookOAuthAdapter.ts +38 -0
- package/lib/modules/oauth/index.ts +79 -0
- package/lib/modules/oauth/module.json +23 -0
- package/lib/modules/oauth/permissions.ts +39 -0
- package/lib/modules/oauth/routes.ts +497 -0
- package/lib/modules/oauth/schema.ts +127 -0
- package/lib/modules/oauth/services/OAuthConnectionService.ts +147 -0
- package/lib/modules/oauth/state.ts +234 -0
- package/lib/modules/oauth/stateJtiCache.ts +85 -0
- package/lib/modules/oauth/verifyIdToken.ts +178 -0
- package/lib/modules/outbox/EventEmitter.ts +106 -0
- package/lib/modules/outbox/OutboxDrainer.ts +163 -0
- package/lib/modules/outbox/handlers/EventHandler.ts +115 -0
- package/lib/modules/outbox/index.ts +43 -0
- package/lib/modules/outbox/module.json +15 -0
- package/lib/modules/outbox/permissions.ts +36 -0
- package/lib/modules/outbox/routes.ts +219 -0
- package/lib/modules/outbox/schema.ts +207 -0
- package/lib/modules/outbox/services/OutboxEventService.ts +223 -0
- package/lib/observability/logger.d.ts +30 -0
- package/lib/observability/logger.d.ts.map +1 -0
- package/lib/observability/logger.js +110 -0
- package/lib/observability/logger.js.map +1 -0
- package/lib/observability/metrics.d.ts +3 -0
- package/lib/observability/metrics.d.ts.map +1 -0
- package/lib/observability/metrics.js +3 -0
- package/lib/observability/metrics.js.map +1 -0
- package/lib/observability/otel.d.ts +3 -0
- package/lib/observability/otel.d.ts.map +1 -0
- package/lib/observability/otel.js +3 -0
- package/lib/observability/otel.js.map +1 -0
- package/lib/observability/safeErrorFields.d.ts +14 -0
- package/lib/observability/safeErrorFields.d.ts.map +1 -0
- package/lib/observability/safeErrorFields.js +14 -0
- package/lib/observability/safeErrorFields.js.map +1 -0
- package/lib/observability/tracing.d.ts +3 -0
- package/lib/observability/tracing.d.ts.map +1 -0
- package/lib/observability/tracing.js +3 -0
- package/lib/observability/tracing.js.map +1 -0
- package/lib/package.json +4 -0
- package/lib/testing.d.ts +3 -0
- package/lib/testing.d.ts.map +1 -0
- package/lib/testing.js +3 -0
- package/lib/testing.js.map +1 -0
- package/package.json +193 -3
- package/templates/default/.claude/agents/qa-brief.md +106 -0
- package/templates/default/.claude/commands/sherpa-brief.md +23 -0
- package/templates/default/.cursor/rules/api.mdc +80 -0
- package/templates/default/.cursor/rules/commits.mdc +88 -0
- package/templates/default/.cursor/rules/security.mdc +92 -0
- package/templates/default/.cursor/rules/testing.mdc +123 -0
- package/templates/default/.cursor/rules/typescript.mdc +86 -0
- package/templates/default/.env.example +79 -0
- package/templates/default/.github/workflows/sherpa-brief.yml +180 -0
- package/templates/default/AGENTS.md +166 -0
- package/templates/default/CLAUDE.md +17 -0
- package/templates/default/README.md +97 -0
- package/templates/default/_gitignore +27 -0
- package/templates/default/docker-compose.yml +83 -0
- package/templates/default/drizzle.config.ts +34 -0
- package/templates/default/eslint.config.mjs +106 -0
- package/templates/default/package.json +57 -0
- package/templates/default/ship-api.config.ts +21 -0
- package/templates/default/src/client.ts +34 -0
- package/templates/default/src/config/modules.ts +23 -0
- package/templates/default/src/db/schema.ts +26 -0
- package/templates/default/src/environment.ts +81 -0
- package/templates/default/src/index.test.ts +53 -0
- package/templates/default/src/index.ts +11 -0
- package/templates/default/src/instrumentation.ts +13 -0
- package/templates/default/src/server.ts +90 -0
- package/templates/default/tsconfig.json +24 -0
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { logger as defaultLogger } from "../../observability/logger.js";
|
|
2
|
+
import { getFrameworkMeter } from "../../observability/metrics.js";
|
|
3
|
+
import { streamSSE } from "./sse.js";
|
|
4
|
+
/**
|
|
5
|
+
* Default maximum bytes per SSE event payload (F15). 256 KB is far
|
|
6
|
+
* above any reasonable single LLM stream chunk (a typical Claude /
|
|
7
|
+
* GPT token-delta is ~1–200 bytes; a tool-call argument blob is
|
|
8
|
+
* ~kilobytes) and well below the bandwidth-amplification threshold
|
|
9
|
+
* that turns one bad upstream event into a DoS surface.
|
|
10
|
+
*
|
|
11
|
+
* Per-stream override via `StreamLLMOptions.maxEventBytes`.
|
|
12
|
+
*/
|
|
13
|
+
const DEFAULT_MAX_EVENT_BYTES = 256 * 1024;
|
|
14
|
+
/**
|
|
15
|
+
* OTel counter incremented every time a streaming event exceeds the
|
|
16
|
+
* size cap and is dropped. Operators alert on this — a nonzero rate
|
|
17
|
+
* indicates either a misbehaving provider or an under-sized cap.
|
|
18
|
+
*/
|
|
19
|
+
const droppedOversizedCounter = (() => {
|
|
20
|
+
const meter = getFrameworkMeter("ship-api.streaming");
|
|
21
|
+
return meter.createCounter("stream.event.dropped_oversized", {
|
|
22
|
+
description: "Streaming events skipped by streamLLM/streamSSE because their " +
|
|
23
|
+
"serialized payload exceeded maxEventBytes. Tag `provider` is " +
|
|
24
|
+
"the LLM provider id when known, else the event's `type`.",
|
|
25
|
+
});
|
|
26
|
+
})();
|
|
27
|
+
export function streamLLM(c, events, opts = {}) {
|
|
28
|
+
const spanName = opts.spanName ?? "llm.stream";
|
|
29
|
+
const maxEventBytes = opts.maxEventBytes ?? DEFAULT_MAX_EVENT_BYTES;
|
|
30
|
+
const log = opts.logger ?? defaultLogger;
|
|
31
|
+
return streamSSE(c, async (stream) => {
|
|
32
|
+
let index = 0;
|
|
33
|
+
const iterator = events[Symbol.asyncIterator]();
|
|
34
|
+
try {
|
|
35
|
+
while (true) {
|
|
36
|
+
if (stream.aborted) {
|
|
37
|
+
// Client disconnected — give the provider iterator a chance
|
|
38
|
+
// to clean up (close upstream HTTP, abort SDK request).
|
|
39
|
+
await iterator.return?.();
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const next = await iterator.next();
|
|
43
|
+
if (next.done)
|
|
44
|
+
return;
|
|
45
|
+
await writeEvent(stream, next.value, index, opts.generateEventId, maxEventBytes, opts.provider, log);
|
|
46
|
+
index++;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
catch (err) {
|
|
50
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
51
|
+
if (opts.onError) {
|
|
52
|
+
try {
|
|
53
|
+
await opts.onError(error);
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
// Swallow — caller-provided hook must not break the close.
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
if (!stream.aborted) {
|
|
60
|
+
await stream.writeSSE({
|
|
61
|
+
event: "error",
|
|
62
|
+
data: JSON.stringify({ message: error.message }),
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
// Best-effort upstream cleanup.
|
|
66
|
+
await iterator.return?.().catch(() => undefined);
|
|
67
|
+
}
|
|
68
|
+
}, { spanName });
|
|
69
|
+
}
|
|
70
|
+
async function writeEvent(stream, event, index, generateEventId, maxEventBytes, provider, log) {
|
|
71
|
+
const { type, ...payload } = event;
|
|
72
|
+
const id = generateEventId ? generateEventId(event, index) : String(index);
|
|
73
|
+
const data = JSON.stringify(payload);
|
|
74
|
+
const eventBytes = Buffer.byteLength(data, "utf8");
|
|
75
|
+
if (eventBytes > maxEventBytes) {
|
|
76
|
+
const providerTag = provider ?? type;
|
|
77
|
+
const sampleTail = data.slice(Math.max(0, data.length - 256));
|
|
78
|
+
log.warn({
|
|
79
|
+
provider: providerTag,
|
|
80
|
+
eventType: type,
|
|
81
|
+
eventBytes,
|
|
82
|
+
maxEventBytes,
|
|
83
|
+
sampleTail,
|
|
84
|
+
}, "stream.event.dropped_oversized");
|
|
85
|
+
droppedOversizedCounter.add(1, { provider: providerTag });
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
await stream.writeSSE({
|
|
89
|
+
id,
|
|
90
|
+
event: type,
|
|
91
|
+
data,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=streamLLM.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"streamLLM.js","sourceRoot":"","sources":["../../../src/http/streaming/streamLLM.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { Context } from "hono";
|
|
2
|
+
import type { AuthTokenPair } from "../../app/auth/jwt/AuthFlow.js";
|
|
3
|
+
/**
|
|
4
|
+
* `authCookies` — set / clear / read the access + refresh cookie pair.
|
|
5
|
+
*
|
|
6
|
+
* The framework's locked default for stateless cookie auth:
|
|
7
|
+
*
|
|
8
|
+
* • Two cookies — `ship_access` (the JWT) and `ship_refresh` (the opaque
|
|
9
|
+
* refresh token).
|
|
10
|
+
* • Both `httpOnly: true`, `secure: true` in production, `sameSite: 'lax'`
|
|
11
|
+
* by default — protects top-level navigation CSRF.
|
|
12
|
+
* • Refresh cookie scoped to `path: '/auth/refresh'` so it only ships to
|
|
13
|
+
* the rotation endpoint. Limits the blast radius if `httpOnly` is ever
|
|
14
|
+
* bypassed by a runtime bug or a consumer mis-configuring CORS.
|
|
15
|
+
* • `maxAge` mirrors the token's `expiresAt` so browsers drop the cookie
|
|
16
|
+
* at the same moment the server stops accepting it.
|
|
17
|
+
*
|
|
18
|
+
* Hardened CSRF mode (double-submit) is in `csrf.ts`. This file is purely
|
|
19
|
+
* about cookie I/O — does not enforce policy.
|
|
20
|
+
*/
|
|
21
|
+
/** Default cookie names. Overridable per-call. */
|
|
22
|
+
export declare const AUTH_COOKIE_NAMES: {
|
|
23
|
+
readonly access: "ship_access";
|
|
24
|
+
readonly refresh: "ship_refresh";
|
|
25
|
+
};
|
|
26
|
+
/** Default refresh-cookie path scope. */
|
|
27
|
+
export declare const REFRESH_COOKIE_PATH = "/auth/refresh";
|
|
28
|
+
export interface AuthCookieConfig {
|
|
29
|
+
/** Override the access-cookie name. Default `"ship_access"`. */
|
|
30
|
+
accessCookieName?: string;
|
|
31
|
+
/** Override the refresh-cookie name. Default `"ship_refresh"`. */
|
|
32
|
+
refreshCookieName?: string;
|
|
33
|
+
/** Override the refresh-cookie path scope. Default `"/auth/refresh"`. */
|
|
34
|
+
refreshCookiePath?: string;
|
|
35
|
+
/**
|
|
36
|
+
* `secure` flag. Default: `true` in production, `false` otherwise — but
|
|
37
|
+
* **always set `true`** in any environment that issues real tokens. The
|
|
38
|
+
* "false in dev" default exists for `localhost` HTTP only.
|
|
39
|
+
*/
|
|
40
|
+
secure?: boolean;
|
|
41
|
+
/** `sameSite` attribute. Default `"Lax"`. */
|
|
42
|
+
sameSite?: "Strict" | "Lax" | "None";
|
|
43
|
+
/**
|
|
44
|
+
* Optional cookie `Domain` attribute. Defaults to host-only
|
|
45
|
+
* (attribute omitted) — the secure default for single-host
|
|
46
|
+
* deployments. Set to `".your-org.tld"` only when you genuinely
|
|
47
|
+
* need cookies to span multiple subdomains.
|
|
48
|
+
*
|
|
49
|
+
* **Validated against a public-suffix list.** Values that are
|
|
50
|
+
* themselves a public suffix (`".com"`, `".co.uk"`, `".com.au"`,
|
|
51
|
+
* etc.) throw at config time — those would leak the cookie to
|
|
52
|
+
* every site under the suffix and breach tenant isolation. Pass a
|
|
53
|
+
* registrable domain (`".example.com"`, `".my-org.co.uk"`)
|
|
54
|
+
* instead.
|
|
55
|
+
*/
|
|
56
|
+
domain?: string;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Set both cookies on the response after a successful issue/rotate. The
|
|
60
|
+
* `expiresAt` values from the `AuthTokenPair` are converted into `maxAge`
|
|
61
|
+
* (seconds) so the browser drops them in lock-step with the server.
|
|
62
|
+
*/
|
|
63
|
+
export declare function setAuthCookies(c: Context, pair: AuthTokenPair, cfg?: AuthCookieConfig): void;
|
|
64
|
+
/**
|
|
65
|
+
* Clear both cookies on logout. Sets identical attributes to `setAuthCookies`
|
|
66
|
+
* so browsers reliably overwrite the existing cookies (browsers match on
|
|
67
|
+
* name+path+domain, not value).
|
|
68
|
+
*/
|
|
69
|
+
export declare function clearAuthCookies(c: Context, cfg?: AuthCookieConfig): void;
|
|
70
|
+
/** Read the access cookie value. Returns `undefined` if absent. */
|
|
71
|
+
export declare function readAccessCookie(c: Context, cfg?: AuthCookieConfig): string | undefined;
|
|
72
|
+
/** Read the refresh cookie value. Returns `undefined` if absent. */
|
|
73
|
+
export declare function readRefreshCookie(c: Context, cfg?: AuthCookieConfig): string | undefined;
|
|
74
|
+
//# sourceMappingURL=authCookies.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authCookies.d.ts","sourceRoot":"","sources":["../../../src/http/utils/authCookies.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAGpC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAGpE;;;;;;;;;;;;;;;;;GAiBG;AAEH,kDAAkD;AAClD,eAAO,MAAM,iBAAiB;;;CAGpB,CAAC;AAEX,yCAAyC;AACzC,eAAO,MAAM,mBAAmB,kBAAkB,CAAC;AAEnD,MAAM,WAAW,gBAAgB;IAC/B,gEAAgE;IAChE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,kEAAkE;IAClE,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,yEAAyE;IACzE,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;IACrC;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAyBD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,GAAG,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAwB5F;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAYzE;AAED,mEAAmE;AACnE,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,gBAAgB,GAAG,MAAM,GAAG,SAAS,CAGvF;AAED,oEAAoE;AACpE,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,gBAAgB,GAAG,MAAM,GAAG,SAAS,CAGxF"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { deleteCookie, getCookie, setCookie } from "hono/cookie";
|
|
2
|
+
import { checkCookieDomainAgainstPublicSuffix } from "./publicSuffix.js";
|
|
3
|
+
/**
|
|
4
|
+
* `authCookies` — set / clear / read the access + refresh cookie pair.
|
|
5
|
+
*
|
|
6
|
+
* The framework's locked default for stateless cookie auth:
|
|
7
|
+
*
|
|
8
|
+
* • Two cookies — `ship_access` (the JWT) and `ship_refresh` (the opaque
|
|
9
|
+
* refresh token).
|
|
10
|
+
* • Both `httpOnly: true`, `secure: true` in production, `sameSite: 'lax'`
|
|
11
|
+
* by default — protects top-level navigation CSRF.
|
|
12
|
+
* • Refresh cookie scoped to `path: '/auth/refresh'` so it only ships to
|
|
13
|
+
* the rotation endpoint. Limits the blast radius if `httpOnly` is ever
|
|
14
|
+
* bypassed by a runtime bug or a consumer mis-configuring CORS.
|
|
15
|
+
* • `maxAge` mirrors the token's `expiresAt` so browsers drop the cookie
|
|
16
|
+
* at the same moment the server stops accepting it.
|
|
17
|
+
*
|
|
18
|
+
* Hardened CSRF mode (double-submit) is in `csrf.ts`. This file is purely
|
|
19
|
+
* about cookie I/O — does not enforce policy.
|
|
20
|
+
*/
|
|
21
|
+
/** Default cookie names. Overridable per-call. */
|
|
22
|
+
export const AUTH_COOKIE_NAMES = {
|
|
23
|
+
access: "ship_access",
|
|
24
|
+
refresh: "ship_refresh",
|
|
25
|
+
};
|
|
26
|
+
/** Default refresh-cookie path scope. */
|
|
27
|
+
export const REFRESH_COOKIE_PATH = "/auth/refresh";
|
|
28
|
+
const DEFAULT_CONFIG = {
|
|
29
|
+
accessCookieName: AUTH_COOKIE_NAMES.access,
|
|
30
|
+
refreshCookieName: AUTH_COOKIE_NAMES.refresh,
|
|
31
|
+
refreshCookiePath: REFRESH_COOKIE_PATH,
|
|
32
|
+
secure: process.env.NODE_ENV === "production",
|
|
33
|
+
sameSite: "Lax",
|
|
34
|
+
};
|
|
35
|
+
function resolveConfig(cfg) {
|
|
36
|
+
const domainFailure = checkCookieDomainAgainstPublicSuffix(cfg?.domain);
|
|
37
|
+
if (domainFailure) {
|
|
38
|
+
throw new Error(`authCookies: invalid AuthCookieConfig.domain — ${domainFailure}`);
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
...DEFAULT_CONFIG,
|
|
42
|
+
...cfg,
|
|
43
|
+
secure: cfg?.secure ?? DEFAULT_CONFIG.secure,
|
|
44
|
+
sameSite: cfg?.sameSite ?? DEFAULT_CONFIG.sameSite,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Set both cookies on the response after a successful issue/rotate. The
|
|
49
|
+
* `expiresAt` values from the `AuthTokenPair` are converted into `maxAge`
|
|
50
|
+
* (seconds) so the browser drops them in lock-step with the server.
|
|
51
|
+
*/
|
|
52
|
+
export function setAuthCookies(c, pair, cfg) {
|
|
53
|
+
const config = resolveConfig(cfg);
|
|
54
|
+
const nowSec = Math.floor(Date.now() / 1000);
|
|
55
|
+
const accessOpts = {
|
|
56
|
+
httpOnly: true,
|
|
57
|
+
secure: config.secure,
|
|
58
|
+
sameSite: config.sameSite,
|
|
59
|
+
path: "/",
|
|
60
|
+
maxAge: Math.max(0, pair.accessTokenExpiresAt - nowSec),
|
|
61
|
+
...(config.domain ? { domain: config.domain } : {}),
|
|
62
|
+
};
|
|
63
|
+
const refreshOpts = {
|
|
64
|
+
httpOnly: true,
|
|
65
|
+
secure: config.secure,
|
|
66
|
+
sameSite: config.sameSite,
|
|
67
|
+
path: config.refreshCookiePath,
|
|
68
|
+
maxAge: Math.max(0, pair.refreshTokenExpiresAt - nowSec),
|
|
69
|
+
...(config.domain ? { domain: config.domain } : {}),
|
|
70
|
+
};
|
|
71
|
+
setCookie(c, config.accessCookieName, pair.accessToken, accessOpts);
|
|
72
|
+
setCookie(c, config.refreshCookieName, pair.refreshToken, refreshOpts);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Clear both cookies on logout. Sets identical attributes to `setAuthCookies`
|
|
76
|
+
* so browsers reliably overwrite the existing cookies (browsers match on
|
|
77
|
+
* name+path+domain, not value).
|
|
78
|
+
*/
|
|
79
|
+
export function clearAuthCookies(c, cfg) {
|
|
80
|
+
const config = resolveConfig(cfg);
|
|
81
|
+
const baseOpts = {
|
|
82
|
+
secure: config.secure,
|
|
83
|
+
sameSite: config.sameSite,
|
|
84
|
+
...(config.domain ? { domain: config.domain } : {}),
|
|
85
|
+
};
|
|
86
|
+
deleteCookie(c, config.accessCookieName, { ...baseOpts, path: "/" });
|
|
87
|
+
deleteCookie(c, config.refreshCookieName, {
|
|
88
|
+
...baseOpts,
|
|
89
|
+
path: config.refreshCookiePath,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
/** Read the access cookie value. Returns `undefined` if absent. */
|
|
93
|
+
export function readAccessCookie(c, cfg) {
|
|
94
|
+
const config = resolveConfig(cfg);
|
|
95
|
+
return getCookie(c, config.accessCookieName);
|
|
96
|
+
}
|
|
97
|
+
/** Read the refresh cookie value. Returns `undefined` if absent. */
|
|
98
|
+
export function readRefreshCookie(c, cfg) {
|
|
99
|
+
const config = resolveConfig(cfg);
|
|
100
|
+
return getCookie(c, config.refreshCookieName);
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=authCookies.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authCookies.js","sourceRoot":"","sources":["../../../src/http/utils/authCookies.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `clientIp` — derive the client IP for trust-sensitive decisions.
|
|
3
|
+
*
|
|
4
|
+
* The framework default — used by `rateLimit()` and any other middleware
|
|
5
|
+
* that needs a per-client key — refuses to trust `X-Forwarded-For`
|
|
6
|
+
* unless the operator declares the upstream proxy ranges via
|
|
7
|
+
* `trustProxy: string[]` (CIDR list). Without that declaration the
|
|
8
|
+
* peer IP is used directly, even if XFF is present.
|
|
9
|
+
*
|
|
10
|
+
* The algorithm (rightmost-untrusted-IP) is the industry-standard
|
|
11
|
+
* defense against XFF spoofing:
|
|
12
|
+
*
|
|
13
|
+
* 1. If the immediate peer is NOT in any `trustProxy` CIDR, the
|
|
14
|
+
* peer's IP wins — XFF is rejected entirely. An attacker
|
|
15
|
+
* contacting the server directly cannot inject XFF values that
|
|
16
|
+
* look like an internal proxy chain.
|
|
17
|
+
*
|
|
18
|
+
* 2. If the peer IS in the trust list, walk XFF right-to-left.
|
|
19
|
+
* Each rightmost entry that is also in the trust list is treated
|
|
20
|
+
* as a known proxy and skipped. The first entry that is NOT in
|
|
21
|
+
* the trust list is the *real* client IP.
|
|
22
|
+
*
|
|
23
|
+
* 3. If every XFF entry is in the trust list (i.e., the chain is
|
|
24
|
+
* composed entirely of internal proxies), fall back to the
|
|
25
|
+
* leftmost XFF entry. This is the rare case where the original
|
|
26
|
+
* client is itself inside the trust ring; we still return *some*
|
|
27
|
+
* identifier so the rate limiter has a key.
|
|
28
|
+
*
|
|
29
|
+
* Compare with the simpler "trust the leftmost XFF entry" pattern —
|
|
30
|
+
* which is what the framework used before this defense landed and what
|
|
31
|
+
* most tutorials still show. That pattern lets any anonymous attacker
|
|
32
|
+
* rotate `X-Forwarded-For: <random>` per request and trivially bypass
|
|
33
|
+
* per-IP rate limits on login / signup / password-reset endpoints.
|
|
34
|
+
*
|
|
35
|
+
* No new package dependency — IPv4 and IPv6 CIDR matching is inline.
|
|
36
|
+
* IPv4-mapped IPv6 (`::ffff:1.2.3.4`) is normalized to IPv4 before
|
|
37
|
+
* matching so a trust list of `10.0.0.0/8` covers `::ffff:10.0.0.1`.
|
|
38
|
+
*/
|
|
39
|
+
export interface ParsedCidr {
|
|
40
|
+
readonly raw: string;
|
|
41
|
+
readonly ip: bigint;
|
|
42
|
+
readonly bits: number;
|
|
43
|
+
readonly v4: boolean;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Parse a CIDR (e.g. `10.0.0.0/8`, `::1/128`, `2001:db8::/32`) or a
|
|
47
|
+
* bare IP (treated as `/32` for v4, `/128` for v6). Returns `null`
|
|
48
|
+
* for malformed input — callers decide whether to throw or skip.
|
|
49
|
+
*/
|
|
50
|
+
export declare function parseCidr(input: string): ParsedCidr | null;
|
|
51
|
+
/**
|
|
52
|
+
* Parse an IP literal (v4 or v6) into a bigint. Returns `null` for
|
|
53
|
+
* malformed input. IPv4 occupies the low 32 bits of the resulting
|
|
54
|
+
* bigint (treated as v4); IPv6 is the full 128 bits.
|
|
55
|
+
*/
|
|
56
|
+
export declare function ipToBigInt(input: string): {
|
|
57
|
+
ip: bigint;
|
|
58
|
+
v4: boolean;
|
|
59
|
+
} | null;
|
|
60
|
+
/** Check whether `ip` (literal) is contained by `cidr` (parsed). */
|
|
61
|
+
export declare function isInCidr(ip: string, cidr: ParsedCidr): boolean;
|
|
62
|
+
/** True if `ip` is contained by any CIDR in the parsed trust list. */
|
|
63
|
+
export declare function isTrustedProxy(ip: string, trustList: readonly ParsedCidr[]): boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Compile a `trustProxy: string[]` config (CIDRs) once at middleware
|
|
66
|
+
* construction time. Malformed entries are dropped silently — the
|
|
67
|
+
* caller already had a chance to validate inputs and an
|
|
68
|
+
* over-broad-but-typo'd list should not bring down request handling.
|
|
69
|
+
*/
|
|
70
|
+
export declare function compileTrustProxy(trustProxy: readonly string[] | undefined): ParsedCidr[];
|
|
71
|
+
export interface ResolveClientIpOpts {
|
|
72
|
+
/** The immediate peer IP (e.g. Node's `socket.remoteAddress`). */
|
|
73
|
+
peerIp?: string;
|
|
74
|
+
/** Raw `X-Forwarded-For` header value as the proxy chain sent it. */
|
|
75
|
+
xff?: string;
|
|
76
|
+
/** Compiled trust list. Empty list disables XFF trust entirely. */
|
|
77
|
+
trustProxy: readonly ParsedCidr[];
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Resolve the client IP from peer + XFF + trust list. Returns
|
|
81
|
+
* `"unknown"` only when no peer can be determined AND no XFF entry
|
|
82
|
+
* survives the trust check — both should be rare in practice.
|
|
83
|
+
*/
|
|
84
|
+
export declare function resolveClientIp(opts: ResolveClientIpOpts): string;
|
|
85
|
+
//# sourceMappingURL=clientIp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clientIp.d.ts","sourceRoot":"","sources":["../../../src/http/utils/clientIp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;CACtB;AAKD;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CA6B1D;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CAe5E;AAkDD,oEAAoE;AACpE,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAU9D;AAED,sEAAsE;AACtE,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,UAAU,EAAE,GAAG,OAAO,CAKpF;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,GAAG,UAAU,EAAE,CAQzF;AAED,MAAM,WAAW,mBAAmB;IAClC,kEAAkE;IAClE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qEAAqE;IACrE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,mEAAmE;IACnE,UAAU,EAAE,SAAS,UAAU,EAAE,CAAC;CACnC;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,mBAAmB,GAAG,MAAM,CAmCjE"}
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `clientIp` — derive the client IP for trust-sensitive decisions.
|
|
3
|
+
*
|
|
4
|
+
* The framework default — used by `rateLimit()` and any other middleware
|
|
5
|
+
* that needs a per-client key — refuses to trust `X-Forwarded-For`
|
|
6
|
+
* unless the operator declares the upstream proxy ranges via
|
|
7
|
+
* `trustProxy: string[]` (CIDR list). Without that declaration the
|
|
8
|
+
* peer IP is used directly, even if XFF is present.
|
|
9
|
+
*
|
|
10
|
+
* The algorithm (rightmost-untrusted-IP) is the industry-standard
|
|
11
|
+
* defense against XFF spoofing:
|
|
12
|
+
*
|
|
13
|
+
* 1. If the immediate peer is NOT in any `trustProxy` CIDR, the
|
|
14
|
+
* peer's IP wins — XFF is rejected entirely. An attacker
|
|
15
|
+
* contacting the server directly cannot inject XFF values that
|
|
16
|
+
* look like an internal proxy chain.
|
|
17
|
+
*
|
|
18
|
+
* 2. If the peer IS in the trust list, walk XFF right-to-left.
|
|
19
|
+
* Each rightmost entry that is also in the trust list is treated
|
|
20
|
+
* as a known proxy and skipped. The first entry that is NOT in
|
|
21
|
+
* the trust list is the *real* client IP.
|
|
22
|
+
*
|
|
23
|
+
* 3. If every XFF entry is in the trust list (i.e., the chain is
|
|
24
|
+
* composed entirely of internal proxies), fall back to the
|
|
25
|
+
* leftmost XFF entry. This is the rare case where the original
|
|
26
|
+
* client is itself inside the trust ring; we still return *some*
|
|
27
|
+
* identifier so the rate limiter has a key.
|
|
28
|
+
*
|
|
29
|
+
* Compare with the simpler "trust the leftmost XFF entry" pattern —
|
|
30
|
+
* which is what the framework used before this defense landed and what
|
|
31
|
+
* most tutorials still show. That pattern lets any anonymous attacker
|
|
32
|
+
* rotate `X-Forwarded-For: <random>` per request and trivially bypass
|
|
33
|
+
* per-IP rate limits on login / signup / password-reset endpoints.
|
|
34
|
+
*
|
|
35
|
+
* No new package dependency — IPv4 and IPv6 CIDR matching is inline.
|
|
36
|
+
* IPv4-mapped IPv6 (`::ffff:1.2.3.4`) is normalized to IPv4 before
|
|
37
|
+
* matching so a trust list of `10.0.0.0/8` covers `::ffff:10.0.0.1`.
|
|
38
|
+
*/
|
|
39
|
+
const V4_MAX_BITS = 32;
|
|
40
|
+
const V6_MAX_BITS = 128;
|
|
41
|
+
/**
|
|
42
|
+
* Parse a CIDR (e.g. `10.0.0.0/8`, `::1/128`, `2001:db8::/32`) or a
|
|
43
|
+
* bare IP (treated as `/32` for v4, `/128` for v6). Returns `null`
|
|
44
|
+
* for malformed input — callers decide whether to throw or skip.
|
|
45
|
+
*/
|
|
46
|
+
export function parseCidr(input) {
|
|
47
|
+
if (typeof input !== "string" || input.length === 0)
|
|
48
|
+
return null;
|
|
49
|
+
const trimmed = input.trim();
|
|
50
|
+
if (trimmed.length === 0)
|
|
51
|
+
return null;
|
|
52
|
+
const slash = trimmed.lastIndexOf("/");
|
|
53
|
+
let ipPart;
|
|
54
|
+
let bitsPart;
|
|
55
|
+
if (slash === -1) {
|
|
56
|
+
ipPart = trimmed;
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
ipPart = trimmed.slice(0, slash);
|
|
60
|
+
bitsPart = trimmed.slice(slash + 1);
|
|
61
|
+
}
|
|
62
|
+
const parsed = ipToBigInt(ipPart);
|
|
63
|
+
if (parsed == null)
|
|
64
|
+
return null;
|
|
65
|
+
const maxBits = parsed.v4 ? V4_MAX_BITS : V6_MAX_BITS;
|
|
66
|
+
let bits;
|
|
67
|
+
if (bitsPart == null) {
|
|
68
|
+
bits = maxBits;
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
if (!/^\d{1,3}$/.test(bitsPart))
|
|
72
|
+
return null;
|
|
73
|
+
bits = Number.parseInt(bitsPart, 10);
|
|
74
|
+
if (!Number.isFinite(bits) || bits < 0 || bits > maxBits)
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
return { raw: trimmed, ip: parsed.ip, bits, v4: parsed.v4 };
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Parse an IP literal (v4 or v6) into a bigint. Returns `null` for
|
|
81
|
+
* malformed input. IPv4 occupies the low 32 bits of the resulting
|
|
82
|
+
* bigint (treated as v4); IPv6 is the full 128 bits.
|
|
83
|
+
*/
|
|
84
|
+
export function ipToBigInt(input) {
|
|
85
|
+
if (typeof input !== "string" || input.length === 0)
|
|
86
|
+
return null;
|
|
87
|
+
const ip = input.trim();
|
|
88
|
+
if (ip.length === 0)
|
|
89
|
+
return null;
|
|
90
|
+
// IPv4-mapped IPv6: `::ffff:1.2.3.4`. Strip the prefix and parse the
|
|
91
|
+
// tail as v4 so trust lists declared in v4 still match.
|
|
92
|
+
if (/^::ffff:\d{1,3}(\.\d{1,3}){3}$/i.test(ip)) {
|
|
93
|
+
return parseV4(ip.slice("::ffff:".length));
|
|
94
|
+
}
|
|
95
|
+
if (ip.includes(":")) {
|
|
96
|
+
return parseV6(ip);
|
|
97
|
+
}
|
|
98
|
+
return parseV4(ip);
|
|
99
|
+
}
|
|
100
|
+
function parseV4(s) {
|
|
101
|
+
const parts = s.split(".");
|
|
102
|
+
if (parts.length !== 4)
|
|
103
|
+
return null;
|
|
104
|
+
let acc = 0n;
|
|
105
|
+
for (const part of parts) {
|
|
106
|
+
if (!/^\d{1,3}$/.test(part))
|
|
107
|
+
return null;
|
|
108
|
+
const n = Number.parseInt(part, 10);
|
|
109
|
+
if (n < 0 || n > 255)
|
|
110
|
+
return null;
|
|
111
|
+
acc = (acc << 8n) | BigInt(n);
|
|
112
|
+
}
|
|
113
|
+
return { ip: acc, v4: true };
|
|
114
|
+
}
|
|
115
|
+
function parseV6(s) {
|
|
116
|
+
// Reject obviously malformed shapes up front.
|
|
117
|
+
if (s.includes(":::"))
|
|
118
|
+
return null;
|
|
119
|
+
// Bracketed addresses (`[::1]`) are stripped in URL parsing; the
|
|
120
|
+
// caller should pass the inner literal.
|
|
121
|
+
if (s.startsWith("[") || s.endsWith("]"))
|
|
122
|
+
return null;
|
|
123
|
+
// Embedded IPv4 (`::1:2:3:4:5:6:7.8.9.10` etc.) is rare and not
|
|
124
|
+
// emitted by anything sensible inside XFF; reject for simplicity.
|
|
125
|
+
if (/\d+\.\d+\.\d+\.\d+/.test(s))
|
|
126
|
+
return null;
|
|
127
|
+
const doubleColon = s.indexOf("::");
|
|
128
|
+
let groups;
|
|
129
|
+
if (doubleColon === -1) {
|
|
130
|
+
groups = s.split(":");
|
|
131
|
+
if (groups.length !== 8)
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
if (s.indexOf("::", doubleColon + 2) !== -1)
|
|
136
|
+
return null;
|
|
137
|
+
const left = s.slice(0, doubleColon);
|
|
138
|
+
const right = s.slice(doubleColon + 2);
|
|
139
|
+
const leftGroups = left.length === 0 ? [] : left.split(":");
|
|
140
|
+
const rightGroups = right.length === 0 ? [] : right.split(":");
|
|
141
|
+
const fill = 8 - (leftGroups.length + rightGroups.length);
|
|
142
|
+
if (fill < 0)
|
|
143
|
+
return null;
|
|
144
|
+
groups = [...leftGroups, ...new Array(fill).fill("0"), ...rightGroups];
|
|
145
|
+
}
|
|
146
|
+
let acc = 0n;
|
|
147
|
+
for (const group of groups) {
|
|
148
|
+
if (!/^[0-9a-f]{1,4}$/i.test(group))
|
|
149
|
+
return null;
|
|
150
|
+
acc = (acc << 16n) | BigInt(Number.parseInt(group, 16));
|
|
151
|
+
}
|
|
152
|
+
return { ip: acc, v4: false };
|
|
153
|
+
}
|
|
154
|
+
/** Check whether `ip` (literal) is contained by `cidr` (parsed). */
|
|
155
|
+
export function isInCidr(ip, cidr) {
|
|
156
|
+
const parsed = ipToBigInt(ip);
|
|
157
|
+
if (!parsed)
|
|
158
|
+
return false;
|
|
159
|
+
// Family must match (after IPv4-mapped IPv6 normalization in
|
|
160
|
+
// ipToBigInt, both sides agree on v4-vs-v6).
|
|
161
|
+
if (parsed.v4 !== cidr.v4)
|
|
162
|
+
return false;
|
|
163
|
+
const maxBits = cidr.v4 ? V4_MAX_BITS : V6_MAX_BITS;
|
|
164
|
+
const shift = BigInt(maxBits - cidr.bits);
|
|
165
|
+
const mask = cidr.bits === 0 ? 0n : ((1n << BigInt(cidr.bits)) - 1n) << shift;
|
|
166
|
+
return (parsed.ip & mask) === (cidr.ip & mask);
|
|
167
|
+
}
|
|
168
|
+
/** True if `ip` is contained by any CIDR in the parsed trust list. */
|
|
169
|
+
export function isTrustedProxy(ip, trustList) {
|
|
170
|
+
for (const cidr of trustList) {
|
|
171
|
+
if (isInCidr(ip, cidr))
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Compile a `trustProxy: string[]` config (CIDRs) once at middleware
|
|
178
|
+
* construction time. Malformed entries are dropped silently — the
|
|
179
|
+
* caller already had a chance to validate inputs and an
|
|
180
|
+
* over-broad-but-typo'd list should not bring down request handling.
|
|
181
|
+
*/
|
|
182
|
+
export function compileTrustProxy(trustProxy) {
|
|
183
|
+
if (!trustProxy || trustProxy.length === 0)
|
|
184
|
+
return [];
|
|
185
|
+
const out = [];
|
|
186
|
+
for (const entry of trustProxy) {
|
|
187
|
+
const parsed = parseCidr(entry);
|
|
188
|
+
if (parsed)
|
|
189
|
+
out.push(parsed);
|
|
190
|
+
}
|
|
191
|
+
return out;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Resolve the client IP from peer + XFF + trust list. Returns
|
|
195
|
+
* `"unknown"` only when no peer can be determined AND no XFF entry
|
|
196
|
+
* survives the trust check — both should be rare in practice.
|
|
197
|
+
*/
|
|
198
|
+
export function resolveClientIp(opts) {
|
|
199
|
+
const { peerIp, xff, trustProxy } = opts;
|
|
200
|
+
// No trust list → no XFF trust. Peer wins (or "unknown" if absent).
|
|
201
|
+
if (trustProxy.length === 0) {
|
|
202
|
+
return normalizeIp(peerIp) ?? "unknown";
|
|
203
|
+
}
|
|
204
|
+
// Peer must be in the trust list for XFF to be honored. An untrusted
|
|
205
|
+
// peer cannot inject hops by setting its own XFF header.
|
|
206
|
+
const normalizedPeer = normalizeIp(peerIp);
|
|
207
|
+
if (!normalizedPeer || !isTrustedProxy(normalizedPeer, trustProxy)) {
|
|
208
|
+
return normalizedPeer ?? "unknown";
|
|
209
|
+
}
|
|
210
|
+
// Walk XFF right-to-left, skipping trusted hops, returning the
|
|
211
|
+
// first untrusted hop (the real client). If every hop is trusted,
|
|
212
|
+
// fall back to the leftmost entry.
|
|
213
|
+
if (xff) {
|
|
214
|
+
const hops = xff
|
|
215
|
+
.split(",")
|
|
216
|
+
.map((s) => normalizeIp(s.trim()))
|
|
217
|
+
.filter((s) => Boolean(s));
|
|
218
|
+
for (let i = hops.length - 1; i >= 0; i--) {
|
|
219
|
+
const hop = hops[i];
|
|
220
|
+
if (!isTrustedProxy(hop, trustProxy)) {
|
|
221
|
+
return hop;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
if (hops.length > 0)
|
|
225
|
+
return hops[0];
|
|
226
|
+
}
|
|
227
|
+
// No XFF (or empty after parsing) → trusted-peer is the best we have.
|
|
228
|
+
return normalizedPeer;
|
|
229
|
+
}
|
|
230
|
+
/** Strip brackets and whitespace; reject obviously-malformed values. */
|
|
231
|
+
function normalizeIp(raw) {
|
|
232
|
+
if (raw == null)
|
|
233
|
+
return undefined;
|
|
234
|
+
const trimmed = raw.trim();
|
|
235
|
+
if (trimmed.length === 0)
|
|
236
|
+
return undefined;
|
|
237
|
+
// Strip `[::1]` brackets if present.
|
|
238
|
+
const inner = trimmed.startsWith("[") && trimmed.endsWith("]") ? trimmed.slice(1, -1) : trimmed;
|
|
239
|
+
// Strip ::ffff: IPv4-mapped prefix for consistency with ipToBigInt.
|
|
240
|
+
if (/^::ffff:\d{1,3}(\.\d{1,3}){3}$/i.test(inner)) {
|
|
241
|
+
return inner.slice("::ffff:".length);
|
|
242
|
+
}
|
|
243
|
+
// Validate it actually parses; otherwise it's garbage from a buggy
|
|
244
|
+
// proxy and we should not treat it as an IP.
|
|
245
|
+
if (ipToBigInt(inner) == null)
|
|
246
|
+
return undefined;
|
|
247
|
+
return inner;
|
|
248
|
+
}
|
|
249
|
+
//# sourceMappingURL=clientIp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clientIp.js","sourceRoot":"","sources":["../../../src/http/utils/clientIp.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/http/utils/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/http/utils/index.ts"],"names":[],"mappings":"AAAA,yBAAyB;AAEzB,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC"}
|