@gettersethya/mira 0.1.0-alpha.2 → 0.1.0-alpha.21
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/README.md +174 -0
- package/dist/src/app/app.d.ts +45 -26
- package/dist/src/app/app.d.ts.map +1 -1
- package/dist/src/app/app.js +138 -41
- package/dist/src/app/app.js.map +1 -1
- package/dist/src/app/builder.d.ts +56 -15
- package/dist/src/app/builder.d.ts.map +1 -1
- package/dist/src/app/builder.js +56 -4
- package/dist/src/app/builder.js.map +1 -1
- package/dist/src/app/define-rule.d.ts +70 -0
- package/dist/src/app/define-rule.d.ts.map +1 -0
- package/dist/src/app/define-rule.js +42 -0
- package/dist/src/app/define-rule.js.map +1 -0
- package/dist/src/app/index.d.ts +8 -3
- package/dist/src/app/index.d.ts.map +1 -1
- package/dist/src/app/index.js +3 -0
- package/dist/src/app/index.js.map +1 -1
- package/dist/src/app/plugin.d.ts +83 -0
- package/dist/src/app/plugin.d.ts.map +1 -0
- package/dist/src/app/plugin.js +20 -0
- package/dist/src/app/plugin.js.map +1 -0
- package/dist/src/app/types.d.ts +4 -4
- package/dist/src/app/types.d.ts.map +1 -1
- package/dist/src/cache/cached-collection.d.ts +7 -5
- package/dist/src/cache/cached-collection.d.ts.map +1 -1
- package/dist/src/cache/cached-collection.js +8 -5
- package/dist/src/cache/cached-collection.js.map +1 -1
- package/dist/src/cache/collection-cache.d.ts +1 -1
- package/dist/src/cache/collection-cache.d.ts.map +1 -1
- package/dist/src/cache/collection-cache.js +1 -1
- package/dist/src/cache/collection-cache.js.map +1 -1
- package/dist/src/cache/ctx-key.d.ts +15 -0
- package/dist/src/cache/ctx-key.d.ts.map +1 -0
- package/dist/src/cache/ctx-key.js +37 -0
- package/dist/src/cache/ctx-key.js.map +1 -0
- package/dist/src/cache/index.d.ts +2 -1
- package/dist/src/cache/index.d.ts.map +1 -1
- package/dist/src/cache/index.js +2 -1
- package/dist/src/cache/index.js.map +1 -1
- package/dist/src/collection-service/collection-service.d.ts +7 -5
- package/dist/src/collection-service/collection-service.d.ts.map +1 -1
- package/dist/src/collection-service/collection-service.js +201 -51
- package/dist/src/collection-service/collection-service.js.map +1 -1
- package/dist/src/collection-service/context.d.ts +2 -0
- package/dist/src/collection-service/context.d.ts.map +1 -1
- package/dist/src/collection-service/decode.d.ts +4 -2
- package/dist/src/collection-service/decode.d.ts.map +1 -1
- package/dist/src/collection-service/decode.js +32 -16
- package/dist/src/collection-service/decode.js.map +1 -1
- package/dist/src/collection-service/errors.d.ts +1 -1
- package/dist/src/collection-service/errors.d.ts.map +1 -1
- package/dist/src/collection-service/errors.js +1 -1
- package/dist/src/collection-service/errors.js.map +1 -1
- package/dist/src/collection-service/index.d.ts +1 -1
- package/dist/src/collection-service/index.d.ts.map +1 -1
- package/dist/src/collection-service/index.js.map +1 -1
- package/dist/src/collection-service/input-schema.d.ts +5 -4
- package/dist/src/collection-service/input-schema.d.ts.map +1 -1
- package/dist/src/collection-service/input-schema.js +31 -18
- package/dist/src/collection-service/input-schema.js.map +1 -1
- package/dist/src/collection-service/where.d.ts +14 -2
- package/dist/src/collection-service/where.d.ts.map +1 -1
- package/dist/src/collection-service/where.js +35 -1
- package/dist/src/collection-service/where.js.map +1 -1
- package/dist/src/config/config.d.ts +4 -4
- package/dist/src/config/config.d.ts.map +1 -1
- package/dist/src/config/config.js +34 -5
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/types.d.ts +9 -0
- package/dist/src/config/types.d.ts.map +1 -1
- package/dist/src/cron/cron-service.d.ts +14 -0
- package/dist/src/cron/cron-service.d.ts.map +1 -0
- package/dist/src/cron/cron-service.js +135 -0
- package/dist/src/cron/cron-service.js.map +1 -0
- package/dist/src/cron/index.d.ts +4 -0
- package/dist/src/cron/index.d.ts.map +1 -0
- package/dist/src/cron/index.js +3 -0
- package/dist/src/cron/index.js.map +1 -0
- package/dist/src/cron/persistence.d.ts +22 -0
- package/dist/src/cron/persistence.d.ts.map +1 -0
- package/dist/src/cron/persistence.js +48 -0
- package/dist/src/cron/persistence.js.map +1 -0
- package/dist/src/cron/types.d.ts +51 -0
- package/dist/src/cron/types.d.ts.map +1 -0
- package/dist/src/cron/types.js +4 -0
- package/dist/src/cron/types.js.map +1 -0
- package/dist/src/crypto/crypto.d.ts +3 -2
- package/dist/src/crypto/crypto.d.ts.map +1 -1
- package/dist/src/crypto/crypto.js +1 -1
- package/dist/src/crypto/crypto.js.map +1 -1
- package/dist/src/crypto/node.d.ts.map +1 -1
- package/dist/src/crypto/node.js.map +1 -1
- package/dist/src/databases/sqlite.d.ts.map +1 -1
- package/dist/src/databases/sqlite.js +2 -2
- package/dist/src/databases/sqlite.js.map +1 -1
- package/dist/src/dialect/dialect-sqlite.d.ts +9 -0
- package/dist/src/dialect/dialect-sqlite.d.ts.map +1 -0
- package/dist/src/dialect/dialect-sqlite.js +109 -0
- package/dist/src/dialect/dialect-sqlite.js.map +1 -0
- package/dist/src/dialect/dialect.d.ts +26 -0
- package/dist/src/dialect/dialect.d.ts.map +1 -0
- package/dist/src/dialect/dialect.js +5 -0
- package/dist/src/dialect/dialect.js.map +1 -0
- package/dist/src/hooks/hook-collection.d.ts +5 -0
- package/dist/src/hooks/hook-collection.d.ts.map +1 -0
- package/dist/src/hooks/hook-collection.js +77 -0
- package/dist/src/hooks/hook-collection.js.map +1 -0
- package/dist/src/hooks/hook-service.d.ts +38 -0
- package/dist/src/hooks/hook-service.d.ts.map +1 -0
- package/dist/src/hooks/hook-service.js +150 -0
- package/dist/src/hooks/hook-service.js.map +1 -0
- package/dist/src/hooks/index.d.ts +4 -0
- package/dist/src/hooks/index.d.ts.map +1 -0
- package/dist/src/hooks/index.js +3 -0
- package/dist/src/hooks/index.js.map +1 -0
- package/dist/src/hooks/types.d.ts +74 -0
- package/dist/src/hooks/types.d.ts.map +1 -0
- package/dist/src/hooks/types.js +2 -0
- package/dist/src/hooks/types.js.map +1 -0
- package/dist/src/http/auth-node.d.ts.map +1 -1
- package/dist/src/http/auth-node.js +1 -1
- package/dist/src/http/auth-node.js.map +1 -1
- package/dist/src/http/auth.d.ts +3 -1
- package/dist/src/http/auth.d.ts.map +1 -1
- package/dist/src/http/auth.js +12 -2
- package/dist/src/http/auth.js.map +1 -1
- package/dist/src/http/cors.d.ts +94 -0
- package/dist/src/http/cors.d.ts.map +1 -0
- package/dist/src/http/cors.js +57 -0
- package/dist/src/http/cors.js.map +1 -0
- package/dist/src/http/errors.d.ts +1 -1
- package/dist/src/http/errors.d.ts.map +1 -1
- package/dist/src/http/errors.js +7 -7
- package/dist/src/http/errors.js.map +1 -1
- package/dist/src/http/file-serve.d.ts +4 -4
- package/dist/src/http/file-serve.d.ts.map +1 -1
- package/dist/src/http/file-serve.js +39 -34
- package/dist/src/http/file-serve.js.map +1 -1
- package/dist/src/http/file-token.d.ts +4 -3
- package/dist/src/http/file-token.d.ts.map +1 -1
- package/dist/src/http/file-token.js +19 -17
- package/dist/src/http/file-token.js.map +1 -1
- package/dist/src/http/files.d.ts +3 -3
- package/dist/src/http/files.d.ts.map +1 -1
- package/dist/src/http/files.js +5 -5
- package/dist/src/http/files.js.map +1 -1
- package/dist/src/http/index.d.ts +8 -5
- package/dist/src/http/index.d.ts.map +1 -1
- package/dist/src/http/index.js +5 -3
- package/dist/src/http/index.js.map +1 -1
- package/dist/src/http/ip-middleware.d.ts +3 -2
- package/dist/src/http/ip-middleware.d.ts.map +1 -1
- package/dist/src/http/ip-middleware.js +7 -4
- package/dist/src/http/ip-middleware.js.map +1 -1
- package/dist/src/http/params.d.ts +3 -3
- package/dist/src/http/params.d.ts.map +1 -1
- package/dist/src/http/params.js +2 -2
- package/dist/src/http/params.js.map +1 -1
- package/dist/src/http/port-retry.d.ts +18 -0
- package/dist/src/http/port-retry.d.ts.map +1 -0
- package/dist/src/http/port-retry.js +43 -0
- package/dist/src/http/port-retry.js.map +1 -0
- package/dist/src/http/router.d.ts +10 -7
- package/dist/src/http/router.d.ts.map +1 -1
- package/dist/src/http/router.js +184 -63
- package/dist/src/http/router.js.map +1 -1
- package/dist/src/http/schema.d.ts +5 -0
- package/dist/src/http/schema.d.ts.map +1 -0
- package/dist/src/http/schema.js +18 -0
- package/dist/src/http/schema.js.map +1 -0
- package/dist/src/http/server-factory-node.d.ts.map +1 -1
- package/dist/src/http/server-factory-node.js +1 -1
- package/dist/src/http/server-factory-node.js.map +1 -1
- package/dist/src/http/server-factory.d.ts +3 -3
- package/dist/src/http/server-factory.d.ts.map +1 -1
- package/dist/src/http/server-factory.js +1 -1
- package/dist/src/http/server-factory.js.map +1 -1
- package/dist/src/http/telemetry-routes.d.ts +5 -0
- package/dist/src/http/telemetry-routes.d.ts.map +1 -0
- package/dist/src/http/telemetry-routes.js +220 -0
- package/dist/src/http/telemetry-routes.js.map +1 -0
- package/dist/src/index.d.ts +18 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +14 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/migrator/dialect-sqlite.d.ts.map +1 -1
- package/dist/src/migrator/dialect-sqlite.js +7 -1
- package/dist/src/migrator/dialect-sqlite.js.map +1 -1
- package/dist/src/migrator/index.d.ts +4 -4
- package/dist/src/migrator/index.d.ts.map +1 -1
- package/dist/src/migrator/index.js +2 -2
- package/dist/src/migrator/index.js.map +1 -1
- package/dist/src/migrator/migrator.d.ts +8 -8
- package/dist/src/migrator/migrator.d.ts.map +1 -1
- package/dist/src/migrator/migrator.js +16 -13
- package/dist/src/migrator/migrator.js.map +1 -1
- package/dist/src/migrator/schema-diff.d.ts +2 -2
- package/dist/src/migrator/schema-diff.d.ts.map +1 -1
- package/dist/src/migrator/schema-diff.js.map +1 -1
- package/dist/src/migrator/types.d.ts +5 -5
- package/dist/src/migrator/types.d.ts.map +1 -1
- package/dist/src/migrator/types.js +6 -7
- package/dist/src/migrator/types.js.map +1 -1
- package/dist/src/platforms/node.d.ts +1 -1
- package/dist/src/platforms/node.d.ts.map +1 -1
- package/dist/src/platforms/node.js +1 -1
- package/dist/src/platforms/node.js.map +1 -1
- package/dist/src/repository/id.d.ts +1 -1
- package/dist/src/repository/id.d.ts.map +1 -1
- package/dist/src/repository/id.js +15 -3
- package/dist/src/repository/id.js.map +1 -1
- package/dist/src/repository/repository.d.ts +3 -2
- package/dist/src/repository/repository.d.ts.map +1 -1
- package/dist/src/repository/repository.js +11 -7
- package/dist/src/repository/repository.js.map +1 -1
- package/dist/src/rule/compiler.d.ts.map +1 -1
- package/dist/src/rule/compiler.js +2 -0
- package/dist/src/rule/compiler.js.map +1 -1
- package/dist/src/rule/enforcer.d.ts.map +1 -1
- package/dist/src/rule/enforcer.js.map +1 -1
- package/dist/src/storage/index.d.ts +1 -1
- package/dist/src/storage/index.d.ts.map +1 -1
- package/dist/src/storage/index.js +1 -1
- package/dist/src/storage/index.js.map +1 -1
- package/dist/src/storage/local-preset.d.ts.map +1 -1
- package/dist/src/storage/local-preset.js.map +1 -1
- package/dist/src/storage/storage.d.ts +2 -2
- package/dist/src/storage/storage.d.ts.map +1 -1
- package/dist/src/storage/storage.js +8 -26
- package/dist/src/storage/storage.js.map +1 -1
- package/dist/src/telemetry/collections.d.ts +4 -0
- package/dist/src/telemetry/collections.d.ts.map +1 -0
- package/dist/src/telemetry/collections.js +19 -0
- package/dist/src/telemetry/collections.js.map +1 -0
- package/dist/src/telemetry/index.d.ts +17 -3
- package/dist/src/telemetry/index.d.ts.map +1 -1
- package/dist/src/telemetry/index.js +15 -5
- package/dist/src/telemetry/index.js.map +1 -1
- package/dist/src/telemetry/logger.d.ts +29 -2
- package/dist/src/telemetry/logger.d.ts.map +1 -1
- package/dist/src/telemetry/logger.js +52 -15
- package/dist/src/telemetry/logger.js.map +1 -1
- package/dist/src/telemetry/sqlite-logger.d.ts +36 -0
- package/dist/src/telemetry/sqlite-logger.d.ts.map +1 -0
- package/dist/src/telemetry/sqlite-logger.js +193 -0
- package/dist/src/telemetry/sqlite-logger.js.map +1 -0
- package/dist/src/telemetry/telemetry-sql-client.d.ts +11 -0
- package/dist/src/telemetry/telemetry-sql-client.d.ts.map +1 -0
- package/dist/src/telemetry/telemetry-sql-client.js +8 -0
- package/dist/src/telemetry/telemetry-sql-client.js.map +1 -0
- package/dist/src/telemetry/tracer.d.ts +16 -1
- package/dist/src/telemetry/tracer.d.ts.map +1 -1
- package/dist/src/telemetry/tracer.js +87 -70
- package/dist/src/telemetry/tracer.js.map +1 -1
- package/dist/src/telemetry/types.d.ts +11 -0
- package/dist/src/telemetry/types.d.ts.map +1 -0
- package/dist/src/telemetry/types.js +2 -0
- package/dist/src/telemetry/types.js.map +1 -0
- package/dist/src/thumbnail/index.d.ts +2 -2
- package/dist/src/thumbnail/index.d.ts.map +1 -1
- package/dist/src/thumbnail/index.js +1 -1
- package/dist/src/thumbnail/index.js.map +1 -1
- package/dist/src/thumbnail/photon.d.ts.map +1 -1
- package/dist/src/thumbnail/photon.js +1 -1
- package/dist/src/thumbnail/photon.js.map +1 -1
- package/dist/src/thumbnail/types.d.ts +1 -1
- package/dist/src/thumbnail/types.d.ts.map +1 -1
- package/dist/src/thumbnail/types.js +2 -2
- package/dist/src/thumbnail/types.js.map +1 -1
- package/dist/tests/app/app.test.js +101 -26
- package/dist/tests/app/app.test.js.map +1 -1
- package/dist/tests/app/builder.test.js +77 -9
- package/dist/tests/app/builder.test.js.map +1 -1
- package/dist/tests/app/define-rule.test.d.ts +2 -0
- package/dist/tests/app/define-rule.test.d.ts.map +1 -0
- package/dist/tests/app/define-rule.test.js +147 -0
- package/dist/tests/app/define-rule.test.js.map +1 -0
- package/dist/tests/cache/cached-collection.test.js +200 -40
- package/dist/tests/cache/cached-collection.test.js.map +1 -1
- package/dist/tests/cache/collection-cache.test.js +1 -1
- package/dist/tests/cache/collection-cache.test.js.map +1 -1
- package/dist/tests/collection-service/auth-credentials.test.d.ts +2 -0
- package/dist/tests/collection-service/auth-credentials.test.d.ts.map +1 -0
- package/dist/tests/collection-service/auth-credentials.test.js +172 -0
- package/dist/tests/collection-service/auth-credentials.test.js.map +1 -0
- package/dist/tests/collection-service/collection-service.test.js +374 -174
- package/dist/tests/collection-service/collection-service.test.js.map +1 -1
- package/dist/tests/collection-service/decode.test.d.ts +2 -0
- package/dist/tests/collection-service/decode.test.d.ts.map +1 -0
- package/dist/tests/collection-service/decode.test.js +37 -0
- package/dist/tests/collection-service/decode.test.js.map +1 -0
- package/dist/tests/collection-service/input-schema.test.js +162 -95
- package/dist/tests/collection-service/input-schema.test.js.map +1 -1
- package/dist/tests/config/config.test.js +15 -4
- package/dist/tests/config/config.test.js.map +1 -1
- package/dist/tests/cron/cron-integration.test.d.ts +2 -0
- package/dist/tests/cron/cron-integration.test.d.ts.map +1 -0
- package/dist/tests/cron/cron-integration.test.js +109 -0
- package/dist/tests/cron/cron-integration.test.js.map +1 -0
- package/dist/tests/cron/cron-persistence.test.d.ts +2 -0
- package/dist/tests/cron/cron-persistence.test.d.ts.map +1 -0
- package/dist/tests/cron/cron-persistence.test.js +123 -0
- package/dist/tests/cron/cron-persistence.test.js.map +1 -0
- package/dist/tests/cron/cron-service.test.d.ts +2 -0
- package/dist/tests/cron/cron-service.test.d.ts.map +1 -0
- package/dist/tests/cron/cron-service.test.js +124 -0
- package/dist/tests/cron/cron-service.test.js.map +1 -0
- package/dist/tests/crypto/crypto.test.js +2 -2
- package/dist/tests/crypto/crypto.test.js.map +1 -1
- package/dist/tests/hooks/hook-collection.test.d.ts +2 -0
- package/dist/tests/hooks/hook-collection.test.d.ts.map +1 -0
- package/dist/tests/hooks/hook-collection.test.js +110 -0
- package/dist/tests/hooks/hook-collection.test.js.map +1 -0
- package/dist/tests/hooks/hook-service.test.d.ts +2 -0
- package/dist/tests/hooks/hook-service.test.d.ts.map +1 -0
- package/dist/tests/hooks/hook-service.test.js +220 -0
- package/dist/tests/hooks/hook-service.test.js.map +1 -0
- package/dist/tests/http/cors.test.d.ts +2 -0
- package/dist/tests/http/cors.test.d.ts.map +1 -0
- package/dist/tests/http/cors.test.js +211 -0
- package/dist/tests/http/cors.test.js.map +1 -0
- package/dist/tests/http/file-serve.test.js +63 -54
- package/dist/tests/http/file-serve.test.js.map +1 -1
- package/dist/tests/http/file-token.test.js +69 -51
- package/dist/tests/http/file-token.test.js.map +1 -1
- package/dist/tests/http/ip-middleware.test.js +13 -13
- package/dist/tests/http/ip-middleware.test.js.map +1 -1
- package/dist/tests/http/port-retry.test.d.ts +2 -0
- package/dist/tests/http/port-retry.test.d.ts.map +1 -0
- package/dist/tests/http/port-retry.test.js +52 -0
- package/dist/tests/http/port-retry.test.js.map +1 -0
- package/dist/tests/http/router.test.js +260 -85
- package/dist/tests/http/router.test.js.map +1 -1
- package/dist/tests/migrator/dialect-sqlite.test.js +1 -1
- package/dist/tests/migrator/dialect-sqlite.test.js.map +1 -1
- package/dist/tests/migrator/integration.test.js +6 -6
- package/dist/tests/migrator/integration.test.js.map +1 -1
- package/dist/tests/migrator/migrator.test.js +5 -5
- package/dist/tests/migrator/migrator.test.js.map +1 -1
- package/dist/tests/migrator/schema-diff.test.js.map +1 -1
- package/dist/tests/repository/repository.test.js +71 -8
- package/dist/tests/repository/repository.test.js.map +1 -1
- package/dist/tests/rule/compiler.test.js +1 -1
- package/dist/tests/rule/compiler.test.js.map +1 -1
- package/dist/tests/rule/enforcer.test.js +9 -9
- package/dist/tests/rule/enforcer.test.js.map +1 -1
- package/dist/tests/storage/storage.test.js +15 -15
- package/dist/tests/storage/storage.test.js.map +1 -1
- package/dist/tests/telemetry/collections.test.d.ts +2 -0
- package/dist/tests/telemetry/collections.test.d.ts.map +1 -0
- package/dist/tests/telemetry/collections.test.js +67 -0
- package/dist/tests/telemetry/collections.test.js.map +1 -0
- package/dist/tests/telemetry/instrumentation.test.js +27 -20
- package/dist/tests/telemetry/instrumentation.test.js.map +1 -1
- package/dist/tests/telemetry/logger.test.js +38 -6
- package/dist/tests/telemetry/logger.test.js.map +1 -1
- package/dist/tests/telemetry/sqlite-logger.test.d.ts +2 -0
- package/dist/tests/telemetry/sqlite-logger.test.d.ts.map +1 -0
- package/dist/tests/telemetry/sqlite-logger.test.js +272 -0
- package/dist/tests/telemetry/sqlite-logger.test.js.map +1 -0
- package/dist/tests/telemetry/telemetry-routes.test.d.ts +2 -0
- package/dist/tests/telemetry/telemetry-routes.test.d.ts.map +1 -0
- package/dist/tests/telemetry/telemetry-routes.test.js +154 -0
- package/dist/tests/telemetry/telemetry-routes.test.js.map +1 -0
- package/dist/tests/telemetry/tracer.test.js +41 -4
- package/dist/tests/telemetry/tracer.test.js.map +1 -1
- package/dist/tests/thumbnail/photon.test.js +35 -35
- package/dist/tests/thumbnail/photon.test.js.map +1 -1
- package/dist/tests/thumbnail/thumbnail.test.js +7 -7
- package/dist/tests/thumbnail/thumbnail.test.js.map +1 -1
- package/package.json +9 -9
package/dist/src/http/auth.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Context, Effect } from "effect";
|
|
2
|
+
import * as jose from "jose";
|
|
2
3
|
export type JwtPayload = {
|
|
3
4
|
sub: string;
|
|
4
5
|
col: string;
|
|
@@ -15,7 +16,7 @@ export declare class AuthError extends AuthError_base<{
|
|
|
15
16
|
reason: string;
|
|
16
17
|
}> {
|
|
17
18
|
}
|
|
18
|
-
declare const AuthService_base: Context.
|
|
19
|
+
declare const AuthService_base: Context.ServiceClass<AuthService, "AuthService", {
|
|
19
20
|
hashPassword(plain: string): Effect.Effect<string>;
|
|
20
21
|
verifyPassword(plain: string, stored: string): Effect.Effect<boolean>;
|
|
21
22
|
}>;
|
|
@@ -34,5 +35,6 @@ export declare function verifyJwt(token: string, secret: string): Effect.Effect<
|
|
|
34
35
|
sub: string;
|
|
35
36
|
col: string;
|
|
36
37
|
}, AuthError, never>;
|
|
38
|
+
export declare function verifyAnyJwt(token: string, secret: string): Effect.Effect<jose.JWTVerifyResult<jose.JWTPayload>, AuthError, never>;
|
|
37
39
|
export {};
|
|
38
40
|
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/http/auth.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/http/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAQ,MAAM,EAAE,MAAM,QAAQ,CAAA;AAC9C,OAAO,KAAK,IAAI,MAAM,MAAM,CAAA;AAE5B,MAAM,MAAM,UAAU,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAA;AACrD,MAAM,MAAM,gBAAgB,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAA;;;;AAE5E,qBAAa,SAAU,SAAQ,eAA8B;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;CAAG;;wBAK3D,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;0BAC5B,MAAM,UAAU,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;;AAJzE,qBAAa,WAAY,SAAQ,gBAMf;CAAG;AAErB,eAAO,MAAM,YAAY,GAAI,OAAO,MAAM,8CAAoE,CAAA;AAE9G,eAAO,MAAM,cAAc,GAAI,OAAO,MAAM,EAAE,QAAQ,MAAM,+CACe,CAAA;AAE3E,wBAAgB,OAAO,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,2CAY1D;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,2CAYtE;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;;;;qBAe5D;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;;;qBActD;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,0EASzD"}
|
package/dist/src/http/auth.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import * as jose from "jose";
|
|
2
1
|
import { Context, Data, Effect } from "effect";
|
|
2
|
+
import * as jose from "jose";
|
|
3
3
|
export class AuthError extends Data.TaggedError("AuthError") {
|
|
4
4
|
}
|
|
5
|
-
export class AuthService extends Context.
|
|
5
|
+
export class AuthService extends Context.Service()("AuthService") {
|
|
6
6
|
}
|
|
7
7
|
export const hashPassword = (plain) => Effect.flatMap(AuthService, (auth) => auth.hashPassword(plain));
|
|
8
8
|
export const verifyPassword = (plain, stored) => Effect.flatMap(AuthService, (auth) => auth.verifyPassword(plain, stored));
|
|
@@ -63,4 +63,14 @@ export function verifyJwt(token, secret) {
|
|
|
63
63
|
catch: (e) => new AuthError({ reason: String(e) })
|
|
64
64
|
});
|
|
65
65
|
}
|
|
66
|
+
export function verifyAnyJwt(token, secret) {
|
|
67
|
+
return Effect.tryPromise({
|
|
68
|
+
try: async () => {
|
|
69
|
+
const encoder = new TextEncoder();
|
|
70
|
+
const result = await jose.jwtVerify(token, encoder.encode(secret));
|
|
71
|
+
return result;
|
|
72
|
+
},
|
|
73
|
+
catch: (e) => new AuthError({ reason: String(e) })
|
|
74
|
+
});
|
|
75
|
+
}
|
|
66
76
|
//# sourceMappingURL=auth.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/http/auth.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/http/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CORS configuration for the Mira HTTP server.
|
|
3
|
+
*
|
|
4
|
+
* Applied as `HttpMiddleware.cors(...)` in `MiraApp.buildLayer()`, alongside
|
|
5
|
+
* the IP annotation middleware. Covers all routes (including error responses —
|
|
6
|
+
* the middleware stamps headers via a pre-response handler, which also runs on
|
|
7
|
+
* the failure path) and answers `OPTIONS` preflights with a `204`.
|
|
8
|
+
*
|
|
9
|
+
* When `cors()` is never called on the builder, the server uses
|
|
10
|
+
* `defaultCorsConfig`, which reflects every requesting origin and allows
|
|
11
|
+
* credentials — so a separately-hosted frontend with cookie sessions works
|
|
12
|
+
* with zero configuration in development.
|
|
13
|
+
*
|
|
14
|
+
* @see defaultCorsConfig — the permissive default
|
|
15
|
+
* @see makeCorsMiddleware — maps this config onto `HttpMiddleware.cors`
|
|
16
|
+
* @see MiraBuilder.cors — where this config is set
|
|
17
|
+
*/
|
|
18
|
+
export interface CorsConfig {
|
|
19
|
+
/**
|
|
20
|
+
* Origins allowed to access the API.
|
|
21
|
+
*
|
|
22
|
+
* - Omitted or `[]` → `Access-Control-Allow-Origin: *` (all origins).
|
|
23
|
+
* - One origin → that origin is always echoed with `Vary: Origin`.
|
|
24
|
+
* - Several origins → the request origin is echoed only when listed,
|
|
25
|
+
* otherwise no `Access-Control-Allow-Origin` header is sent.
|
|
26
|
+
* - Predicate → the request origin is echoed only when it returns true.
|
|
27
|
+
*
|
|
28
|
+
* A literal `"*"` entry combined with `credentials: true` is rejected by
|
|
29
|
+
* `assertValidCorsConfig` — browsers forbid wildcard + credentials.
|
|
30
|
+
*/
|
|
31
|
+
readonly allowedOrigins?: ReadonlyArray<string> | ((origin: string) => boolean);
|
|
32
|
+
/**
|
|
33
|
+
* Value of the `Access-Control-Allow-Methods` preflight header.
|
|
34
|
+
* Defaults to `["GET", "HEAD", "PUT", "PATCH", "POST", "DELETE"]`.
|
|
35
|
+
*/
|
|
36
|
+
readonly allowedMethods?: ReadonlyArray<string>;
|
|
37
|
+
/**
|
|
38
|
+
* Value of the `Access-Control-Allow-Headers` preflight header.
|
|
39
|
+
* Defaults to reflecting the request's `Access-Control-Request-Headers`,
|
|
40
|
+
* which always covers every header the client SDK sends.
|
|
41
|
+
*/
|
|
42
|
+
readonly allowedHeaders?: ReadonlyArray<string>;
|
|
43
|
+
/**
|
|
44
|
+
* Value of the `Access-Control-Expose-Headers` header.
|
|
45
|
+
* Unset by default (no headers exposed).
|
|
46
|
+
*/
|
|
47
|
+
readonly exposedHeaders?: ReadonlyArray<string>;
|
|
48
|
+
/**
|
|
49
|
+
* Value of the `Access-Control-Max-Age` preflight header, in seconds.
|
|
50
|
+
* Unset by default (preflights are not cached).
|
|
51
|
+
*/
|
|
52
|
+
readonly maxAge?: number;
|
|
53
|
+
/**
|
|
54
|
+
* Whether to send `Access-Control-Allow-Credentials: true`.
|
|
55
|
+
* Requires explicit `allowedOrigins` — wildcard + credentials throws.
|
|
56
|
+
* Defaults to false.
|
|
57
|
+
*/
|
|
58
|
+
readonly credentials?: boolean;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* The default CORS configuration: reflects every requesting origin and sends
|
|
62
|
+
* `Access-Control-Allow-Credentials: true`, so a frontend on another origin
|
|
63
|
+
* works with zero configuration **including cookie-based auth**.
|
|
64
|
+
*
|
|
65
|
+
* A literal `Access-Control-Allow-Origin: *` cannot be combined with
|
|
66
|
+
* credentials (browsers reject it), so the default uses a predicate that
|
|
67
|
+
* accepts any present origin and lets the middleware echo the request's
|
|
68
|
+
* `Origin` back instead. Requests without an `Origin` header (same-origin,
|
|
69
|
+
* non-browser clients) simply receive no CORS header.
|
|
70
|
+
*
|
|
71
|
+
* This is a development-first default: any website can issue credentialed
|
|
72
|
+
* requests with the user's cookie. Lock it down with `Mira.builder().cors()`
|
|
73
|
+
* for production.
|
|
74
|
+
*
|
|
75
|
+
* @see CorsConfig
|
|
76
|
+
*/
|
|
77
|
+
export declare const defaultCorsConfig: CorsConfig;
|
|
78
|
+
/**
|
|
79
|
+
* Rejects CORS configurations that browsers refuse to honor: `credentials`
|
|
80
|
+
* combined with a wildcard origin (omitted, empty, or containing `"*"`).
|
|
81
|
+
* A predicate origin check cannot be inspected statically and is always
|
|
82
|
+
* allowed — it echoes only origins it accepts, which is safe.
|
|
83
|
+
*
|
|
84
|
+
* @throws If the config combines `credentials: true` with a wildcard origin.
|
|
85
|
+
*/
|
|
86
|
+
export declare function assertValidCorsConfig(config: CorsConfig): void;
|
|
87
|
+
/**
|
|
88
|
+
* Maps a `CorsConfig` onto Effect's `HttpMiddleware.cors` middleware.
|
|
89
|
+
* Validates first, so misconfiguration fails at boot, not per request.
|
|
90
|
+
*
|
|
91
|
+
* @see CorsConfig
|
|
92
|
+
*/
|
|
93
|
+
export declare const makeCorsMiddleware: (config: CorsConfig) => <E, R>(httpApp: import("effect/Effect").Effect<import("effect/http/HttpServerResponse").HttpServerResponse, E, R>) => import("effect/Effect").Effect<import("effect/http/HttpServerResponse").HttpServerResponse, E, R | import("effect/http/HttpServerRequest").HttpServerRequest>;
|
|
94
|
+
//# sourceMappingURL=cors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cors.d.ts","sourceRoot":"","sources":["../../../src/http/cors.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,UAAU;IACzB;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,CAAA;IAC/E;;;OAGG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IAC/C;;;;OAIG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IAC/C;;;OAGG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IAC/C;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB;;;;OAIG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAA;CAC/B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,iBAAiB,EAAE,UAG/B,CAAA;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,UAAU,QASvD;AAED;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAAI,QAAQ,UAAU,wRAUpD,CAAA"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { HttpMiddleware } from "effect/http";
|
|
2
|
+
/**
|
|
3
|
+
* The default CORS configuration: reflects every requesting origin and sends
|
|
4
|
+
* `Access-Control-Allow-Credentials: true`, so a frontend on another origin
|
|
5
|
+
* works with zero configuration **including cookie-based auth**.
|
|
6
|
+
*
|
|
7
|
+
* A literal `Access-Control-Allow-Origin: *` cannot be combined with
|
|
8
|
+
* credentials (browsers reject it), so the default uses a predicate that
|
|
9
|
+
* accepts any present origin and lets the middleware echo the request's
|
|
10
|
+
* `Origin` back instead. Requests without an `Origin` header (same-origin,
|
|
11
|
+
* non-browser clients) simply receive no CORS header.
|
|
12
|
+
*
|
|
13
|
+
* This is a development-first default: any website can issue credentialed
|
|
14
|
+
* requests with the user's cookie. Lock it down with `Mira.builder().cors()`
|
|
15
|
+
* for production.
|
|
16
|
+
*
|
|
17
|
+
* @see CorsConfig
|
|
18
|
+
*/
|
|
19
|
+
export const defaultCorsConfig = {
|
|
20
|
+
allowedOrigins: (origin) => typeof origin === "string" && origin.length > 0,
|
|
21
|
+
credentials: true
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Rejects CORS configurations that browsers refuse to honor: `credentials`
|
|
25
|
+
* combined with a wildcard origin (omitted, empty, or containing `"*"`).
|
|
26
|
+
* A predicate origin check cannot be inspected statically and is always
|
|
27
|
+
* allowed — it echoes only origins it accepts, which is safe.
|
|
28
|
+
*
|
|
29
|
+
* @throws If the config combines `credentials: true` with a wildcard origin.
|
|
30
|
+
*/
|
|
31
|
+
export function assertValidCorsConfig(config) {
|
|
32
|
+
if (config.credentials !== true)
|
|
33
|
+
return;
|
|
34
|
+
const origins = config.allowedOrigins;
|
|
35
|
+
if (origins === undefined || (Array.isArray(origins) && (origins.length === 0 || origins.includes("*")))) {
|
|
36
|
+
throw new Error("Invalid CORS config: credentials: true requires explicit allowedOrigins. " +
|
|
37
|
+
'Browsers reject Access-Control-Allow-Origin: "*" with credentials — list the allowed origins explicitly or use a predicate.');
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Maps a `CorsConfig` onto Effect's `HttpMiddleware.cors` middleware.
|
|
42
|
+
* Validates first, so misconfiguration fails at boot, not per request.
|
|
43
|
+
*
|
|
44
|
+
* @see CorsConfig
|
|
45
|
+
*/
|
|
46
|
+
export const makeCorsMiddleware = (config) => {
|
|
47
|
+
assertValidCorsConfig(config);
|
|
48
|
+
return HttpMiddleware.cors({
|
|
49
|
+
allowedOrigins: config.allowedOrigins,
|
|
50
|
+
allowedMethods: config.allowedMethods,
|
|
51
|
+
allowedHeaders: config.allowedHeaders,
|
|
52
|
+
exposedHeaders: config.exposedHeaders,
|
|
53
|
+
maxAge: config.maxAge,
|
|
54
|
+
credentials: config.credentials
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
//# sourceMappingURL=cors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cors.js","sourceRoot":"","sources":["../../../src/http/cors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AA8D5C;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAe;IAC3C,cAAc,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;IAC3E,WAAW,EAAE,IAAI;CAClB,CAAA;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,qBAAqB,CAAC,MAAkB;IACtD,IAAI,MAAM,CAAC,WAAW,KAAK,IAAI;QAAE,OAAM;IACvC,MAAM,OAAO,GAAG,MAAM,CAAC,cAAc,CAAA;IACrC,IAAI,OAAO,KAAK,SAAS,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QACzG,MAAM,IAAI,KAAK,CACb,2EAA2E;YACzE,6HAA6H,CAChI,CAAA;IACH,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,MAAkB,EAAE,EAAE;IACvD,qBAAqB,CAAC,MAAM,CAAC,CAAA;IAC7B,OAAO,cAAc,CAAC,IAAI,CAAC;QACzB,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,WAAW,EAAE,MAAM,CAAC,WAAW;KAChC,CAAC,CAAA;AACJ,CAAC,CAAA"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { HttpServerResponse } from "@effect/platform";
|
|
2
1
|
import { Effect } from "effect";
|
|
2
|
+
import { HttpServerResponse } from "effect/http";
|
|
3
3
|
import type { CollectionError } from "../collection-service/errors.js";
|
|
4
4
|
import type { FileStorageError } from "../storage/storage.js";
|
|
5
5
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/http/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/http/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAC/B,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAEhD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAA;AACrE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAE5D;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,qBAAqB,GAAI,CAAC,EAAE,CAAC,EACxC,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,eAAe,GAAG,gBAAgB,EAAE,CAAC,CAAC,KAC3D,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,kBAAkB,CAAC,kBAAkB,EAAE,CAAC,CAmCxD,CAAA"}
|
package/dist/src/http/errors.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { HttpServerResponse } from "@effect/platform";
|
|
2
1
|
import { Effect } from "effect";
|
|
2
|
+
import { HttpServerResponse } from "effect/http";
|
|
3
3
|
/**
|
|
4
4
|
* Effect error handler that maps `CollectionError` and `FileStorageError` variants
|
|
5
5
|
* to HTTP response objects with appropriate status codes.
|
|
@@ -26,11 +26,11 @@ import { Effect } from "effect";
|
|
|
26
26
|
* @see CollectionError — the union type this handler catches
|
|
27
27
|
*/
|
|
28
28
|
export const catchCollectionErrors = (eff) => Effect.catchTags(eff, {
|
|
29
|
-
NotFoundError: (e) => Effect.fail(HttpServerResponse.
|
|
30
|
-
ForbiddenError: () => Effect.fail(HttpServerResponse.
|
|
31
|
-
ValidationError: (e) => Effect.fail(HttpServerResponse.
|
|
32
|
-
ReadOnlyError: () => Effect.fail(HttpServerResponse.
|
|
33
|
-
FileStorageError: (e) => Effect.fail(HttpServerResponse.
|
|
34
|
-
SqlError: () => Effect.fail(HttpServerResponse.
|
|
29
|
+
NotFoundError: (e) => Effect.fail(HttpServerResponse.jsonUnsafe({ error: "not_found", message: `Record not found in "${e.collection}"` }, { status: 404 })),
|
|
30
|
+
ForbiddenError: () => Effect.fail(HttpServerResponse.jsonUnsafe({ error: "forbidden" }, { status: 403 })),
|
|
31
|
+
ValidationError: (e) => Effect.fail(HttpServerResponse.jsonUnsafe({ error: "validation_failed", issues: e.issues }, { status: 422 })),
|
|
32
|
+
ReadOnlyError: () => Effect.fail(HttpServerResponse.jsonUnsafe({ error: "read_only" }, { status: 405 })),
|
|
33
|
+
FileStorageError: (e) => Effect.fail(HttpServerResponse.jsonUnsafe({ error: "storage_error", reason: e.reason }, { status: 502 })),
|
|
34
|
+
SqlError: () => Effect.fail(HttpServerResponse.jsonUnsafe({ error: "internal_error" }, { status: 500 })),
|
|
35
35
|
});
|
|
36
36
|
//# sourceMappingURL=errors.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/http/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/http/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAC/B,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAKhD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CACnC,GAA4D,EACA,EAAE,CAC9D,MAAM,CAAC,SAAS,CAAC,GAAG,EAAE;IACpB,aAAa,EAAE,CAAC,CAAC,EAAE,EAAE,CACnB,MAAM,CAAC,IAAI,CACT,kBAAkB,CAAC,UAAU,CAC3B,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,wBAAwB,CAAC,CAAC,UAAU,GAAG,EAAE,EACxE,EAAE,MAAM,EAAE,GAAY,EAAE,CACzB,CACF;IACH,cAAc,EAAE,GAAG,EAAE,CACnB,MAAM,CAAC,IAAI,CACT,kBAAkB,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,GAAY,EAAE,CAAC,CAChF;IACH,eAAe,EAAE,CAAC,CAAC,EAAE,EAAE,CACrB,MAAM,CAAC,IAAI,CACT,kBAAkB,CAAC,UAAU,CAC3B,EAAE,KAAK,EAAE,mBAAmB,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,EAChD,EAAE,MAAM,EAAE,GAAY,EAAE,CACzB,CACF;IACH,aAAa,EAAE,GAAG,EAAE,CAClB,MAAM,CAAC,IAAI,CACT,kBAAkB,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,GAAY,EAAE,CAAC,CAChF;IACH,gBAAgB,EAAE,CAAC,CAAC,EAAE,EAAE,CACtB,MAAM,CAAC,IAAI,CACT,kBAAkB,CAAC,UAAU,CAC3B,EAAE,KAAK,EAAE,eAAe,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,EAC5C,EAAE,MAAM,EAAE,GAAY,EAAE,CACzB,CACF;IACH,QAAQ,EAAE,GAAG,EAAE,CACb,MAAM,CAAC,IAAI,CACT,kBAAkB,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,gBAAgB,EAAE,EAAE,EAAE,MAAM,EAAE,GAAY,EAAE,CAAC,CACrF;CACJ,CAAC,CAAA"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { HttpRouter, HttpServerRequest, HttpServerResponse } from "@effect/platform";
|
|
2
|
-
import { Effect } from "effect";
|
|
3
1
|
import type { AnyCollectionDef } from "@gettersethya/mira-client";
|
|
2
|
+
import { Effect } from "effect";
|
|
3
|
+
import { HttpRouter, HttpServerRequest, HttpServerResponse } from "effect/http";
|
|
4
|
+
import { AppConfig } from "../config/index.js";
|
|
4
5
|
import { Repository } from "../repository/repository.js";
|
|
5
6
|
import { FileStorage } from "../storage/storage.js";
|
|
6
7
|
import { ThumbnailService } from "../thumbnail/types.js";
|
|
7
|
-
import { AppConfig } from "../config/index.js";
|
|
8
8
|
export type FileServeServices = Repository | FileStorage | ThumbnailService | AppConfig;
|
|
9
|
-
export declare function makeFileServeRoute(collections: ReadonlyArray<AnyCollectionDef>): Effect.Effect<HttpServerResponse.HttpServerResponse, never, FileServeServices | HttpServerRequest.HttpServerRequest | HttpRouter.RouteContext>;
|
|
9
|
+
export declare function makeFileServeRoute(collections: ReadonlyArray<AnyCollectionDef>, adminCollections?: ReadonlyArray<string>): Effect.Effect<HttpServerResponse.HttpServerResponse, never, FileServeServices | HttpServerRequest.HttpServerRequest | HttpRouter.RouteContext>;
|
|
10
10
|
//# sourceMappingURL=file-serve.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-serve.d.ts","sourceRoot":"","sources":["../../../src/http/file-serve.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"file-serve.d.ts","sourceRoot":"","sources":["../../../src/http/file-serve.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AACjE,OAAO,EAAE,MAAM,EAAoB,MAAM,QAAQ,CAAA;AACjD,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAI/E,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;AAEvD,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAClD,OAAO,EAAiB,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAItE,MAAM,MAAM,iBAAiB,GAAG,UAAU,GAAG,WAAW,GAAG,gBAAgB,GAAG,SAAS,CAAA;AAmCvF,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,aAAa,CAAC,gBAAgB,CAAC,EAC5C,gBAAgB,GAAE,aAAa,CAAC,MAAM,CAAM,GAC3C,MAAM,CAAC,MAAM,CACd,kBAAkB,CAAC,kBAAkB,EACrC,KAAK,EACL,iBAAiB,GAAG,iBAAiB,CAAC,iBAAiB,GAAG,UAAU,CAAC,YAAY,CAClF,CAgCA"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { Effect, Redacted, Stream } from "effect";
|
|
2
|
+
import { HttpRouter, HttpServerRequest, HttpServerResponse } from "effect/http";
|
|
3
3
|
import { andWhere, idClause, resolveCtxPlaceholders } from "../collection-service/where.js";
|
|
4
|
-
import { Repository } from "../repository/repository.js";
|
|
5
|
-
import { FileStorage } from "../storage/storage.js";
|
|
6
|
-
import { ThumbnailService, parseThumbSpec } from "../thumbnail/types.js";
|
|
7
4
|
import { AppConfig } from "../config/index.js";
|
|
5
|
+
import { Repository } from "../repository/repository.js";
|
|
8
6
|
import { enforcerForAction } from "../rule/enforcer.js";
|
|
7
|
+
import { FileStorage } from "../storage/storage.js";
|
|
8
|
+
import { parseThumbSpec, ThumbnailService } from "../thumbnail/types.js";
|
|
9
9
|
import { verifyFileToken } from "./auth.js";
|
|
10
10
|
const MIME_MAP = {
|
|
11
11
|
jpg: "image/jpeg",
|
|
@@ -34,23 +34,24 @@ function getQueryParam(req, name) {
|
|
|
34
34
|
const queryStr = req.url.includes("?") ? req.url.split("?")[1] : "";
|
|
35
35
|
return new URLSearchParams(queryStr).get(name) ?? undefined;
|
|
36
36
|
}
|
|
37
|
-
export function makeFileServeRoute(collections) {
|
|
37
|
+
export function makeFileServeRoute(collections, adminCollections = []) {
|
|
38
38
|
const collectionMap = new Map(collections.map((c) => [c.name, c]));
|
|
39
|
+
const adminSet = new Set(adminCollections);
|
|
39
40
|
return Effect.flatMap(HttpRouter.RouteContext, (routeCtx) => {
|
|
40
41
|
const colName = routeCtx.params["collection"];
|
|
41
42
|
const recordId = routeCtx.params["id"];
|
|
42
43
|
const filename = routeCtx.params["filename"];
|
|
43
44
|
if (colName === undefined || recordId === undefined || filename === undefined) {
|
|
44
|
-
return Effect.succeed(HttpServerResponse.
|
|
45
|
+
return Effect.succeed(HttpServerResponse.jsonUnsafe({ error: "not_found" }, { status: 404 }));
|
|
45
46
|
}
|
|
46
47
|
const collection = collectionMap.get(colName);
|
|
47
48
|
if (collection === undefined) {
|
|
48
|
-
return Effect.succeed(HttpServerResponse.
|
|
49
|
+
return Effect.succeed(HttpServerResponse.jsonUnsafe({ error: "not_found", message: `Unknown collection "${colName}"` }, { status: 404 }));
|
|
49
50
|
}
|
|
50
|
-
return Effect.flatMap(HttpServerRequest.HttpServerRequest, (req) => Effect.
|
|
51
|
+
return Effect.flatMap(HttpServerRequest.HttpServerRequest, (req) => Effect.catchCause(serveFile(collection, recordId, filename, req, adminSet), () => Effect.succeed(HttpServerResponse.jsonUnsafe({ error: "internal" }, { status: 500 }))));
|
|
51
52
|
});
|
|
52
53
|
}
|
|
53
|
-
function serveFile(collection, recordId, filename, req) {
|
|
54
|
+
function serveFile(collection, recordId, filename, req, adminSet) {
|
|
54
55
|
return Effect.gen(function* () {
|
|
55
56
|
const config = yield* AppConfig;
|
|
56
57
|
const jwtSecret = Redacted.value(config.jwtSecret);
|
|
@@ -62,7 +63,7 @@ function serveFile(collection, recordId, filename, req) {
|
|
|
62
63
|
.viewFilter(collection.name, { where: idClause(recordId) })
|
|
63
64
|
.pipe(Effect.orElseSucceed(() => []));
|
|
64
65
|
if (rows.length === 0) {
|
|
65
|
-
return HttpServerResponse.
|
|
66
|
+
return HttpServerResponse.jsonUnsafe({ error: "not_found" }, { status: 404 });
|
|
66
67
|
}
|
|
67
68
|
const record = rows[0];
|
|
68
69
|
// Step 3: find the file field whose stored value equals `filename`
|
|
@@ -76,44 +77,48 @@ function serveFile(collection, recordId, filename, req) {
|
|
|
76
77
|
}
|
|
77
78
|
}
|
|
78
79
|
if (fieldName === undefined || fieldProp === undefined) {
|
|
79
|
-
return HttpServerResponse.
|
|
80
|
+
return HttpServerResponse.jsonUnsafe({ error: "not_found" }, { status: 404 });
|
|
80
81
|
}
|
|
81
82
|
// Step 4: protected field — verify token and enforce view rule
|
|
82
83
|
if (fieldProp["x-protected"] === true) {
|
|
83
84
|
const tokenParam = getQueryParam(req, "token");
|
|
84
85
|
if (tokenParam === undefined) {
|
|
85
|
-
return HttpServerResponse.
|
|
86
|
+
return HttpServerResponse.jsonUnsafe({ error: "forbidden" }, { status: 403 });
|
|
86
87
|
}
|
|
87
88
|
const tokenPayload = yield* verifyFileToken(tokenParam, jwtSecret).pipe(Effect.orElseSucceed(() => null));
|
|
88
89
|
if (tokenPayload === null || tokenPayload.filecol !== collection.name) {
|
|
89
|
-
return HttpServerResponse.
|
|
90
|
+
return HttpServerResponse.jsonUnsafe({ error: "forbidden" }, { status: 403 });
|
|
90
91
|
}
|
|
91
92
|
// Reconstruct auth context from file token sub + col
|
|
92
93
|
const authRows = yield* repo
|
|
93
94
|
.viewFilter(tokenPayload.col, { where: idClause(tokenPayload.sub) })
|
|
94
95
|
.pipe(Effect.orElseSucceed(() => []));
|
|
95
96
|
if (authRows.length === 0) {
|
|
96
|
-
return HttpServerResponse.
|
|
97
|
+
return HttpServerResponse.jsonUnsafe({ error: "forbidden" }, { status: 403 });
|
|
97
98
|
}
|
|
98
99
|
const ctx = {
|
|
99
100
|
auth: { collection: tokenPayload.col, record: authRows[0] },
|
|
100
101
|
headers: {},
|
|
101
102
|
query: {}
|
|
102
103
|
};
|
|
103
|
-
//
|
|
104
|
-
|
|
105
|
-
if (
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
104
|
+
// Admin tokens (declared by an admin plugin, e.g. the dashboard) bypass
|
|
105
|
+
// the per-collection view rule for protected file downloads.
|
|
106
|
+
if (!adminSet.has(tokenPayload.col)) {
|
|
107
|
+
// Enforce the collection's view rule against the specific record
|
|
108
|
+
const ruleResult = enforcerForAction(collection.schema, "view");
|
|
109
|
+
if (ruleResult === null) {
|
|
110
|
+
return HttpServerResponse.jsonUnsafe({ error: "forbidden" }, { status: 403 });
|
|
111
|
+
}
|
|
112
|
+
const ruleWhere = yield* resolveCtxPlaceholders(ruleResult, ctx, collection.name, "view").pipe(Effect.catchTag("ForbiddenError", () => Effect.succeed(null)));
|
|
113
|
+
if (ruleWhere === null) {
|
|
114
|
+
return HttpServerResponse.jsonUnsafe({ error: "forbidden" }, { status: 403 });
|
|
115
|
+
}
|
|
116
|
+
const allowed = yield* repo
|
|
117
|
+
.viewFilter(collection.name, { where: andWhere(ruleWhere, idClause(recordId)) })
|
|
118
|
+
.pipe(Effect.orElseSucceed(() => []));
|
|
119
|
+
if (allowed.length === 0) {
|
|
120
|
+
return HttpServerResponse.jsonUnsafe({ error: "forbidden" }, { status: 403 });
|
|
121
|
+
}
|
|
117
122
|
}
|
|
118
123
|
}
|
|
119
124
|
// Steps 5-8: derive MIME, handle thumbnail with persistent cache, serve bytes
|
|
@@ -130,23 +135,23 @@ function serveFile(collection, recordId, filename, req) {
|
|
|
130
135
|
else {
|
|
131
136
|
const original = yield* fileStorage.read(filename).pipe(Effect.catchTag("FileStorageNotFound", () => Effect.succeed(null)), Effect.orDie);
|
|
132
137
|
if (original === null) {
|
|
133
|
-
return HttpServerResponse.
|
|
138
|
+
return HttpServerResponse.jsonUnsafe({ error: "not_found" }, { status: 404 });
|
|
134
139
|
}
|
|
135
140
|
// On thumb error fall back to original rather than returning an error
|
|
136
141
|
const resized = yield* thumbSvc
|
|
137
142
|
.resize(original, mimeType, thumbSpec)
|
|
138
|
-
.pipe(Effect.
|
|
143
|
+
.pipe(Effect.catch(() => Effect.succeed(original)));
|
|
139
144
|
// Best-effort: persist the thumbnail for future requests
|
|
140
145
|
yield* fileStorage
|
|
141
|
-
.upload(cacheKey, Stream.
|
|
142
|
-
.pipe(Effect.
|
|
146
|
+
.upload(cacheKey, Stream.fromArray([resized]), mimeType)
|
|
147
|
+
.pipe(Effect.catch(() => Effect.void));
|
|
143
148
|
bytes = resized;
|
|
144
149
|
}
|
|
145
150
|
}
|
|
146
151
|
else {
|
|
147
152
|
const result = yield* fileStorage.read(filename).pipe(Effect.catchTag("FileStorageNotFound", () => Effect.succeed(null)), Effect.orDie);
|
|
148
153
|
if (result === null) {
|
|
149
|
-
return HttpServerResponse.
|
|
154
|
+
return HttpServerResponse.jsonUnsafe({ error: "not_found" }, { status: 404 });
|
|
150
155
|
}
|
|
151
156
|
bytes = result;
|
|
152
157
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-serve.js","sourceRoot":"","sources":["../../../src/http/file-serve.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"file-serve.js","sourceRoot":"","sources":["../../../src/http/file-serve.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { HttpRouter, HttpServerRequest, HttpServerResponse } from "@effect/platform";
|
|
2
|
-
import { Effect } from "effect";
|
|
3
1
|
import type { AnyCollectionDef } from "@gettersethya/mira-client";
|
|
4
|
-
import {
|
|
2
|
+
import { Effect } from "effect";
|
|
3
|
+
import type { HttpRouter } from "effect/http";
|
|
4
|
+
import { HttpServerRequest, HttpServerResponse } from "effect/http";
|
|
5
5
|
import { AppConfig } from "../config/index.js";
|
|
6
|
+
import { Repository } from "../repository/repository.js";
|
|
6
7
|
export declare function makeFileTokenRoute(collections: ReadonlyArray<AnyCollectionDef>): Effect.Effect<HttpServerResponse.HttpServerResponse, never, Repository | AppConfig | HttpServerRequest.HttpServerRequest | HttpRouter.RouteContext>;
|
|
7
8
|
//# sourceMappingURL=file-token.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-token.d.ts","sourceRoot":"","sources":["../../../src/http/file-token.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"file-token.d.ts","sourceRoot":"","sources":["../../../src/http/file-token.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AACjE,OAAO,EAAE,MAAM,EAAoB,MAAM,QAAQ,CAAA;AACjD,OAAO,KAAK,EAAE,UAAU,EAAC,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAGnE,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;AAmBvD,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,aAAa,CAAC,gBAAgB,CAAC,GAC3C,MAAM,CAAC,MAAM,CACd,kBAAkB,CAAC,kBAAkB,EACrC,KAAK,EACL,UAAU,GAAG,SAAS,GAAG,iBAAiB,CAAC,iBAAiB,GAAG,UAAU,CAAC,YAAY,CACvF,CAUA"}
|
|
@@ -1,35 +1,37 @@
|
|
|
1
|
-
import { HttpServerRequest, HttpServerResponse } from "@effect/platform";
|
|
2
1
|
import { Effect, Redacted, Schema } from "effect";
|
|
3
|
-
import {
|
|
2
|
+
import { HttpServerRequest, HttpServerResponse } from "effect/http";
|
|
4
3
|
import { idClause } from "../collection-service/where.js";
|
|
5
4
|
import { AppConfig } from "../config/index.js";
|
|
5
|
+
import { Repository } from "../repository/repository.js";
|
|
6
6
|
import { signFileToken, verifyJwt } from "./auth.js";
|
|
7
7
|
const TokenRequestSchema = Schema.Struct({
|
|
8
8
|
collection: Schema.String
|
|
9
9
|
});
|
|
10
|
-
function
|
|
10
|
+
function extractToken(req) {
|
|
11
11
|
const auth = req.headers["authorization"];
|
|
12
|
-
if (typeof auth
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
if (typeof auth === "string") {
|
|
13
|
+
const m = auth.match(/^Bearer\s+(.+)$/i);
|
|
14
|
+
if (m !== null)
|
|
15
|
+
return m[1];
|
|
16
|
+
}
|
|
17
|
+
return req.cookies["mira_token"] ?? null;
|
|
16
18
|
}
|
|
17
19
|
export function makeFileTokenRoute(collections) {
|
|
18
20
|
const collectionMap = new Map(collections.map((c) => [c.name, c]));
|
|
19
|
-
return Effect.flatMap(HttpServerRequest.HttpServerRequest, (req) => Effect.
|
|
21
|
+
return Effect.flatMap(HttpServerRequest.HttpServerRequest, (req) => Effect.catchCause(issueToken(req, collectionMap), () => Effect.succeed(HttpServerResponse.jsonUnsafe({ error: "internal" }, { status: 500 }))));
|
|
20
22
|
}
|
|
21
23
|
function issueToken(req, collectionMap) {
|
|
22
24
|
return Effect.gen(function* () {
|
|
23
25
|
const config = yield* AppConfig;
|
|
24
26
|
const jwtSecret = Redacted.value(config.jwtSecret);
|
|
25
|
-
// Require Bearer
|
|
26
|
-
const rawToken =
|
|
27
|
+
// Require auth token from Bearer header or mira_token cookie
|
|
28
|
+
const rawToken = extractToken(req);
|
|
27
29
|
if (rawToken === null) {
|
|
28
|
-
return HttpServerResponse.
|
|
30
|
+
return HttpServerResponse.jsonUnsafe({ error: "unauthorized" }, { status: 401 });
|
|
29
31
|
}
|
|
30
32
|
const authPayload = yield* verifyJwt(rawToken, jwtSecret).pipe(Effect.orElseSucceed(() => null));
|
|
31
33
|
if (authPayload === null) {
|
|
32
|
-
return HttpServerResponse.
|
|
34
|
+
return HttpServerResponse.jsonUnsafe({ error: "unauthorized" }, { status: 401 });
|
|
33
35
|
}
|
|
34
36
|
// Verify the auth user still exists
|
|
35
37
|
const repo = yield* Repository;
|
|
@@ -37,19 +39,19 @@ function issueToken(req, collectionMap) {
|
|
|
37
39
|
.viewFilter(authPayload.col, { where: idClause(authPayload.sub) })
|
|
38
40
|
.pipe(Effect.orElseSucceed(() => []));
|
|
39
41
|
if (authRows.length === 0) {
|
|
40
|
-
return HttpServerResponse.
|
|
42
|
+
return HttpServerResponse.jsonUnsafe({ error: "unauthorized" }, { status: 401 });
|
|
41
43
|
}
|
|
42
44
|
// Parse body for target collection
|
|
43
|
-
const body = yield* req.json.pipe(Effect.flatMap(Schema.
|
|
45
|
+
const body = yield* req.json.pipe(Effect.flatMap(Schema.decodeUnknownEffect(TokenRequestSchema)), Effect.orElseSucceed(() => null));
|
|
44
46
|
if (body === null) {
|
|
45
|
-
return HttpServerResponse.
|
|
47
|
+
return HttpServerResponse.jsonUnsafe({ error: "validation_failed", issues: ["collection is required"] }, { status: 422 });
|
|
46
48
|
}
|
|
47
49
|
if (!collectionMap.has(body.collection)) {
|
|
48
|
-
return HttpServerResponse.
|
|
50
|
+
return HttpServerResponse.jsonUnsafe({ error: "not_found", message: `Unknown collection "${body.collection}"` }, { status: 404 });
|
|
49
51
|
}
|
|
50
52
|
const fileToken = yield* signFileToken({ sub: authPayload.sub, col: authPayload.col, filecol: body.collection }, jwtSecret).pipe(Effect.orDie);
|
|
51
53
|
const expiresAt = Date.now() + 5 * 60 * 1000;
|
|
52
|
-
return HttpServerResponse.
|
|
54
|
+
return HttpServerResponse.jsonUnsafe({ token: fileToken, expiresAt }, { status: 200 });
|
|
53
55
|
}).pipe(Effect.orDie);
|
|
54
56
|
}
|
|
55
57
|
//# sourceMappingURL=file-token.js.map
|