@openora/core 0.4.1-canary.16 → 0.4.1-canary.161
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 +10 -10
- package/bin/migrate.mjs +55 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/admin-console/__tests__/backoffice.router.test.js +82 -51
- package/dist/admin-console/__tests__/backoffice.router.test.js.map +1 -1
- package/dist/admin-console/__tests__/backoffice.service.int.test.d.ts +2 -0
- package/dist/admin-console/__tests__/backoffice.service.int.test.d.ts.map +1 -0
- package/dist/admin-console/__tests__/backoffice.service.int.test.js +351 -0
- package/dist/admin-console/__tests__/backoffice.service.int.test.js.map +1 -0
- package/dist/admin-console/contract/index.d.ts +302 -28
- package/dist/admin-console/contract/index.d.ts.map +1 -1
- package/dist/admin-console/contract/index.js +74 -6
- package/dist/admin-console/contract/index.js.map +1 -1
- package/dist/admin-console/plugin.d.ts +186 -1
- package/dist/admin-console/plugin.d.ts.map +1 -1
- package/dist/admin-console/plugin.js +6 -6
- package/dist/admin-console/plugin.js.map +1 -1
- package/dist/admin-console/router/index.d.ts +135 -18
- package/dist/admin-console/router/index.d.ts.map +1 -1
- package/dist/admin-console/router/index.js +18 -2
- package/dist/admin-console/router/index.js.map +1 -1
- package/dist/admin-console/service/backoffice.service.d.ts +70 -10
- package/dist/admin-console/service/backoffice.service.d.ts.map +1 -1
- package/dist/admin-console/service/backoffice.service.js +67 -11
- package/dist/admin-console/service/backoffice.service.js.map +1 -1
- package/dist/analytics/__tests__/analytics.contract.test.d.ts +2 -0
- package/dist/analytics/__tests__/analytics.contract.test.d.ts.map +1 -0
- package/dist/analytics/__tests__/analytics.contract.test.js +36 -0
- package/dist/analytics/__tests__/analytics.contract.test.js.map +1 -0
- package/dist/analytics/__tests__/analytics.router.test.d.ts +2 -0
- package/dist/analytics/__tests__/analytics.router.test.d.ts.map +1 -0
- package/dist/analytics/__tests__/analytics.router.test.js +56 -0
- package/dist/analytics/__tests__/analytics.router.test.js.map +1 -0
- package/dist/analytics/__tests__/financial-analytics.service.test.d.ts +2 -0
- package/dist/analytics/__tests__/financial-analytics.service.test.d.ts.map +1 -0
- package/dist/analytics/__tests__/financial-analytics.service.test.js +87 -0
- package/dist/analytics/__tests__/financial-analytics.service.test.js.map +1 -0
- package/dist/analytics/__tests__/funnel-analytics.service.test.d.ts +2 -0
- package/dist/analytics/__tests__/funnel-analytics.service.test.d.ts.map +1 -0
- package/dist/analytics/__tests__/funnel-analytics.service.test.js +42 -0
- package/dist/analytics/__tests__/funnel-analytics.service.test.js.map +1 -0
- package/dist/analytics/contract/financial.d.ts +121 -0
- package/dist/analytics/contract/financial.d.ts.map +1 -0
- package/dist/analytics/contract/financial.js +45 -0
- package/dist/analytics/contract/financial.js.map +1 -0
- package/dist/analytics/contract/funnel.d.ts +52 -0
- package/dist/analytics/contract/funnel.d.ts.map +1 -0
- package/dist/analytics/contract/funnel.js +24 -0
- package/dist/analytics/contract/funnel.js.map +1 -0
- package/dist/analytics/contract/index.d.ts +68 -0
- package/dist/analytics/contract/index.d.ts.map +1 -0
- package/dist/analytics/contract/index.js +9 -0
- package/dist/analytics/contract/index.js.map +1 -0
- package/dist/analytics/index.d.ts +2 -0
- package/dist/analytics/index.d.ts.map +1 -0
- package/dist/analytics/index.js +2 -0
- package/dist/analytics/index.js.map +1 -0
- package/dist/analytics/plugin.d.ts +188 -0
- package/dist/analytics/plugin.d.ts.map +1 -0
- package/dist/analytics/plugin.js +13 -0
- package/dist/analytics/plugin.js.map +1 -0
- package/dist/analytics/router/index.d.ts +69 -0
- package/dist/analytics/router/index.d.ts.map +1 -0
- package/dist/analytics/router/index.js +24 -0
- package/dist/analytics/router/index.js.map +1 -0
- package/dist/analytics/server.d.ts +5 -0
- package/dist/analytics/server.d.ts.map +1 -0
- package/dist/analytics/server.js +5 -0
- package/dist/analytics/server.js.map +1 -0
- package/dist/analytics/service/financial-analytics.service.d.ts +14 -0
- package/dist/analytics/service/financial-analytics.service.d.ts.map +1 -0
- package/dist/analytics/service/financial-analytics.service.js +146 -0
- package/dist/analytics/service/financial-analytics.service.js.map +1 -0
- package/dist/analytics/service/funnel-analytics.service.d.ts +11 -0
- package/dist/analytics/service/funnel-analytics.service.d.ts.map +1 -0
- package/dist/analytics/service/funnel-analytics.service.js +83 -0
- package/dist/analytics/service/funnel-analytics.service.js.map +1 -0
- package/dist/audit/__tests__/audit.service.int.test.d.ts +2 -0
- package/dist/audit/__tests__/audit.service.int.test.d.ts.map +1 -0
- package/dist/audit/__tests__/audit.service.int.test.js +906 -0
- package/dist/audit/__tests__/audit.service.int.test.js.map +1 -0
- package/dist/audit/__tests__/map-event.test.d.ts +2 -0
- package/dist/audit/__tests__/map-event.test.d.ts.map +1 -0
- package/dist/audit/__tests__/map-event.test.js +242 -0
- package/dist/audit/__tests__/map-event.test.js.map +1 -0
- package/dist/audit/contract/index.d.ts +154 -10
- package/dist/audit/contract/index.d.ts.map +1 -1
- package/dist/audit/contract/index.js +45 -5
- package/dist/audit/contract/index.js.map +1 -1
- package/dist/audit/migrate.d.ts.map +1 -1
- package/dist/audit/migrate.js +12 -0
- package/dist/audit/migrate.js.map +1 -1
- package/dist/audit/plugin.d.ts +187 -1
- package/dist/audit/plugin.d.ts.map +1 -1
- package/dist/audit/plugin.js +734 -51
- package/dist/audit/plugin.js.map +1 -1
- package/dist/audit/router/index.d.ts +73 -5
- package/dist/audit/router/index.d.ts.map +1 -1
- package/dist/audit/router/index.js +2 -5
- package/dist/audit/router/index.js.map +1 -1
- package/dist/audit/service/audit.service.d.ts +40 -14
- package/dist/audit/service/audit.service.d.ts.map +1 -1
- package/dist/audit/service/audit.service.js +86 -16
- package/dist/audit/service/audit.service.js.map +1 -1
- package/dist/casino/gaming/__tests__/admin-reporting.int.test.d.ts +2 -0
- package/dist/casino/gaming/__tests__/admin-reporting.int.test.d.ts.map +1 -0
- package/dist/casino/gaming/__tests__/admin-reporting.int.test.js +143 -0
- package/dist/casino/gaming/__tests__/admin-reporting.int.test.js.map +1 -0
- package/dist/casino/gaming/__tests__/game-category.service.int.test.d.ts +2 -0
- package/dist/casino/gaming/__tests__/game-category.service.int.test.d.ts.map +1 -0
- package/dist/casino/gaming/__tests__/game-category.service.int.test.js +134 -0
- package/dist/casino/gaming/__tests__/game-category.service.int.test.js.map +1 -0
- package/dist/casino/gaming/__tests__/game-provider.service.int.test.d.ts +2 -0
- package/dist/casino/gaming/__tests__/game-provider.service.int.test.d.ts.map +1 -0
- package/dist/casino/gaming/__tests__/game-provider.service.int.test.js +274 -0
- package/dist/casino/gaming/__tests__/game-provider.service.int.test.js.map +1 -0
- package/dist/casino/gaming/__tests__/gaming-catalog-admin.router.int.test.d.ts +2 -0
- package/dist/casino/gaming/__tests__/gaming-catalog-admin.router.int.test.d.ts.map +1 -0
- package/dist/casino/gaming/__tests__/gaming-catalog-admin.router.int.test.js +174 -0
- package/dist/casino/gaming/__tests__/gaming-catalog-admin.router.int.test.js.map +1 -0
- package/dist/casino/gaming/__tests__/gaming-migration.int.test.d.ts +2 -0
- package/dist/casino/gaming/__tests__/gaming-migration.int.test.d.ts.map +1 -0
- package/dist/casino/gaming/__tests__/gaming-migration.int.test.js +171 -0
- package/dist/casino/gaming/__tests__/gaming-migration.int.test.js.map +1 -0
- package/dist/casino/gaming/__tests__/gaming.service.int.test.d.ts +2 -0
- package/dist/casino/gaming/__tests__/gaming.service.int.test.d.ts.map +1 -0
- package/dist/casino/gaming/__tests__/gaming.service.int.test.js +744 -0
- package/dist/casino/gaming/__tests__/gaming.service.int.test.js.map +1 -0
- package/dist/casino/gaming/adapters/mock/mock-game-adapter.d.ts.map +1 -1
- package/dist/casino/gaming/adapters/mock/mock-game-adapter.js +3 -1
- package/dist/casino/gaming/adapters/mock/mock-game-adapter.js.map +1 -1
- package/dist/casino/gaming/admin-reporting.d.ts +9 -0
- package/dist/casino/gaming/admin-reporting.d.ts.map +1 -0
- package/dist/casino/gaming/admin-reporting.js +79 -0
- package/dist/casino/gaming/admin-reporting.js.map +1 -0
- package/dist/casino/gaming/contract/index.d.ts +536 -15
- package/dist/casino/gaming/contract/index.d.ts.map +1 -1
- package/dist/casino/gaming/contract/index.js +176 -5
- package/dist/casino/gaming/contract/index.js.map +1 -1
- package/dist/casino/gaming/drizzle/migrations/0002_yummy_lifeguard.sql +4 -0
- package/dist/casino/gaming/drizzle/migrations/0003_wealthy_greymalkin.sql +2 -0
- package/dist/casino/gaming/drizzle/migrations/0004_serious_storm.sql +4 -0
- package/dist/casino/gaming/drizzle/migrations/0005_natural_thunderbolt_ross.sql +223 -0
- package/dist/casino/gaming/drizzle/migrations/meta/0002_snapshot.json +237 -0
- package/dist/casino/gaming/drizzle/migrations/meta/0003_snapshot.json +259 -0
- package/dist/casino/gaming/drizzle/migrations/meta/0004_snapshot.json +259 -0
- package/dist/casino/gaming/drizzle/migrations/meta/0005_snapshot.json +680 -0
- package/dist/casino/gaming/drizzle/migrations/meta/_journal.json +28 -0
- package/dist/casino/gaming/plugin.d.ts +187 -1
- package/dist/casino/gaming/plugin.d.ts.map +1 -1
- package/dist/casino/gaming/plugin.js +22 -5
- package/dist/casino/gaming/plugin.js.map +1 -1
- package/dist/casino/gaming/router/index.d.ts +379 -14
- package/dist/casino/gaming/router/index.d.ts.map +1 -1
- package/dist/casino/gaming/router/index.js +68 -7
- package/dist/casino/gaming/router/index.js.map +1 -1
- package/dist/casino/gaming/schema/index.d.ts +534 -4
- package/dist/casino/gaming/schema/index.d.ts.map +1 -1
- package/dist/casino/gaming/schema/index.js +89 -8
- package/dist/casino/gaming/schema/index.js.map +1 -1
- package/dist/casino/gaming/service/game-category.service.d.ts +109 -0
- package/dist/casino/gaming/service/game-category.service.d.ts.map +1 -0
- package/dist/casino/gaming/service/game-category.service.js +176 -0
- package/dist/casino/gaming/service/game-category.service.js.map +1 -0
- package/dist/casino/gaming/service/game-provider.service.d.ts +118 -0
- package/dist/casino/gaming/service/game-provider.service.d.ts.map +1 -0
- package/dist/casino/gaming/service/game-provider.service.js +251 -0
- package/dist/casino/gaming/service/game-provider.service.js.map +1 -0
- package/dist/casino/gaming/service/gaming.service.d.ts +178 -19
- package/dist/casino/gaming/service/gaming.service.d.ts.map +1 -1
- package/dist/casino/gaming/service/gaming.service.js +350 -41
- package/dist/casino/gaming/service/gaming.service.js.map +1 -1
- package/dist/casino/lobby/__tests__/lobby-contract.test.d.ts +2 -0
- package/dist/casino/lobby/__tests__/lobby-contract.test.d.ts.map +1 -0
- package/dist/casino/lobby/__tests__/lobby-contract.test.js +39 -0
- package/dist/casino/lobby/__tests__/lobby-contract.test.js.map +1 -0
- package/dist/casino/lobby/__tests__/lobby-layout.int.test.d.ts +2 -0
- package/dist/casino/lobby/__tests__/lobby-layout.int.test.d.ts.map +1 -0
- package/dist/casino/lobby/__tests__/lobby-layout.int.test.js +145 -0
- package/dist/casino/lobby/__tests__/lobby-layout.int.test.js.map +1 -0
- package/dist/casino/lobby/__tests__/lobby.cache.int.test.d.ts +2 -0
- package/dist/casino/lobby/__tests__/lobby.cache.int.test.d.ts.map +1 -0
- package/dist/casino/lobby/__tests__/lobby.cache.int.test.js +227 -0
- package/dist/casino/lobby/__tests__/lobby.cache.int.test.js.map +1 -0
- package/dist/casino/lobby/contract/index.d.ts +152 -8
- package/dist/casino/lobby/contract/index.d.ts.map +1 -1
- package/dist/casino/lobby/contract/index.js +41 -3
- package/dist/casino/lobby/contract/index.js.map +1 -1
- package/dist/casino/lobby/drizzle/migrations/0001_true_clea.sql +20 -0
- package/dist/casino/lobby/drizzle/migrations/meta/0001_snapshot.json +343 -0
- package/dist/casino/lobby/drizzle/migrations/meta/_journal.json +7 -0
- package/dist/casino/lobby/plugin.d.ts +185 -1
- package/dist/casino/lobby/plugin.d.ts.map +1 -1
- package/dist/casino/lobby/plugin.js +9 -5
- package/dist/casino/lobby/plugin.js.map +1 -1
- package/dist/casino/lobby/router/index.d.ts +76 -6
- package/dist/casino/lobby/router/index.d.ts.map +1 -1
- package/dist/casino/lobby/router/index.js +13 -2
- package/dist/casino/lobby/router/index.js.map +1 -1
- package/dist/casino/lobby/schema/index.d.ts +222 -0
- package/dist/casino/lobby/schema/index.d.ts.map +1 -1
- package/dist/casino/lobby/schema/index.js +21 -1
- package/dist/casino/lobby/schema/index.js.map +1 -1
- package/dist/casino/lobby/service/lobby.service.d.ts +73 -8
- package/dist/casino/lobby/service/lobby.service.d.ts.map +1 -1
- package/dist/casino/lobby/service/lobby.service.js +312 -38
- package/dist/casino/lobby/service/lobby.service.js.map +1 -1
- package/dist/casino/server.d.ts +1 -0
- package/dist/casino/server.d.ts.map +1 -1
- package/dist/casino/server.js +1 -0
- package/dist/casino/server.js.map +1 -1
- package/dist/casino/shared/game-catalog.d.ts +32 -0
- package/dist/casino/shared/game-catalog.d.ts.map +1 -0
- package/dist/casino/shared/game-catalog.js +67 -0
- package/dist/casino/shared/game-catalog.js.map +1 -0
- package/dist/cms/__tests__/cms.reads.int.test.d.ts +2 -0
- package/dist/cms/__tests__/cms.reads.int.test.d.ts.map +1 -0
- package/dist/cms/__tests__/cms.reads.int.test.js +66 -0
- package/dist/cms/__tests__/cms.reads.int.test.js.map +1 -0
- package/dist/cms/__tests__/cms.router.int.test.d.ts +2 -0
- package/dist/cms/__tests__/cms.router.int.test.d.ts.map +1 -0
- package/dist/cms/__tests__/cms.router.int.test.js +356 -0
- package/dist/cms/__tests__/cms.router.int.test.js.map +1 -0
- package/dist/cms/__tests__/cms.service.int.test.d.ts +2 -0
- package/dist/cms/__tests__/cms.service.int.test.d.ts.map +1 -0
- package/dist/cms/__tests__/cms.service.int.test.js +908 -0
- package/dist/cms/__tests__/cms.service.int.test.js.map +1 -0
- package/dist/cms/contract/index.d.ts +413 -42
- package/dist/cms/contract/index.d.ts.map +1 -1
- package/dist/cms/contract/index.js +161 -35
- package/dist/cms/contract/index.js.map +1 -1
- package/dist/cms/drizzle/migrations/0001_steep_starjammers.sql +29 -0
- package/dist/cms/drizzle/migrations/0002_naive_kingpin.sql +14 -0
- package/dist/cms/drizzle/migrations/0003_worthless_titanium_man.sql +2 -0
- package/dist/cms/drizzle/migrations/meta/0001_snapshot.json +303 -0
- package/dist/cms/drizzle/migrations/meta/0002_snapshot.json +412 -0
- package/dist/cms/drizzle/migrations/meta/0003_snapshot.json +442 -0
- package/dist/cms/drizzle/migrations/meta/_journal.json +21 -0
- package/dist/cms/moderation/validate-banner-image-url.d.ts +8 -0
- package/dist/cms/moderation/validate-banner-image-url.d.ts.map +1 -0
- package/dist/cms/moderation/validate-banner-image-url.js +20 -0
- package/dist/cms/moderation/validate-banner-image-url.js.map +1 -0
- package/dist/cms/plugin.d.ts +185 -1
- package/dist/cms/plugin.d.ts.map +1 -1
- package/dist/cms/plugin.js +5 -5
- package/dist/cms/plugin.js.map +1 -1
- package/dist/cms/router/index.d.ts +219 -37
- package/dist/cms/router/index.d.ts.map +1 -1
- package/dist/cms/router/index.js +83 -21
- package/dist/cms/router/index.js.map +1 -1
- package/dist/cms/schema/index.d.ts +283 -28
- package/dist/cms/schema/index.d.ts.map +1 -1
- package/dist/cms/schema/index.js +57 -7
- package/dist/cms/schema/index.js.map +1 -1
- package/dist/cms/server.d.ts +1 -1
- package/dist/cms/server.d.ts.map +1 -1
- package/dist/cms/server.js +1 -1
- package/dist/cms/server.js.map +1 -1
- package/dist/cms/service/cms.service.d.ts +229 -45
- package/dist/cms/service/cms.service.d.ts.map +1 -1
- package/dist/cms/service/cms.service.js +702 -67
- package/dist/cms/service/cms.service.js.map +1 -1
- package/dist/common/errors/__tests__/errors.mapper.test.d.ts +2 -0
- package/dist/common/errors/__tests__/errors.mapper.test.d.ts.map +1 -0
- package/dist/common/errors/__tests__/errors.mapper.test.js +59 -0
- package/dist/common/errors/__tests__/errors.mapper.test.js.map +1 -0
- package/dist/common/errors/errors.classes.js +3 -3
- package/dist/common/errors/errors.classes.js.map +1 -1
- package/dist/common/errors/errors.mapper.js +1 -1
- package/dist/common/errors/errors.mapper.js.map +1 -1
- package/dist/compliance/__tests__/assert.test.d.ts +2 -0
- package/dist/compliance/__tests__/assert.test.d.ts.map +1 -0
- package/dist/compliance/__tests__/assert.test.js +34 -0
- package/dist/compliance/__tests__/assert.test.js.map +1 -0
- package/dist/compliance/__tests__/compliance.service.int.test.d.ts +2 -0
- package/dist/compliance/__tests__/compliance.service.int.test.d.ts.map +1 -0
- package/dist/compliance/__tests__/compliance.service.int.test.js +453 -0
- package/dist/compliance/__tests__/compliance.service.int.test.js.map +1 -0
- package/dist/compliance/__tests__/hmac-kyc-webhook-verifier.int.test.d.ts +2 -0
- package/dist/compliance/__tests__/hmac-kyc-webhook-verifier.int.test.d.ts.map +1 -0
- package/dist/compliance/__tests__/hmac-kyc-webhook-verifier.int.test.js +82 -0
- package/dist/compliance/__tests__/hmac-kyc-webhook-verifier.int.test.js.map +1 -0
- package/dist/compliance/__tests__/kyc-admin.router.int.test.d.ts +2 -0
- package/dist/compliance/__tests__/kyc-admin.router.int.test.d.ts.map +1 -0
- package/dist/compliance/__tests__/kyc-admin.router.int.test.js +198 -0
- package/dist/compliance/__tests__/kyc-admin.router.int.test.js.map +1 -0
- package/dist/compliance/__tests__/kyc-webhook.router.int.test.d.ts +2 -0
- package/dist/compliance/__tests__/kyc-webhook.router.int.test.d.ts.map +1 -0
- package/dist/compliance/__tests__/kyc-webhook.router.int.test.js +177 -0
- package/dist/compliance/__tests__/kyc-webhook.router.int.test.js.map +1 -0
- package/dist/compliance/__tests__/kyc.service.int.test.d.ts +2 -0
- package/dist/compliance/__tests__/kyc.service.int.test.d.ts.map +1 -0
- package/dist/compliance/__tests__/kyc.service.int.test.js +397 -0
- package/dist/compliance/__tests__/kyc.service.int.test.js.map +1 -0
- package/dist/compliance/__tests__/limits.contract.test.d.ts +2 -0
- package/dist/compliance/__tests__/limits.contract.test.d.ts.map +1 -0
- package/dist/compliance/__tests__/limits.contract.test.js +83 -0
- package/dist/compliance/__tests__/limits.contract.test.js.map +1 -0
- package/dist/compliance/__tests__/regulatory-overview.router.int.test.d.ts +2 -0
- package/dist/compliance/__tests__/regulatory-overview.router.int.test.d.ts.map +1 -0
- package/dist/compliance/__tests__/regulatory-overview.router.int.test.js +102 -0
- package/dist/compliance/__tests__/regulatory-overview.router.int.test.js.map +1 -0
- package/dist/compliance/__tests__/rg-eval.test.js +28 -1
- package/dist/compliance/__tests__/rg-eval.test.js.map +1 -1
- package/dist/compliance/__tests__/rg-monitoring.service.int.test.d.ts +2 -0
- package/dist/compliance/__tests__/rg-monitoring.service.int.test.d.ts.map +1 -0
- package/dist/compliance/__tests__/rg-monitoring.service.int.test.js +526 -0
- package/dist/compliance/__tests__/rg-monitoring.service.int.test.js.map +1 -0
- package/dist/compliance/__tests__/rg-self-service.int.test.d.ts +2 -0
- package/dist/compliance/__tests__/rg-self-service.int.test.d.ts.map +1 -0
- package/dist/compliance/__tests__/rg-self-service.int.test.js +539 -0
- package/dist/compliance/__tests__/rg-self-service.int.test.js.map +1 -0
- package/dist/compliance/__tests__/rg.contract.test.js +60 -20
- package/dist/compliance/__tests__/rg.contract.test.js.map +1 -1
- package/dist/compliance/__tests__/rg.router.int.test.d.ts +2 -0
- package/dist/compliance/__tests__/rg.router.int.test.d.ts.map +1 -0
- package/dist/compliance/__tests__/rg.router.int.test.js +325 -0
- package/dist/compliance/__tests__/rg.router.int.test.js.map +1 -0
- package/dist/compliance/__tests__/rg.service.int.test.d.ts +2 -0
- package/dist/compliance/__tests__/rg.service.int.test.d.ts.map +1 -0
- package/dist/compliance/__tests__/rg.service.int.test.js +747 -0
- package/dist/compliance/__tests__/rg.service.int.test.js.map +1 -0
- package/dist/compliance/adapters/hmac-kyc-webhook-verifier.d.ts +16 -3
- package/dist/compliance/adapters/hmac-kyc-webhook-verifier.d.ts.map +1 -1
- package/dist/compliance/adapters/hmac-kyc-webhook-verifier.js +47 -5
- package/dist/compliance/adapters/hmac-kyc-webhook-verifier.js.map +1 -1
- package/dist/compliance/adapters/rg-limit-gate.d.ts +17 -0
- package/dist/compliance/adapters/rg-limit-gate.d.ts.map +1 -0
- package/dist/compliance/adapters/rg-limit-gate.js +107 -0
- package/dist/compliance/adapters/rg-limit-gate.js.map +1 -0
- package/dist/compliance/contract/index.d.ts +1451 -124
- package/dist/compliance/contract/index.d.ts.map +1 -1
- package/dist/compliance/contract/index.js +178 -9
- package/dist/compliance/contract/index.js.map +1 -1
- package/dist/compliance/contract/limits.d.ts +52 -0
- package/dist/compliance/contract/limits.d.ts.map +1 -1
- package/dist/compliance/contract/limits.js +27 -7
- package/dist/compliance/contract/limits.js.map +1 -1
- package/dist/compliance/contract/rg.d.ts +337 -7
- package/dist/compliance/contract/rg.d.ts.map +1 -1
- package/dist/compliance/contract/rg.js +61 -15
- package/dist/compliance/contract/rg.js.map +1 -1
- package/dist/compliance/drizzle/migrations/0002_condemned_monster_badoon.sql +3 -0
- package/dist/compliance/drizzle/migrations/0003_public_spirit.sql +1 -0
- package/dist/compliance/drizzle/migrations/0004_military_silk_fever.sql +2 -0
- package/dist/compliance/drizzle/migrations/0005_reflective_magma.sql +13 -0
- package/dist/compliance/drizzle/migrations/0006_backfill_session_limit_currency.sql +15 -0
- package/dist/compliance/drizzle/migrations/0007_romantic_toxin.sql +6 -0
- package/dist/compliance/drizzle/migrations/0008_omniscient_northstar.sql +14 -0
- package/dist/compliance/drizzle/migrations/0009_living_felicia_hardy.sql +12 -0
- package/dist/compliance/drizzle/migrations/meta/0002_snapshot.json +673 -0
- package/dist/compliance/drizzle/migrations/meta/0003_snapshot.json +679 -0
- package/dist/compliance/drizzle/migrations/meta/0004_snapshot.json +679 -0
- package/dist/compliance/drizzle/migrations/meta/0005_snapshot.json +754 -0
- package/dist/compliance/drizzle/migrations/meta/0006_snapshot.json +754 -0
- package/dist/compliance/drizzle/migrations/meta/0007_snapshot.json +785 -0
- package/dist/compliance/drizzle/migrations/meta/0008_snapshot.json +870 -0
- package/dist/compliance/drizzle/migrations/meta/0009_snapshot.json +974 -0
- package/dist/compliance/drizzle/migrations/meta/_journal.json +56 -0
- package/dist/compliance/plugin.d.ts +188 -1
- package/dist/compliance/plugin.d.ts.map +1 -1
- package/dist/compliance/plugin.js +86 -14
- package/dist/compliance/plugin.js.map +1 -1
- package/dist/compliance/router/index.d.ts +928 -67
- package/dist/compliance/router/index.d.ts.map +1 -1
- package/dist/compliance/router/index.js +148 -25
- package/dist/compliance/router/index.js.map +1 -1
- package/dist/compliance/schema/index.d.ts +515 -6
- package/dist/compliance/schema/index.d.ts.map +1 -1
- package/dist/compliance/schema/index.js +68 -6
- package/dist/compliance/schema/index.js.map +1 -1
- package/dist/compliance/server.d.ts +1 -1
- package/dist/compliance/server.d.ts.map +1 -1
- package/dist/compliance/server.js +1 -1
- package/dist/compliance/server.js.map +1 -1
- package/dist/compliance/service/compliance.service.d.ts +121 -37
- package/dist/compliance/service/compliance.service.d.ts.map +1 -1
- package/dist/compliance/service/compliance.service.js +341 -55
- package/dist/compliance/service/compliance.service.js.map +1 -1
- package/dist/compliance/service/kyc.service.d.ts +228 -10
- package/dist/compliance/service/kyc.service.d.ts.map +1 -1
- package/dist/compliance/service/kyc.service.js +566 -62
- package/dist/compliance/service/kyc.service.js.map +1 -1
- package/dist/compliance/service/rg-eval.d.ts +7 -2
- package/dist/compliance/service/rg-eval.d.ts.map +1 -1
- package/dist/compliance/service/rg-eval.js +10 -2
- package/dist/compliance/service/rg-eval.js.map +1 -1
- package/dist/compliance/service/rg-monitoring.service.d.ts +24 -6
- package/dist/compliance/service/rg-monitoring.service.d.ts.map +1 -1
- package/dist/compliance/service/rg-monitoring.service.js +109 -20
- package/dist/compliance/service/rg-monitoring.service.js.map +1 -1
- package/dist/compliance/service/rg-self-service.service.d.ts +84 -0
- package/dist/compliance/service/rg-self-service.service.d.ts.map +1 -0
- package/dist/compliance/service/rg-self-service.service.js +449 -0
- package/dist/compliance/service/rg-self-service.service.js.map +1 -0
- package/dist/compliance/service/rg.service.d.ts +103 -15
- package/dist/compliance/service/rg.service.d.ts.map +1 -1
- package/dist/compliance/service/rg.service.js +325 -61
- package/dist/compliance/service/rg.service.js.map +1 -1
- package/dist/contracts/__tests__/compose-contract.test.d.ts +2 -0
- package/dist/contracts/__tests__/compose-contract.test.d.ts.map +1 -0
- package/dist/contracts/__tests__/compose-contract.test.js +27 -0
- package/dist/contracts/__tests__/compose-contract.test.js.map +1 -0
- package/dist/contracts/__tests__/identity.test.d.ts +2 -0
- package/dist/contracts/__tests__/identity.test.d.ts.map +1 -0
- package/dist/contracts/__tests__/identity.test.js +54 -0
- package/dist/contracts/__tests__/identity.test.js.map +1 -0
- package/dist/contracts/__tests__/kit.test.js +21 -1
- package/dist/contracts/__tests__/kit.test.js.map +1 -1
- package/dist/contracts/__tests__/player.test.d.ts +2 -0
- package/dist/contracts/__tests__/player.test.d.ts.map +1 -0
- package/dist/contracts/__tests__/player.test.js +51 -0
- package/dist/contracts/__tests__/player.test.js.map +1 -0
- package/dist/contracts/adapters/__tests__/geo-ip.test.d.ts +2 -0
- package/dist/contracts/adapters/__tests__/geo-ip.test.d.ts.map +1 -0
- package/dist/contracts/adapters/__tests__/geo-ip.test.js +13 -0
- package/dist/contracts/adapters/__tests__/geo-ip.test.js.map +1 -0
- package/dist/contracts/adapters/__tests__/lobby-section-catalog.test.d.ts +2 -0
- package/dist/contracts/adapters/__tests__/lobby-section-catalog.test.d.ts.map +1 -0
- package/dist/contracts/adapters/__tests__/lobby-section-catalog.test.js +25 -0
- package/dist/contracts/adapters/__tests__/lobby-section-catalog.test.js.map +1 -0
- package/dist/contracts/adapters/__tests__/rate-limit.test.d.ts +2 -0
- package/dist/contracts/adapters/__tests__/rate-limit.test.d.ts.map +1 -0
- package/dist/contracts/adapters/__tests__/rate-limit.test.js +13 -0
- package/dist/contracts/adapters/__tests__/rate-limit.test.js.map +1 -0
- package/dist/contracts/adapters/__tests__/token.test.d.ts +2 -0
- package/dist/contracts/adapters/__tests__/token.test.d.ts.map +1 -0
- package/dist/contracts/adapters/__tests__/token.test.js +14 -0
- package/dist/contracts/adapters/__tests__/token.test.js.map +1 -0
- package/dist/contracts/adapters/admin-game-reporting.d.ts +43 -0
- package/dist/contracts/adapters/admin-game-reporting.d.ts.map +1 -0
- package/dist/contracts/adapters/admin-game-reporting.js +17 -0
- package/dist/contracts/adapters/admin-game-reporting.js.map +1 -0
- package/dist/contracts/adapters/admin-permission.d.ts +11 -0
- package/dist/contracts/adapters/admin-permission.d.ts.map +1 -1
- package/dist/contracts/adapters/admin-permission.js +6 -4
- package/dist/contracts/adapters/admin-permission.js.map +1 -1
- package/dist/contracts/adapters/admin-player-activity.d.ts +51 -0
- package/dist/contracts/adapters/admin-player-activity.d.ts.map +1 -0
- package/dist/contracts/adapters/admin-player-activity.js +3 -0
- package/dist/contracts/adapters/admin-player-activity.js.map +1 -0
- package/dist/contracts/adapters/admin-role-assignment-directory.d.ts +12 -0
- package/dist/contracts/adapters/admin-role-assignment-directory.d.ts.map +1 -0
- package/dist/contracts/adapters/admin-role-assignment-directory.js +3 -0
- package/dist/contracts/adapters/admin-role-assignment-directory.js.map +1 -0
- package/dist/contracts/adapters/admin-security.d.ts +27 -0
- package/dist/contracts/adapters/admin-security.d.ts.map +1 -0
- package/dist/contracts/adapters/admin-security.js +9 -0
- package/dist/contracts/adapters/admin-security.js.map +1 -0
- package/dist/contracts/adapters/admin-user-directory.d.ts +52 -4
- package/dist/contracts/adapters/admin-user-directory.d.ts.map +1 -1
- package/dist/contracts/adapters/admin-user-directory.js +8 -0
- package/dist/contracts/adapters/admin-user-directory.js.map +1 -1
- package/dist/contracts/adapters/admin-wallet-reporting.d.ts +11 -0
- package/dist/contracts/adapters/admin-wallet-reporting.d.ts.map +1 -1
- package/dist/contracts/adapters/admin-wallet-reporting.js +9 -0
- package/dist/contracts/adapters/admin-wallet-reporting.js.map +1 -1
- package/dist/contracts/adapters/aggregator.d.ts +12 -0
- package/dist/contracts/adapters/aggregator.d.ts.map +1 -1
- package/dist/contracts/adapters/aggregator.js +5 -3
- package/dist/contracts/adapters/aggregator.js.map +1 -1
- package/dist/contracts/adapters/audit.d.ts +30 -4
- package/dist/contracts/adapters/audit.d.ts.map +1 -1
- package/dist/contracts/adapters/audit.js.map +1 -1
- package/dist/contracts/adapters/broker.d.ts +23 -0
- package/dist/contracts/adapters/broker.d.ts.map +1 -1
- package/dist/contracts/adapters/broker.js +8 -6
- package/dist/contracts/adapters/broker.js.map +1 -1
- package/dist/contracts/adapters/cache.d.ts +11 -0
- package/dist/contracts/adapters/cache.d.ts.map +1 -1
- package/dist/contracts/adapters/cache.js +8 -6
- package/dist/contracts/adapters/cache.js.map +1 -1
- package/dist/contracts/adapters/chat-block-writer.d.ts +18 -0
- package/dist/contracts/adapters/chat-block-writer.d.ts.map +1 -0
- package/dist/contracts/adapters/chat-block-writer.js +7 -0
- package/dist/contracts/adapters/chat-block-writer.js.map +1 -0
- package/dist/contracts/adapters/chat-moderation.d.ts +75 -0
- package/dist/contracts/adapters/chat-moderation.d.ts.map +1 -0
- package/dist/contracts/adapters/chat-moderation.js +3 -0
- package/dist/contracts/adapters/chat-moderation.js.map +1 -0
- package/dist/contracts/adapters/chat-room-access.d.ts +6 -0
- package/dist/contracts/adapters/chat-room-access.d.ts.map +1 -0
- package/dist/contracts/adapters/chat-room-access.js +3 -0
- package/dist/contracts/adapters/chat-room-access.js.map +1 -0
- package/dist/contracts/adapters/chat-system-writer.d.ts +19 -0
- package/dist/contracts/adapters/chat-system-writer.d.ts.map +1 -0
- package/dist/contracts/adapters/chat-system-writer.js +3 -0
- package/dist/contracts/adapters/chat-system-writer.js.map +1 -0
- package/dist/contracts/adapters/email-template.d.ts +12 -0
- package/dist/contracts/adapters/email-template.d.ts.map +1 -0
- package/dist/contracts/adapters/email-template.js +3 -0
- package/dist/contracts/adapters/email-template.js.map +1 -0
- package/dist/contracts/adapters/error-tracking.d.ts +12 -0
- package/dist/contracts/adapters/error-tracking.d.ts.map +1 -0
- package/dist/contracts/adapters/error-tracking.js +3 -0
- package/dist/contracts/adapters/error-tracking.js.map +1 -0
- package/dist/contracts/adapters/exchange-rate-provider.d.ts +14 -0
- package/dist/contracts/adapters/exchange-rate-provider.d.ts.map +1 -0
- package/dist/contracts/adapters/exchange-rate-provider.js +5 -0
- package/dist/contracts/adapters/exchange-rate-provider.js.map +1 -0
- package/dist/contracts/adapters/exchange-rate-reader.d.ts +16 -0
- package/dist/contracts/adapters/exchange-rate-reader.d.ts.map +1 -0
- package/dist/contracts/adapters/exchange-rate-reader.js +3 -0
- package/dist/contracts/adapters/exchange-rate-reader.js.map +1 -0
- package/dist/contracts/adapters/game-geo-check.d.ts +33 -0
- package/dist/contracts/adapters/game-geo-check.d.ts.map +1 -0
- package/dist/contracts/adapters/game-geo-check.js +23 -0
- package/dist/contracts/adapters/game-geo-check.js.map +1 -0
- package/dist/contracts/adapters/game.d.ts +13 -1
- package/dist/contracts/adapters/game.d.ts.map +1 -1
- package/dist/contracts/adapters/game.js +4 -2
- package/dist/contracts/adapters/game.js.map +1 -1
- package/dist/contracts/adapters/gaming-commands.d.ts +25 -0
- package/dist/contracts/adapters/gaming-commands.d.ts.map +1 -0
- package/dist/contracts/adapters/gaming-commands.js +8 -0
- package/dist/contracts/adapters/gaming-commands.js.map +1 -0
- package/dist/contracts/adapters/geo-check-commands.d.ts +8 -0
- package/dist/contracts/adapters/geo-check-commands.d.ts.map +1 -0
- package/dist/contracts/adapters/geo-check-commands.js +3 -0
- package/dist/contracts/adapters/geo-check-commands.js.map +1 -0
- package/dist/contracts/adapters/geo-ip.d.ts +2 -0
- package/dist/contracts/adapters/geo-ip.d.ts.map +1 -1
- package/dist/contracts/adapters/geo-ip.js +13 -2
- package/dist/contracts/adapters/geo-ip.js.map +1 -1
- package/dist/contracts/adapters/identity-reader.d.ts +20 -4
- package/dist/contracts/adapters/identity-reader.d.ts.map +1 -1
- package/dist/contracts/adapters/identity-reader.js.map +1 -1
- package/dist/contracts/adapters/identity.d.ts +15 -0
- package/dist/contracts/adapters/identity.d.ts.map +1 -1
- package/dist/contracts/adapters/identity.js +5 -2
- package/dist/contracts/adapters/identity.js.map +1 -1
- package/dist/contracts/adapters/index.d.ts +80 -22
- package/dist/contracts/adapters/index.d.ts.map +1 -1
- package/dist/contracts/adapters/index.js +42 -14
- package/dist/contracts/adapters/index.js.map +1 -1
- package/dist/contracts/adapters/job-queue.d.ts +55 -0
- package/dist/contracts/adapters/job-queue.d.ts.map +1 -1
- package/dist/contracts/adapters/job-queue.js +11 -9
- package/dist/contracts/adapters/job-queue.js.map +1 -1
- package/dist/contracts/adapters/kyc.d.ts +110 -11
- package/dist/contracts/adapters/kyc.d.ts.map +1 -1
- package/dist/contracts/adapters/kyc.js +23 -0
- package/dist/contracts/adapters/kyc.js.map +1 -1
- package/dist/contracts/adapters/lobby-section-catalog.d.ts +39 -0
- package/dist/contracts/adapters/lobby-section-catalog.d.ts.map +1 -0
- package/dist/contracts/adapters/lobby-section-catalog.js +34 -0
- package/dist/contracts/adapters/lobby-section-catalog.js.map +1 -0
- package/dist/contracts/adapters/login-enforcement.d.ts +8 -0
- package/dist/contracts/adapters/login-enforcement.d.ts.map +1 -1
- package/dist/contracts/adapters/login-enforcement.js +8 -6
- package/dist/contracts/adapters/login-enforcement.js.map +1 -1
- package/dist/contracts/adapters/mail-recipient-directory.d.ts +17 -0
- package/dist/contracts/adapters/mail-recipient-directory.d.ts.map +1 -0
- package/dist/contracts/adapters/mail-recipient-directory.js +3 -0
- package/dist/contracts/adapters/mail-recipient-directory.js.map +1 -0
- package/dist/contracts/adapters/mail.d.ts +30 -0
- package/dist/contracts/adapters/mail.d.ts.map +1 -0
- package/dist/contracts/adapters/mail.js +4 -0
- package/dist/contracts/adapters/mail.js.map +1 -0
- package/dist/contracts/adapters/outbox.d.ts +14 -0
- package/dist/contracts/adapters/outbox.d.ts.map +1 -1
- package/dist/contracts/adapters/outbox.js +14 -12
- package/dist/contracts/adapters/outbox.js.map +1 -1
- package/dist/contracts/adapters/payment.d.ts +141 -3
- package/dist/contracts/adapters/payment.d.ts.map +1 -1
- package/dist/contracts/adapters/payment.js +11 -3
- package/dist/contracts/adapters/payment.js.map +1 -1
- package/dist/contracts/adapters/play-eligibility.d.ts +15 -0
- package/dist/contracts/adapters/play-eligibility.d.ts.map +1 -0
- package/dist/contracts/adapters/play-eligibility.js +3 -0
- package/dist/contracts/adapters/play-eligibility.js.map +1 -0
- package/dist/contracts/adapters/player-activity.d.ts +6 -0
- package/dist/contracts/adapters/player-activity.d.ts.map +1 -0
- package/dist/contracts/adapters/player-activity.js +3 -0
- package/dist/contracts/adapters/player-activity.js.map +1 -0
- package/dist/contracts/adapters/player-provisioning.d.ts +29 -0
- package/dist/contracts/adapters/player-provisioning.d.ts.map +1 -0
- package/dist/contracts/adapters/player-provisioning.js +3 -0
- package/dist/contracts/adapters/player-provisioning.js.map +1 -0
- package/dist/contracts/adapters/player-tags.d.ts +4 -0
- package/dist/contracts/adapters/player-tags.d.ts.map +1 -1
- package/dist/contracts/adapters/player-tags.js.map +1 -1
- package/dist/contracts/adapters/rate-limit.d.ts +43 -3
- package/dist/contracts/adapters/rate-limit.d.ts.map +1 -1
- package/dist/contracts/adapters/rate-limit.js +31 -6
- package/dist/contracts/adapters/rate-limit.js.map +1 -1
- package/dist/contracts/adapters/realtime.d.ts +156 -7
- package/dist/contracts/adapters/realtime.d.ts.map +1 -1
- package/dist/contracts/adapters/realtime.js +33 -10
- package/dist/contracts/adapters/realtime.js.map +1 -1
- package/dist/contracts/adapters/rg-limits.d.ts +47 -0
- package/dist/contracts/adapters/rg-limits.d.ts.map +1 -0
- package/dist/contracts/adapters/rg-limits.js +18 -0
- package/dist/contracts/adapters/rg-limits.js.map +1 -0
- package/dist/contracts/adapters/rng.d.ts +11 -0
- package/dist/contracts/adapters/rng.d.ts.map +1 -1
- package/dist/contracts/adapters/rng.js +11 -9
- package/dist/contracts/adapters/rng.js.map +1 -1
- package/dist/contracts/adapters/session-idle-policy.d.ts +16 -0
- package/dist/contracts/adapters/session-idle-policy.d.ts.map +1 -0
- package/dist/contracts/adapters/session-idle-policy.js +13 -0
- package/dist/contracts/adapters/session-idle-policy.js.map +1 -0
- package/dist/contracts/adapters/sms.d.ts +15 -0
- package/dist/contracts/adapters/sms.d.ts.map +1 -0
- package/dist/contracts/adapters/sms.js +9 -0
- package/dist/contracts/adapters/sms.js.map +1 -0
- package/dist/contracts/adapters/social-commands.d.ts +12 -0
- package/dist/contracts/adapters/social-commands.d.ts.map +1 -0
- package/dist/contracts/adapters/social-commands.js +7 -0
- package/dist/contracts/adapters/social-commands.js.map +1 -0
- package/dist/contracts/adapters/swap.d.ts +80 -0
- package/dist/contracts/adapters/swap.d.ts.map +1 -0
- package/dist/contracts/adapters/swap.js +5 -0
- package/dist/contracts/adapters/swap.js.map +1 -0
- package/dist/contracts/adapters/tag-evaluation-commands.d.ts +20 -0
- package/dist/contracts/adapters/tag-evaluation-commands.d.ts.map +1 -0
- package/dist/contracts/adapters/tag-evaluation-commands.js +13 -0
- package/dist/contracts/adapters/tag-evaluation-commands.js.map +1 -0
- package/dist/contracts/adapters/token.d.ts +28 -5
- package/dist/contracts/adapters/token.d.ts.map +1 -1
- package/dist/contracts/adapters/token.js +10 -8
- package/dist/contracts/adapters/token.js.map +1 -1
- package/dist/contracts/adapters/wallet-asset-catalog.d.ts +34 -0
- package/dist/contracts/adapters/wallet-asset-catalog.d.ts.map +1 -0
- package/dist/contracts/adapters/wallet-asset-catalog.js +3 -0
- package/dist/contracts/adapters/wallet-asset-catalog.js.map +1 -0
- package/dist/contracts/adapters/wallet-commands.d.ts +25 -0
- package/dist/contracts/adapters/wallet-commands.d.ts.map +1 -1
- package/dist/contracts/adapters/wallet-commands.js.map +1 -1
- package/dist/contracts/adapters/wallet-reader.d.ts +43 -1
- package/dist/contracts/adapters/wallet-reader.d.ts.map +1 -1
- package/dist/contracts/adapters/wallet-reader.js.map +1 -1
- package/dist/contracts/kit.d.ts +18 -0
- package/dist/contracts/kit.d.ts.map +1 -1
- package/dist/contracts/kit.js +9 -0
- package/dist/contracts/kit.js.map +1 -1
- package/dist/contracts/schemas/__tests__/common-schemas.test.js +33 -4
- package/dist/contracts/schemas/__tests__/common-schemas.test.js.map +1 -1
- package/dist/contracts/schemas/__tests__/events.test.d.ts +2 -0
- package/dist/contracts/schemas/__tests__/events.test.d.ts.map +1 -0
- package/dist/contracts/schemas/__tests__/events.test.js +238 -0
- package/dist/contracts/schemas/__tests__/events.test.js.map +1 -0
- package/dist/contracts/schemas/__tests__/game-schemas.test.d.ts +2 -0
- package/dist/contracts/schemas/__tests__/game-schemas.test.d.ts.map +1 -0
- package/dist/contracts/schemas/__tests__/game-schemas.test.js +43 -0
- package/dist/contracts/schemas/__tests__/game-schemas.test.js.map +1 -0
- package/dist/contracts/schemas/__tests__/igaming-config.test.d.ts +2 -0
- package/dist/contracts/schemas/__tests__/igaming-config.test.d.ts.map +1 -0
- package/dist/contracts/schemas/__tests__/igaming-config.test.js +38 -0
- package/dist/contracts/schemas/__tests__/igaming-config.test.js.map +1 -0
- package/dist/contracts/schemas/__tests__/platform-config.test.d.ts +2 -0
- package/dist/contracts/schemas/__tests__/platform-config.test.d.ts.map +1 -0
- package/dist/contracts/schemas/__tests__/platform-config.test.js +16 -0
- package/dist/contracts/schemas/__tests__/platform-config.test.js.map +1 -0
- package/dist/contracts/schemas/__tests__/player-schemas.test.d.ts +2 -0
- package/dist/contracts/schemas/__tests__/player-schemas.test.d.ts.map +1 -0
- package/dist/contracts/schemas/__tests__/player-schemas.test.js +30 -0
- package/dist/contracts/schemas/__tests__/player-schemas.test.js.map +1 -0
- package/dist/contracts/schemas/__tests__/tag-schemas.test.d.ts +2 -0
- package/dist/contracts/schemas/__tests__/tag-schemas.test.d.ts.map +1 -0
- package/dist/contracts/schemas/__tests__/tag-schemas.test.js +42 -0
- package/dist/contracts/schemas/__tests__/tag-schemas.test.js.map +1 -0
- package/dist/contracts/schemas/chat-attachment.d.ts +20 -0
- package/dist/contracts/schemas/chat-attachment.d.ts.map +1 -0
- package/dist/contracts/schemas/chat-attachment.js +14 -0
- package/dist/contracts/schemas/chat-attachment.js.map +1 -0
- package/dist/contracts/schemas/chat-command-metadata.d.ts +73 -0
- package/dist/contracts/schemas/chat-command-metadata.d.ts.map +1 -0
- package/dist/contracts/schemas/chat-command-metadata.js +67 -0
- package/dist/contracts/schemas/chat-command-metadata.js.map +1 -0
- package/dist/contracts/schemas/chat-command.d.ts +224 -0
- package/dist/contracts/schemas/chat-command.d.ts.map +1 -0
- package/dist/contracts/schemas/chat-command.js +55 -0
- package/dist/contracts/schemas/chat-command.js.map +1 -0
- package/dist/contracts/schemas/common.d.ts +36 -0
- package/dist/contracts/schemas/common.d.ts.map +1 -1
- package/dist/contracts/schemas/common.js +67 -2
- package/dist/contracts/schemas/common.js.map +1 -1
- package/dist/contracts/schemas/compliance.d.ts +24 -1
- package/dist/contracts/schemas/compliance.d.ts.map +1 -1
- package/dist/contracts/schemas/compliance.js +13 -0
- package/dist/contracts/schemas/compliance.js.map +1 -1
- package/dist/contracts/schemas/display-currency.d.ts +14 -0
- package/dist/contracts/schemas/display-currency.d.ts.map +1 -0
- package/dist/contracts/schemas/display-currency.js +45 -0
- package/dist/contracts/schemas/display-currency.js.map +1 -0
- package/dist/contracts/schemas/events.d.ts +1158 -12
- package/dist/contracts/schemas/events.d.ts.map +1 -1
- package/dist/contracts/schemas/events.js +746 -70
- package/dist/contracts/schemas/events.js.map +1 -1
- package/dist/contracts/schemas/game.d.ts +48 -0
- package/dist/contracts/schemas/game.d.ts.map +1 -0
- package/dist/contracts/schemas/game.js +36 -0
- package/dist/contracts/schemas/game.js.map +1 -0
- package/dist/contracts/schemas/iam.d.ts +32 -0
- package/dist/contracts/schemas/iam.d.ts.map +1 -1
- package/dist/contracts/schemas/iam.js +35 -0
- package/dist/contracts/schemas/iam.js.map +1 -1
- package/dist/contracts/schemas/identity.d.ts +241 -4
- package/dist/contracts/schemas/identity.d.ts.map +1 -1
- package/dist/contracts/schemas/identity.js +226 -8
- package/dist/contracts/schemas/identity.js.map +1 -1
- package/dist/contracts/schemas/igaming-config.d.ts +31 -1
- package/dist/contracts/schemas/igaming-config.d.ts.map +1 -1
- package/dist/contracts/schemas/igaming-config.js +9 -1
- package/dist/contracts/schemas/igaming-config.js.map +1 -1
- package/dist/contracts/schemas/index.d.ts +8 -0
- package/dist/contracts/schemas/index.d.ts.map +1 -1
- package/dist/contracts/schemas/index.js +8 -0
- package/dist/contracts/schemas/index.js.map +1 -1
- package/dist/contracts/schemas/lobby.d.ts +27 -0
- package/dist/contracts/schemas/lobby.d.ts.map +1 -0
- package/dist/contracts/schemas/lobby.js +22 -0
- package/dist/contracts/schemas/lobby.js.map +1 -0
- package/dist/contracts/schemas/mail.d.ts +196 -0
- package/dist/contracts/schemas/mail.d.ts.map +1 -0
- package/dist/contracts/schemas/mail.js +83 -0
- package/dist/contracts/schemas/mail.js.map +1 -0
- package/dist/contracts/schemas/platform-config.d.ts +211 -32
- package/dist/contracts/schemas/platform-config.d.ts.map +1 -1
- package/dist/contracts/schemas/platform-config.js +239 -7
- package/dist/contracts/schemas/platform-config.js.map +1 -1
- package/dist/contracts/schemas/player.d.ts +96 -4
- package/dist/contracts/schemas/player.d.ts.map +1 -1
- package/dist/contracts/schemas/player.js +83 -9
- package/dist/contracts/schemas/player.js.map +1 -1
- package/dist/contracts/schemas/reporting.d.ts +20 -0
- package/dist/contracts/schemas/reporting.d.ts.map +1 -0
- package/dist/contracts/schemas/reporting.js +13 -0
- package/dist/contracts/schemas/reporting.js.map +1 -0
- package/dist/contracts/schemas/tag.d.ts +86 -2
- package/dist/contracts/schemas/tag.d.ts.map +1 -1
- package/dist/contracts/schemas/tag.js +13 -1
- package/dist/contracts/schemas/tag.js.map +1 -1
- package/dist/contracts/schemas/wallet-tx.d.ts +50 -3
- package/dist/contracts/schemas/wallet-tx.d.ts.map +1 -1
- package/dist/contracts/schemas/wallet-tx.js +50 -3
- package/dist/contracts/schemas/wallet-tx.js.map +1 -1
- package/dist/engagement/chat/__tests__/chat-moderation-expiry.int.test.d.ts +2 -0
- package/dist/engagement/chat/__tests__/chat-moderation-expiry.int.test.d.ts.map +1 -0
- package/dist/engagement/chat/__tests__/chat-moderation-expiry.int.test.js +155 -0
- package/dist/engagement/chat/__tests__/chat-moderation-expiry.int.test.js.map +1 -0
- package/dist/engagement/chat/__tests__/chat-mute-listing.int.test.d.ts +2 -0
- package/dist/engagement/chat/__tests__/chat-mute-listing.int.test.d.ts.map +1 -0
- package/dist/engagement/chat/__tests__/chat-mute-listing.int.test.js +81 -0
- package/dist/engagement/chat/__tests__/chat-mute-listing.int.test.js.map +1 -0
- package/dist/engagement/chat/__tests__/chat.router.test.d.ts +2 -0
- package/dist/engagement/chat/__tests__/chat.router.test.d.ts.map +1 -0
- package/dist/engagement/chat/__tests__/chat.router.test.js +44 -0
- package/dist/engagement/chat/__tests__/chat.router.test.js.map +1 -0
- package/dist/engagement/chat/__tests__/chat.service.int.test.d.ts +2 -0
- package/dist/engagement/chat/__tests__/chat.service.int.test.d.ts.map +1 -0
- package/dist/engagement/chat/__tests__/chat.service.int.test.js +2349 -0
- package/dist/engagement/chat/__tests__/chat.service.int.test.js.map +1 -0
- package/dist/engagement/chat/__tests__/contract.test.d.ts +2 -0
- package/dist/engagement/chat/__tests__/contract.test.d.ts.map +1 -0
- package/dist/engagement/chat/__tests__/contract.test.js +44 -0
- package/dist/engagement/chat/__tests__/contract.test.js.map +1 -0
- package/dist/engagement/chat/__tests__/global-chat-room.int.test.d.ts +2 -0
- package/dist/engagement/chat/__tests__/global-chat-room.int.test.d.ts.map +1 -0
- package/dist/engagement/chat/__tests__/global-chat-room.int.test.js +100 -0
- package/dist/engagement/chat/__tests__/global-chat-room.int.test.js.map +1 -0
- package/dist/engagement/chat/__tests__/moderation.test.js +2 -0
- package/dist/engagement/chat/__tests__/moderation.test.js.map +1 -1
- package/dist/engagement/chat/__tests__/room-ownership-handover.int.test.d.ts +2 -0
- package/dist/engagement/chat/__tests__/room-ownership-handover.int.test.d.ts.map +1 -0
- package/dist/engagement/chat/__tests__/room-ownership-handover.int.test.js +736 -0
- package/dist/engagement/chat/__tests__/room-ownership-handover.int.test.js.map +1 -0
- package/dist/engagement/chat/__tests__/validate-attachment.test.d.ts +2 -0
- package/dist/engagement/chat/__tests__/validate-attachment.test.d.ts.map +1 -0
- package/dist/engagement/chat/__tests__/validate-attachment.test.js +38 -0
- package/dist/engagement/chat/__tests__/validate-attachment.test.js.map +1 -0
- package/dist/engagement/chat/contract/constants.d.ts +15 -0
- package/dist/engagement/chat/contract/constants.d.ts.map +1 -0
- package/dist/engagement/chat/contract/constants.js +20 -0
- package/dist/engagement/chat/contract/constants.js.map +1 -0
- package/dist/engagement/chat/contract/index.d.ts +2190 -16
- package/dist/engagement/chat/contract/index.d.ts.map +1 -1
- package/dist/engagement/chat/contract/index.js +457 -12
- package/dist/engagement/chat/contract/index.js.map +1 -1
- package/dist/engagement/chat/drizzle/migrations/0001_cloudy_groot.sql +32 -0
- package/dist/engagement/chat/drizzle/migrations/0002_steep_zodiak.sql +3 -0
- package/dist/engagement/chat/drizzle/migrations/0003_stormy_king_bedlam.sql +9 -0
- package/dist/engagement/chat/drizzle/migrations/0004_panoramic_robin_chapel.sql +6 -0
- package/dist/engagement/chat/drizzle/migrations/0005_tranquil_gwen_stacy.sql +100 -0
- package/dist/engagement/chat/drizzle/migrations/0006_tiny_ultron.sql +3 -0
- package/dist/engagement/chat/drizzle/migrations/0007_seed_global_chat_room.sql +8 -0
- package/dist/engagement/chat/drizzle/migrations/0008_robust_korvac.sql +1 -0
- package/dist/engagement/chat/drizzle/migrations/0009_massive_bill_hollister.sql +1 -0
- package/dist/engagement/chat/drizzle/migrations/0010_backfill_role_assigned_at.sql +9 -0
- package/dist/engagement/chat/drizzle/migrations/0011_light_changeling.sql +1 -0
- package/dist/engagement/chat/drizzle/migrations/0012_strange_mephisto.sql +3 -0
- package/dist/engagement/chat/drizzle/migrations/0013_chilly_sprite.sql +6 -0
- package/dist/engagement/chat/drizzle/migrations/0014_chat_moderation_expiry_recorded.sql +19 -0
- package/dist/engagement/chat/drizzle/migrations/meta/0001_snapshot.json +557 -0
- package/dist/engagement/chat/drizzle/migrations/meta/0002_snapshot.json +576 -0
- package/dist/engagement/chat/drizzle/migrations/meta/0003_snapshot.json +652 -0
- package/dist/engagement/chat/drizzle/migrations/meta/0004_snapshot.json +666 -0
- package/dist/engagement/chat/drizzle/migrations/meta/0005_snapshot.json +1422 -0
- package/dist/engagement/chat/drizzle/migrations/meta/0006_snapshot.json +1456 -0
- package/dist/engagement/chat/drizzle/migrations/meta/0007_snapshot.json +1456 -0
- package/dist/engagement/chat/drizzle/migrations/meta/0008_snapshot.json +1462 -0
- package/dist/engagement/chat/drizzle/migrations/meta/0009_snapshot.json +1468 -0
- package/dist/engagement/chat/drizzle/migrations/meta/0010_snapshot.json +1468 -0
- package/dist/engagement/chat/drizzle/migrations/meta/0011_snapshot.json +1489 -0
- package/dist/engagement/chat/drizzle/migrations/meta/0012_snapshot.json +1517 -0
- package/dist/engagement/chat/drizzle/migrations/meta/0013_snapshot.json +1517 -0
- package/dist/engagement/chat/drizzle/migrations/meta/0014_snapshot.json +1544 -0
- package/dist/engagement/chat/drizzle/migrations/meta/_journal.json +98 -0
- package/dist/engagement/chat/index.d.ts +1 -2
- package/dist/engagement/chat/index.d.ts.map +1 -1
- package/dist/engagement/chat/index.js +1 -2
- package/dist/engagement/chat/index.js.map +1 -1
- package/dist/engagement/chat/moderation/index.d.ts +1 -0
- package/dist/engagement/chat/moderation/index.d.ts.map +1 -1
- package/dist/engagement/chat/moderation/index.js +1 -0
- package/dist/engagement/chat/moderation/index.js.map +1 -1
- package/dist/engagement/chat/moderation/profanity.d.ts.map +1 -1
- package/dist/engagement/chat/moderation/profanity.js +2 -0
- package/dist/engagement/chat/moderation/profanity.js.map +1 -1
- package/dist/engagement/chat/moderation/validate-attachment.d.ts +9 -0
- package/dist/engagement/chat/moderation/validate-attachment.d.ts.map +1 -0
- package/dist/engagement/chat/moderation/validate-attachment.js +27 -0
- package/dist/engagement/chat/moderation/validate-attachment.js.map +1 -0
- package/dist/engagement/chat/plugin.d.ts +187 -1
- package/dist/engagement/chat/plugin.d.ts.map +1 -1
- package/dist/engagement/chat/plugin.js +211 -5
- package/dist/engagement/chat/plugin.js.map +1 -1
- package/dist/engagement/chat/router/index.d.ts +1662 -16
- package/dist/engagement/chat/router/index.d.ts.map +1 -1
- package/dist/engagement/chat/router/index.js +302 -27
- package/dist/engagement/chat/router/index.js.map +1 -1
- package/dist/engagement/chat/schema/index.d.ts +1621 -0
- package/dist/engagement/chat/schema/index.d.ts.map +1 -1
- package/dist/engagement/chat/schema/index.js +192 -4
- package/dist/engagement/chat/schema/index.js.map +1 -1
- package/dist/engagement/chat/service/chat-ban.service.d.ts +26 -0
- package/dist/engagement/chat/service/chat-ban.service.d.ts.map +1 -0
- package/dist/engagement/chat/service/chat-ban.service.js +144 -0
- package/dist/engagement/chat/service/chat-ban.service.js.map +1 -0
- package/dist/engagement/chat/service/chat-message-moderation.service.d.ts +14 -0
- package/dist/engagement/chat/service/chat-message-moderation.service.d.ts.map +1 -0
- package/dist/engagement/chat/service/chat-message-moderation.service.js +48 -0
- package/dist/engagement/chat/service/chat-message-moderation.service.js.map +1 -0
- package/dist/engagement/chat/service/chat-moderation-expiry.service.d.ts +22 -0
- package/dist/engagement/chat/service/chat-moderation-expiry.service.d.ts.map +1 -0
- package/dist/engagement/chat/service/chat-moderation-expiry.service.js +80 -0
- package/dist/engagement/chat/service/chat-moderation-expiry.service.js.map +1 -0
- package/dist/engagement/chat/service/chat-moderation.service.d.ts +30 -0
- package/dist/engagement/chat/service/chat-moderation.service.d.ts.map +1 -0
- package/dist/engagement/chat/service/chat-moderation.service.js +40 -0
- package/dist/engagement/chat/service/chat-moderation.service.js.map +1 -0
- package/dist/engagement/chat/service/chat-mute.service.d.ts +26 -0
- package/dist/engagement/chat/service/chat-mute.service.d.ts.map +1 -0
- package/dist/engagement/chat/service/chat-mute.service.js +159 -0
- package/dist/engagement/chat/service/chat-mute.service.js.map +1 -0
- package/dist/engagement/chat/service/chat-room-ban.service.d.ts +29 -0
- package/dist/engagement/chat/service/chat-room-ban.service.d.ts.map +1 -0
- package/dist/engagement/chat/service/chat-room-ban.service.js +107 -0
- package/dist/engagement/chat/service/chat-room-ban.service.js.map +1 -0
- package/dist/engagement/chat/service/chat-room-membership.service.d.ts +107 -0
- package/dist/engagement/chat/service/chat-room-membership.service.d.ts.map +1 -0
- package/dist/engagement/chat/service/chat-room-membership.service.js +536 -0
- package/dist/engagement/chat/service/chat-room-membership.service.js.map +1 -0
- package/dist/engagement/chat/service/chat-room-mute.service.d.ts +25 -0
- package/dist/engagement/chat/service/chat-room-mute.service.d.ts.map +1 -0
- package/dist/engagement/chat/service/chat-room-mute.service.js +89 -0
- package/dist/engagement/chat/service/chat-room-mute.service.js.map +1 -0
- package/dist/engagement/chat/service/chat-room-purge.service.d.ts +13 -0
- package/dist/engagement/chat/service/chat-room-purge.service.d.ts.map +1 -0
- package/dist/engagement/chat/service/chat-room-purge.service.js +75 -0
- package/dist/engagement/chat/service/chat-room-purge.service.js.map +1 -0
- package/dist/engagement/chat/service/chat.service.d.ts +1144 -35
- package/dist/engagement/chat/service/chat.service.d.ts.map +1 -1
- package/dist/engagement/chat/service/chat.service.js +1243 -70
- package/dist/engagement/chat/service/chat.service.js.map +1 -1
- package/dist/engagement/chat/service/errors/chat-moderation.errors.d.ts +42 -0
- package/dist/engagement/chat/service/errors/chat-moderation.errors.d.ts.map +1 -0
- package/dist/engagement/chat/service/errors/chat-moderation.errors.js +32 -0
- package/dist/engagement/chat/service/errors/chat-moderation.errors.js.map +1 -0
- package/dist/engagement/chat-commands/__tests__/migration-upgrade.int.test.d.ts +2 -0
- package/dist/engagement/chat-commands/__tests__/migration-upgrade.int.test.d.ts.map +1 -0
- package/dist/engagement/chat-commands/__tests__/migration-upgrade.int.test.js +98 -0
- package/dist/engagement/chat-commands/__tests__/migration-upgrade.int.test.js.map +1 -0
- package/dist/engagement/chat-commands/contract/index.d.ts +201 -0
- package/dist/engagement/chat-commands/contract/index.d.ts.map +1 -0
- package/dist/engagement/chat-commands/contract/index.js +70 -0
- package/dist/engagement/chat-commands/contract/index.js.map +1 -0
- package/dist/engagement/chat-commands/drizzle/migrations/0000_daffy_lady_bullseye.sql +24 -0
- package/dist/engagement/chat-commands/drizzle/migrations/0001_sturdy_barracuda.sql +1 -0
- package/dist/engagement/chat-commands/drizzle/migrations/0002_single_currency_command_limits.sql +45 -0
- package/dist/engagement/chat-commands/drizzle/migrations/meta/0000_snapshot.json +164 -0
- package/dist/engagement/chat-commands/drizzle/migrations/meta/0001_snapshot.json +83 -0
- package/dist/engagement/chat-commands/drizzle/migrations/meta/0002_snapshot.json +83 -0
- package/dist/engagement/chat-commands/drizzle/migrations/meta/_journal.json +27 -0
- package/dist/engagement/chat-commands/drizzle.config.d.ts +4 -0
- package/dist/engagement/chat-commands/drizzle.config.d.ts.map +1 -0
- package/dist/engagement/chat-commands/drizzle.config.js +21 -0
- package/dist/engagement/chat-commands/drizzle.config.js.map +1 -0
- package/dist/engagement/chat-commands/migrate.d.ts +2 -0
- package/dist/engagement/chat-commands/migrate.d.ts.map +1 -0
- package/dist/engagement/chat-commands/migrate.js +20 -0
- package/dist/engagement/chat-commands/migrate.js.map +1 -0
- package/dist/engagement/chat-commands/plugin.d.ts +188 -0
- package/dist/engagement/chat-commands/plugin.d.ts.map +1 -0
- package/dist/engagement/chat-commands/plugin.js +15 -0
- package/dist/engagement/chat-commands/plugin.js.map +1 -0
- package/dist/engagement/chat-commands/router/index.d.ts +137 -0
- package/dist/engagement/chat-commands/router/index.d.ts.map +1 -0
- package/dist/engagement/chat-commands/router/index.js +24 -0
- package/dist/engagement/chat-commands/router/index.js.map +1 -0
- package/dist/engagement/chat-commands/schema/index.d.ts +140 -0
- package/dist/engagement/chat-commands/schema/index.d.ts.map +1 -0
- package/dist/engagement/chat-commands/schema/index.js +13 -0
- package/dist/engagement/chat-commands/schema/index.js.map +1 -0
- package/dist/engagement/chat-commands/seed/index.d.ts +3 -0
- package/dist/engagement/chat-commands/seed/index.d.ts.map +1 -0
- package/dist/engagement/chat-commands/seed/index.js +66 -0
- package/dist/engagement/chat-commands/seed/index.js.map +1 -0
- package/dist/engagement/chat-commands/service/__tests__/chat-commands.service.test.d.ts +2 -0
- package/dist/engagement/chat-commands/service/__tests__/chat-commands.service.test.d.ts.map +1 -0
- package/dist/engagement/chat-commands/service/__tests__/chat-commands.service.test.js +157 -0
- package/dist/engagement/chat-commands/service/__tests__/chat-commands.service.test.js.map +1 -0
- package/dist/engagement/chat-commands/service/chat-commands.service.d.ts +60 -0
- package/dist/engagement/chat-commands/service/chat-commands.service.d.ts.map +1 -0
- package/dist/engagement/chat-commands/service/chat-commands.service.js +147 -0
- package/dist/engagement/chat-commands/service/chat-commands.service.js.map +1 -0
- package/dist/engagement/contracts.d.ts +2 -0
- package/dist/engagement/contracts.d.ts.map +1 -1
- package/dist/engagement/contracts.js +2 -0
- package/dist/engagement/contracts.js.map +1 -1
- package/dist/engagement/index.d.ts +2 -0
- package/dist/engagement/index.d.ts.map +1 -1
- package/dist/engagement/index.js +2 -0
- package/dist/engagement/index.js.map +1 -1
- package/dist/engagement/notifications/__tests__/chat-room-notifications.int.test.d.ts +2 -0
- package/dist/engagement/notifications/__tests__/chat-room-notifications.int.test.d.ts.map +1 -0
- package/dist/engagement/notifications/__tests__/chat-room-notifications.int.test.js +184 -0
- package/dist/engagement/notifications/__tests__/chat-room-notifications.int.test.js.map +1 -0
- package/dist/engagement/notifications/__tests__/notification-event-map.test.d.ts +2 -0
- package/dist/engagement/notifications/__tests__/notification-event-map.test.d.ts.map +1 -0
- package/dist/engagement/notifications/__tests__/notification-event-map.test.js +319 -0
- package/dist/engagement/notifications/__tests__/notification-event-map.test.js.map +1 -0
- package/dist/engagement/notifications/__tests__/notifications.router.int.test.d.ts +2 -0
- package/dist/engagement/notifications/__tests__/notifications.router.int.test.d.ts.map +1 -0
- package/dist/engagement/notifications/__tests__/notifications.router.int.test.js +148 -0
- package/dist/engagement/notifications/__tests__/notifications.router.int.test.js.map +1 -0
- package/dist/engagement/notifications/__tests__/notifications.service.int.test.d.ts +2 -0
- package/dist/engagement/notifications/__tests__/notifications.service.int.test.d.ts.map +1 -0
- package/dist/engagement/notifications/__tests__/notifications.service.int.test.js +298 -0
- package/dist/engagement/notifications/__tests__/notifications.service.int.test.js.map +1 -0
- package/dist/engagement/notifications/contract/index.d.ts +126 -13
- package/dist/engagement/notifications/contract/index.d.ts.map +1 -1
- package/dist/engagement/notifications/contract/index.js +46 -5
- package/dist/engagement/notifications/contract/index.js.map +1 -1
- package/dist/engagement/notifications/drizzle/migrations/0001_classy_pixie.sql +1 -0
- package/dist/engagement/notifications/drizzle/migrations/0002_open_madame_web.sql +2 -0
- package/dist/engagement/notifications/drizzle/migrations/meta/0001_snapshot.json +98 -0
- package/dist/engagement/notifications/drizzle/migrations/meta/0002_snapshot.json +119 -0
- package/dist/engagement/notifications/drizzle/migrations/meta/_journal.json +14 -0
- package/dist/engagement/notifications/plugin.d.ts +204 -1
- package/dist/engagement/notifications/plugin.d.ts.map +1 -1
- package/dist/engagement/notifications/plugin.js +431 -47
- package/dist/engagement/notifications/plugin.js.map +1 -1
- package/dist/engagement/notifications/react/notifications.d.ts +20 -0
- package/dist/engagement/notifications/react/notifications.d.ts.map +1 -0
- package/dist/engagement/notifications/react/notifications.js +39 -0
- package/dist/engagement/notifications/react/notifications.js.map +1 -0
- package/dist/engagement/notifications/router/index.d.ts +74 -13
- package/dist/engagement/notifications/router/index.d.ts.map +1 -1
- package/dist/engagement/notifications/router/index.js +37 -16
- package/dist/engagement/notifications/router/index.js.map +1 -1
- package/dist/engagement/notifications/schema/index.d.ts +36 -0
- package/dist/engagement/notifications/schema/index.d.ts.map +1 -1
- package/dist/engagement/notifications/schema/index.js +7 -2
- package/dist/engagement/notifications/schema/index.js.map +1 -1
- package/dist/engagement/notifications/service/notifications.service.d.ts +33 -21
- package/dist/engagement/notifications/service/notifications.service.d.ts.map +1 -1
- package/dist/engagement/notifications/service/notifications.service.js +41 -11
- package/dist/engagement/notifications/service/notifications.service.js.map +1 -1
- package/dist/engagement/react.d.ts +1 -1
- package/dist/engagement/react.d.ts.map +1 -1
- package/dist/engagement/react.js +2 -2
- package/dist/engagement/react.js.map +1 -1
- package/dist/engagement/server.d.ts +2 -0
- package/dist/engagement/server.d.ts.map +1 -1
- package/dist/engagement/server.js +2 -0
- package/dist/engagement/server.js.map +1 -1
- package/dist/engagement/social/__tests__/social.plugin.int.test.d.ts +2 -0
- package/dist/engagement/social/__tests__/social.plugin.int.test.d.ts.map +1 -0
- package/dist/engagement/social/__tests__/social.plugin.int.test.js +100 -0
- package/dist/engagement/social/__tests__/social.plugin.int.test.js.map +1 -0
- package/dist/engagement/social/__tests__/social.router.int.test.d.ts +2 -0
- package/dist/engagement/social/__tests__/social.router.int.test.d.ts.map +1 -0
- package/dist/engagement/social/__tests__/social.router.int.test.js +215 -0
- package/dist/engagement/social/__tests__/social.router.int.test.js.map +1 -0
- package/dist/engagement/social/__tests__/social.service.int.test.d.ts +2 -0
- package/dist/engagement/social/__tests__/social.service.int.test.d.ts.map +1 -0
- package/dist/engagement/social/__tests__/social.service.int.test.js +810 -0
- package/dist/engagement/social/__tests__/social.service.int.test.js.map +1 -0
- package/dist/engagement/social/contract/index.d.ts +187 -0
- package/dist/engagement/social/contract/index.d.ts.map +1 -0
- package/dist/engagement/social/contract/index.js +107 -0
- package/dist/engagement/social/contract/index.js.map +1 -0
- package/dist/engagement/social/drizzle/migrations/0000_fine_jamie_braddock.sql +24 -0
- package/dist/engagement/social/drizzle/migrations/0001_lame_eddie_brock.sql +10 -0
- package/dist/engagement/social/drizzle/migrations/0002_foamy_saracen.sql +1 -0
- package/dist/engagement/social/drizzle/migrations/0003_fuzzy_shadow_king.sql +4 -0
- package/dist/engagement/social/drizzle/migrations/0004_friendship-cancel-constraint.sql +2 -0
- package/dist/engagement/social/drizzle/migrations/meta/0000_snapshot.json +232 -0
- package/dist/engagement/social/drizzle/migrations/meta/0001_snapshot.json +129 -0
- package/dist/engagement/social/drizzle/migrations/meta/0002_snapshot.json +134 -0
- package/dist/engagement/social/drizzle/migrations/meta/0003_snapshot.json +145 -0
- package/dist/engagement/social/drizzle/migrations/meta/0004_snapshot.json +145 -0
- package/dist/engagement/social/drizzle/migrations/meta/_journal.json +41 -0
- package/dist/engagement/social/drizzle.config.d.ts +4 -0
- package/dist/engagement/social/drizzle.config.d.ts.map +1 -0
- package/dist/engagement/social/drizzle.config.js +21 -0
- package/dist/engagement/social/drizzle.config.js.map +1 -0
- package/dist/engagement/social/index.d.ts +3 -0
- package/dist/engagement/social/index.d.ts.map +1 -0
- package/dist/engagement/social/index.js +6 -0
- package/dist/engagement/social/index.js.map +1 -0
- package/dist/engagement/social/migrate.d.ts +5 -0
- package/dist/engagement/social/migrate.d.ts.map +1 -0
- package/dist/engagement/social/migrate.js +17 -0
- package/dist/engagement/social/migrate.js.map +1 -0
- package/dist/engagement/social/plugin.d.ts +188 -0
- package/dist/engagement/social/plugin.d.ts.map +1 -0
- package/dist/engagement/social/plugin.js +17 -0
- package/dist/engagement/social/plugin.js.map +1 -0
- package/dist/engagement/social/router/index.d.ts +98 -0
- package/dist/engagement/social/router/index.d.ts.map +1 -0
- package/dist/engagement/social/router/index.js +68 -0
- package/dist/engagement/social/router/index.js.map +1 -0
- package/dist/engagement/social/schema/index.d.ts +145 -0
- package/dist/engagement/social/schema/index.d.ts.map +1 -0
- package/dist/engagement/social/schema/index.js +24 -0
- package/dist/engagement/social/schema/index.js.map +1 -0
- package/dist/engagement/social/service/social.service.d.ts +73 -0
- package/dist/engagement/social/service/social.service.d.ts.map +1 -0
- package/dist/engagement/social/service/social.service.js +479 -0
- package/dist/engagement/social/service/social.service.js.map +1 -0
- package/dist/fx/contracts.d.ts +2 -0
- package/dist/fx/contracts.d.ts.map +1 -0
- package/dist/fx/contracts.js +2 -0
- package/dist/fx/contracts.js.map +1 -0
- package/dist/fx/exchange-rate/__tests__/exchange-rate-reader.service.int.test.d.ts +2 -0
- package/dist/fx/exchange-rate/__tests__/exchange-rate-reader.service.int.test.d.ts.map +1 -0
- package/dist/fx/exchange-rate/__tests__/exchange-rate-reader.service.int.test.js +236 -0
- package/dist/fx/exchange-rate/__tests__/exchange-rate-reader.service.int.test.js.map +1 -0
- package/dist/fx/exchange-rate/__tests__/select-provider.test.d.ts +2 -0
- package/dist/fx/exchange-rate/__tests__/select-provider.test.d.ts.map +1 -0
- package/dist/fx/exchange-rate/__tests__/select-provider.test.js +26 -0
- package/dist/fx/exchange-rate/__tests__/select-provider.test.js.map +1 -0
- package/dist/fx/exchange-rate/adapters/exchange-rate-reader.service.d.ts +59 -0
- package/dist/fx/exchange-rate/adapters/exchange-rate-reader.service.d.ts.map +1 -0
- package/dist/fx/exchange-rate/adapters/exchange-rate-reader.service.js +212 -0
- package/dist/fx/exchange-rate/adapters/exchange-rate-reader.service.js.map +1 -0
- package/dist/fx/exchange-rate/contract/index.d.ts +44 -0
- package/dist/fx/exchange-rate/contract/index.d.ts.map +1 -0
- package/dist/fx/exchange-rate/contract/index.js +30 -0
- package/dist/fx/exchange-rate/contract/index.js.map +1 -0
- package/dist/fx/exchange-rate/drizzle/migrations/0000_hot_trauma.sql +10 -0
- package/dist/fx/exchange-rate/drizzle/migrations/meta/0000_snapshot.json +92 -0
- package/dist/fx/exchange-rate/drizzle/migrations/meta/_journal.json +13 -0
- package/dist/fx/exchange-rate/drizzle.config.d.ts +4 -0
- package/dist/fx/exchange-rate/drizzle.config.d.ts.map +1 -0
- package/dist/fx/exchange-rate/drizzle.config.js +18 -0
- package/dist/fx/exchange-rate/drizzle.config.js.map +1 -0
- package/dist/fx/exchange-rate/index.d.ts +3 -0
- package/dist/fx/exchange-rate/index.d.ts.map +1 -0
- package/dist/fx/exchange-rate/index.js +3 -0
- package/dist/fx/exchange-rate/index.js.map +1 -0
- package/dist/fx/exchange-rate/migrate.d.ts +5 -0
- package/dist/fx/exchange-rate/migrate.d.ts.map +1 -0
- package/dist/fx/exchange-rate/migrate.js +14 -0
- package/dist/fx/exchange-rate/migrate.js.map +1 -0
- package/dist/fx/exchange-rate/plugin.d.ts +187 -0
- package/dist/fx/exchange-rate/plugin.d.ts.map +1 -0
- package/dist/fx/exchange-rate/plugin.js +42 -0
- package/dist/fx/exchange-rate/plugin.js.map +1 -0
- package/dist/fx/exchange-rate/react/exchange-rate.d.ts +12 -0
- package/dist/fx/exchange-rate/react/exchange-rate.d.ts.map +1 -0
- package/dist/fx/exchange-rate/react/exchange-rate.js +17 -0
- package/dist/fx/exchange-rate/react/exchange-rate.js.map +1 -0
- package/dist/fx/exchange-rate/router/index.d.ts +22 -0
- package/dist/fx/exchange-rate/router/index.d.ts.map +1 -0
- package/dist/fx/exchange-rate/router/index.js +18 -0
- package/dist/fx/exchange-rate/router/index.js.map +1 -0
- package/dist/fx/exchange-rate/schema/index.d.ts +116 -0
- package/dist/fx/exchange-rate/schema/index.d.ts.map +1 -0
- package/dist/fx/exchange-rate/schema/index.js +18 -0
- package/dist/fx/exchange-rate/schema/index.js.map +1 -0
- package/dist/fx/exchange-rate/service/exchange-rate.service.d.ts +22 -0
- package/dist/fx/exchange-rate/service/exchange-rate.service.d.ts.map +1 -0
- package/dist/fx/exchange-rate/service/exchange-rate.service.js +38 -0
- package/dist/fx/exchange-rate/service/exchange-rate.service.js.map +1 -0
- package/dist/fx/index.d.ts +2 -0
- package/dist/fx/index.d.ts.map +1 -0
- package/dist/fx/index.js +2 -0
- package/dist/fx/index.js.map +1 -0
- package/dist/fx/react.d.ts +2 -0
- package/dist/fx/react.d.ts.map +1 -0
- package/dist/fx/react.js +2 -0
- package/dist/fx/react.js.map +1 -0
- package/dist/fx/server.d.ts +2 -0
- package/dist/fx/server.d.ts.map +1 -0
- package/dist/fx/server.js +2 -0
- package/dist/fx/server.js.map +1 -0
- package/dist/iam/__tests__/admin-player-activity.int.test.d.ts +2 -0
- package/dist/iam/__tests__/admin-player-activity.int.test.d.ts.map +1 -0
- package/dist/iam/__tests__/admin-player-activity.int.test.js +119 -0
- package/dist/iam/__tests__/admin-player-activity.int.test.js.map +1 -0
- package/dist/iam/__tests__/iam.service.int.test.d.ts +2 -0
- package/dist/iam/__tests__/iam.service.int.test.d.ts.map +1 -0
- package/dist/iam/__tests__/iam.service.int.test.js +580 -0
- package/dist/iam/__tests__/iam.service.int.test.js.map +1 -0
- package/dist/iam/adapters/admin-player-activity.d.ts +10 -0
- package/dist/iam/adapters/admin-player-activity.d.ts.map +1 -0
- package/dist/iam/adapters/admin-player-activity.js +106 -0
- package/dist/iam/adapters/admin-player-activity.js.map +1 -0
- package/dist/iam/adapters/admin-role-assignment-directory.d.ts +8 -0
- package/dist/iam/adapters/admin-role-assignment-directory.d.ts.map +1 -0
- package/dist/iam/adapters/admin-role-assignment-directory.js +23 -0
- package/dist/iam/adapters/admin-role-assignment-directory.js.map +1 -0
- package/dist/iam/contract/index.d.ts +58 -0
- package/dist/iam/contract/index.d.ts.map +1 -1
- package/dist/iam/contract/index.js +30 -4
- package/dist/iam/contract/index.js.map +1 -1
- package/dist/iam/plugin.d.ts +187 -1
- package/dist/iam/plugin.d.ts.map +1 -1
- package/dist/iam/plugin.js +10 -5
- package/dist/iam/plugin.js.map +1 -1
- package/dist/iam/router/index.d.ts +37 -0
- package/dist/iam/router/index.d.ts.map +1 -1
- package/dist/iam/router/index.js +7 -1
- package/dist/iam/router/index.js.map +1 -1
- package/dist/iam/seed/data/default-admin-roles.d.ts.map +1 -1
- package/dist/iam/seed/data/default-admin-roles.js +6 -0
- package/dist/iam/seed/data/default-admin-roles.js.map +1 -1
- package/dist/iam/service/iam.service.d.ts +55 -26
- package/dist/iam/service/iam.service.d.ts.map +1 -1
- package/dist/iam/service/iam.service.js +122 -17
- package/dist/iam/service/iam.service.js.map +1 -1
- package/dist/mail/__tests__/default-email-template-renderer.test.d.ts +2 -0
- package/dist/mail/__tests__/default-email-template-renderer.test.d.ts.map +1 -0
- package/dist/mail/__tests__/default-email-template-renderer.test.js +131 -0
- package/dist/mail/__tests__/default-email-template-renderer.test.js.map +1 -0
- package/dist/mail/__tests__/mail.service.test.d.ts +2 -0
- package/dist/mail/__tests__/mail.service.test.d.ts.map +1 -0
- package/dist/mail/__tests__/mail.service.test.js +248 -0
- package/dist/mail/__tests__/mail.service.test.js.map +1 -0
- package/dist/mail/adapters/default-email-template-renderer.d.ts +5 -0
- package/dist/mail/adapters/default-email-template-renderer.d.ts.map +1 -0
- package/dist/mail/adapters/default-email-template-renderer.js +125 -0
- package/dist/mail/adapters/default-email-template-renderer.js.map +1 -0
- package/dist/mail/adapters/stdout-email-sender.d.ts +5 -0
- package/dist/mail/adapters/stdout-email-sender.d.ts.map +1 -0
- package/dist/mail/adapters/stdout-email-sender.js +8 -0
- package/dist/mail/adapters/stdout-email-sender.js.map +1 -0
- package/dist/mail/contract/index.d.ts +138 -0
- package/dist/mail/contract/index.d.ts.map +1 -0
- package/dist/mail/contract/index.js +17 -0
- package/dist/mail/contract/index.js.map +1 -0
- package/dist/mail/index.d.ts +5 -0
- package/dist/mail/index.d.ts.map +1 -0
- package/dist/mail/index.js +5 -0
- package/dist/mail/index.js.map +1 -0
- package/dist/mail/plugin.d.ts +187 -0
- package/dist/mail/plugin.d.ts.map +1 -0
- package/dist/mail/plugin.js +66 -0
- package/dist/mail/plugin.js.map +1 -0
- package/dist/mail/service/mail-payload.service.d.ts +8 -0
- package/dist/mail/service/mail-payload.service.d.ts.map +1 -0
- package/dist/mail/service/mail-payload.service.js +43 -0
- package/dist/mail/service/mail-payload.service.js.map +1 -0
- package/dist/mail/service/mail.service.d.ts +30 -0
- package/dist/mail/service/mail.service.d.ts.map +1 -0
- package/dist/mail/service/mail.service.js +160 -0
- package/dist/mail/service/mail.service.js.map +1 -0
- package/dist/pam/identity/__tests__/admin-security.int.test.d.ts +2 -0
- package/dist/pam/identity/__tests__/admin-security.int.test.d.ts.map +1 -0
- package/dist/pam/identity/__tests__/admin-security.int.test.js +153 -0
- package/dist/pam/identity/__tests__/admin-security.int.test.js.map +1 -0
- package/dist/pam/identity/__tests__/admin-user-directory.int.test.d.ts +2 -0
- package/dist/pam/identity/__tests__/admin-user-directory.int.test.d.ts.map +1 -0
- package/dist/pam/identity/__tests__/admin-user-directory.int.test.js +234 -0
- package/dist/pam/identity/__tests__/admin-user-directory.int.test.js.map +1 -0
- package/dist/pam/identity/__tests__/device-fingerprint.test.d.ts +2 -0
- package/dist/pam/identity/__tests__/device-fingerprint.test.d.ts.map +1 -0
- package/dist/pam/identity/__tests__/device-fingerprint.test.js +105 -0
- package/dist/pam/identity/__tests__/device-fingerprint.test.js.map +1 -0
- package/dist/pam/identity/__tests__/identity.rate-limit.int.test.d.ts +2 -0
- package/dist/pam/identity/__tests__/identity.rate-limit.int.test.d.ts.map +1 -0
- package/dist/pam/identity/__tests__/identity.rate-limit.int.test.js +198 -0
- package/dist/pam/identity/__tests__/identity.rate-limit.int.test.js.map +1 -0
- package/dist/pam/identity/__tests__/identity.registration-gates.int.test.d.ts +2 -0
- package/dist/pam/identity/__tests__/identity.registration-gates.int.test.d.ts.map +1 -0
- package/dist/pam/identity/__tests__/identity.registration-gates.int.test.js +119 -0
- package/dist/pam/identity/__tests__/identity.registration-gates.int.test.js.map +1 -0
- package/dist/pam/identity/__tests__/identity.service.int.test.d.ts +2 -0
- package/dist/pam/identity/__tests__/identity.service.int.test.d.ts.map +1 -0
- package/dist/pam/identity/__tests__/identity.service.int.test.js +1179 -0
- package/dist/pam/identity/__tests__/identity.service.int.test.js.map +1 -0
- package/dist/pam/identity/__tests__/login-enforcement.service.int.test.d.ts +2 -0
- package/dist/pam/identity/__tests__/login-enforcement.service.int.test.d.ts.map +1 -0
- package/dist/pam/identity/__tests__/login-enforcement.service.int.test.js +99 -0
- package/dist/pam/identity/__tests__/login-enforcement.service.int.test.js.map +1 -0
- package/dist/pam/identity/__tests__/phone-login.service.int.test.d.ts +2 -0
- package/dist/pam/identity/__tests__/phone-login.service.int.test.d.ts.map +1 -0
- package/dist/pam/identity/__tests__/phone-login.service.int.test.js +394 -0
- package/dist/pam/identity/__tests__/phone-login.service.int.test.js.map +1 -0
- package/dist/pam/identity/__tests__/phone-verification.service.int.test.d.ts +2 -0
- package/dist/pam/identity/__tests__/phone-verification.service.int.test.d.ts.map +1 -0
- package/dist/pam/identity/__tests__/phone-verification.service.int.test.js +274 -0
- package/dist/pam/identity/__tests__/phone-verification.service.int.test.js.map +1 -0
- package/dist/pam/identity/__tests__/play-eligibility.test.d.ts +2 -0
- package/dist/pam/identity/__tests__/play-eligibility.test.d.ts.map +1 -0
- package/dist/pam/identity/__tests__/play-eligibility.test.js +30 -0
- package/dist/pam/identity/__tests__/play-eligibility.test.js.map +1 -0
- package/dist/pam/identity/__tests__/rg-guard.test.d.ts +2 -0
- package/dist/pam/identity/__tests__/rg-guard.test.d.ts.map +1 -0
- package/dist/pam/identity/__tests__/rg-guard.test.js +21 -0
- package/dist/pam/identity/__tests__/rg-guard.test.js.map +1 -0
- package/dist/pam/identity/__tests__/session-idle.service.int.test.d.ts +2 -0
- package/dist/pam/identity/__tests__/session-idle.service.int.test.d.ts.map +1 -0
- package/dist/pam/identity/__tests__/session-idle.service.int.test.js +137 -0
- package/dist/pam/identity/__tests__/session-idle.service.int.test.js.map +1 -0
- package/dist/pam/identity/__tests__/session.service.int.test.d.ts +2 -0
- package/dist/pam/identity/__tests__/session.service.int.test.d.ts.map +1 -0
- package/dist/pam/identity/__tests__/session.service.int.test.js +127 -0
- package/dist/pam/identity/__tests__/session.service.int.test.js.map +1 -0
- package/dist/pam/identity/__tests__/two-factor-delivery.test.d.ts +2 -0
- package/dist/pam/identity/__tests__/two-factor-delivery.test.d.ts.map +1 -0
- package/dist/pam/identity/__tests__/two-factor-delivery.test.js +23 -0
- package/dist/pam/identity/__tests__/two-factor-delivery.test.js.map +1 -0
- package/dist/pam/identity/__tests__/user-commands.int.test.d.ts +2 -0
- package/dist/pam/identity/__tests__/user-commands.int.test.d.ts.map +1 -0
- package/dist/pam/identity/__tests__/user-commands.int.test.js +33 -0
- package/dist/pam/identity/__tests__/user-commands.int.test.js.map +1 -0
- package/dist/pam/identity/__tests__/username-backfill.int.test.d.ts +2 -0
- package/dist/pam/identity/__tests__/username-backfill.int.test.d.ts.map +1 -0
- package/dist/pam/identity/__tests__/username-backfill.int.test.js +103 -0
- package/dist/pam/identity/__tests__/username-backfill.int.test.js.map +1 -0
- package/dist/pam/identity/__tests__/withdrawal-pin.service.int.test.d.ts +2 -0
- package/dist/pam/identity/__tests__/withdrawal-pin.service.int.test.d.ts.map +1 -0
- package/dist/pam/identity/__tests__/withdrawal-pin.service.int.test.js +172 -0
- package/dist/pam/identity/__tests__/withdrawal-pin.service.int.test.js.map +1 -0
- package/dist/pam/identity/adapters/identity-reader.service.d.ts +9 -4
- package/dist/pam/identity/adapters/identity-reader.service.d.ts.map +1 -1
- package/dist/pam/identity/adapters/identity-reader.service.js +61 -2
- package/dist/pam/identity/adapters/identity-reader.service.js.map +1 -1
- package/dist/pam/identity/adapters/mock/mock-kyc-adapter.d.ts +3 -3
- package/dist/pam/identity/adapters/mock/mock-kyc-adapter.d.ts.map +1 -1
- package/dist/pam/identity/adapters/mock/mock-kyc-adapter.js +3 -3
- package/dist/pam/identity/adapters/mock/mock-kyc-adapter.js.map +1 -1
- package/dist/pam/identity/adapters/mock/mock-sms-adapter.d.ts +8 -0
- package/dist/pam/identity/adapters/mock/mock-sms-adapter.d.ts.map +1 -0
- package/dist/pam/identity/adapters/mock/mock-sms-adapter.js +7 -0
- package/dist/pam/identity/adapters/mock/mock-sms-adapter.js.map +1 -0
- package/dist/pam/identity/admin-user-directory.d.ts +50 -8
- package/dist/pam/identity/admin-user-directory.d.ts.map +1 -1
- package/dist/pam/identity/admin-user-directory.js +111 -35
- package/dist/pam/identity/admin-user-directory.js.map +1 -1
- package/dist/pam/identity/contract/index.d.ts +518 -16
- package/dist/pam/identity/contract/index.d.ts.map +1 -1
- package/dist/pam/identity/contract/index.js +210 -8
- package/dist/pam/identity/contract/index.js.map +1 -1
- package/dist/pam/identity/drizzle/migrations/0001_rainy_peter_quill.sql +18 -0
- package/dist/pam/identity/drizzle/migrations/0002_outstanding_patriot.sql +1 -0
- package/dist/pam/identity/drizzle/migrations/0003_open_shotgun.sql +1 -0
- package/dist/pam/identity/drizzle/migrations/0004_round_giant_girl.sql +1 -0
- package/dist/pam/identity/drizzle/migrations/0005_daily_black_tom.sql +1 -0
- package/dist/pam/identity/drizzle/migrations/0006_brave_sabra.sql +1 -0
- package/dist/pam/identity/drizzle/migrations/0007_fuzzy_barracuda.sql +44 -0
- package/dist/pam/identity/drizzle/migrations/0008_pink_bucky.sql +23 -0
- package/dist/pam/identity/drizzle/migrations/0009_hard_sauron.sql +2 -0
- package/dist/pam/identity/drizzle/migrations/0010_lying_young_avengers.sql +19 -0
- package/dist/pam/identity/drizzle/migrations/0011_useful_the_executioner.sql +2 -0
- package/dist/pam/identity/drizzle/migrations/0012_worried_nuke.sql +2 -0
- package/dist/pam/identity/drizzle/migrations/0013_backfill_two_factor_method.sql +6 -0
- package/dist/pam/identity/drizzle/migrations/0014_spicy_mephistopheles.sql +1 -0
- package/dist/pam/identity/drizzle/migrations/0015_parallel_moira_mactaggert.sql +3 -0
- package/dist/pam/identity/drizzle/migrations/meta/0001_snapshot.json +684 -0
- package/dist/pam/identity/drizzle/migrations/meta/0002_snapshot.json +690 -0
- package/dist/pam/identity/drizzle/migrations/meta/0003_snapshot.json +695 -0
- package/dist/pam/identity/drizzle/migrations/meta/0004_snapshot.json +680 -0
- package/dist/pam/identity/drizzle/migrations/meta/0005_snapshot.json +695 -0
- package/dist/pam/identity/drizzle/migrations/meta/0006_snapshot.json +701 -0
- package/dist/pam/identity/drizzle/migrations/meta/0007_snapshot.json +737 -0
- package/dist/pam/identity/drizzle/migrations/meta/0008_snapshot.json +913 -0
- package/dist/pam/identity/drizzle/migrations/meta/0009_snapshot.json +926 -0
- package/dist/pam/identity/drizzle/migrations/meta/0010_snapshot.json +1066 -0
- package/dist/pam/identity/drizzle/migrations/meta/0011_snapshot.json +1078 -0
- package/dist/pam/identity/drizzle/migrations/meta/0012_snapshot.json +1090 -0
- package/dist/pam/identity/drizzle/migrations/meta/0013_snapshot.json +1090 -0
- package/dist/pam/identity/drizzle/migrations/meta/0014_snapshot.json +1096 -0
- package/dist/pam/identity/drizzle/migrations/meta/0015_snapshot.json +1116 -0
- package/dist/pam/identity/drizzle/migrations/meta/_journal.json +105 -0
- package/dist/pam/identity/plugin.d.ts +187 -1
- package/dist/pam/identity/plugin.d.ts.map +1 -1
- package/dist/pam/identity/plugin.js +185 -20
- package/dist/pam/identity/plugin.js.map +1 -1
- package/dist/pam/identity/react/account.d.ts +89 -13
- package/dist/pam/identity/react/account.d.ts.map +1 -1
- package/dist/pam/identity/react/account.js +100 -6
- package/dist/pam/identity/react/account.js.map +1 -1
- package/dist/pam/identity/react/auth.d.ts +23 -13
- package/dist/pam/identity/react/auth.d.ts.map +1 -1
- package/dist/pam/identity/router/index.d.ts +482 -18
- package/dist/pam/identity/router/index.d.ts.map +1 -1
- package/dist/pam/identity/router/index.js +168 -19
- package/dist/pam/identity/router/index.js.map +1 -1
- package/dist/pam/identity/schema/index.d.ts +1083 -224
- package/dist/pam/identity/schema/index.d.ts.map +1 -1
- package/dist/pam/identity/schema/index.js +119 -3
- package/dist/pam/identity/schema/index.js.map +1 -1
- package/dist/pam/identity/service/admin-security.service.d.ts +84 -0
- package/dist/pam/identity/service/admin-security.service.d.ts.map +1 -0
- package/dist/pam/identity/service/admin-security.service.js +284 -0
- package/dist/pam/identity/service/admin-security.service.js.map +1 -0
- package/dist/pam/identity/service/capture-timezone.service.d.ts +10 -0
- package/dist/pam/identity/service/capture-timezone.service.d.ts.map +1 -0
- package/dist/pam/identity/service/capture-timezone.service.js +21 -0
- package/dist/pam/identity/service/capture-timezone.service.js.map +1 -0
- package/dist/pam/identity/service/device-fingerprint.service.d.ts +32 -0
- package/dist/pam/identity/service/device-fingerprint.service.d.ts.map +1 -0
- package/dist/pam/identity/service/device-fingerprint.service.js +79 -0
- package/dist/pam/identity/service/device-fingerprint.service.js.map +1 -0
- package/dist/pam/identity/service/fresh-reauthentication.service.d.ts +21 -0
- package/dist/pam/identity/service/fresh-reauthentication.service.d.ts.map +1 -0
- package/dist/pam/identity/service/fresh-reauthentication.service.js +45 -0
- package/dist/pam/identity/service/fresh-reauthentication.service.js.map +1 -0
- package/dist/pam/identity/service/identity.service.d.ts +236 -41
- package/dist/pam/identity/service/identity.service.d.ts.map +1 -1
- package/dist/pam/identity/service/identity.service.js +1656 -147
- package/dist/pam/identity/service/identity.service.js.map +1 -1
- package/dist/pam/identity/service/lockout-policy.service.d.ts +30 -0
- package/dist/pam/identity/service/lockout-policy.service.d.ts.map +1 -0
- package/dist/pam/identity/service/lockout-policy.service.js +40 -0
- package/dist/pam/identity/service/lockout-policy.service.js.map +1 -0
- package/dist/pam/identity/service/phone-login.service.d.ts +65 -0
- package/dist/pam/identity/service/phone-login.service.d.ts.map +1 -0
- package/dist/pam/identity/service/phone-login.service.js +393 -0
- package/dist/pam/identity/service/phone-login.service.js.map +1 -0
- package/dist/pam/identity/service/phone-verification.service.d.ts +39 -0
- package/dist/pam/identity/service/phone-verification.service.d.ts.map +1 -0
- package/dist/pam/identity/service/phone-verification.service.js +223 -0
- package/dist/pam/identity/service/phone-verification.service.js.map +1 -0
- package/dist/pam/identity/service/play-eligibility.service.d.ts +8 -0
- package/dist/pam/identity/service/play-eligibility.service.d.ts.map +1 -0
- package/dist/pam/identity/service/play-eligibility.service.js +21 -0
- package/dist/pam/identity/service/play-eligibility.service.js.map +1 -0
- package/dist/pam/identity/service/rg-guard.service.d.ts +37 -0
- package/dist/pam/identity/service/rg-guard.service.d.ts.map +1 -0
- package/dist/pam/identity/service/rg-guard.service.js +60 -0
- package/dist/pam/identity/service/rg-guard.service.js.map +1 -0
- package/dist/pam/identity/service/security-controls.service.d.ts +4 -0
- package/dist/pam/identity/service/security-controls.service.d.ts.map +1 -0
- package/dist/pam/identity/service/security-controls.service.js +38 -0
- package/dist/pam/identity/service/security-controls.service.js.map +1 -0
- package/dist/pam/identity/service/session-idle.service.d.ts +22 -0
- package/dist/pam/identity/service/session-idle.service.d.ts.map +1 -0
- package/dist/pam/identity/service/session-idle.service.js +101 -0
- package/dist/pam/identity/service/session-idle.service.js.map +1 -0
- package/dist/pam/identity/service/session.service.d.ts +63 -6
- package/dist/pam/identity/service/session.service.d.ts.map +1 -1
- package/dist/pam/identity/service/session.service.js +137 -23
- package/dist/pam/identity/service/session.service.js.map +1 -1
- package/dist/pam/identity/service/trusted-device.service.d.ts +57 -0
- package/dist/pam/identity/service/trusted-device.service.d.ts.map +1 -0
- package/dist/pam/identity/service/trusted-device.service.js +163 -0
- package/dist/pam/identity/service/trusted-device.service.js.map +1 -0
- package/dist/pam/identity/service/two-factor-challenge.service.d.ts +36 -0
- package/dist/pam/identity/service/two-factor-challenge.service.d.ts.map +1 -0
- package/dist/pam/identity/service/two-factor-challenge.service.js +30 -0
- package/dist/pam/identity/service/two-factor-challenge.service.js.map +1 -0
- package/dist/pam/identity/service/two-factor-delivery.service.d.ts +67 -0
- package/dist/pam/identity/service/two-factor-delivery.service.d.ts.map +1 -0
- package/dist/pam/identity/service/two-factor-delivery.service.js +135 -0
- package/dist/pam/identity/service/two-factor-delivery.service.js.map +1 -0
- package/dist/pam/identity/service/two-factor-lockout.service.d.ts +25 -0
- package/dist/pam/identity/service/two-factor-lockout.service.d.ts.map +1 -0
- package/dist/pam/identity/service/two-factor-lockout.service.js +121 -0
- package/dist/pam/identity/service/two-factor-lockout.service.js.map +1 -0
- package/dist/pam/identity/service/user-commands.service.d.ts +11 -0
- package/dist/pam/identity/service/user-commands.service.d.ts.map +1 -0
- package/dist/pam/identity/service/user-commands.service.js +32 -0
- package/dist/pam/identity/service/user-commands.service.js.map +1 -0
- package/dist/pam/identity/service/withdrawal-pin-hash.service.d.ts +3 -0
- package/dist/pam/identity/service/withdrawal-pin-hash.service.d.ts.map +1 -0
- package/dist/pam/identity/service/withdrawal-pin-hash.service.js +10 -0
- package/dist/pam/identity/service/withdrawal-pin-hash.service.js.map +1 -0
- package/dist/pam/identity/service/withdrawal-pin.service.d.ts +36 -0
- package/dist/pam/identity/service/withdrawal-pin.service.d.ts.map +1 -0
- package/dist/pam/identity/service/withdrawal-pin.service.js +132 -0
- package/dist/pam/identity/service/withdrawal-pin.service.js.map +1 -0
- package/dist/pam/player-management/__tests__/kyc-status-writer.int.test.d.ts +2 -0
- package/dist/pam/player-management/__tests__/kyc-status-writer.int.test.d.ts.map +1 -0
- package/dist/pam/player-management/__tests__/kyc-status-writer.int.test.js +81 -0
- package/dist/pam/player-management/__tests__/kyc-status-writer.int.test.js.map +1 -0
- package/dist/pam/player-management/__tests__/player.router.int.test.d.ts +2 -0
- package/dist/pam/player-management/__tests__/player.router.int.test.d.ts.map +1 -0
- package/dist/pam/player-management/__tests__/player.router.int.test.js +107 -0
- package/dist/pam/player-management/__tests__/player.router.int.test.js.map +1 -0
- package/dist/pam/player-management/__tests__/player.service.int.test.d.ts +2 -0
- package/dist/pam/player-management/__tests__/player.service.int.test.d.ts.map +1 -0
- package/dist/pam/player-management/__tests__/player.service.int.test.js +479 -0
- package/dist/pam/player-management/__tests__/player.service.int.test.js.map +1 -0
- package/dist/pam/player-management/contract/index.d.ts +125 -15
- package/dist/pam/player-management/contract/index.d.ts.map +1 -1
- package/dist/pam/player-management/contract/index.js +35 -5
- package/dist/pam/player-management/contract/index.js.map +1 -1
- package/dist/pam/player-management/plugin.d.ts +186 -1
- package/dist/pam/player-management/plugin.d.ts.map +1 -1
- package/dist/pam/player-management/plugin.js +11 -8
- package/dist/pam/player-management/plugin.js.map +1 -1
- package/dist/pam/player-management/router/index.d.ts +95 -15
- package/dist/pam/player-management/router/index.d.ts.map +1 -1
- package/dist/pam/player-management/router/index.js +54 -17
- package/dist/pam/player-management/router/index.js.map +1 -1
- package/dist/pam/player-management/service/kyc-status-writer.d.ts +5 -7
- package/dist/pam/player-management/service/kyc-status-writer.d.ts.map +1 -1
- package/dist/pam/player-management/service/kyc-status-writer.js +23 -19
- package/dist/pam/player-management/service/kyc-status-writer.js.map +1 -1
- package/dist/pam/player-management/service/player.service.d.ts +65 -22
- package/dist/pam/player-management/service/player.service.d.ts.map +1 -1
- package/dist/pam/player-management/service/player.service.js +148 -43
- package/dist/pam/player-management/service/player.service.js.map +1 -1
- package/dist/pam/player-note/__tests__/player-note.router.int.test.d.ts +2 -0
- package/dist/pam/player-note/__tests__/player-note.router.int.test.d.ts.map +1 -0
- package/dist/pam/player-note/__tests__/player-note.router.int.test.js +52 -0
- package/dist/pam/player-note/__tests__/player-note.router.int.test.js.map +1 -0
- package/dist/pam/player-note/contract/index.d.ts +14 -0
- package/dist/pam/player-note/contract/index.d.ts.map +1 -1
- package/dist/pam/player-note/contract/index.js +8 -2
- package/dist/pam/player-note/contract/index.js.map +1 -1
- package/dist/pam/player-note/plugin.d.ts +186 -1
- package/dist/pam/player-note/plugin.d.ts.map +1 -1
- package/dist/pam/player-note/plugin.js +6 -4
- package/dist/pam/player-note/plugin.js.map +1 -1
- package/dist/pam/player-note/router/index.d.ts +10 -1
- package/dist/pam/player-note/router/index.d.ts.map +1 -1
- package/dist/pam/player-note/router/index.js +20 -3
- package/dist/pam/player-note/router/index.js.map +1 -1
- package/dist/pam/player-note/service/player-note.service.d.ts +5 -3
- package/dist/pam/player-note/service/player-note.service.d.ts.map +1 -1
- package/dist/pam/player-note/service/player-note.service.js +5 -3
- package/dist/pam/player-note/service/player-note.service.js.map +1 -1
- package/dist/pam/profile/__tests__/profile.service.int.test.d.ts +2 -0
- package/dist/pam/profile/__tests__/profile.service.int.test.d.ts.map +1 -0
- package/dist/pam/profile/__tests__/profile.service.int.test.js +296 -0
- package/dist/pam/profile/__tests__/profile.service.int.test.js.map +1 -0
- package/dist/pam/profile/contract/index.d.ts +74 -36
- package/dist/pam/profile/contract/index.d.ts.map +1 -1
- package/dist/pam/profile/contract/index.js +16 -1
- package/dist/pam/profile/contract/index.js.map +1 -1
- package/dist/pam/profile/drizzle/migrations/0001_powerful_tiger_shark.sql +1 -0
- package/dist/pam/profile/drizzle/migrations/0002_sour_alex_wilder.sql +7 -0
- package/dist/pam/profile/drizzle/migrations/0003_absurd_morbius.sql +4 -0
- package/dist/pam/profile/drizzle/migrations/0004_fuzzy_korvac.sql +1 -0
- package/dist/pam/profile/drizzle/migrations/0005_moaning_rachel_grey.sql +2 -0
- package/dist/pam/profile/drizzle/migrations/meta/0001_snapshot.json +191 -0
- package/dist/pam/profile/drizzle/migrations/meta/0002_snapshot.json +200 -0
- package/dist/pam/profile/drizzle/migrations/meta/0003_snapshot.json +224 -0
- package/dist/pam/profile/drizzle/migrations/meta/0004_snapshot.json +230 -0
- package/dist/pam/profile/drizzle/migrations/meta/0005_snapshot.json +242 -0
- package/dist/pam/profile/drizzle/migrations/meta/_journal.json +35 -0
- package/dist/pam/profile/migrate.d.ts.map +1 -1
- package/dist/pam/profile/migrate.js +3 -1
- package/dist/pam/profile/migrate.js.map +1 -1
- package/dist/pam/profile/plugin.d.ts +186 -1
- package/dist/pam/profile/plugin.d.ts.map +1 -1
- package/dist/pam/profile/plugin.js +8 -4
- package/dist/pam/profile/plugin.js.map +1 -1
- package/dist/pam/profile/react/profile.d.ts +34 -6
- package/dist/pam/profile/react/profile.d.ts.map +1 -1
- package/dist/pam/profile/react/profile.js +12 -0
- package/dist/pam/profile/react/profile.js.map +1 -1
- package/dist/pam/profile/router/index.d.ts +32 -4
- package/dist/pam/profile/router/index.d.ts.map +1 -1
- package/dist/pam/profile/router/index.js +4 -1
- package/dist/pam/profile/router/index.js.map +1 -1
- package/dist/pam/profile/schema/index.d.ts +193 -6
- package/dist/pam/profile/schema/index.d.ts.map +1 -1
- package/dist/pam/profile/schema/index.js +22 -10
- package/dist/pam/profile/schema/index.js.map +1 -1
- package/dist/pam/profile/service/profile.service.d.ts +55 -8
- package/dist/pam/profile/service/profile.service.d.ts.map +1 -1
- package/dist/pam/profile/service/profile.service.js +128 -23
- package/dist/pam/profile/service/profile.service.js.map +1 -1
- package/dist/pam/react.d.ts +2 -2
- package/dist/pam/react.d.ts.map +1 -1
- package/dist/pam/react.js +2 -2
- package/dist/pam/react.js.map +1 -1
- package/dist/pam/shared/__tests__/shared-mappers.test.d.ts +2 -0
- package/dist/pam/shared/__tests__/shared-mappers.test.d.ts.map +1 -0
- package/dist/pam/shared/__tests__/shared-mappers.test.js +61 -0
- package/dist/pam/shared/__tests__/shared-mappers.test.js.map +1 -0
- package/dist/pam/shared/language.d.ts +3 -1
- package/dist/pam/shared/language.d.ts.map +1 -1
- package/dist/pam/shared/language.js +6 -0
- package/dist/pam/shared/language.js.map +1 -1
- package/dist/pam/shared/otp.d.ts +3 -0
- package/dist/pam/shared/otp.d.ts.map +1 -0
- package/dist/pam/shared/otp.js +11 -0
- package/dist/pam/shared/otp.js.map +1 -0
- package/dist/pam/shared/player-mapper.d.ts +14 -4
- package/dist/pam/shared/player-mapper.d.ts.map +1 -1
- package/dist/pam/shared/player-mapper.js +14 -5
- package/dist/pam/shared/player-mapper.js.map +1 -1
- package/dist/pam/tag/__tests__/get-active-tag-keys.int.test.d.ts +2 -0
- package/dist/pam/tag/__tests__/get-active-tag-keys.int.test.d.ts.map +1 -0
- package/dist/pam/tag/__tests__/get-active-tag-keys.int.test.js +77 -0
- package/dist/pam/tag/__tests__/get-active-tag-keys.int.test.js.map +1 -0
- package/dist/pam/tag/__tests__/tag-evaluation.service.int.test.d.ts +2 -0
- package/dist/pam/tag/__tests__/tag-evaluation.service.int.test.d.ts.map +1 -0
- package/dist/pam/tag/__tests__/tag-evaluation.service.int.test.js +1024 -0
- package/dist/pam/tag/__tests__/tag-evaluation.service.int.test.js.map +1 -0
- package/dist/pam/tag/__tests__/tag-mappers.test.js +25 -0
- package/dist/pam/tag/__tests__/tag-mappers.test.js.map +1 -1
- package/dist/pam/tag/__tests__/tag-rule.service.int.test.d.ts +2 -0
- package/dist/pam/tag/__tests__/tag-rule.service.int.test.d.ts.map +1 -0
- package/dist/pam/tag/__tests__/tag-rule.service.int.test.js +145 -0
- package/dist/pam/tag/__tests__/tag-rule.service.int.test.js.map +1 -0
- package/dist/pam/tag/__tests__/tag.router.int.test.d.ts +2 -0
- package/dist/pam/tag/__tests__/tag.router.int.test.d.ts.map +1 -0
- package/dist/pam/tag/__tests__/tag.router.int.test.js +222 -0
- package/dist/pam/tag/__tests__/tag.router.int.test.js.map +1 -0
- package/dist/pam/tag/__tests__/tag.service.int.test.d.ts +2 -0
- package/dist/pam/tag/__tests__/tag.service.int.test.d.ts.map +1 -0
- package/dist/pam/tag/__tests__/tag.service.int.test.js +571 -0
- package/dist/pam/tag/__tests__/tag.service.int.test.js.map +1 -0
- package/dist/pam/tag/contract/index.d.ts +139 -1
- package/dist/pam/tag/contract/index.d.ts.map +1 -1
- package/dist/pam/tag/contract/index.js +12 -2
- package/dist/pam/tag/contract/index.js.map +1 -1
- package/dist/pam/tag/contract/player-tag-assign-metadata.d.ts +37 -0
- package/dist/pam/tag/contract/player-tag-assign-metadata.d.ts.map +1 -0
- package/dist/pam/tag/contract/player-tag-assign-metadata.js +20 -0
- package/dist/pam/tag/contract/player-tag-assign-metadata.js.map +1 -0
- package/dist/pam/tag/drizzle/migrations/0002_silent_skaar.sql +4 -0
- package/dist/pam/tag/drizzle/migrations/0003_overconfident_guardian.sql +3 -0
- package/dist/pam/tag/drizzle/migrations/0004_curvy_wither.sql +2 -0
- package/dist/pam/tag/drizzle/migrations/meta/0002_snapshot.json +335 -0
- package/dist/pam/tag/drizzle/migrations/meta/0003_snapshot.json +343 -0
- package/dist/pam/tag/drizzle/migrations/meta/0004_snapshot.json +345 -0
- package/dist/pam/tag/drizzle/migrations/meta/_journal.json +21 -0
- package/dist/pam/tag/migrate.d.ts.map +1 -1
- package/dist/pam/tag/migrate.js +34 -0
- package/dist/pam/tag/migrate.js.map +1 -1
- package/dist/pam/tag/plugin.d.ts +186 -1
- package/dist/pam/tag/plugin.d.ts.map +1 -1
- package/dist/pam/tag/plugin.js +46 -19
- package/dist/pam/tag/plugin.js.map +1 -1
- package/dist/pam/tag/router/index.d.ts +114 -1
- package/dist/pam/tag/router/index.d.ts.map +1 -1
- package/dist/pam/tag/router/index.js +38 -9
- package/dist/pam/tag/router/index.js.map +1 -1
- package/dist/pam/tag/schema/index.d.ts +32 -3
- package/dist/pam/tag/schema/index.d.ts.map +1 -1
- package/dist/pam/tag/schema/index.js +15 -2
- package/dist/pam/tag/schema/index.js.map +1 -1
- package/dist/pam/tag/seed/data/default-tag-rules.d.ts.map +1 -1
- package/dist/pam/tag/seed/data/default-tag-rules.js +42 -0
- package/dist/pam/tag/seed/data/default-tag-rules.js.map +1 -1
- package/dist/pam/tag/seed/data/default-tags.d.ts.map +1 -1
- package/dist/pam/tag/seed/data/default-tags.js +6 -0
- package/dist/pam/tag/seed/data/default-tags.js.map +1 -1
- package/dist/pam/tag/service/tag-evaluation.service.d.ts +147 -17
- package/dist/pam/tag/service/tag-evaluation.service.d.ts.map +1 -1
- package/dist/pam/tag/service/tag-evaluation.service.js +491 -48
- package/dist/pam/tag/service/tag-evaluation.service.js.map +1 -1
- package/dist/pam/tag/service/tag-mappers.d.ts +1 -1
- package/dist/pam/tag/service/tag-mappers.d.ts.map +1 -1
- package/dist/pam/tag/service/tag-mappers.js +1 -0
- package/dist/pam/tag/service/tag-mappers.js.map +1 -1
- package/dist/pam/tag/service/tag-rule.service.d.ts +8 -6
- package/dist/pam/tag/service/tag-rule.service.d.ts.map +1 -1
- package/dist/pam/tag/service/tag-rule.service.js +8 -2
- package/dist/pam/tag/service/tag-rule.service.js.map +1 -1
- package/dist/pam/tag/service/tag.service.d.ts +162 -16
- package/dist/pam/tag/service/tag.service.d.ts.map +1 -1
- package/dist/pam/tag/service/tag.service.js +297 -30
- package/dist/pam/tag/service/tag.service.js.map +1 -1
- package/dist/react/client.d.ts +2 -1
- package/dist/react/client.d.ts.map +1 -1
- package/dist/react/client.js +2 -1
- package/dist/react/client.js.map +1 -1
- package/dist/react/context/__tests__/realtime-client.test.d.ts +2 -0
- package/dist/react/context/__tests__/realtime-client.test.d.ts.map +1 -0
- package/dist/react/context/__tests__/realtime-client.test.js +75 -0
- package/dist/react/context/__tests__/realtime-client.test.js.map +1 -0
- package/dist/react/context/realtime-client.d.ts +15 -0
- package/dist/react/context/realtime-client.d.ts.map +1 -1
- package/dist/react/context/realtime-client.js.map +1 -1
- package/dist/react/hooks/__tests__/use-event-stream.test.d.ts +2 -0
- package/dist/react/hooks/__tests__/use-event-stream.test.d.ts.map +1 -0
- package/dist/react/hooks/__tests__/use-event-stream.test.js +153 -0
- package/dist/react/hooks/__tests__/use-event-stream.test.js.map +1 -0
- package/dist/react/hooks/use-event-stream.d.ts +3 -3
- package/dist/react/hooks/use-event-stream.d.ts.map +1 -1
- package/dist/react/hooks/use-event-stream.js +60 -28
- package/dist/react/hooks/use-event-stream.js.map +1 -1
- package/dist/server/auth/__tests__/admin-guard.int.test.d.ts +2 -0
- package/dist/server/auth/__tests__/admin-guard.int.test.d.ts.map +1 -0
- package/dist/server/auth/__tests__/admin-guard.int.test.js +199 -0
- package/dist/server/auth/__tests__/admin-guard.int.test.js.map +1 -0
- package/dist/server/auth/__tests__/auth.test.d.ts +2 -0
- package/dist/server/auth/__tests__/auth.test.d.ts.map +1 -0
- package/dist/server/auth/__tests__/auth.test.js +150 -0
- package/dist/server/auth/__tests__/auth.test.js.map +1 -0
- package/dist/server/auth/__tests__/permission-levels.test.d.ts +2 -0
- package/dist/server/auth/__tests__/permission-levels.test.d.ts.map +1 -0
- package/dist/server/auth/__tests__/permission-levels.test.js +89 -0
- package/dist/server/auth/__tests__/permission-levels.test.js.map +1 -0
- package/dist/server/auth/__tests__/permissions.test.d.ts +2 -0
- package/dist/server/auth/__tests__/permissions.test.d.ts.map +1 -0
- package/dist/server/auth/__tests__/permissions.test.js +15 -0
- package/dist/server/auth/__tests__/permissions.test.js.map +1 -0
- package/dist/server/auth/__tests__/session-resolver.int.test.d.ts +2 -0
- package/dist/server/auth/__tests__/session-resolver.int.test.d.ts.map +1 -0
- package/dist/server/auth/__tests__/session-resolver.int.test.js +59 -0
- package/dist/server/auth/__tests__/session-resolver.int.test.js.map +1 -0
- package/dist/server/auth/__tests__/sign-session-cookie.test.d.ts +2 -0
- package/dist/server/auth/__tests__/sign-session-cookie.test.d.ts.map +1 -0
- package/dist/server/auth/__tests__/sign-session-cookie.test.js +59 -0
- package/dist/server/auth/__tests__/sign-session-cookie.test.js.map +1 -0
- package/dist/server/auth/admin-guard.d.ts +13 -10
- package/dist/server/auth/admin-guard.d.ts.map +1 -1
- package/dist/server/auth/admin-guard.js +106 -44
- package/dist/server/auth/admin-guard.js.map +1 -1
- package/dist/server/auth/auth.d.ts +48 -5
- package/dist/server/auth/auth.d.ts.map +1 -1
- package/dist/server/auth/auth.js +78 -19
- package/dist/server/auth/auth.js.map +1 -1
- package/dist/server/auth/index.d.ts +3 -1
- package/dist/server/auth/index.d.ts.map +1 -1
- package/dist/server/auth/index.js +1 -0
- package/dist/server/auth/index.js.map +1 -1
- package/dist/server/auth/permissions.d.ts +169 -38
- package/dist/server/auth/permissions.d.ts.map +1 -1
- package/dist/server/auth/permissions.js +18 -22
- package/dist/server/auth/permissions.js.map +1 -1
- package/dist/server/auth/session-resolver.d.ts +4 -0
- package/dist/server/auth/session-resolver.d.ts.map +1 -1
- package/dist/server/auth/session-resolver.js +9 -2
- package/dist/server/auth/session-resolver.js.map +1 -1
- package/dist/server/auth/sign-session-cookie.d.ts +18 -0
- package/dist/server/auth/sign-session-cookie.d.ts.map +1 -0
- package/dist/server/auth/sign-session-cookie.js +15 -0
- package/dist/server/auth/sign-session-cookie.js.map +1 -0
- package/dist/server/db/__tests__/migrate.test.d.ts +2 -0
- package/dist/server/db/__tests__/migrate.test.d.ts.map +1 -0
- package/dist/server/db/__tests__/migrate.test.js +158 -0
- package/dist/server/db/__tests__/migrate.test.js.map +1 -0
- package/dist/server/db/__tests__/query-helpers.test.js +232 -1
- package/dist/server/db/__tests__/query-helpers.test.js.map +1 -1
- package/dist/server/db/__tests__/zod-jsonb.test.d.ts +2 -0
- package/dist/server/db/__tests__/zod-jsonb.test.d.ts.map +1 -0
- package/dist/server/db/__tests__/zod-jsonb.test.js +56 -0
- package/dist/server/db/__tests__/zod-jsonb.test.js.map +1 -0
- package/dist/server/db/drizzle.service.d.ts.map +1 -1
- package/dist/server/db/drizzle.service.js +8 -0
- package/dist/server/db/drizzle.service.js.map +1 -1
- package/dist/server/db/index.d.ts +2 -1
- package/dist/server/db/index.d.ts.map +1 -1
- package/dist/server/db/index.js +2 -1
- package/dist/server/db/index.js.map +1 -1
- package/dist/server/db/migrate.d.ts +38 -0
- package/dist/server/db/migrate.d.ts.map +1 -1
- package/dist/server/db/migrate.js +81 -12
- package/dist/server/db/migrate.js.map +1 -1
- package/dist/server/db/outbox/__tests__/relay.int.test.d.ts +2 -0
- package/dist/server/db/outbox/__tests__/relay.int.test.d.ts.map +1 -0
- package/dist/server/db/outbox/__tests__/relay.int.test.js +183 -0
- package/dist/server/db/outbox/__tests__/relay.int.test.js.map +1 -0
- package/dist/server/db/query-helpers.d.ts +14 -0
- package/dist/server/db/query-helpers.d.ts.map +1 -1
- package/dist/server/db/query-helpers.js +111 -0
- package/dist/server/db/query-helpers.js.map +1 -1
- package/dist/server/db/zod-jsonb.d.ts +52 -0
- package/dist/server/db/zod-jsonb.d.ts.map +1 -0
- package/dist/server/db/zod-jsonb.js +52 -0
- package/dist/server/db/zod-jsonb.js.map +1 -0
- package/dist/server/kernel/__tests__/bullmq-job-queue.int.test.d.ts +2 -0
- package/dist/server/kernel/__tests__/bullmq-job-queue.int.test.d.ts.map +1 -0
- package/dist/server/kernel/__tests__/bullmq-job-queue.int.test.js +240 -0
- package/dist/server/kernel/__tests__/bullmq-job-queue.int.test.js.map +1 -0
- package/dist/server/kernel/__tests__/cache.int.test.d.ts +2 -0
- package/dist/server/kernel/__tests__/cache.int.test.d.ts.map +1 -0
- package/dist/server/kernel/__tests__/cache.int.test.js +52 -0
- package/dist/server/kernel/__tests__/cache.int.test.js.map +1 -0
- package/dist/server/kernel/__tests__/domain-error.test.d.ts +2 -0
- package/dist/server/kernel/__tests__/domain-error.test.d.ts.map +1 -0
- package/dist/server/kernel/__tests__/domain-error.test.js +35 -0
- package/dist/server/kernel/__tests__/domain-error.test.js.map +1 -0
- package/dist/server/kernel/__tests__/error-reporter.test.d.ts +2 -0
- package/dist/server/kernel/__tests__/error-reporter.test.d.ts.map +1 -0
- package/dist/server/kernel/__tests__/error-reporter.test.js +52 -0
- package/dist/server/kernel/__tests__/error-reporter.test.js.map +1 -0
- package/dist/server/kernel/__tests__/event-bus.int.test.d.ts +2 -0
- package/dist/server/kernel/__tests__/event-bus.int.test.d.ts.map +1 -0
- package/dist/server/kernel/__tests__/event-bus.int.test.js +201 -0
- package/dist/server/kernel/__tests__/event-bus.int.test.js.map +1 -0
- package/dist/server/kernel/__tests__/helpers.test.js +26 -0
- package/dist/server/kernel/__tests__/helpers.test.js.map +1 -1
- package/dist/server/kernel/__tests__/logger.test.d.ts +2 -0
- package/dist/server/kernel/__tests__/logger.test.d.ts.map +1 -0
- package/dist/server/kernel/__tests__/logger.test.js +44 -0
- package/dist/server/kernel/__tests__/logger.test.js.map +1 -0
- package/dist/server/kernel/__tests__/orpc-error-map.test.d.ts +2 -0
- package/dist/server/kernel/__tests__/orpc-error-map.test.d.ts.map +1 -0
- package/dist/server/kernel/__tests__/orpc-error-map.test.js +54 -0
- package/dist/server/kernel/__tests__/orpc-error-map.test.js.map +1 -0
- package/dist/server/kernel/__tests__/platform-config-loader.test.d.ts +2 -0
- package/dist/server/kernel/__tests__/platform-config-loader.test.d.ts.map +1 -0
- package/dist/server/kernel/__tests__/platform-config-loader.test.js +112 -0
- package/dist/server/kernel/__tests__/platform-config-loader.test.js.map +1 -0
- package/dist/server/kernel/__tests__/rate-limiter.int.test.d.ts +2 -0
- package/dist/server/kernel/__tests__/rate-limiter.int.test.d.ts.map +1 -0
- package/dist/server/kernel/__tests__/rate-limiter.int.test.js +44 -0
- package/dist/server/kernel/__tests__/rate-limiter.int.test.js.map +1 -0
- package/dist/server/kernel/__tests__/redis-cache.int.test.d.ts +2 -0
- package/dist/server/kernel/__tests__/redis-cache.int.test.d.ts.map +1 -0
- package/dist/server/kernel/__tests__/redis-cache.int.test.js +49 -0
- package/dist/server/kernel/__tests__/redis-cache.int.test.js.map +1 -0
- package/dist/server/kernel/__tests__/redis-pubsub-realtime-transport.int.test.d.ts +2 -0
- package/dist/server/kernel/__tests__/redis-pubsub-realtime-transport.int.test.d.ts.map +1 -0
- package/dist/server/kernel/__tests__/redis-pubsub-realtime-transport.int.test.js +251 -0
- package/dist/server/kernel/__tests__/redis-pubsub-realtime-transport.int.test.js.map +1 -0
- package/dist/server/kernel/__tests__/redis-rate-limiter.int.test.d.ts +2 -0
- package/dist/server/kernel/__tests__/redis-rate-limiter.int.test.d.ts.map +1 -0
- package/dist/server/kernel/__tests__/redis-rate-limiter.int.test.js +61 -0
- package/dist/server/kernel/__tests__/redis-rate-limiter.int.test.js.map +1 -0
- package/dist/server/kernel/__tests__/redis-streams-broker.int.test.d.ts +2 -0
- package/dist/server/kernel/__tests__/redis-streams-broker.int.test.d.ts.map +1 -0
- package/dist/server/kernel/__tests__/redis-streams-broker.int.test.js +190 -0
- package/dist/server/kernel/__tests__/redis-streams-broker.int.test.js.map +1 -0
- package/dist/server/kernel/__tests__/request-context.test.d.ts +2 -0
- package/dist/server/kernel/__tests__/request-context.test.d.ts.map +1 -0
- package/dist/server/kernel/__tests__/request-context.test.js +64 -0
- package/dist/server/kernel/__tests__/request-context.test.js.map +1 -0
- package/dist/server/kernel/__tests__/router-utils.test.d.ts +2 -0
- package/dist/server/kernel/__tests__/router-utils.test.d.ts.map +1 -0
- package/dist/server/kernel/__tests__/router-utils.test.js +87 -0
- package/dist/server/kernel/__tests__/router-utils.test.js.map +1 -0
- package/dist/server/kernel/bullmq-job-queue.d.ts.map +1 -1
- package/dist/server/kernel/bullmq-job-queue.js +27 -4
- package/dist/server/kernel/bullmq-job-queue.js.map +1 -1
- package/dist/server/kernel/cache.d.ts +0 -12
- package/dist/server/kernel/cache.d.ts.map +1 -1
- package/dist/server/kernel/cache.js +0 -55
- package/dist/server/kernel/cache.js.map +1 -1
- package/dist/server/kernel/container.d.ts +7 -6
- package/dist/server/kernel/container.d.ts.map +1 -1
- package/dist/server/kernel/container.js +3 -0
- package/dist/server/kernel/container.js.map +1 -1
- package/dist/server/kernel/domain-error.d.ts +15 -5
- package/dist/server/kernel/domain-error.d.ts.map +1 -1
- package/dist/server/kernel/domain-error.js +4 -2
- package/dist/server/kernel/domain-error.js.map +1 -1
- package/dist/server/kernel/error-reporter.d.ts +5 -0
- package/dist/server/kernel/error-reporter.d.ts.map +1 -0
- package/dist/server/kernel/error-reporter.js +20 -0
- package/dist/server/kernel/error-reporter.js.map +1 -0
- package/dist/server/kernel/event-bus.d.ts +2 -18
- package/dist/server/kernel/event-bus.d.ts.map +1 -1
- package/dist/server/kernel/event-bus.js +28 -44
- package/dist/server/kernel/event-bus.js.map +1 -1
- package/dist/server/kernel/event-stream.d.ts.map +1 -1
- package/dist/server/kernel/event-stream.js +19 -4
- package/dist/server/kernel/event-stream.js.map +1 -1
- package/dist/server/kernel/index.d.ts +10 -8
- package/dist/server/kernel/index.d.ts.map +1 -1
- package/dist/server/kernel/index.js +8 -7
- package/dist/server/kernel/index.js.map +1 -1
- package/dist/server/kernel/logger.d.ts.map +1 -1
- package/dist/server/kernel/logger.js +51 -2
- package/dist/server/kernel/logger.js.map +1 -1
- package/dist/server/kernel/orpc-error-map.d.ts.map +1 -1
- package/dist/server/kernel/orpc-error-map.js +4 -1
- package/dist/server/kernel/orpc-error-map.js.map +1 -1
- package/dist/server/kernel/rate-limiter.d.ts +2 -10
- package/dist/server/kernel/rate-limiter.d.ts.map +1 -1
- package/dist/server/kernel/rate-limiter.js +0 -34
- package/dist/server/kernel/rate-limiter.js.map +1 -1
- package/dist/server/kernel/realtime-authorizer.d.ts +2 -4
- package/dist/server/kernel/realtime-authorizer.d.ts.map +1 -1
- package/dist/server/kernel/realtime-authorizer.js +3 -2
- package/dist/server/kernel/realtime-authorizer.js.map +1 -1
- package/dist/server/kernel/redis-cache.d.ts +3 -0
- package/dist/server/kernel/redis-cache.d.ts.map +1 -1
- package/dist/server/kernel/redis-cache.js +10 -0
- package/dist/server/kernel/redis-cache.js.map +1 -1
- package/dist/server/kernel/redis-client.d.ts.map +1 -1
- package/dist/server/kernel/redis-client.js +5 -1
- package/dist/server/kernel/redis-client.js.map +1 -1
- package/dist/server/kernel/redis-pubsub-realtime-transport.d.ts +51 -0
- package/dist/server/kernel/redis-pubsub-realtime-transport.d.ts.map +1 -0
- package/dist/server/kernel/redis-pubsub-realtime-transport.js +0 -0
- package/dist/server/kernel/redis-pubsub-realtime-transport.js.map +1 -0
- package/dist/server/kernel/redis-rate-limiter.d.ts +1 -0
- package/dist/server/kernel/redis-rate-limiter.d.ts.map +1 -1
- package/dist/server/kernel/redis-rate-limiter.js +11 -0
- package/dist/server/kernel/redis-rate-limiter.js.map +1 -1
- package/dist/server/kernel/redis-streams-broker.d.ts +65 -0
- package/dist/server/kernel/redis-streams-broker.d.ts.map +1 -0
- package/dist/server/kernel/redis-streams-broker.js +203 -0
- package/dist/server/kernel/redis-streams-broker.js.map +1 -0
- package/dist/server/kernel/request-context.d.ts +4 -0
- package/dist/server/kernel/request-context.d.ts.map +1 -1
- package/dist/server/kernel/request-context.js +4 -0
- package/dist/server/kernel/request-context.js.map +1 -1
- package/dist/server/kernel/router-utils.d.ts +7 -0
- package/dist/server/kernel/router-utils.d.ts.map +1 -1
- package/dist/server/kernel/router-utils.js +31 -2
- package/dist/server/kernel/router-utils.js.map +1 -1
- package/dist/server/plugin-host/__tests__/core-plugins.test.d.ts +2 -0
- package/dist/server/plugin-host/__tests__/core-plugins.test.d.ts.map +1 -0
- package/dist/server/plugin-host/__tests__/core-plugins.test.js +27 -0
- package/dist/server/plugin-host/__tests__/core-plugins.test.js.map +1 -0
- package/dist/server/plugin-host/__tests__/load-plugins.test.d.ts +2 -0
- package/dist/server/plugin-host/__tests__/load-plugins.test.d.ts.map +1 -0
- package/dist/server/plugin-host/__tests__/load-plugins.test.js +31 -0
- package/dist/server/plugin-host/__tests__/load-plugins.test.js.map +1 -0
- package/dist/server/plugin-host/__tests__/module-registry.test.js.map +1 -1
- package/dist/server/plugin-host/__tests__/required-ports.test.js +1 -0
- package/dist/server/plugin-host/__tests__/required-ports.test.js.map +1 -1
- package/dist/server/plugin-host/__tests__/typed-plugin.test.d.ts +2 -0
- package/dist/server/plugin-host/__tests__/typed-plugin.test.d.ts.map +1 -0
- package/dist/server/plugin-host/__tests__/typed-plugin.test.js +82 -0
- package/dist/server/plugin-host/__tests__/typed-plugin.test.js.map +1 -0
- package/dist/server/plugin-host/core-plugins.d.ts +16 -0
- package/dist/server/plugin-host/core-plugins.d.ts.map +1 -0
- package/dist/server/plugin-host/core-plugins.js +42 -0
- package/dist/server/plugin-host/core-plugins.js.map +1 -0
- package/dist/server/plugin-host/define-plugin.d.ts +24 -24
- package/dist/server/plugin-host/define-plugin.d.ts.map +1 -1
- package/dist/server/plugin-host/define-plugin.js +1 -3
- package/dist/server/plugin-host/define-plugin.js.map +1 -1
- package/dist/server/plugin-host/index.d.ts +3 -3
- package/dist/server/plugin-host/index.d.ts.map +1 -1
- package/dist/server/plugin-host/index.js +2 -2
- package/dist/server/plugin-host/index.js.map +1 -1
- package/dist/server/plugin-host/load-extensions.d.ts +2 -2
- package/dist/server/plugin-host/load-extensions.js +2 -2
- package/dist/server/plugin-host/load-plugins.d.ts +7 -3
- package/dist/server/plugin-host/load-plugins.d.ts.map +1 -1
- package/dist/server/plugin-host/load-plugins.js +10 -2
- package/dist/server/plugin-host/load-plugins.js.map +1 -1
- package/dist/server/plugin-host/module-registry.d.ts +9 -14
- package/dist/server/plugin-host/module-registry.d.ts.map +1 -1
- package/dist/server/plugin-host/module-registry.js +2 -9
- package/dist/server/plugin-host/module-registry.js.map +1 -1
- package/dist/server/runtime/__tests__/create-app.test.d.ts +2 -0
- package/dist/server/runtime/__tests__/create-app.test.d.ts.map +1 -0
- package/dist/server/runtime/__tests__/create-app.test.js +158 -0
- package/dist/server/runtime/__tests__/create-app.test.js.map +1 -0
- package/dist/server/runtime/assert-durable-seams.d.ts +19 -0
- package/dist/server/runtime/assert-durable-seams.d.ts.map +1 -0
- package/dist/server/runtime/assert-durable-seams.js +37 -0
- package/dist/server/runtime/assert-durable-seams.js.map +1 -0
- package/dist/server/runtime/core-token-catalog.d.ts +185 -0
- package/dist/server/runtime/core-token-catalog.d.ts.map +1 -0
- package/dist/server/runtime/core-token-catalog.js +74 -0
- package/dist/server/runtime/core-token-catalog.js.map +1 -0
- package/dist/server/runtime/create-app.d.ts +20 -23
- package/dist/server/runtime/create-app.d.ts.map +1 -1
- package/dist/server/runtime/create-app.js +164 -91
- package/dist/server/runtime/create-app.js.map +1 -1
- package/dist/server/runtime/index.d.ts +3 -4
- package/dist/server/runtime/index.d.ts.map +1 -1
- package/dist/server/runtime/index.js +1 -3
- package/dist/server/runtime/index.js.map +1 -1
- package/dist/testing/global-setup.d.ts +15 -0
- package/dist/testing/global-setup.d.ts.map +1 -0
- package/dist/testing/global-setup.js +33 -0
- package/dist/testing/global-setup.js.map +1 -0
- package/dist/testing/index.d.ts +6 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +6 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/mock.d.ts +58 -15
- package/dist/testing/mock.d.ts.map +1 -1
- package/dist/testing/mock.js +163 -39
- package/dist/testing/mock.js.map +1 -1
- package/dist/testing/real-infra.d.ts +68 -0
- package/dist/testing/real-infra.d.ts.map +1 -0
- package/dist/testing/real-infra.js +151 -0
- package/dist/testing/real-infra.js.map +1 -0
- package/dist/testing/realtime-transport-conformance.d.ts +35 -0
- package/dist/testing/realtime-transport-conformance.d.ts.map +1 -0
- package/dist/testing/realtime-transport-conformance.js +94 -0
- package/dist/testing/realtime-transport-conformance.js.map +1 -0
- package/dist/testing/seed-player.d.ts +119 -0
- package/dist/testing/seed-player.d.ts.map +1 -0
- package/dist/testing/seed-player.js +43 -0
- package/dist/testing/seed-player.js.map +1 -0
- package/dist/testing/seed-wallet.d.ts +9 -0
- package/dist/testing/seed-wallet.d.ts.map +1 -0
- package/dist/testing/seed-wallet.js +27 -0
- package/dist/testing/seed-wallet.js.map +1 -0
- package/dist/wallet/__tests__/admin-reporting.int.test.d.ts +2 -0
- package/dist/wallet/__tests__/admin-reporting.int.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/admin-reporting.int.test.js +236 -0
- package/dist/wallet/__tests__/admin-reporting.int.test.js.map +1 -0
- package/dist/wallet/__tests__/bonus-rollover-concurrency.int.test.d.ts +2 -0
- package/dist/wallet/__tests__/bonus-rollover-concurrency.int.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/bonus-rollover-concurrency.int.test.js +163 -0
- package/dist/wallet/__tests__/bonus-rollover-concurrency.int.test.js.map +1 -0
- package/dist/wallet/__tests__/bonus-rollover.int.test.d.ts +2 -0
- package/dist/wallet/__tests__/bonus-rollover.int.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/bonus-rollover.int.test.js +444 -0
- package/dist/wallet/__tests__/bonus-rollover.int.test.js.map +1 -0
- package/dist/wallet/__tests__/custody-sweep-gate.test.d.ts +2 -0
- package/dist/wallet/__tests__/custody-sweep-gate.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/custody-sweep-gate.test.js +70 -0
- package/dist/wallet/__tests__/custody-sweep-gate.test.js.map +1 -0
- package/dist/wallet/__tests__/custody-sweep.service.int.test.d.ts +2 -0
- package/dist/wallet/__tests__/custody-sweep.service.int.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/custody-sweep.service.int.test.js +274 -0
- package/dist/wallet/__tests__/custody-sweep.service.int.test.js.map +1 -0
- package/dist/wallet/__tests__/deposit-gate.test.d.ts +2 -0
- package/dist/wallet/__tests__/deposit-gate.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/deposit-gate.test.js +46 -0
- package/dist/wallet/__tests__/deposit-gate.test.js.map +1 -0
- package/dist/wallet/__tests__/rail-for.test.d.ts +2 -0
- package/dist/wallet/__tests__/rail-for.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/rail-for.test.js +29 -0
- package/dist/wallet/__tests__/rail-for.test.js.map +1 -0
- package/dist/wallet/__tests__/reconciliation-diff.test.d.ts +2 -0
- package/dist/wallet/__tests__/reconciliation-diff.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/reconciliation-diff.test.js +49 -0
- package/dist/wallet/__tests__/reconciliation-diff.test.js.map +1 -0
- package/dist/wallet/__tests__/reconciliation.service.int.test.d.ts +2 -0
- package/dist/wallet/__tests__/reconciliation.service.int.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/reconciliation.service.int.test.js +618 -0
- package/dist/wallet/__tests__/reconciliation.service.int.test.js.map +1 -0
- package/dist/wallet/__tests__/settlement-network.test.d.ts +2 -0
- package/dist/wallet/__tests__/settlement-network.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/settlement-network.test.js +54 -0
- package/dist/wallet/__tests__/settlement-network.test.js.map +1 -0
- package/dist/wallet/__tests__/swap.service.int.test.d.ts +2 -0
- package/dist/wallet/__tests__/swap.service.int.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/swap.service.int.test.js +398 -0
- package/dist/wallet/__tests__/swap.service.int.test.js.map +1 -0
- package/dist/wallet/__tests__/wallet-address-format.test.d.ts +2 -0
- package/dist/wallet/__tests__/wallet-address-format.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/wallet-address-format.test.js +102 -0
- package/dist/wallet/__tests__/wallet-address-format.test.js.map +1 -0
- package/dist/wallet/__tests__/wallet-asset.router.int.test.d.ts +2 -0
- package/dist/wallet/__tests__/wallet-asset.router.int.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/wallet-asset.router.int.test.js +263 -0
- package/dist/wallet/__tests__/wallet-asset.router.int.test.js.map +1 -0
- package/dist/wallet/__tests__/wallet-auto-rule.router.int.test.d.ts +2 -0
- package/dist/wallet/__tests__/wallet-auto-rule.router.int.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/wallet-auto-rule.router.int.test.js +137 -0
- package/dist/wallet/__tests__/wallet-auto-rule.router.int.test.js.map +1 -0
- package/dist/wallet/__tests__/wallet-auto-withdrawal-config.router.int.test.d.ts +2 -0
- package/dist/wallet/__tests__/wallet-auto-withdrawal-config.router.int.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/wallet-auto-withdrawal-config.router.int.test.js +205 -0
- package/dist/wallet/__tests__/wallet-auto-withdrawal-config.router.int.test.js.map +1 -0
- package/dist/wallet/__tests__/wallet-auto-withdrawal.int.test.d.ts +2 -0
- package/dist/wallet/__tests__/wallet-auto-withdrawal.int.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/wallet-auto-withdrawal.int.test.js +900 -0
- package/dist/wallet/__tests__/wallet-auto-withdrawal.int.test.js.map +1 -0
- package/dist/wallet/__tests__/wallet-balance-stream.router.int.test.d.ts +2 -0
- package/dist/wallet/__tests__/wallet-balance-stream.router.int.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/wallet-balance-stream.router.int.test.js +38 -0
- package/dist/wallet/__tests__/wallet-balance-stream.router.int.test.js.map +1 -0
- package/dist/wallet/__tests__/wallet-bonus-rollover-config.router.int.test.d.ts +2 -0
- package/dist/wallet/__tests__/wallet-bonus-rollover-config.router.int.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/wallet-bonus-rollover-config.router.int.test.js +114 -0
- package/dist/wallet/__tests__/wallet-bonus-rollover-config.router.int.test.js.map +1 -0
- package/dist/wallet/__tests__/wallet-commands.service.int.test.d.ts +2 -0
- package/dist/wallet/__tests__/wallet-commands.service.int.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/wallet-commands.service.int.test.js +419 -0
- package/dist/wallet/__tests__/wallet-commands.service.int.test.js.map +1 -0
- package/dist/wallet/__tests__/wallet-currency-code.test.d.ts +2 -0
- package/dist/wallet/__tests__/wallet-currency-code.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/wallet-currency-code.test.js +48 -0
- package/dist/wallet/__tests__/wallet-currency-code.test.js.map +1 -0
- package/dist/wallet/__tests__/wallet-custody-routes.router.test.d.ts +2 -0
- package/dist/wallet/__tests__/wallet-custody-routes.router.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/wallet-custody-routes.router.test.js +129 -0
- package/dist/wallet/__tests__/wallet-custody-routes.router.test.js.map +1 -0
- package/dist/wallet/__tests__/wallet-kyc-gate.int.test.d.ts +2 -0
- package/dist/wallet/__tests__/wallet-kyc-gate.int.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/wallet-kyc-gate.int.test.js +104 -0
- package/dist/wallet/__tests__/wallet-kyc-gate.int.test.js.map +1 -0
- package/dist/wallet/__tests__/wallet-reader.service.int.test.d.ts +2 -0
- package/dist/wallet/__tests__/wallet-reader.service.int.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/wallet-reader.service.int.test.js +111 -0
- package/dist/wallet/__tests__/wallet-reader.service.int.test.js.map +1 -0
- package/dist/wallet/__tests__/wallet-rg-limit-gate.int.test.d.ts +2 -0
- package/dist/wallet/__tests__/wallet-rg-limit-gate.int.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/wallet-rg-limit-gate.int.test.js +93 -0
- package/dist/wallet/__tests__/wallet-rg-limit-gate.int.test.js.map +1 -0
- package/dist/wallet/__tests__/wallet-transaction-direction-backfill.test.d.ts +2 -0
- package/dist/wallet/__tests__/wallet-transaction-direction-backfill.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/wallet-transaction-direction-backfill.test.js +37 -0
- package/dist/wallet/__tests__/wallet-transaction-direction-backfill.test.js.map +1 -0
- package/dist/wallet/__tests__/wallet-webhook.router.int.test.d.ts +2 -0
- package/dist/wallet/__tests__/wallet-webhook.router.int.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/wallet-webhook.router.int.test.js +311 -0
- package/dist/wallet/__tests__/wallet-webhook.router.int.test.js.map +1 -0
- package/dist/wallet/__tests__/wallet-withdrawal-address-cap.int.test.d.ts +2 -0
- package/dist/wallet/__tests__/wallet-withdrawal-address-cap.int.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/wallet-withdrawal-address-cap.int.test.js +64 -0
- package/dist/wallet/__tests__/wallet-withdrawal-address-cap.int.test.js.map +1 -0
- package/dist/wallet/__tests__/wallet-withdrawal-address.router.int.test.d.ts +2 -0
- package/dist/wallet/__tests__/wallet-withdrawal-address.router.int.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/wallet-withdrawal-address.router.int.test.js +179 -0
- package/dist/wallet/__tests__/wallet-withdrawal-address.router.int.test.js.map +1 -0
- package/dist/wallet/__tests__/wallet.rate-limit.int.test.d.ts +2 -0
- package/dist/wallet/__tests__/wallet.rate-limit.int.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/wallet.rate-limit.int.test.js +117 -0
- package/dist/wallet/__tests__/wallet.rate-limit.int.test.js.map +1 -0
- package/dist/wallet/__tests__/wallet.router.int.test.d.ts +2 -0
- package/dist/wallet/__tests__/wallet.router.int.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/wallet.router.int.test.js +104 -0
- package/dist/wallet/__tests__/wallet.router.int.test.js.map +1 -0
- package/dist/wallet/__tests__/wallet.service.int.test.d.ts +2 -0
- package/dist/wallet/__tests__/wallet.service.int.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/wallet.service.int.test.js +1674 -0
- package/dist/wallet/__tests__/wallet.service.int.test.js.map +1 -0
- package/dist/wallet/adapters/wallet-asset-catalog.service.d.ts +14 -0
- package/dist/wallet/adapters/wallet-asset-catalog.service.d.ts.map +1 -0
- package/dist/wallet/adapters/wallet-asset-catalog.service.js +37 -0
- package/dist/wallet/adapters/wallet-asset-catalog.service.js.map +1 -0
- package/dist/wallet/adapters/wallet-reader.service.d.ts +8 -1
- package/dist/wallet/adapters/wallet-reader.service.d.ts.map +1 -1
- package/dist/wallet/adapters/wallet-reader.service.js +52 -1
- package/dist/wallet/adapters/wallet-reader.service.js.map +1 -1
- package/dist/wallet/admin-reporting.d.ts +3 -3
- package/dist/wallet/admin-reporting.d.ts.map +1 -1
- package/dist/wallet/admin-reporting.js +11 -3
- package/dist/wallet/admin-reporting.js.map +1 -1
- package/dist/wallet/contract/index.d.ts +1018 -19
- package/dist/wallet/contract/index.d.ts.map +1 -1
- package/dist/wallet/contract/index.js +513 -15
- package/dist/wallet/contract/index.js.map +1 -1
- package/dist/wallet/drizzle/migrations/0003_certain_ogun.sql +2 -0
- package/dist/wallet/drizzle/migrations/0004_reflective_shriek.sql +2 -0
- package/dist/wallet/drizzle/migrations/0005_gigantic_dust.sql +10 -0
- package/dist/wallet/drizzle/migrations/0006_lush_morg.sql +1 -0
- package/dist/wallet/drizzle/migrations/0007_bouncy_swordsman.sql +17 -0
- package/dist/wallet/drizzle/migrations/0008_gorgeous_colonel_america.sql +1 -0
- package/dist/wallet/drizzle/migrations/0009_smooth_sue_storm.sql +17 -0
- package/dist/wallet/drizzle/migrations/0010_worthless_quasimodo.sql +84 -0
- package/dist/wallet/drizzle/migrations/0011_premium_natasha_romanoff.sql +30 -0
- package/dist/wallet/drizzle/migrations/0012_long_wong.sql +15 -0
- package/dist/wallet/drizzle/migrations/0013_polite_peter_parker.sql +1 -0
- package/dist/wallet/drizzle/migrations/0014_abandoned_madripoor.sql +20 -0
- package/dist/wallet/drizzle/migrations/0015_right_oracle.sql +3 -0
- package/dist/wallet/drizzle/migrations/0016_curly_ben_urich.sql +2 -0
- package/dist/wallet/drizzle/migrations/0017_workable_wolf_cub.sql +2 -0
- package/dist/wallet/drizzle/migrations/0018_marvelous_demogoblin.sql +3 -0
- package/dist/wallet/drizzle/migrations/0019_awesome_drax.sql +2 -0
- package/dist/wallet/drizzle/migrations/0020_salty_infant_terrible.sql +1 -0
- package/dist/wallet/drizzle/migrations/0021_mean_chameleon.sql +3 -0
- package/dist/wallet/drizzle/migrations/0022_natural_exodus.sql +1 -0
- package/dist/wallet/drizzle/migrations/meta/0003_snapshot.json +567 -0
- package/dist/wallet/drizzle/migrations/meta/0004_snapshot.json +631 -0
- package/dist/wallet/drizzle/migrations/meta/0006_snapshot.json +638 -0
- package/dist/wallet/drizzle/migrations/meta/0007_snapshot.json +723 -0
- package/dist/wallet/drizzle/migrations/meta/0008_snapshot.json +716 -0
- package/dist/wallet/drizzle/migrations/meta/0009_snapshot.json +895 -0
- package/dist/wallet/drizzle/migrations/meta/0010_snapshot.json +1565 -0
- package/dist/wallet/drizzle/migrations/meta/0011_snapshot.json +1777 -0
- package/dist/wallet/drizzle/migrations/meta/0012_snapshot.json +1907 -0
- package/dist/wallet/drizzle/migrations/meta/0013_snapshot.json +1913 -0
- package/dist/wallet/drizzle/migrations/meta/0014_snapshot.json +1925 -0
- package/dist/wallet/drizzle/migrations/meta/0015_snapshot.json +1937 -0
- package/dist/wallet/drizzle/migrations/meta/0016_snapshot.json +1943 -0
- package/dist/wallet/drizzle/migrations/meta/0017_snapshot.json +1945 -0
- package/dist/wallet/drizzle/migrations/meta/0018_snapshot.json +1967 -0
- package/dist/wallet/drizzle/migrations/meta/0019_snapshot.json +1973 -0
- package/dist/wallet/drizzle/migrations/meta/0020_snapshot.json +1979 -0
- package/dist/wallet/drizzle/migrations/meta/0021_snapshot.json +1986 -0
- package/dist/wallet/drizzle/migrations/meta/0022_snapshot.json +1987 -0
- package/dist/wallet/drizzle/migrations/meta/_journal.json +140 -0
- package/dist/wallet/index.d.ts.map +1 -1
- package/dist/wallet/index.js +0 -2
- package/dist/wallet/index.js.map +1 -1
- package/dist/wallet/migrate.d.ts +0 -1
- package/dist/wallet/migrate.d.ts.map +1 -1
- package/dist/wallet/migrate.js +0 -4
- package/dist/wallet/migrate.js.map +1 -1
- package/dist/wallet/plugin.d.ts +187 -1
- package/dist/wallet/plugin.d.ts.map +1 -1
- package/dist/wallet/plugin.js +223 -19
- package/dist/wallet/plugin.js.map +1 -1
- package/dist/wallet/router/index.d.ts +557 -12
- package/dist/wallet/router/index.d.ts.map +1 -1
- package/dist/wallet/router/index.js +270 -36
- package/dist/wallet/router/index.js.map +1 -1
- package/dist/wallet/schema/index.d.ts +1990 -9
- package/dist/wallet/schema/index.d.ts.map +1 -1
- package/dist/wallet/schema/index.js +290 -7
- package/dist/wallet/schema/index.js.map +1 -1
- package/dist/wallet/seed/index.d.ts +3 -0
- package/dist/wallet/seed/index.d.ts.map +1 -0
- package/dist/wallet/seed/index.js +3 -0
- package/dist/wallet/seed/index.js.map +1 -0
- package/dist/wallet/seed/seed-auto-withdrawal-config.d.ts +11 -0
- package/dist/wallet/seed/seed-auto-withdrawal-config.d.ts.map +1 -0
- package/dist/wallet/seed/seed-auto-withdrawal-config.js +16 -0
- package/dist/wallet/seed/seed-auto-withdrawal-config.js.map +1 -0
- package/dist/wallet/seed/seed-bonus-rollover-config.d.ts +3 -0
- package/dist/wallet/seed/seed-bonus-rollover-config.d.ts.map +1 -0
- package/dist/wallet/seed/seed-bonus-rollover-config.js +8 -0
- package/dist/wallet/seed/seed-bonus-rollover-config.js.map +1 -0
- package/dist/wallet/service/custody-sweep.service.d.ts +77 -0
- package/dist/wallet/service/custody-sweep.service.d.ts.map +1 -0
- package/dist/wallet/service/custody-sweep.service.js +388 -0
- package/dist/wallet/service/custody-sweep.service.js.map +1 -0
- package/dist/wallet/service/reconciliation-finding.service.d.ts +68 -0
- package/dist/wallet/service/reconciliation-finding.service.d.ts.map +1 -0
- package/dist/wallet/service/reconciliation-finding.service.js +82 -0
- package/dist/wallet/service/reconciliation-finding.service.js.map +1 -0
- package/dist/wallet/service/reconciliation.service.d.ts +143 -0
- package/dist/wallet/service/reconciliation.service.d.ts.map +1 -0
- package/dist/wallet/service/reconciliation.service.js +685 -0
- package/dist/wallet/service/reconciliation.service.js.map +1 -0
- package/dist/wallet/service/swap.service.d.ts +78 -0
- package/dist/wallet/service/swap.service.d.ts.map +1 -0
- package/dist/wallet/service/swap.service.js +336 -0
- package/dist/wallet/service/swap.service.js.map +1 -0
- package/dist/wallet/service/wallet-commands.service.d.ts +19 -4
- package/dist/wallet/service/wallet-commands.service.d.ts.map +1 -1
- package/dist/wallet/service/wallet-commands.service.js +238 -31
- package/dist/wallet/service/wallet-commands.service.js.map +1 -1
- package/dist/wallet/service/wallet.service.d.ts +679 -30
- package/dist/wallet/service/wallet.service.d.ts.map +1 -1
- package/dist/wallet/service/wallet.service.js +1351 -155
- package/dist/wallet/service/wallet.service.js.map +1 -1
- package/generators/src/config.ts +547 -0
- package/generators/src/templates/adapter.hbs +19 -0
- package/generators/src/templates/contract.hbs +19 -0
- package/generators/src/templates/job-worker.hbs +34 -0
- package/generators/src/templates/module/drizzle.config.hbs +22 -0
- package/generators/src/templates/module/index.hbs +5 -0
- package/generators/src/templates/module/migrate.hbs +17 -0
- package/generators/src/templates/module/plugin.hbs +19 -0
- package/generators/src/templates/module/router.hbs +19 -0
- package/generators/src/templates/module/schema.hbs +14 -0
- package/generators/src/templates/module/service.hbs +26 -0
- package/generators/src/templates/plugin.hbs +20 -0
- package/package.json +168 -11
- package/dist/admin-console/__tests__/backoffice.service.test.d.ts +0 -2
- package/dist/admin-console/__tests__/backoffice.service.test.d.ts.map +0 -1
- package/dist/admin-console/__tests__/backoffice.service.test.js +0 -156
- package/dist/admin-console/__tests__/backoffice.service.test.js.map +0 -1
- package/dist/audit/__tests__/audit.service.test.d.ts +0 -2
- package/dist/audit/__tests__/audit.service.test.d.ts.map +0 -1
- package/dist/audit/__tests__/audit.service.test.js +0 -442
- package/dist/audit/__tests__/audit.service.test.js.map +0 -1
- package/dist/casino/gaming/__tests__/gaming.service.test.d.ts +0 -2
- package/dist/casino/gaming/__tests__/gaming.service.test.d.ts.map +0 -1
- package/dist/casino/gaming/__tests__/gaming.service.test.js +0 -55
- package/dist/casino/gaming/__tests__/gaming.service.test.js.map +0 -1
- package/dist/casino/lobby/__tests__/lobby.cache.test.d.ts +0 -2
- package/dist/casino/lobby/__tests__/lobby.cache.test.d.ts.map +0 -1
- package/dist/casino/lobby/__tests__/lobby.cache.test.js +0 -47
- package/dist/casino/lobby/__tests__/lobby.cache.test.js.map +0 -1
- package/dist/casino/lobby/__tests__/lobby.service.test.d.ts +0 -2
- package/dist/casino/lobby/__tests__/lobby.service.test.d.ts.map +0 -1
- package/dist/casino/lobby/__tests__/lobby.service.test.js +0 -11
- package/dist/casino/lobby/__tests__/lobby.service.test.js.map +0 -1
- package/dist/cms/__tests__/cms.cache.test.d.ts +0 -2
- package/dist/cms/__tests__/cms.cache.test.d.ts.map +0 -1
- package/dist/cms/__tests__/cms.cache.test.js +0 -87
- package/dist/cms/__tests__/cms.cache.test.js.map +0 -1
- package/dist/cms/__tests__/cms.router.test.d.ts +0 -2
- package/dist/cms/__tests__/cms.router.test.d.ts.map +0 -1
- package/dist/cms/__tests__/cms.router.test.js +0 -51
- package/dist/cms/__tests__/cms.router.test.js.map +0 -1
- package/dist/cms/__tests__/cms.service.test.d.ts +0 -2
- package/dist/cms/__tests__/cms.service.test.d.ts.map +0 -1
- package/dist/cms/__tests__/cms.service.test.js +0 -17
- package/dist/cms/__tests__/cms.service.test.js.map +0 -1
- package/dist/compliance/__tests__/compliance.service.test.d.ts +0 -2
- package/dist/compliance/__tests__/compliance.service.test.d.ts.map +0 -1
- package/dist/compliance/__tests__/compliance.service.test.js +0 -96
- package/dist/compliance/__tests__/compliance.service.test.js.map +0 -1
- package/dist/compliance/__tests__/hmac-kyc-webhook-verifier.test.d.ts +0 -2
- package/dist/compliance/__tests__/hmac-kyc-webhook-verifier.test.d.ts.map +0 -1
- package/dist/compliance/__tests__/hmac-kyc-webhook-verifier.test.js +0 -25
- package/dist/compliance/__tests__/hmac-kyc-webhook-verifier.test.js.map +0 -1
- package/dist/compliance/__tests__/kyc.service.test.d.ts +0 -2
- package/dist/compliance/__tests__/kyc.service.test.d.ts.map +0 -1
- package/dist/compliance/__tests__/kyc.service.test.js +0 -177
- package/dist/compliance/__tests__/kyc.service.test.js.map +0 -1
- package/dist/compliance/__tests__/rg-monitoring.service.test.d.ts +0 -2
- package/dist/compliance/__tests__/rg-monitoring.service.test.d.ts.map +0 -1
- package/dist/compliance/__tests__/rg-monitoring.service.test.js +0 -110
- package/dist/compliance/__tests__/rg-monitoring.service.test.js.map +0 -1
- package/dist/compliance/__tests__/rg.router.test.d.ts +0 -2
- package/dist/compliance/__tests__/rg.router.test.d.ts.map +0 -1
- package/dist/compliance/__tests__/rg.router.test.js +0 -66
- package/dist/compliance/__tests__/rg.router.test.js.map +0 -1
- package/dist/compliance/__tests__/rg.service.test.d.ts +0 -2
- package/dist/compliance/__tests__/rg.service.test.d.ts.map +0 -1
- package/dist/compliance/__tests__/rg.service.test.js +0 -212
- package/dist/compliance/__tests__/rg.service.test.js.map +0 -1
- package/dist/contracts/adapters/email.d.ts +0 -10
- package/dist/contracts/adapters/email.d.ts.map +0 -1
- package/dist/contracts/adapters/email.js +0 -8
- package/dist/contracts/adapters/email.js.map +0 -1
- package/dist/contracts/adapters/notification.d.ts +0 -6
- package/dist/contracts/adapters/notification.d.ts.map +0 -1
- package/dist/contracts/adapters/notification.js +0 -8
- package/dist/contracts/adapters/notification.js.map +0 -1
- package/dist/contracts/schemas/__tests__/identity-schemas.test.d.ts +0 -2
- package/dist/contracts/schemas/__tests__/identity-schemas.test.d.ts.map +0 -1
- package/dist/contracts/schemas/__tests__/identity-schemas.test.js +0 -38
- package/dist/contracts/schemas/__tests__/identity-schemas.test.js.map +0 -1
- package/dist/engagement/chat/__tests__/chat.service.test.d.ts +0 -2
- package/dist/engagement/chat/__tests__/chat.service.test.d.ts.map +0 -1
- package/dist/engagement/chat/__tests__/chat.service.test.js +0 -170
- package/dist/engagement/chat/__tests__/chat.service.test.js.map +0 -1
- package/dist/engagement/chat/react/use-chat-stream.d.ts +0 -26
- package/dist/engagement/chat/react/use-chat-stream.d.ts.map +0 -1
- package/dist/engagement/chat/react/use-chat-stream.js +0 -54
- package/dist/engagement/chat/react/use-chat-stream.js.map +0 -1
- package/dist/engagement/notifications/__tests__/notifications.service.test.d.ts +0 -2
- package/dist/engagement/notifications/__tests__/notifications.service.test.d.ts.map +0 -1
- package/dist/engagement/notifications/__tests__/notifications.service.test.js +0 -84
- package/dist/engagement/notifications/__tests__/notifications.service.test.js.map +0 -1
- package/dist/engagement/notifications/adapters/mock/mock-notification-adapter.d.ts +0 -5
- package/dist/engagement/notifications/adapters/mock/mock-notification-adapter.d.ts.map +0 -1
- package/dist/engagement/notifications/adapters/mock/mock-notification-adapter.js +0 -6
- package/dist/engagement/notifications/adapters/mock/mock-notification-adapter.js.map +0 -1
- package/dist/iam/__tests__/iam.service.test.d.ts +0 -2
- package/dist/iam/__tests__/iam.service.test.d.ts.map +0 -1
- package/dist/iam/__tests__/iam.service.test.js +0 -744
- package/dist/iam/__tests__/iam.service.test.js.map +0 -1
- package/dist/pam/identity/__tests__/admin-user-directory.test.d.ts +0 -2
- package/dist/pam/identity/__tests__/admin-user-directory.test.d.ts.map +0 -1
- package/dist/pam/identity/__tests__/admin-user-directory.test.js +0 -93
- package/dist/pam/identity/__tests__/admin-user-directory.test.js.map +0 -1
- package/dist/pam/identity/__tests__/identity.rate-limit.test.d.ts +0 -2
- package/dist/pam/identity/__tests__/identity.rate-limit.test.d.ts.map +0 -1
- package/dist/pam/identity/__tests__/identity.rate-limit.test.js +0 -127
- package/dist/pam/identity/__tests__/identity.rate-limit.test.js.map +0 -1
- package/dist/pam/identity/__tests__/identity.service.test.d.ts +0 -2
- package/dist/pam/identity/__tests__/identity.service.test.d.ts.map +0 -1
- package/dist/pam/identity/__tests__/identity.service.test.js +0 -292
- package/dist/pam/identity/__tests__/identity.service.test.js.map +0 -1
- package/dist/pam/identity/__tests__/login-enforcement.service.test.d.ts +0 -2
- package/dist/pam/identity/__tests__/login-enforcement.service.test.d.ts.map +0 -1
- package/dist/pam/identity/__tests__/login-enforcement.service.test.js +0 -41
- package/dist/pam/identity/__tests__/login-enforcement.service.test.js.map +0 -1
- package/dist/pam/player-management/__tests__/kyc-status-writer.test.d.ts +0 -2
- package/dist/pam/player-management/__tests__/kyc-status-writer.test.d.ts.map +0 -1
- package/dist/pam/player-management/__tests__/kyc-status-writer.test.js +0 -38
- package/dist/pam/player-management/__tests__/kyc-status-writer.test.js.map +0 -1
- package/dist/pam/player-management/__tests__/player.router.test.d.ts +0 -2
- package/dist/pam/player-management/__tests__/player.router.test.d.ts.map +0 -1
- package/dist/pam/player-management/__tests__/player.router.test.js +0 -57
- package/dist/pam/player-management/__tests__/player.router.test.js.map +0 -1
- package/dist/pam/player-management/__tests__/player.service.test.d.ts +0 -2
- package/dist/pam/player-management/__tests__/player.service.test.d.ts.map +0 -1
- package/dist/pam/player-management/__tests__/player.service.test.js +0 -144
- package/dist/pam/player-management/__tests__/player.service.test.js.map +0 -1
- package/dist/pam/profile/__tests__/profile.service.test.d.ts +0 -2
- package/dist/pam/profile/__tests__/profile.service.test.d.ts.map +0 -1
- package/dist/pam/profile/__tests__/profile.service.test.js +0 -48
- package/dist/pam/profile/__tests__/profile.service.test.js.map +0 -1
- package/dist/pam/tag/__tests__/get-active-tag-keys.test.d.ts +0 -2
- package/dist/pam/tag/__tests__/get-active-tag-keys.test.d.ts.map +0 -1
- package/dist/pam/tag/__tests__/get-active-tag-keys.test.js +0 -38
- package/dist/pam/tag/__tests__/get-active-tag-keys.test.js.map +0 -1
- package/dist/pam/tag/__tests__/tag-evaluation.service.test.d.ts +0 -2
- package/dist/pam/tag/__tests__/tag-evaluation.service.test.d.ts.map +0 -1
- package/dist/pam/tag/__tests__/tag-evaluation.service.test.js +0 -269
- package/dist/pam/tag/__tests__/tag-evaluation.service.test.js.map +0 -1
- package/dist/pam/tag/__tests__/tag-rule.service.test.d.ts +0 -2
- package/dist/pam/tag/__tests__/tag-rule.service.test.d.ts.map +0 -1
- package/dist/pam/tag/__tests__/tag-rule.service.test.js +0 -149
- package/dist/pam/tag/__tests__/tag-rule.service.test.js.map +0 -1
- package/dist/pam/tag/__tests__/tag.router.test.d.ts +0 -2
- package/dist/pam/tag/__tests__/tag.router.test.d.ts.map +0 -1
- package/dist/pam/tag/__tests__/tag.router.test.js +0 -38
- package/dist/pam/tag/__tests__/tag.router.test.js.map +0 -1
- package/dist/pam/tag/__tests__/tag.service.test.d.ts +0 -2
- package/dist/pam/tag/__tests__/tag.service.test.d.ts.map +0 -1
- package/dist/pam/tag/__tests__/tag.service.test.js +0 -262
- package/dist/pam/tag/__tests__/tag.service.test.js.map +0 -1
- package/dist/server/auth/__tests__/admin-guard.test.d.ts +0 -2
- package/dist/server/auth/__tests__/admin-guard.test.d.ts.map +0 -1
- package/dist/server/auth/__tests__/admin-guard.test.js +0 -133
- package/dist/server/auth/__tests__/admin-guard.test.js.map +0 -1
- package/dist/server/auth/__tests__/session-resolver.test.d.ts +0 -2
- package/dist/server/auth/__tests__/session-resolver.test.d.ts.map +0 -1
- package/dist/server/auth/__tests__/session-resolver.test.js +0 -27
- package/dist/server/auth/__tests__/session-resolver.test.js.map +0 -1
- package/dist/server/db/outbox/__tests__/relay.test.d.ts +0 -2
- package/dist/server/db/outbox/__tests__/relay.test.d.ts.map +0 -1
- package/dist/server/db/outbox/__tests__/relay.test.js +0 -124
- package/dist/server/db/outbox/__tests__/relay.test.js.map +0 -1
- package/dist/server/kernel/__tests__/bullmq-job-queue.test.d.ts +0 -2
- package/dist/server/kernel/__tests__/bullmq-job-queue.test.d.ts.map +0 -1
- package/dist/server/kernel/__tests__/bullmq-job-queue.test.js +0 -190
- package/dist/server/kernel/__tests__/bullmq-job-queue.test.js.map +0 -1
- package/dist/server/kernel/__tests__/cache.test.d.ts +0 -2
- package/dist/server/kernel/__tests__/cache.test.d.ts.map +0 -1
- package/dist/server/kernel/__tests__/cache.test.js +0 -84
- package/dist/server/kernel/__tests__/cache.test.js.map +0 -1
- package/dist/server/kernel/__tests__/event-bus.test.d.ts +0 -2
- package/dist/server/kernel/__tests__/event-bus.test.d.ts.map +0 -1
- package/dist/server/kernel/__tests__/event-bus.test.js +0 -116
- package/dist/server/kernel/__tests__/event-bus.test.js.map +0 -1
- package/dist/server/kernel/__tests__/job-queue.test.d.ts +0 -2
- package/dist/server/kernel/__tests__/job-queue.test.d.ts.map +0 -1
- package/dist/server/kernel/__tests__/job-queue.test.js +0 -135
- package/dist/server/kernel/__tests__/job-queue.test.js.map +0 -1
- package/dist/server/kernel/__tests__/rate-limiter.test.d.ts +0 -2
- package/dist/server/kernel/__tests__/rate-limiter.test.d.ts.map +0 -1
- package/dist/server/kernel/__tests__/rate-limiter.test.js +0 -74
- package/dist/server/kernel/__tests__/rate-limiter.test.js.map +0 -1
- package/dist/server/kernel/__tests__/realtime-authorizer.test.d.ts +0 -2
- package/dist/server/kernel/__tests__/realtime-authorizer.test.d.ts.map +0 -1
- package/dist/server/kernel/__tests__/realtime-authorizer.test.js +0 -19
- package/dist/server/kernel/__tests__/realtime-authorizer.test.js.map +0 -1
- package/dist/server/kernel/__tests__/realtime-transport.test.d.ts +0 -2
- package/dist/server/kernel/__tests__/realtime-transport.test.d.ts.map +0 -1
- package/dist/server/kernel/__tests__/realtime-transport.test.js +0 -50
- package/dist/server/kernel/__tests__/realtime-transport.test.js.map +0 -1
- package/dist/server/kernel/__tests__/redis-cache.test.d.ts +0 -2
- package/dist/server/kernel/__tests__/redis-cache.test.d.ts.map +0 -1
- package/dist/server/kernel/__tests__/redis-cache.test.js +0 -49
- package/dist/server/kernel/__tests__/redis-cache.test.js.map +0 -1
- package/dist/server/kernel/__tests__/redis-rate-limiter.test.d.ts +0 -2
- package/dist/server/kernel/__tests__/redis-rate-limiter.test.d.ts.map +0 -1
- package/dist/server/kernel/__tests__/redis-rate-limiter.test.js +0 -56
- package/dist/server/kernel/__tests__/redis-rate-limiter.test.js.map +0 -1
- package/dist/server/kernel/job-queue.d.ts +0 -40
- package/dist/server/kernel/job-queue.d.ts.map +0 -1
- package/dist/server/kernel/job-queue.js +0 -200
- package/dist/server/kernel/job-queue.js.map +0 -1
- package/dist/server/kernel/realtime-transport.d.ts +0 -8
- package/dist/server/kernel/realtime-transport.d.ts.map +0 -1
- package/dist/server/kernel/realtime-transport.js +0 -57
- package/dist/server/kernel/realtime-transport.js.map +0 -1
- package/dist/server/runtime/openapi.d.ts +0 -15
- package/dist/server/runtime/openapi.d.ts.map +0 -1
- package/dist/server/runtime/openapi.js +0 -26
- package/dist/server/runtime/openapi.js.map +0 -1
- package/dist/wallet/__tests__/admin-reporting.test.d.ts +0 -2
- package/dist/wallet/__tests__/admin-reporting.test.d.ts.map +0 -1
- package/dist/wallet/__tests__/admin-reporting.test.js +0 -124
- package/dist/wallet/__tests__/admin-reporting.test.js.map +0 -1
- package/dist/wallet/__tests__/wallet-auto-rule.router.test.d.ts +0 -2
- package/dist/wallet/__tests__/wallet-auto-rule.router.test.d.ts.map +0 -1
- package/dist/wallet/__tests__/wallet-auto-rule.router.test.js +0 -100
- package/dist/wallet/__tests__/wallet-auto-rule.router.test.js.map +0 -1
- package/dist/wallet/__tests__/wallet-auto-withdrawal.test.d.ts +0 -2
- package/dist/wallet/__tests__/wallet-auto-withdrawal.test.d.ts.map +0 -1
- package/dist/wallet/__tests__/wallet-auto-withdrawal.test.js +0 -517
- package/dist/wallet/__tests__/wallet-auto-withdrawal.test.js.map +0 -1
- package/dist/wallet/__tests__/wallet-commands.service.test.d.ts +0 -2
- package/dist/wallet/__tests__/wallet-commands.service.test.d.ts.map +0 -1
- package/dist/wallet/__tests__/wallet-commands.service.test.js +0 -176
- package/dist/wallet/__tests__/wallet-commands.service.test.js.map +0 -1
- package/dist/wallet/__tests__/wallet-kyc-gate.test.d.ts +0 -2
- package/dist/wallet/__tests__/wallet-kyc-gate.test.d.ts.map +0 -1
- package/dist/wallet/__tests__/wallet-kyc-gate.test.js +0 -61
- package/dist/wallet/__tests__/wallet-kyc-gate.test.js.map +0 -1
- package/dist/wallet/__tests__/wallet-webhook.router.test.d.ts +0 -2
- package/dist/wallet/__tests__/wallet-webhook.router.test.d.ts.map +0 -1
- package/dist/wallet/__tests__/wallet-webhook.router.test.js +0 -78
- package/dist/wallet/__tests__/wallet-webhook.router.test.js.map +0 -1
- package/dist/wallet/__tests__/wallet.rate-limit.test.d.ts +0 -2
- package/dist/wallet/__tests__/wallet.rate-limit.test.d.ts.map +0 -1
- package/dist/wallet/__tests__/wallet.rate-limit.test.js +0 -34
- package/dist/wallet/__tests__/wallet.rate-limit.test.js.map +0 -1
- package/dist/wallet/__tests__/wallet.router.test.d.ts +0 -2
- package/dist/wallet/__tests__/wallet.router.test.d.ts.map +0 -1
- package/dist/wallet/__tests__/wallet.router.test.js +0 -45
- package/dist/wallet/__tests__/wallet.router.test.js.map +0 -1
- package/dist/wallet/__tests__/wallet.service.test.d.ts +0 -2
- package/dist/wallet/__tests__/wallet.service.test.d.ts.map +0 -1
- package/dist/wallet/__tests__/wallet.service.test.js +0 -971
- package/dist/wallet/__tests__/wallet.service.test.js.map +0 -1
- package/turbo-generators/src/config.ts +0 -478
- package/turbo-generators/src/templates/adapter.hbs +0 -19
- package/turbo-generators/src/templates/contract.hbs +0 -18
- package/turbo-generators/src/templates/job-worker.hbs +0 -34
- package/turbo-generators/src/templates/module/agents.hbs +0 -67
- package/turbo-generators/src/templates/module/drizzle.config.hbs +0 -22
- package/turbo-generators/src/templates/module/index.hbs +0 -5
- package/turbo-generators/src/templates/module/migrate.hbs +0 -15
- package/turbo-generators/src/templates/module/package.json.hbs +0 -62
- package/turbo-generators/src/templates/module/plugin.hbs +0 -20
- package/turbo-generators/src/templates/module/router.hbs +0 -19
- package/turbo-generators/src/templates/module/schema.hbs +0 -21
- package/turbo-generators/src/templates/module/service.hbs +0 -26
- package/turbo-generators/src/templates/module/tsconfig.json.hbs +0 -8
- package/turbo-generators/src/templates/plugin.hbs +0 -20
- /package/{turbo-generators → generators}/src/templates/adr.hbs +0 -0
- /package/{turbo-generators → generators}/src/templates/config.hbs +0 -0
|
@@ -1,9 +1,18 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
1
2
|
import { ORPCError } from '@orpc/server';
|
|
2
|
-
import { createAuth, assertRateLimit, findOneOrThrow, makeNotFoundError, } from '@openora/core/server';
|
|
3
|
+
import { createAuth, assertRateLimit, extractClientMeta, getCurrentClientMeta, findOneOrThrow, makeConflictError, makeNotFoundError, createLogger, } from '@openora/core/server';
|
|
3
4
|
import { parseCookies } from 'better-auth/cookies';
|
|
4
|
-
import { eq, sql } from 'drizzle-orm';
|
|
5
|
+
import { and, eq, isNull, lte, ne, sql } from 'drizzle-orm';
|
|
6
|
+
import * as z from 'zod';
|
|
5
7
|
import { user, session, account, verification, twoFactor } from '../schema/index.js';
|
|
8
|
+
import { captureTimezone } from './capture-timezone.service.js';
|
|
9
|
+
import { maskEmail, maskPhone, } from './two-factor-delivery.service.js';
|
|
10
|
+
import { RATE_LIMIT_KEYS, makeRateLimitKey } from '@openora/core/contracts';
|
|
6
11
|
import { assertSupportedLanguage } from '../../shared/language.js';
|
|
12
|
+
import { assertAccountNotBlocked } from './rg-guard.service.js';
|
|
13
|
+
import { DEFAULT_LOCKOUT_DURATION_MS, DEFAULT_MAX_LOGIN_ATTEMPTS, computeLockoutTier, createAccountLockedError, hasFailedLoginWindowExpired, makeLoginSecurityState, } from './lockout-policy.service.js';
|
|
14
|
+
import { getSecurityControls } from './security-controls.service.js';
|
|
15
|
+
import { resolveChallengeMethod, verifyChallengeCode } from './two-factor-challenge.service.js';
|
|
7
16
|
function nodeHeadersToHeaders(nodeHeaders) {
|
|
8
17
|
const headers = new Headers();
|
|
9
18
|
for (const [key, value] of Object.entries(nodeHeaders)) {
|
|
@@ -14,14 +23,22 @@ function nodeHeadersToHeaders(nodeHeaders) {
|
|
|
14
23
|
}
|
|
15
24
|
return headers;
|
|
16
25
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
26
|
+
// Deletes every session row for `userId` created at or before `deadline`, except the
|
|
27
|
+
// caller's freshly minted one (matched by `sparedToken`), and returns the ids of what
|
|
28
|
+
// it deleted. Run a short delay after a password change: better-auth rotates the
|
|
29
|
+
// password hash and deletes sessions in separate, untransacted statements, so a
|
|
30
|
+
// sign-in that verified the OLD password just before the rotation can still insert
|
|
31
|
+
// its session row immediately after `deleteUserSessions()` ran. That row predates
|
|
32
|
+
// `deadline` (captured once the change is known committed), so this catches it while
|
|
33
|
+
// sparing anything created afterwards.
|
|
34
|
+
// Exported for direct testing; the service schedules it via setTimeout.
|
|
35
|
+
export async function sweepRacedSessionsAfterPasswordChange(db, params) {
|
|
36
|
+
const { userId, sparedToken, deadline } = params;
|
|
37
|
+
const deleted = await db
|
|
38
|
+
.delete(session)
|
|
39
|
+
.where(and(eq(session.userId, userId), ne(session.token, sparedToken), lte(session.createdAt, deadline)))
|
|
40
|
+
.returning({ id: session.id });
|
|
41
|
+
return deleted.map((row) => row.id);
|
|
25
42
|
}
|
|
26
43
|
function toIso(value) {
|
|
27
44
|
return value instanceof Date ? value.toISOString() : value;
|
|
@@ -31,22 +48,18 @@ function toUser(u) {
|
|
|
31
48
|
id: u.id,
|
|
32
49
|
email: u.email,
|
|
33
50
|
name: u.name,
|
|
51
|
+
username: u.username,
|
|
34
52
|
emailVerified: u.emailVerified,
|
|
35
53
|
theme: u.theme ?? 'system',
|
|
36
54
|
language: u.language ?? 'en',
|
|
55
|
+
twoFactorEnabled: u.twoFactorEnabled ?? false,
|
|
37
56
|
createdAt: toIso(u.createdAt),
|
|
38
57
|
updatedAt: toIso(u.updatedAt),
|
|
39
58
|
};
|
|
40
59
|
return u.image !== undefined ? { ...base, image: u.image } : base;
|
|
41
60
|
}
|
|
42
|
-
function
|
|
43
|
-
|
|
44
|
-
for (const cookie of cookies) {
|
|
45
|
-
resHeaders.append('set-cookie', cookie);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
function clientIp(headers) {
|
|
49
|
-
return headers.get('x-forwarded-for')?.split(',')[0]?.trim() || headers.get('x-real-ip') || null;
|
|
61
|
+
function makeLoginRateLimitKey(email) {
|
|
62
|
+
return `login:${email.toLowerCase()}`;
|
|
50
63
|
}
|
|
51
64
|
// Key on the `.two_factor` cookie VALUE, never the raw Cookie header: an attacker can
|
|
52
65
|
// otherwise churn the rate-limit key each retry by appending unrelated cookie pairs.
|
|
@@ -62,31 +75,113 @@ function twoFactorPendingCookieValue(headers) {
|
|
|
62
75
|
}
|
|
63
76
|
return undefined;
|
|
64
77
|
}
|
|
78
|
+
// A web Response exposes Set-Cookie as full attribute strings; a request carries only
|
|
79
|
+
// the name=value pairs.
|
|
80
|
+
function requestCookieHeader(res) {
|
|
81
|
+
return (res.headers.getSetCookie?.() ?? [])
|
|
82
|
+
.map((cookie) => {
|
|
83
|
+
const [pair = ''] = cookie.split(';');
|
|
84
|
+
return pair.trim();
|
|
85
|
+
})
|
|
86
|
+
.filter((pair) => pair.length > 0)
|
|
87
|
+
.join('; ');
|
|
88
|
+
}
|
|
89
|
+
function hasTrustDeviceCookie(headers) {
|
|
90
|
+
const cookieHeader = headers.get('cookie');
|
|
91
|
+
if (!cookieHeader) {
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
for (const [name] of parseCookies(cookieHeader)) {
|
|
95
|
+
if (name.endsWith('.trust_device')) {
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
// better-auth sets `<prefix>.dont_remember` when a user signs in with `rememberMe: false`.
|
|
102
|
+
// Presence is enough here: we only use it to shorten the caller's own rotated session,
|
|
103
|
+
// so a forged cookie can at worst clamp its owner's session earlier - never extend one.
|
|
104
|
+
function hasDontRememberCookie(headers) {
|
|
105
|
+
const cookieHeader = headers.get('cookie');
|
|
106
|
+
if (!cookieHeader) {
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
for (const [name] of parseCookies(cookieHeader)) {
|
|
110
|
+
if (name.endsWith('.dont_remember') || name === 'dont_remember') {
|
|
111
|
+
return true;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
// Drops the one pair and leaves every other byte alone: the cookies that stay carry
|
|
117
|
+
// signed, percent-encoded values better-auth re-verifies exactly as the browser sent them.
|
|
118
|
+
function withoutTrustDeviceCookie(headers) {
|
|
119
|
+
const cookieHeader = headers.get('cookie');
|
|
120
|
+
if (!cookieHeader) {
|
|
121
|
+
return headers;
|
|
122
|
+
}
|
|
123
|
+
const kept = cookieHeader
|
|
124
|
+
.split(';')
|
|
125
|
+
.map((pair) => pair.trim())
|
|
126
|
+
.filter((pair) => {
|
|
127
|
+
const [name = ''] = pair.split('=');
|
|
128
|
+
return !name.endsWith('.trust_device');
|
|
129
|
+
});
|
|
130
|
+
const next = new Headers(headers);
|
|
131
|
+
if (kept.length === 0) {
|
|
132
|
+
next.delete('cookie');
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
next.set('cookie', kept.join('; '));
|
|
136
|
+
}
|
|
137
|
+
return next;
|
|
138
|
+
}
|
|
65
139
|
const SUCCESS = { success: true };
|
|
66
140
|
export const UserNotFoundError = makeNotFoundError('User');
|
|
141
|
+
export const UsernameConflictError = makeConflictError('Username', 'Username is already in use');
|
|
142
|
+
const BetterAuthErrorBodySchema = z.object({
|
|
143
|
+
message: z.string().optional(),
|
|
144
|
+
code: z.string().optional(),
|
|
145
|
+
});
|
|
67
146
|
// better-auth calls use `asResponse: true`, which returns an error *Response*
|
|
68
147
|
// (4xx/5xx) rather than throwing. Surface those as ORPCErrors so oRPC maps them
|
|
69
148
|
// to the right HTTP status instead of the handler silently returning success.
|
|
70
149
|
// Only reads the body on failure, so a subsequent res.json() on success is safe.
|
|
71
|
-
|
|
150
|
+
// 401 -> UNAUTHORIZED (bad credentials), 403 -> FORBIDDEN (better-auth's
|
|
151
|
+
// TOO_MANY_ATTEMPTS on checkVerificationOTP/resetPasswordEmailOTP), else BAD_REQUEST.
|
|
152
|
+
// `opts.genericMessage` lets a BAD_REQUEST *or* FORBIDDEN caller opt into a fixed
|
|
153
|
+
// message instead of better-auth's raw one - some better-auth 400s (eg
|
|
154
|
+
// checkVerificationOTP's USER_NOT_FOUND-before-INVALID_OTP ordering) leak account
|
|
155
|
+
// existence otherwise. When genericMessage is set, a 403 is masked down to
|
|
156
|
+
// BAD_REQUEST too, so a caller can't tell "too many attempts" apart from "wrong code".
|
|
157
|
+
async function ensureOk(res, opts) {
|
|
72
158
|
if (res.ok) {
|
|
73
159
|
return;
|
|
74
160
|
}
|
|
161
|
+
const code = res.status === 401 ? 'UNAUTHORIZED' : res.status === 403 ? 'FORBIDDEN' : 'BAD_REQUEST';
|
|
162
|
+
if ((code === 'BAD_REQUEST' || code === 'FORBIDDEN') && opts?.genericMessage) {
|
|
163
|
+
throw new ORPCError(code === 'FORBIDDEN' ? 'BAD_REQUEST' : code, {
|
|
164
|
+
message: opts.genericMessage,
|
|
165
|
+
});
|
|
166
|
+
}
|
|
75
167
|
let message = `Request failed (${res.status})`;
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
168
|
+
let betterAuthCode;
|
|
169
|
+
const body = BetterAuthErrorBodySchema.safeParse(await res.json().catch(() => null));
|
|
170
|
+
if (body.success) {
|
|
171
|
+
if (body.data.message) {
|
|
172
|
+
message = body.data.message;
|
|
173
|
+
}
|
|
174
|
+
if (body.data.code) {
|
|
175
|
+
betterAuthCode = body.data.code;
|
|
80
176
|
}
|
|
81
177
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
178
|
+
throw new ORPCError(code, {
|
|
179
|
+
message,
|
|
180
|
+
...(betterAuthCode ? { data: { code: betterAuthCode } } : {}),
|
|
181
|
+
});
|
|
86
182
|
}
|
|
87
|
-
const DEFAULT_MAX_LOGIN_ATTEMPTS = 5;
|
|
88
|
-
const DEFAULT_LOCKOUT_DURATION_MS = 15 * 60 * 1000;
|
|
89
183
|
const MINUTE_MS = 60 * 1000;
|
|
184
|
+
export const SESSION_DURATION_IN_SECONDS = 30 * 24 * 60 * 60; // 30 days
|
|
90
185
|
// Coarse abuse throttles keyed by the caller identifier the context provides (email/
|
|
91
186
|
// token/session), NOT IP. The lockout above is a per-account credential-failure
|
|
92
187
|
// counter; these bound raw request volume on each brute-force surface. An overlay
|
|
@@ -96,29 +191,76 @@ const MINUTE_MS = 60 * 1000;
|
|
|
96
191
|
// throttles (register/resend/etc.) keep the default fail-open.
|
|
97
192
|
const LOGIN_RATE_LIMIT = { limit: 10, windowMs: 5 * MINUTE_MS, onUnavailable: 'deny' };
|
|
98
193
|
const REGISTER_RATE_LIMIT = { limit: 5, windowMs: 15 * MINUTE_MS };
|
|
194
|
+
// Keyed on the caller, not the handle: the abuse shape here is enumerating many
|
|
195
|
+
// usernames from one client, not probing one username repeatedly.
|
|
196
|
+
const USERNAME_AVAILABILITY_RATE_LIMIT = { limit: 30, windowMs: MINUTE_MS };
|
|
99
197
|
const PASSWORD_RESET_REQUEST_RATE_LIMIT = { limit: 3, windowMs: 15 * MINUTE_MS };
|
|
100
198
|
const PASSWORD_RESET_RATE_LIMIT = {
|
|
101
199
|
limit: 5,
|
|
102
200
|
windowMs: 15 * MINUTE_MS,
|
|
103
201
|
onUnavailable: 'deny',
|
|
104
202
|
};
|
|
203
|
+
const PASSWORD_RESET_VERIFY_RATE_LIMIT = {
|
|
204
|
+
limit: 5,
|
|
205
|
+
windowMs: 5 * MINUTE_MS,
|
|
206
|
+
onUnavailable: 'deny',
|
|
207
|
+
};
|
|
105
208
|
const VERIFY_2FA_RATE_LIMIT = { limit: 5, windowMs: 5 * MINUTE_MS, onUnavailable: 'deny' };
|
|
106
|
-
|
|
107
|
-
|
|
209
|
+
// Fails closed with the verify budget below: better-auth issues a fresh code (and a fresh
|
|
210
|
+
// 3-attempt counter) per resend, so an unbounded resend loop is an unbounded guess budget.
|
|
211
|
+
const EMAIL_VERIFICATION_RATE_LIMIT = {
|
|
212
|
+
limit: 3,
|
|
213
|
+
windowMs: 15 * MINUTE_MS,
|
|
214
|
+
onUnavailable: 'deny',
|
|
215
|
+
};
|
|
216
|
+
// Fails closed like the other secret-guessing budgets: the emailed code is six digits,
|
|
217
|
+
// so an unthrottled window is a brute-force window, not a degraded-UX window.
|
|
218
|
+
const VERIFY_EMAIL_RATE_LIMIT = {
|
|
219
|
+
limit: 5,
|
|
220
|
+
windowMs: 15 * MINUTE_MS,
|
|
221
|
+
onUnavailable: 'deny',
|
|
222
|
+
};
|
|
108
223
|
const CHANGE_PASSWORD_RATE_LIMIT = { limit: 5, windowMs: 15 * MINUTE_MS };
|
|
224
|
+
// How long after a password change to re-sweep the user's sessions for a row that a
|
|
225
|
+
// concurrent old-password sign-in raced in just after better-auth's revoke ran. This
|
|
226
|
+
// is the residual exposure window; keep it short.
|
|
227
|
+
const RACED_SESSION_SWEEP_DELAY_MS = 2_000;
|
|
228
|
+
// better-auth's `createSession` gives a `dontRememberMe` session this fixed TTL
|
|
229
|
+
// (`getDate(3600 * 24, 'sec')`). `revokeOtherSessions` mints the caller's replacement
|
|
230
|
+
// session without that flag, so we re-apply the clamp when the request carries the
|
|
231
|
+
// `dont_remember` cookie. Matches `SESSION_TTL_MS` in phone-login.service.
|
|
232
|
+
const DONT_REMEMBER_SESSION_TTL_MS = 24 * 60 * 60 * 1000;
|
|
109
233
|
const TWO_FACTOR_PASSWORD_RATE_LIMIT = { limit: 5, windowMs: 5 * MINUTE_MS };
|
|
110
|
-
//
|
|
111
|
-
//
|
|
112
|
-
|
|
234
|
+
// Fails closed: every call spends real money on an `sms` enrolment and fills a mailbox
|
|
235
|
+
// on an `email` one, and better-auth issues a fresh code per send, so an unbounded
|
|
236
|
+
// resend loop is both a toll-fraud channel and an unbounded guess budget.
|
|
237
|
+
const SEND_2FA_OTP_RATE_LIMIT = {
|
|
238
|
+
limit: 3,
|
|
239
|
+
windowMs: 5 * MINUTE_MS,
|
|
240
|
+
onUnavailable: 'deny',
|
|
241
|
+
};
|
|
242
|
+
const ANTI_PHISHING_CODE_RATE_LIMIT = {
|
|
243
|
+
limit: 5,
|
|
244
|
+
windowMs: 5 * MINUTE_MS,
|
|
245
|
+
onUnavailable: 'deny',
|
|
246
|
+
};
|
|
247
|
+
const FAKE_LOGIN_SHADOW_TTL_MS = 7 * 24 * 60 * 60 * 1000;
|
|
248
|
+
function loginShadowKey(email) {
|
|
249
|
+
return `login-shadow:${email}`;
|
|
250
|
+
}
|
|
251
|
+
const loginShadowLogger = createLogger('login-shadow');
|
|
252
|
+
const identityLogger = createLogger('identity');
|
|
253
|
+
function hasErrorCode(error, code) {
|
|
254
|
+
if (typeof error !== 'object' || error === null || !('data' in error)) {
|
|
255
|
+
return false;
|
|
256
|
+
}
|
|
257
|
+
const data = error.data;
|
|
258
|
+
return typeof data === 'object' && data !== null && 'code' in data && data.code === code;
|
|
259
|
+
}
|
|
113
260
|
function computeLockoutState({ attempts, maxAttempts, durationMs, nowMs, }) {
|
|
114
261
|
const isLocking = attempts >= maxAttempts;
|
|
115
262
|
return { isLocking, lockoutUntil: isLocking ? new Date(nowMs + durationMs) : null };
|
|
116
263
|
}
|
|
117
|
-
// A finite rgBlockedUntil in the past = a lapsed cooling-off; a null one = indefinite
|
|
118
|
-
// (self-exclusion / permanent). Blocked only while set and not elapsed.
|
|
119
|
-
function isRgBlocked(u) {
|
|
120
|
-
return u.rgBlocked && (u.rgBlockedUntil === null || u.rgBlockedUntil > new Date());
|
|
121
|
-
}
|
|
122
264
|
/**
|
|
123
265
|
* Thin wrapper over the shared better-auth instance (register/login/2FA/
|
|
124
266
|
* password/email flows) that layers on platform-specific policy better-auth
|
|
@@ -132,44 +274,303 @@ export class IdentityService {
|
|
|
132
274
|
auth;
|
|
133
275
|
drizzle;
|
|
134
276
|
events;
|
|
135
|
-
|
|
277
|
+
identityReader;
|
|
278
|
+
mailDispatch;
|
|
136
279
|
options;
|
|
137
280
|
limiter;
|
|
138
281
|
platformConfig;
|
|
139
|
-
|
|
282
|
+
playerProvisioning;
|
|
283
|
+
geoCheck;
|
|
284
|
+
cache;
|
|
285
|
+
// Addresses whose reset code is being sent because a sign-up hit an existing account.
|
|
286
|
+
// Held only for the duration of that send: `requestPasswordResetEmailOTP` drives
|
|
287
|
+
// `sendVerificationOTP` -> `render` inside the same await, so the flag is read before
|
|
288
|
+
// the `finally` clears it. Not cache-backed - it never has to outlive the call or
|
|
289
|
+
// cross a process.
|
|
290
|
+
existingAccountSignUps = new Set();
|
|
291
|
+
trustedDevices;
|
|
292
|
+
twoFactorLockout;
|
|
293
|
+
twoFactorDelivery;
|
|
294
|
+
sessions;
|
|
295
|
+
constructor({ drizzle, events, identityReader, mailDispatch, options, limiter, platformConfig, geoCheck, playerProvisioning, cache, trustedDevices, twoFactorLockout, twoFactorDelivery, sessions, }) {
|
|
140
296
|
this.drizzle = drizzle;
|
|
141
297
|
this.events = events;
|
|
142
|
-
this.
|
|
298
|
+
this.identityReader = identityReader;
|
|
299
|
+
this.mailDispatch = mailDispatch;
|
|
143
300
|
this.options = options;
|
|
144
301
|
this.limiter = limiter;
|
|
145
302
|
this.platformConfig = platformConfig;
|
|
303
|
+
this.geoCheck = geoCheck;
|
|
304
|
+
this.playerProvisioning = playerProvisioning;
|
|
305
|
+
this.cache = cache;
|
|
306
|
+
this.trustedDevices = trustedDevices;
|
|
307
|
+
this.twoFactorLockout = twoFactorLockout;
|
|
308
|
+
this.twoFactorDelivery = twoFactorDelivery;
|
|
309
|
+
this.sessions = sessions;
|
|
146
310
|
this.auth = createAuth({
|
|
147
311
|
db: drizzle.db,
|
|
148
312
|
schema: { user, session, account, verification, twoFactor },
|
|
149
|
-
...(
|
|
313
|
+
...(mailDispatch
|
|
314
|
+
? {
|
|
315
|
+
dispatchOtpMail: async ({ to, template }) => {
|
|
316
|
+
const idempotencyKey = `otp:${template.key}:${randomUUID()}`;
|
|
317
|
+
const recipient = await this.findUserByEmail(to);
|
|
318
|
+
if (recipient) {
|
|
319
|
+
await mailDispatch.toUser({ userId: recipient.id, template, idempotencyKey });
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
await mailDispatch.toAddress({ email: to, template, idempotencyKey });
|
|
323
|
+
},
|
|
324
|
+
}
|
|
325
|
+
: {}),
|
|
326
|
+
// Binds the plugin's OTP hook to the transport fan-out. Without it better-auth
|
|
327
|
+
// still mints codes for the `email`/`sms` methods and drops them on the floor.
|
|
328
|
+
twoFactor: { sendOtp: (args) => twoFactorDelivery.deliver(args) },
|
|
329
|
+
requireEmailVerification: this.platformConfig?.registration?.requireEmailVerification ?? false,
|
|
330
|
+
isExistingAccountSignUp: (lookupEmail) => this.existingAccountSignUps.has(lookupEmail.toLowerCase()),
|
|
331
|
+
isAdminPasswordReset: (lookupEmail) => this.isAdminPasswordReset(lookupEmail),
|
|
332
|
+
onExistingUserSignUp: async (existing) => {
|
|
333
|
+
const key = existing.email.toLowerCase();
|
|
334
|
+
this.existingAccountSignUps.add(key);
|
|
335
|
+
try {
|
|
336
|
+
const response = await this.api.requestPasswordResetEmailOTP({
|
|
337
|
+
body: { email: existing.email },
|
|
338
|
+
headers: new Headers(),
|
|
339
|
+
asResponse: true,
|
|
340
|
+
});
|
|
341
|
+
await ensureOk(response);
|
|
342
|
+
}
|
|
343
|
+
finally {
|
|
344
|
+
this.existingAccountSignUps.delete(key);
|
|
345
|
+
}
|
|
346
|
+
},
|
|
347
|
+
onPasswordReset: async (resetUser) => {
|
|
348
|
+
await this.drizzle.db
|
|
349
|
+
.update(user)
|
|
350
|
+
.set({ passwordMeetsPolicy: true })
|
|
351
|
+
.where(eq(user.id, resetUser.id));
|
|
352
|
+
this.events.emit('identity.password.reset', {
|
|
353
|
+
userId: resetUser.id,
|
|
354
|
+
playerId: await this.identityReader.getPlayerIdByUserIdSafe(resetUser.id),
|
|
355
|
+
...getCurrentClientMeta(),
|
|
356
|
+
});
|
|
357
|
+
await this.clearLockout(resetUser.id);
|
|
358
|
+
},
|
|
150
359
|
});
|
|
151
360
|
}
|
|
361
|
+
async findUserByEmail(email) {
|
|
362
|
+
const [row] = await this.drizzle.db
|
|
363
|
+
.select({ id: user.id })
|
|
364
|
+
.from(user)
|
|
365
|
+
.where(eq(user.email, email.toLowerCase()))
|
|
366
|
+
.limit(1);
|
|
367
|
+
return row;
|
|
368
|
+
}
|
|
152
369
|
get api() {
|
|
153
370
|
// Library boundary: the admin/organization plugin endpoints aren't on better-auth's
|
|
154
371
|
// base `api` type. Sanctioned cast, see conventions.
|
|
155
372
|
return this.auth.api;
|
|
156
373
|
}
|
|
374
|
+
forwardCookies(authResponse, resHeaders) {
|
|
375
|
+
const cookies = authResponse.headers.getSetCookie?.() ?? [];
|
|
376
|
+
for (const cookie of cookies) {
|
|
377
|
+
resHeaders.append('set-cookie', cookie);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
157
380
|
async currentUserId(headers) {
|
|
158
|
-
|
|
159
|
-
|
|
381
|
+
return (await this.currentSession(headers))?.userId ?? null;
|
|
382
|
+
}
|
|
383
|
+
// Both the caller's userId and the id of the session row they are authenticating
|
|
384
|
+
// with, for handlers that must tell the caller's own device apart from their others
|
|
385
|
+
// (eg sparing the acting session from a revoke-all).
|
|
386
|
+
async currentSession(headers) {
|
|
387
|
+
const resolved = await this.auth.api.getSession({ headers });
|
|
388
|
+
const userId = resolved?.user?.id;
|
|
389
|
+
return userId ? { userId, sessionId: resolved?.session?.id } : null;
|
|
390
|
+
}
|
|
391
|
+
async securityControlsFor(userId) {
|
|
392
|
+
// 0 when trusted devices are not wired at all (some deployments), matching what
|
|
393
|
+
// `trust()` itself does with a non-positive `trustedDeviceDays`: a client reading 0
|
|
394
|
+
// knows the offer is not real anywhere it might otherwise render one.
|
|
395
|
+
const controls = await getSecurityControls(this.drizzle, userId, this.trustedDevices?.getTrustedDeviceDays() ?? 0);
|
|
396
|
+
if (!controls) {
|
|
397
|
+
throw new UserNotFoundError(userId);
|
|
398
|
+
}
|
|
399
|
+
return controls;
|
|
400
|
+
}
|
|
401
|
+
// Same gate as password login and phone login, from the one shared implementation.
|
|
402
|
+
assertAccountNotBlocked(account, meta) {
|
|
403
|
+
return assertAccountNotBlocked({ drizzle: this.drizzle, events: this.events }, account, meta, {
|
|
404
|
+
revokeSessions: true,
|
|
405
|
+
errorData: { rgBlocked: { code: 'RG_BLOCKED' }, suspended: { code: 'ACCOUNT_SUSPENDED' } },
|
|
406
|
+
});
|
|
160
407
|
}
|
|
161
|
-
|
|
162
|
-
|
|
408
|
+
/**
|
|
409
|
+
* Emitted on every registration attempt that produced no account. The audit trail is
|
|
410
|
+
* the one place that records what actually happened - the HTTP response deliberately
|
|
411
|
+
* does not, because a truthful answer on a known address is an enumeration oracle.
|
|
412
|
+
*/
|
|
413
|
+
emitRegistrationFailed(reason, input, { ip, userAgent }) {
|
|
414
|
+
this.events.emit('identity.user.registration.failed', {
|
|
415
|
+
email: input.email,
|
|
416
|
+
username: input.username,
|
|
417
|
+
reason,
|
|
418
|
+
ip,
|
|
419
|
+
userAgent,
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
async register(input, reqHeaders) {
|
|
423
|
+
// Read before the config guard: a rejected attempt is audited too, and an audit row
|
|
424
|
+
// with no origin is barely a record.
|
|
425
|
+
const { ip, userAgent } = extractClientMeta(reqHeaders);
|
|
426
|
+
const meta = { ip, userAgent };
|
|
427
|
+
const registration = this.platformConfig?.registration;
|
|
428
|
+
const provisioning = this.playerProvisioning;
|
|
429
|
+
if (!registration || !provisioning) {
|
|
430
|
+
this.emitRegistrationFailed('registration_disabled', input, meta);
|
|
431
|
+
throw new ORPCError('FORBIDDEN', { message: 'Registration is unavailable' });
|
|
432
|
+
}
|
|
433
|
+
// `assertRateLimit` throws and is shared by a dozen call sites, so the emit wraps it
|
|
434
|
+
// here rather than moving into it.
|
|
435
|
+
try {
|
|
436
|
+
await assertRateLimit(this.limiter, `register:${input.email.toLowerCase()}`, REGISTER_RATE_LIMIT);
|
|
437
|
+
await assertRateLimit(this.limiter, `register-ip:${ip ?? 'unknown'}`, REGISTER_RATE_LIMIT);
|
|
438
|
+
}
|
|
439
|
+
catch (err) {
|
|
440
|
+
this.emitRegistrationFailed('rate_limited', input, meta);
|
|
441
|
+
throw err;
|
|
442
|
+
}
|
|
443
|
+
if (this.geoCheck && !(await this.geoCheck.checkRegistration(ip)).allowed) {
|
|
444
|
+
this.emitRegistrationFailed('geo_blocked', input, meta);
|
|
445
|
+
throw new ORPCError('FORBIDDEN', { message: 'Registration is unavailable' });
|
|
446
|
+
}
|
|
163
447
|
const headers = nodeHeadersToHeaders(reqHeaders);
|
|
164
|
-
const authResponse = await this.
|
|
165
|
-
body: {
|
|
448
|
+
const authResponse = await this.api.signUpEmail({
|
|
449
|
+
body: {
|
|
450
|
+
email: input.email,
|
|
451
|
+
password: input.password,
|
|
452
|
+
name: input.username,
|
|
453
|
+
username: input.username,
|
|
454
|
+
},
|
|
166
455
|
headers,
|
|
167
456
|
asResponse: true,
|
|
168
457
|
});
|
|
169
|
-
|
|
458
|
+
if (!authResponse.ok) {
|
|
459
|
+
// The `lower(username)` unique index is the only arbiter - a pre-flight check
|
|
460
|
+
// could not close the race anyway, so the taken handle is read off the failure.
|
|
461
|
+
if (await this.findUserIdByUsername(input.username)) {
|
|
462
|
+
this.emitRegistrationFailed('username_taken', input, meta);
|
|
463
|
+
throw new UsernameConflictError();
|
|
464
|
+
}
|
|
465
|
+
// `ensureOk` always throws on a non-ok response, so emitting first needs no catch.
|
|
466
|
+
this.emitRegistrationFailed('error', input, meta);
|
|
467
|
+
await ensureOk(authResponse, { genericMessage: 'Registration is unavailable' });
|
|
468
|
+
}
|
|
170
469
|
const body = (await authResponse.json());
|
|
171
|
-
|
|
172
|
-
|
|
470
|
+
// A known address gets an indistinguishable success response (and a reset mail)
|
|
471
|
+
// rather than a new account, so only a genuinely new user is provisioned.
|
|
472
|
+
if ((await this.findUserIdByEmail(input.email)) !== body.user.id) {
|
|
473
|
+
// The known-address branch: no account was created, so the attempt failed even
|
|
474
|
+
// though the caller is told it succeeded. Only the audit trail says so.
|
|
475
|
+
this.emitRegistrationFailed('email_already_registered', input, meta);
|
|
476
|
+
return { status: 'check-email' };
|
|
477
|
+
}
|
|
478
|
+
await this.drizzle.db
|
|
479
|
+
.update(user)
|
|
480
|
+
.set({ passwordMeetsPolicy: true })
|
|
481
|
+
.where(eq(user.id, body.user.id));
|
|
482
|
+
let consent;
|
|
483
|
+
try {
|
|
484
|
+
consent = await this.recordRegistrationConsent(provisioning, body.user.id, registration.termsVersion, { ip, userAgent });
|
|
485
|
+
}
|
|
486
|
+
catch (err) {
|
|
487
|
+
this.emitRegistrationFailed('error', input, meta);
|
|
488
|
+
throw err;
|
|
489
|
+
}
|
|
490
|
+
const { playerId, consentStored } = consent;
|
|
491
|
+
// After the consent write, which is what materialises the player row the zone lands on.
|
|
492
|
+
// No session yet, but the browser is here now and a first login may be days away.
|
|
493
|
+
await captureTimezone(this.playerProvisioning, body.user.id, input.timezone);
|
|
494
|
+
this.events.emit('identity.user.registered', {
|
|
495
|
+
userId: body.user.id,
|
|
496
|
+
playerId: playerId ?? (await this.identityReader.getPlayerIdByUserIdSafe(body.user.id)),
|
|
497
|
+
// Only claimed when the consent row was actually written - a discarded capture
|
|
498
|
+
// must not leave an audit trail implying evidence that does not exist.
|
|
499
|
+
...(consentStored
|
|
500
|
+
? {
|
|
501
|
+
termsVersion: registration.termsVersion,
|
|
502
|
+
acceptedTerms: input.acceptedTerms,
|
|
503
|
+
acceptedAge: input.acceptedAge,
|
|
504
|
+
}
|
|
505
|
+
: {}),
|
|
506
|
+
ip,
|
|
507
|
+
userAgent,
|
|
508
|
+
});
|
|
509
|
+
// Sent here rather than by better-auth's sendOnSignUp hook: that hook also fires on
|
|
510
|
+
// the synthetic duplicate-email response, mailing a live code to an address whose
|
|
511
|
+
// owner never asked for it - and `verifyEmail` signs that code's bearer in.
|
|
512
|
+
// A mail failure is logged, never surfaced: the account exists either way and the
|
|
513
|
+
// player can ask for a new code, so failing the call here would only mislead them.
|
|
514
|
+
const otpResponse = await this.api.sendVerificationOTP({
|
|
515
|
+
body: { email: input.email, type: 'email-verification' },
|
|
516
|
+
headers,
|
|
517
|
+
asResponse: true,
|
|
518
|
+
});
|
|
519
|
+
if (!otpResponse.ok) {
|
|
520
|
+
identityLogger.error({ userId: body.user.id, status: otpResponse.status }, 'verification code could not be sent - player must request a new one');
|
|
521
|
+
}
|
|
522
|
+
return { status: 'check-email' };
|
|
523
|
+
}
|
|
524
|
+
async findUserIdByUsername(username) {
|
|
525
|
+
const [row] = await this.drizzle.db
|
|
526
|
+
.select({ id: user.id })
|
|
527
|
+
.from(user)
|
|
528
|
+
.where(eq(sql `lower(${user.username})`, username.toLowerCase()))
|
|
529
|
+
.limit(1);
|
|
530
|
+
return row?.id ?? null;
|
|
531
|
+
}
|
|
532
|
+
async findUserIdByEmail(email) {
|
|
533
|
+
const [row] = await this.drizzle.db
|
|
534
|
+
.select({ id: user.id })
|
|
535
|
+
.from(user)
|
|
536
|
+
.where(eq(user.email, email.toLowerCase()))
|
|
537
|
+
.limit(1);
|
|
538
|
+
return row?.id ?? null;
|
|
539
|
+
}
|
|
540
|
+
/**
|
|
541
|
+
* Better Auth commits the user inside its own transaction before returning, so a
|
|
542
|
+
* failure here would otherwise leave an account with no consent record. The user is
|
|
543
|
+
* deleted instead (sessions and accounts cascade), making registration all-or-nothing.
|
|
544
|
+
*/
|
|
545
|
+
async recordRegistrationConsent(provisioning, userId, termsVersion, { ip, userAgent }) {
|
|
546
|
+
const now = new Date();
|
|
547
|
+
let outcome;
|
|
548
|
+
try {
|
|
549
|
+
outcome = await provisioning.createForRegistration({
|
|
550
|
+
userId,
|
|
551
|
+
termsVersion,
|
|
552
|
+
termsAcceptedAt: now,
|
|
553
|
+
ageAcceptedAt: now,
|
|
554
|
+
registrationIp: ip,
|
|
555
|
+
registrationUserAgent: userAgent,
|
|
556
|
+
});
|
|
557
|
+
}
|
|
558
|
+
catch (err) {
|
|
559
|
+
identityLogger.error({ err, userId }, 'registration consent write failed - rolling back user');
|
|
560
|
+
await this.drizzle.db.delete(user).where(eq(user.id, userId));
|
|
561
|
+
throw new ORPCError('INTERNAL_SERVER_ERROR', { message: 'Registration is unavailable' });
|
|
562
|
+
}
|
|
563
|
+
if (!outcome.created) {
|
|
564
|
+
// A player row already existed, so this consent capture was discarded. Never
|
|
565
|
+
// silent: the acceptance evidence is a compliance record.
|
|
566
|
+
identityLogger.error({ userId, termsVersion }, 'registration consent not stored - player row already existed');
|
|
567
|
+
}
|
|
568
|
+
return { playerId: outcome.playerId ?? null, consentStored: outcome.created };
|
|
569
|
+
}
|
|
570
|
+
async usernameAvailable(username, reqHeaders) {
|
|
571
|
+
const { ip } = extractClientMeta(reqHeaders);
|
|
572
|
+
await assertRateLimit(this.limiter, `check-username:${ip ?? 'unknown'}`, USERNAME_AVAILABILITY_RATE_LIMIT);
|
|
573
|
+
return { available: !(await this.findUserIdByUsername(username)) };
|
|
173
574
|
}
|
|
174
575
|
/**
|
|
175
576
|
* Credentials are verified FIRST; the RG login block is checked only AFTER
|
|
@@ -184,12 +585,11 @@ export class IdentityService {
|
|
|
184
585
|
* read a stale count and slip past the lockout threshold.
|
|
185
586
|
*/
|
|
186
587
|
async login(input, reqHeaders, resHeaders) {
|
|
588
|
+
const { ip, userAgent } = extractClientMeta(reqHeaders);
|
|
187
589
|
const headers = nodeHeadersToHeaders(reqHeaders);
|
|
188
|
-
const ip = clientIp(headers);
|
|
189
|
-
const userAgent = headers.get('user-agent') || null;
|
|
190
590
|
// better-auth lowercases emails on write, so the lockout lookup must match on the same form.
|
|
191
591
|
const email = input.email.toLowerCase();
|
|
192
|
-
await assertRateLimit(this.limiter,
|
|
592
|
+
await assertRateLimit(this.limiter, makeLoginRateLimitKey(email), LOGIN_RATE_LIMIT);
|
|
193
593
|
const configLockoutEnabled = this.options?.lockout?.enabled ?? true;
|
|
194
594
|
// Read once for the lockout budget, the admin-bypass check, and the RG login gate
|
|
195
595
|
// (indexed email lookup). Read unconditionally - the RG gate runs even when lockout
|
|
@@ -199,9 +599,13 @@ export class IdentityService {
|
|
|
199
599
|
id: user.id,
|
|
200
600
|
failedLoginAttempts: user.failedLoginAttempts,
|
|
201
601
|
lockoutUntil: user.lockoutUntil,
|
|
602
|
+
lockoutCount: user.lockoutCount,
|
|
603
|
+
lastLockoutAt: user.lastLockoutAt,
|
|
604
|
+
lastFailedLoginAt: user.lastFailedLoginAt,
|
|
202
605
|
role: user.role,
|
|
203
606
|
rgBlocked: user.rgBlocked,
|
|
204
607
|
rgBlockedUntil: user.rgBlockedUntil,
|
|
608
|
+
requireTwoFactorOnLogin: user.requireTwoFactorOnLogin,
|
|
205
609
|
})
|
|
206
610
|
.from(user)
|
|
207
611
|
.where(eq(user.email, email))
|
|
@@ -210,8 +614,9 @@ export class IdentityService {
|
|
|
210
614
|
const isAdmin = existingUser?.role === 'admin';
|
|
211
615
|
const bypassForAdmins = this.options?.lockout?.bypassForAdmins ?? false;
|
|
212
616
|
const lockoutEnabled = configLockoutEnabled && !(isAdmin && bypassForAdmins);
|
|
617
|
+
const nowMs = Date.now();
|
|
213
618
|
if (lockoutEnabled && existingUser?.lockoutUntil) {
|
|
214
|
-
if (new Date(existingUser.lockoutUntil) > new Date()) {
|
|
619
|
+
if (new Date(existingUser.lockoutUntil) > new Date(nowMs)) {
|
|
215
620
|
throw createAccountLockedError(new Date(existingUser.lockoutUntil));
|
|
216
621
|
}
|
|
217
622
|
// Lock window elapsed: clear it so the next failure starts from a fresh budget
|
|
@@ -219,78 +624,193 @@ export class IdentityService {
|
|
|
219
624
|
await this.clearLockout(existingUser.id);
|
|
220
625
|
existingUser = { ...existingUser, failedLoginAttempts: 0, lockoutUntil: null };
|
|
221
626
|
}
|
|
627
|
+
if (lockoutEnabled &&
|
|
628
|
+
existingUser &&
|
|
629
|
+
hasFailedLoginWindowExpired(existingUser.lastFailedLoginAt, existingUser.lastLockoutAt, nowMs)) {
|
|
630
|
+
await this.resetLockoutTier(existingUser.id);
|
|
631
|
+
existingUser = {
|
|
632
|
+
...existingUser,
|
|
633
|
+
failedLoginAttempts: 0,
|
|
634
|
+
lockoutUntil: null,
|
|
635
|
+
lockoutCount: 0,
|
|
636
|
+
lastLockoutAt: null,
|
|
637
|
+
lastFailedLoginAt: null,
|
|
638
|
+
};
|
|
639
|
+
}
|
|
640
|
+
let fakeLoginShadow;
|
|
641
|
+
if (lockoutEnabled && !existingUser) {
|
|
642
|
+
fakeLoginShadow = await this.loginShadowGet(loginShadowKey(email));
|
|
643
|
+
if (fakeLoginShadow?.lastFailedLoginAt) {
|
|
644
|
+
const lastFailedLoginAt = new Date(fakeLoginShadow.lastFailedLoginAt);
|
|
645
|
+
if (hasFailedLoginWindowExpired(lastFailedLoginAt, null, nowMs)) {
|
|
646
|
+
fakeLoginShadow = {
|
|
647
|
+
failedAttempts: 0,
|
|
648
|
+
lockoutUntil: null,
|
|
649
|
+
lockoutCount: 0,
|
|
650
|
+
lastLockoutAt: null,
|
|
651
|
+
lastFailedLoginAt: null,
|
|
652
|
+
};
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
if (fakeLoginShadow?.lockoutUntil) {
|
|
656
|
+
if (new Date(fakeLoginShadow.lockoutUntil) > new Date()) {
|
|
657
|
+
throw createAccountLockedError(new Date(fakeLoginShadow.lockoutUntil));
|
|
658
|
+
}
|
|
659
|
+
fakeLoginShadow = { ...fakeLoginShadow, failedAttempts: 0, lockoutUntil: null };
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
// better-auth honours its trust-device cookie on its own and offers no way to revoke
|
|
663
|
+
// one. The revocable half of a trusted device is the row this module keeps, so a login
|
|
664
|
+
// presenting the cookie without a live row has to fall back to the full challenge.
|
|
665
|
+
let signInHeaders = headers;
|
|
666
|
+
if (existingUser && this.trustedDevices && hasTrustDeviceCookie(headers)) {
|
|
667
|
+
// "Require 2FA every login" outranks the cookie outright, so no lookup is needed -
|
|
668
|
+
// how well this browser is trusted stops mattering while the preference holds.
|
|
669
|
+
const trusted = !existingUser.requireTwoFactorOnLogin &&
|
|
670
|
+
(await this.trustedDevices.isTrusted(existingUser.id, userAgent));
|
|
671
|
+
if (!trusted) {
|
|
672
|
+
signInHeaders = withoutTrustDeviceCookie(headers);
|
|
673
|
+
}
|
|
674
|
+
}
|
|
222
675
|
try {
|
|
223
676
|
const authResponse = await this.auth.api.signInEmail({
|
|
224
677
|
body: { email, password: input.password, rememberMe: input.rememberMe },
|
|
225
|
-
headers,
|
|
678
|
+
headers: signInHeaders,
|
|
226
679
|
asResponse: true,
|
|
227
680
|
});
|
|
228
681
|
await ensureOk(authResponse);
|
|
229
|
-
// RG
|
|
230
|
-
// distinguish a restricted account from a wrong password.
|
|
231
|
-
//
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
.set({ expiresAt: new Date() })
|
|
237
|
-
.where(eq(session.userId, existingUser.id));
|
|
238
|
-
this.events.emit('rg.exclusion.login_blocked', { userId: existingUser.id, ip, userAgent });
|
|
239
|
-
throw new ORPCError('FORBIDDEN', {
|
|
240
|
-
message: 'Account access is currently restricted (responsible gambling).',
|
|
241
|
-
});
|
|
242
|
-
}
|
|
243
|
-
forwardCookies(authResponse, resHeaders);
|
|
682
|
+
// RG and backoffice blocks, applied only AFTER credentials verify so a pre-auth
|
|
683
|
+
// probe can't distinguish a restricted account from a wrong password. Resolves
|
|
684
|
+
// playerId once, so the eventual login success event can carry it too.
|
|
685
|
+
const playerId = existingUser
|
|
686
|
+
? await this.assertAccountNotBlocked(existingUser, { ip, userAgent })
|
|
687
|
+
: null;
|
|
688
|
+
this.forwardCookies(authResponse, resHeaders);
|
|
244
689
|
const body = (await authResponse.json());
|
|
245
690
|
if (body.twoFactorRedirect || !body.user || !body.token) {
|
|
246
|
-
|
|
691
|
+
// The challenge screen has to know whether to ask for an authenticator code or
|
|
692
|
+
// to push one, and there is no session yet to read the account's method from.
|
|
693
|
+
// Naming it here reveals nothing the challenge would not show anyway. Same for
|
|
694
|
+
// the trust window: an operator's configured length is not account-specific.
|
|
695
|
+
return {
|
|
696
|
+
twoFactorRedirect: true,
|
|
697
|
+
trustedDeviceDays: this.trustedDevices?.getTrustedDeviceDays() ?? 0,
|
|
698
|
+
...(existingUser
|
|
699
|
+
? { twoFactorMethod: await this.resolveTwoFactorMethod(existingUser.id) }
|
|
700
|
+
: {}),
|
|
701
|
+
};
|
|
247
702
|
}
|
|
248
703
|
if (lockoutEnabled && existingUser) {
|
|
249
704
|
await this.clearLockout(existingUser.id);
|
|
250
705
|
}
|
|
251
|
-
this.
|
|
706
|
+
await this.drizzle.db
|
|
707
|
+
.update(session)
|
|
708
|
+
.set({ ipAddress: ip, userAgent })
|
|
709
|
+
.where(eq(session.token, body.token));
|
|
710
|
+
this.events.emit('identity.user.login', {
|
|
711
|
+
userId: body.user.id,
|
|
712
|
+
playerId,
|
|
713
|
+
ip,
|
|
714
|
+
userAgent,
|
|
715
|
+
});
|
|
716
|
+
this.events.emit('identity.authentication.succeeded', {
|
|
717
|
+
userId: body.user.id,
|
|
718
|
+
playerId,
|
|
719
|
+
method: 'password',
|
|
720
|
+
ip,
|
|
721
|
+
userAgent,
|
|
722
|
+
});
|
|
723
|
+
await captureTimezone(this.playerProvisioning, body.user.id, input.timezone);
|
|
724
|
+
const sessionDurationSeconds = this.auth.options.session?.expiresIn ?? SESSION_DURATION_IN_SECONDS;
|
|
252
725
|
const expiresAt = body.session?.expiresAt
|
|
253
726
|
? toIso(body.session.expiresAt)
|
|
254
|
-
: new Date(Date.now() +
|
|
727
|
+
: new Date(Date.now() + sessionDurationSeconds * 1000).toISOString();
|
|
255
728
|
return {
|
|
256
729
|
user: toUser(body.user),
|
|
257
730
|
session: { token: body.token, expiresAt },
|
|
731
|
+
security: makeLoginSecurityState({
|
|
732
|
+
failedLoginAttempts: 0,
|
|
733
|
+
maxAttempts: this.options?.lockout?.maxAttempts ?? DEFAULT_MAX_LOGIN_ATTEMPTS,
|
|
734
|
+
lockoutUntil: null,
|
|
735
|
+
}),
|
|
258
736
|
};
|
|
259
737
|
}
|
|
260
738
|
catch (error) {
|
|
261
739
|
// An RG block is not a credential failure - surface it as-is, without touching the
|
|
262
|
-
// lockout budget or emitting login.failed (the RG event was already emitted).
|
|
263
|
-
|
|
740
|
+
// lockout budget or emitting login.failed (the RG event was already emitted). Match on
|
|
741
|
+
// the RG_BLOCKED marker, not the bare FORBIDDEN code - ensureOk also maps a banned-user
|
|
742
|
+
// 403 (better-auth's admin plugin) to FORBIDDEN, and that path must still fall through
|
|
743
|
+
// to the generic branch below to emit login.failed.
|
|
744
|
+
if (error instanceof ORPCError &&
|
|
745
|
+
error.code === 'FORBIDDEN' &&
|
|
746
|
+
(hasErrorCode(error, 'RG_BLOCKED') || hasErrorCode(error, 'ACCOUNT_SUSPENDED'))) {
|
|
264
747
|
throw error;
|
|
265
748
|
}
|
|
266
749
|
// Only a genuine credential rejection counts toward lockout - a transient DB/network
|
|
267
750
|
// error must never lock the account out.
|
|
268
|
-
const
|
|
751
|
+
const isAccountLocked = error instanceof ORPCError &&
|
|
752
|
+
error.code === 'UNAUTHORIZED' &&
|
|
753
|
+
hasErrorCode(error, 'ACCOUNT_LOCKED');
|
|
754
|
+
const isCredentialFailure = error instanceof ORPCError && error.code === 'UNAUTHORIZED' && !isAccountLocked;
|
|
755
|
+
let attemptsRemaining;
|
|
269
756
|
if (lockoutEnabled && existingUser && isCredentialFailure) {
|
|
270
757
|
const maxAttempts = this.options?.lockout?.maxAttempts ?? DEFAULT_MAX_LOGIN_ATTEMPTS;
|
|
271
|
-
const
|
|
758
|
+
const fallbackDurationMs = this.options?.lockout?.durationMs ?? DEFAULT_LOCKOUT_DURATION_MS;
|
|
272
759
|
// Atomic increment: concurrent failures can't each read a stale count and slip past
|
|
273
760
|
// the threshold (the read-modify-write this replaces was bypassable under load).
|
|
274
761
|
const [row] = await this.drizzle.db
|
|
275
762
|
.update(user)
|
|
276
|
-
.set({
|
|
763
|
+
.set({
|
|
764
|
+
failedLoginAttempts: sql `${user.failedLoginAttempts} + 1`,
|
|
765
|
+
lastFailedLoginAt: new Date(),
|
|
766
|
+
})
|
|
277
767
|
.where(eq(user.id, existingUser.id))
|
|
278
768
|
.returning({ failedLoginAttempts: user.failedLoginAttempts });
|
|
279
769
|
const newAttempts = row?.failedLoginAttempts ?? existingUser.failedLoginAttempts + 1;
|
|
280
|
-
|
|
770
|
+
attemptsRemaining = Math.max(maxAttempts - newAttempts, 0);
|
|
771
|
+
const { isLocking } = computeLockoutState({
|
|
281
772
|
attempts: newAttempts,
|
|
282
773
|
maxAttempts,
|
|
283
|
-
durationMs,
|
|
774
|
+
durationMs: fallbackDurationMs,
|
|
284
775
|
nowMs: Date.now(),
|
|
285
776
|
});
|
|
286
|
-
if (isLocking
|
|
287
|
-
|
|
777
|
+
if (isLocking) {
|
|
778
|
+
const nowMs = Date.now();
|
|
779
|
+
// Escalate the lockout duration for repeat offenders inside the 24h window.
|
|
780
|
+
const { tier, durationMs } = computeLockoutTier({
|
|
781
|
+
lockoutCount: existingUser.lockoutCount ?? 0,
|
|
782
|
+
lastFailedLoginAt: existingUser.lastFailedLoginAt ?? null,
|
|
783
|
+
fallbackLastLockoutAt: existingUser.lastLockoutAt ?? null,
|
|
784
|
+
nowMs,
|
|
785
|
+
fallbackDurationMs,
|
|
786
|
+
});
|
|
787
|
+
const lockoutUntil = new Date(nowMs + durationMs);
|
|
788
|
+
const [lockoutRow] = await this.drizzle.db
|
|
288
789
|
.update(user)
|
|
289
|
-
.set({ lockoutUntil })
|
|
290
|
-
|
|
790
|
+
.set({ lockoutUntil, lockoutCount: tier, lastLockoutAt: new Date(nowMs) })
|
|
791
|
+
// Only the first request that reaches the threshold creates the lockout.
|
|
792
|
+
// Other concurrent failures must observe and return the winner's lockout
|
|
793
|
+
// instead of overwriting its tier or emitting a duplicate event.
|
|
794
|
+
.where(and(eq(user.id, existingUser.id), isNull(user.lockoutUntil)))
|
|
795
|
+
.returning({ lockoutUntil: user.lockoutUntil });
|
|
796
|
+
if (!lockoutRow) {
|
|
797
|
+
const [current] = await this.drizzle.db
|
|
798
|
+
.select({ lockoutUntil: user.lockoutUntil })
|
|
799
|
+
.from(user)
|
|
800
|
+
.where(eq(user.id, existingUser.id))
|
|
801
|
+
.limit(1);
|
|
802
|
+
if (current?.lockoutUntil) {
|
|
803
|
+
throw createAccountLockedError(current.lockoutUntil);
|
|
804
|
+
}
|
|
805
|
+
throw new ORPCError('INTERNAL_SERVER_ERROR', {
|
|
806
|
+
message: 'Unable to establish account lockout.',
|
|
807
|
+
});
|
|
808
|
+
}
|
|
809
|
+
await this.limiter?.reset(makeLoginRateLimitKey(email));
|
|
291
810
|
this.events.emit('identity.user.lockout.triggered', {
|
|
292
811
|
userId: existingUser.id,
|
|
293
812
|
email,
|
|
813
|
+
tier,
|
|
294
814
|
lockoutUntil: lockoutUntil.toISOString(),
|
|
295
815
|
ip,
|
|
296
816
|
userAgent,
|
|
@@ -298,8 +818,69 @@ export class IdentityService {
|
|
|
298
818
|
throw createAccountLockedError(lockoutUntil);
|
|
299
819
|
}
|
|
300
820
|
}
|
|
821
|
+
else if (lockoutEnabled && !existingUser && isCredentialFailure) {
|
|
822
|
+
const maxAttempts = this.options?.lockout?.maxAttempts ?? DEFAULT_MAX_LOGIN_ATTEMPTS;
|
|
823
|
+
const fallbackDurationMs = this.options?.lockout?.durationMs ?? DEFAULT_LOCKOUT_DURATION_MS;
|
|
824
|
+
const newAttempts = (fakeLoginShadow?.failedAttempts ?? 0) + 1;
|
|
825
|
+
attemptsRemaining = Math.max(maxAttempts - newAttempts, 0);
|
|
826
|
+
const { isLocking } = computeLockoutState({
|
|
827
|
+
attempts: newAttempts,
|
|
828
|
+
maxAttempts,
|
|
829
|
+
durationMs: fallbackDurationMs,
|
|
830
|
+
nowMs: Date.now(),
|
|
831
|
+
});
|
|
832
|
+
if (isLocking) {
|
|
833
|
+
const nowMs = Date.now();
|
|
834
|
+
const { tier, durationMs } = computeLockoutTier({
|
|
835
|
+
lockoutCount: fakeLoginShadow?.lockoutCount ?? 0,
|
|
836
|
+
lastFailedLoginAt: fakeLoginShadow?.lastFailedLoginAt
|
|
837
|
+
? new Date(fakeLoginShadow.lastFailedLoginAt)
|
|
838
|
+
: null,
|
|
839
|
+
fallbackLastLockoutAt: fakeLoginShadow?.lastLockoutAt
|
|
840
|
+
? new Date(fakeLoginShadow.lastLockoutAt)
|
|
841
|
+
: null,
|
|
842
|
+
nowMs,
|
|
843
|
+
fallbackDurationMs,
|
|
844
|
+
});
|
|
845
|
+
const lockoutUntil = new Date(nowMs + durationMs);
|
|
846
|
+
await this.loginShadowSet(loginShadowKey(email), {
|
|
847
|
+
failedAttempts: newAttempts,
|
|
848
|
+
lockoutUntil: lockoutUntil.toISOString(),
|
|
849
|
+
lockoutCount: tier,
|
|
850
|
+
lastLockoutAt: new Date(nowMs).toISOString(),
|
|
851
|
+
lastFailedLoginAt: new Date(nowMs).toISOString(),
|
|
852
|
+
});
|
|
853
|
+
await this.limiter?.reset(makeLoginRateLimitKey(email));
|
|
854
|
+
throw createAccountLockedError(lockoutUntil);
|
|
855
|
+
}
|
|
856
|
+
await this.loginShadowSet(loginShadowKey(email), {
|
|
857
|
+
failedAttempts: newAttempts,
|
|
858
|
+
lockoutUntil: null,
|
|
859
|
+
lockoutCount: fakeLoginShadow?.lockoutCount ?? 0,
|
|
860
|
+
lastLockoutAt: fakeLoginShadow?.lastLockoutAt ?? null,
|
|
861
|
+
lastFailedLoginAt: new Date().toISOString(),
|
|
862
|
+
});
|
|
863
|
+
}
|
|
301
864
|
const reason = isCredentialFailure ? 'invalid_credentials' : 'error';
|
|
302
|
-
this.events.emit('identity.user.login.failed', {
|
|
865
|
+
this.events.emit('identity.user.login.failed', {
|
|
866
|
+
email,
|
|
867
|
+
reason,
|
|
868
|
+
ip,
|
|
869
|
+
userAgent,
|
|
870
|
+
...(attemptsRemaining !== undefined ? { attemptsRemaining } : {}),
|
|
871
|
+
});
|
|
872
|
+
if (isCredentialFailure && error instanceof ORPCError && attemptsRemaining !== undefined) {
|
|
873
|
+
const maxAttempts = this.options?.lockout?.maxAttempts ?? DEFAULT_MAX_LOGIN_ATTEMPTS;
|
|
874
|
+
const security = makeLoginSecurityState({
|
|
875
|
+
failedLoginAttempts: attemptsRemaining === undefined ? 0 : maxAttempts - attemptsRemaining,
|
|
876
|
+
maxAttempts,
|
|
877
|
+
lockoutUntil: null,
|
|
878
|
+
});
|
|
879
|
+
throw new ORPCError('UNAUTHORIZED', {
|
|
880
|
+
message: error.message,
|
|
881
|
+
data: { ...error.data, ...security },
|
|
882
|
+
});
|
|
883
|
+
}
|
|
303
884
|
throw error;
|
|
304
885
|
}
|
|
305
886
|
}
|
|
@@ -309,7 +890,95 @@ export class IdentityService {
|
|
|
309
890
|
.set({ failedLoginAttempts: 0, lockoutUntil: null })
|
|
310
891
|
.where(eq(user.id, userId));
|
|
311
892
|
}
|
|
312
|
-
|
|
893
|
+
resetLockoutTier(userId) {
|
|
894
|
+
return this.drizzle.db
|
|
895
|
+
.update(user)
|
|
896
|
+
.set({
|
|
897
|
+
failedLoginAttempts: 0,
|
|
898
|
+
lockoutUntil: null,
|
|
899
|
+
lockoutCount: 0,
|
|
900
|
+
lastLockoutAt: null,
|
|
901
|
+
lastFailedLoginAt: null,
|
|
902
|
+
})
|
|
903
|
+
.where(eq(user.id, userId));
|
|
904
|
+
}
|
|
905
|
+
async loginShadowGet(key) {
|
|
906
|
+
if (!this.cache) {
|
|
907
|
+
return undefined;
|
|
908
|
+
}
|
|
909
|
+
try {
|
|
910
|
+
return await this.cache.get(key);
|
|
911
|
+
}
|
|
912
|
+
catch (err) {
|
|
913
|
+
loginShadowLogger.warn({ key, err }, 'login shadow cache read failed');
|
|
914
|
+
return undefined;
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
async loginShadowSet(key, value) {
|
|
918
|
+
if (!this.cache) {
|
|
919
|
+
return;
|
|
920
|
+
}
|
|
921
|
+
try {
|
|
922
|
+
await this.cache.set(key, value, { ttlMs: FAKE_LOGIN_SHADOW_TTL_MS });
|
|
923
|
+
}
|
|
924
|
+
catch (err) {
|
|
925
|
+
loginShadowLogger.warn({ key, err }, 'login shadow cache write failed');
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
adminPasswordResetMarkerKey(email) {
|
|
929
|
+
return `admin-password-reset:${email.toLowerCase()}`;
|
|
930
|
+
}
|
|
931
|
+
async isAdminPasswordReset(email) {
|
|
932
|
+
if (!this.cache) {
|
|
933
|
+
return false;
|
|
934
|
+
}
|
|
935
|
+
const key = this.adminPasswordResetMarkerKey(email);
|
|
936
|
+
try {
|
|
937
|
+
const isAdmin = (await this.cache.get(key)) === true;
|
|
938
|
+
if (isAdmin) {
|
|
939
|
+
await this.cache.delete(key);
|
|
940
|
+
}
|
|
941
|
+
return isAdmin;
|
|
942
|
+
}
|
|
943
|
+
catch (err) {
|
|
944
|
+
identityLogger.warn({ err }, 'admin password reset marker cache read failed');
|
|
945
|
+
return false;
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
async adminRequestPasswordReset(userId, actorId, meta) {
|
|
949
|
+
const existingUser = findOneOrThrow(await this.drizzle.db
|
|
950
|
+
.select({ id: user.id, email: user.email })
|
|
951
|
+
.from(user)
|
|
952
|
+
.where(eq(user.id, userId))
|
|
953
|
+
.limit(1), new UserNotFoundError(userId));
|
|
954
|
+
const email = existingUser.email.toLowerCase();
|
|
955
|
+
try {
|
|
956
|
+
await this.cache?.set(this.adminPasswordResetMarkerKey(email), true, { ttlMs: 120_000 });
|
|
957
|
+
}
|
|
958
|
+
catch (err) {
|
|
959
|
+
identityLogger.warn({ email, err }, 'admin password reset marker cache write failed');
|
|
960
|
+
}
|
|
961
|
+
// Mirrors requestPasswordReset - the send failure is swallowed the same way.
|
|
962
|
+
try {
|
|
963
|
+
await this.api.requestPasswordResetEmailOTP({
|
|
964
|
+
body: { email },
|
|
965
|
+
headers: new Headers(),
|
|
966
|
+
asResponse: true,
|
|
967
|
+
});
|
|
968
|
+
}
|
|
969
|
+
catch {
|
|
970
|
+
// intentionally ignored
|
|
971
|
+
}
|
|
972
|
+
this.events.emit('identity.password.admin_reset_requested', {
|
|
973
|
+
userId,
|
|
974
|
+
email,
|
|
975
|
+
actorId,
|
|
976
|
+
ip: meta?.ip ?? null,
|
|
977
|
+
userAgent: meta?.userAgent ?? null,
|
|
978
|
+
});
|
|
979
|
+
return SUCCESS;
|
|
980
|
+
}
|
|
981
|
+
async unlockUser(userId, actorId, meta) {
|
|
313
982
|
const existingUser = findOneOrThrow(await this.drizzle.db
|
|
314
983
|
.select({
|
|
315
984
|
id: user.id,
|
|
@@ -321,6 +990,7 @@ export class IdentityService {
|
|
|
321
990
|
.where(eq(user.id, userId))
|
|
322
991
|
.limit(1), new UserNotFoundError(userId));
|
|
323
992
|
await this.clearLockout(userId);
|
|
993
|
+
await this.limiter?.reset(makeLoginRateLimitKey(existingUser.email));
|
|
324
994
|
this.events.emit('identity.user.unlocked', {
|
|
325
995
|
userId,
|
|
326
996
|
email: existingUser.email,
|
|
@@ -329,18 +999,26 @@ export class IdentityService {
|
|
|
329
999
|
previousLockoutUntil: existingUser.lockoutUntil
|
|
330
1000
|
? existingUser.lockoutUntil.toISOString()
|
|
331
1001
|
: null,
|
|
1002
|
+
ip: meta?.ip ?? null,
|
|
1003
|
+
userAgent: meta?.userAgent ?? null,
|
|
332
1004
|
});
|
|
333
1005
|
return SUCCESS;
|
|
334
1006
|
}
|
|
335
1007
|
async logout(reqHeaders, resHeaders) {
|
|
1008
|
+
const { ip, userAgent } = extractClientMeta(reqHeaders);
|
|
336
1009
|
const headers = nodeHeadersToHeaders(reqHeaders);
|
|
337
1010
|
// Resolve the user BEFORE signOut so the audit log can attribute the logout.
|
|
338
1011
|
const session = await this.auth.api.getSession({ headers });
|
|
339
1012
|
const userId = session?.user?.id;
|
|
340
1013
|
const authResponse = await this.auth.api.signOut({ headers, asResponse: true });
|
|
341
|
-
forwardCookies(authResponse, resHeaders);
|
|
1014
|
+
this.forwardCookies(authResponse, resHeaders);
|
|
342
1015
|
if (userId) {
|
|
343
|
-
this.events.emit('identity.user.logout', {
|
|
1016
|
+
this.events.emit('identity.user.logout', {
|
|
1017
|
+
userId,
|
|
1018
|
+
playerId: await this.identityReader.getPlayerIdByUserIdSafe(userId),
|
|
1019
|
+
ip,
|
|
1020
|
+
userAgent,
|
|
1021
|
+
});
|
|
344
1022
|
}
|
|
345
1023
|
return SUCCESS;
|
|
346
1024
|
}
|
|
@@ -352,61 +1030,460 @@ export class IdentityService {
|
|
|
352
1030
|
}
|
|
353
1031
|
return toUser(session.user);
|
|
354
1032
|
}
|
|
1033
|
+
/**
|
|
1034
|
+
* Starts enrolment. All three methods share the one secret better-auth mints here;
|
|
1035
|
+
* `method` only decides how the code that activates it arrives, and is written
|
|
1036
|
+
* before the send so the delivery hook knows where to route. better-auth flips
|
|
1037
|
+
* `twoFactorEnabled` only once the first code clears, so abandoning a first
|
|
1038
|
+
* enrolment leaves the account unprotected exactly as it was.
|
|
1039
|
+
*
|
|
1040
|
+
* A transport failure on the first send throws (see `sendOtpForCurrentMethod`)
|
|
1041
|
+
* after `two_factor_method` is already written, but that write is inert on its
|
|
1042
|
+
* own: `twoFactorStatus` reports it only once `enabled` is true, and the CONFLICT
|
|
1043
|
+
* guard below only fires once it is. The caller recovers by retrying either
|
|
1044
|
+
* `sendTwoFactorOtp` (resend) or this route again - both read the method that was
|
|
1045
|
+
* already persisted, so neither loses the player's choice.
|
|
1046
|
+
*/
|
|
355
1047
|
async enableTwoFactor(input, reqHeaders, resHeaders) {
|
|
356
1048
|
const headers = nodeHeadersToHeaders(reqHeaders);
|
|
357
1049
|
const userId = await this.currentUserId(headers);
|
|
358
1050
|
await assertRateLimit(this.limiter, `enable2fa:${userId ?? 'anonymous'}`, TWO_FACTOR_PASSWORD_RATE_LIMIT);
|
|
1051
|
+
if (!userId) {
|
|
1052
|
+
throw new ORPCError('UNAUTHORIZED', { message: 'Not signed in' });
|
|
1053
|
+
}
|
|
1054
|
+
await this.assertMethodAvailable(userId, input.method);
|
|
1055
|
+
// There is no switch-in-place: a player changes method by disabling and enrolling
|
|
1056
|
+
// again. better-auth's enable leg deletes and recreates the `twoFactor` row with a
|
|
1057
|
+
// fresh secret and fresh backup codes, and marks it verified straight away when one
|
|
1058
|
+
// was already verified - so re-running it on a live account destroys the working
|
|
1059
|
+
// authenticator the moment the call lands, and abandoning the step strands the
|
|
1060
|
+
// player on a secret they never scanned with `two_factor_enabled` still true.
|
|
1061
|
+
if (await this.isTwoFactorEnabled(userId)) {
|
|
1062
|
+
throw new ORPCError('CONFLICT', {
|
|
1063
|
+
message: 'Two-factor authentication is already enabled. Disable it first to change method.',
|
|
1064
|
+
});
|
|
1065
|
+
}
|
|
359
1066
|
const res = await this.api.enableTwoFactor({
|
|
360
1067
|
body: { password: input.password },
|
|
361
1068
|
headers,
|
|
362
1069
|
asResponse: true,
|
|
363
1070
|
});
|
|
364
1071
|
await ensureOk(res);
|
|
365
|
-
forwardCookies(res, resHeaders);
|
|
1072
|
+
this.forwardCookies(res, resHeaders);
|
|
366
1073
|
const body = (await res.json());
|
|
367
|
-
|
|
1074
|
+
await this.setTwoFactorMethod(userId, input.method);
|
|
1075
|
+
if (input.method === 'app') {
|
|
1076
|
+
return { totpUri: body.totpURI, backupCodes: body.backupCodes };
|
|
1077
|
+
}
|
|
1078
|
+
// The first code has to reach the player before they can activate the method, so
|
|
1079
|
+
// the send belongs to enrolment rather than a separate call the client must know
|
|
1080
|
+
// to make. "Resend code" then replays it through sendTwoFactorOtp.
|
|
1081
|
+
const masked = await this.sendOtpForCurrentMethod(userId, headers, resHeaders);
|
|
1082
|
+
return { backupCodes: body.backupCodes, maskedDestination: masked };
|
|
1083
|
+
}
|
|
1084
|
+
/**
|
|
1085
|
+
* Re-sends the one-time code for an account on the `email` or `sms` method - the
|
|
1086
|
+
* "Resend code" action during enrolment, and the send leg of a login challenge.
|
|
1087
|
+
* Resolves its subject from a live session first and the pending-challenge cookie
|
|
1088
|
+
* second, because at login there is no session yet.
|
|
1089
|
+
*/
|
|
1090
|
+
async sendTwoFactorOtp(reqHeaders, resHeaders) {
|
|
1091
|
+
const headers = nodeHeadersToHeaders(reqHeaders);
|
|
1092
|
+
const pendingCookie = twoFactorPendingCookieValue(headers);
|
|
1093
|
+
const userId = (await this.currentUserId(headers)) ??
|
|
1094
|
+
(await this.twoFactorLockout?.resolvePendingUserId(pendingCookie));
|
|
1095
|
+
if (!userId) {
|
|
1096
|
+
throw new ORPCError('UNAUTHORIZED', { message: 'Not signed in' });
|
|
1097
|
+
}
|
|
1098
|
+
await assertRateLimit(this.limiter, `send2faOtp:${userId}`, SEND_2FA_OTP_RATE_LIMIT);
|
|
1099
|
+
// An account inside a lockout window cannot spend a code, so minting one only
|
|
1100
|
+
// hands out fresh guesses - and, on `sms`, bills the operator for them.
|
|
1101
|
+
await this.twoFactorLockout?.assertNotLocked(userId);
|
|
1102
|
+
return { maskedDestination: await this.sendOtpForCurrentMethod(userId, headers, resHeaders) };
|
|
1103
|
+
}
|
|
1104
|
+
/** Whether a second factor is active, which method it uses, and where a code can go. */
|
|
1105
|
+
async twoFactorStatus(reqHeaders) {
|
|
1106
|
+
const headers = nodeHeadersToHeaders(reqHeaders);
|
|
1107
|
+
const userId = await this.currentUserId(headers);
|
|
1108
|
+
if (!userId) {
|
|
1109
|
+
throw new ORPCError('UNAUTHORIZED', { message: 'Not signed in' });
|
|
1110
|
+
}
|
|
1111
|
+
const [row] = await this.drizzle.db
|
|
1112
|
+
.select({
|
|
1113
|
+
email: user.email,
|
|
1114
|
+
phoneNumber: user.phoneNumber,
|
|
1115
|
+
phoneVerified: user.phoneVerified,
|
|
1116
|
+
twoFactorEnabled: user.twoFactorEnabled,
|
|
1117
|
+
twoFactorMethod: user.twoFactorMethod,
|
|
1118
|
+
})
|
|
1119
|
+
.from(user)
|
|
1120
|
+
.where(eq(user.id, userId))
|
|
1121
|
+
.limit(1);
|
|
1122
|
+
if (!row) {
|
|
1123
|
+
throw new UserNotFoundError(userId);
|
|
1124
|
+
}
|
|
1125
|
+
const enabled = row.twoFactorEnabled ?? false;
|
|
1126
|
+
return {
|
|
1127
|
+
enabled,
|
|
1128
|
+
// The column outlives an abandoned enrolment, so an account that never cleared
|
|
1129
|
+
// its first code must still read as having no active method.
|
|
1130
|
+
method: enabled ? (row.twoFactorMethod ?? null) : null,
|
|
1131
|
+
maskedEmail: maskEmail(row.email),
|
|
1132
|
+
maskedPhone: row.phoneVerified && row.phoneNumber ? maskPhone(row.phoneNumber) : null,
|
|
1133
|
+
};
|
|
1134
|
+
}
|
|
1135
|
+
/**
|
|
1136
|
+
* Rejects a method the account cannot actually receive a code on. Enrolling into
|
|
1137
|
+
* `sms` without a verified phone would mint a secret the player can never clear,
|
|
1138
|
+
* locking them out of their own account at the next login.
|
|
1139
|
+
*/
|
|
1140
|
+
async assertMethodAvailable(userId, method) {
|
|
1141
|
+
if (method === 'app') {
|
|
1142
|
+
return;
|
|
1143
|
+
}
|
|
1144
|
+
const [row] = await this.drizzle.db
|
|
1145
|
+
.select({
|
|
1146
|
+
emailVerified: user.emailVerified,
|
|
1147
|
+
phoneNumber: user.phoneNumber,
|
|
1148
|
+
phoneVerified: user.phoneVerified,
|
|
1149
|
+
})
|
|
1150
|
+
.from(user)
|
|
1151
|
+
.where(eq(user.id, userId))
|
|
1152
|
+
.limit(1);
|
|
1153
|
+
// A code can only guard the account if the address it goes to is one the account
|
|
1154
|
+
// has proven it holds. `registration.requireEmailVerification` is off by default,
|
|
1155
|
+
// so an unverified or mistyped address would otherwise enrol and lock the player
|
|
1156
|
+
// out at the next login - the same failure the phone check already prevents.
|
|
1157
|
+
if (method === 'email' && !row?.emailVerified) {
|
|
1158
|
+
throw new ORPCError('BAD_REQUEST', {
|
|
1159
|
+
message: 'Verify your email address before using email for two-factor authentication',
|
|
1160
|
+
});
|
|
1161
|
+
}
|
|
1162
|
+
if (method === 'sms' && (!row?.phoneNumber || !row.phoneVerified)) {
|
|
1163
|
+
throw new ORPCError('BAD_REQUEST', {
|
|
1164
|
+
message: 'Add and verify a phone number before using SMS for two-factor authentication',
|
|
1165
|
+
});
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
1168
|
+
/**
|
|
1169
|
+
* The account's delivery method, defaulting to `app`: an enrolment that predates the
|
|
1170
|
+
* column reads as null, and every one of those was an authenticator.
|
|
1171
|
+
*/
|
|
1172
|
+
async resolveTwoFactorMethod(userId) {
|
|
1173
|
+
const [row] = await this.drizzle.db
|
|
1174
|
+
.select({ twoFactorMethod: user.twoFactorMethod })
|
|
1175
|
+
.from(user)
|
|
1176
|
+
.where(eq(user.id, userId))
|
|
1177
|
+
.limit(1);
|
|
1178
|
+
return row?.twoFactorMethod ?? 'app';
|
|
1179
|
+
}
|
|
1180
|
+
async isTwoFactorEnabled(userId) {
|
|
1181
|
+
const [row] = await this.drizzle.db
|
|
1182
|
+
.select({ twoFactorEnabled: user.twoFactorEnabled })
|
|
1183
|
+
.from(user)
|
|
1184
|
+
.where(eq(user.id, userId))
|
|
1185
|
+
.limit(1);
|
|
1186
|
+
return row?.twoFactorEnabled ?? false;
|
|
1187
|
+
}
|
|
1188
|
+
async setTwoFactorMethod(userId, method) {
|
|
1189
|
+
await this.drizzle.db.update(user).set({ twoFactorMethod: method }).where(eq(user.id, userId));
|
|
1190
|
+
}
|
|
1191
|
+
verifyChallengeCode(method, body, headers) {
|
|
1192
|
+
return verifyChallengeCode(this.api, method, body, headers);
|
|
1193
|
+
}
|
|
1194
|
+
async sendOtpForCurrentMethod(userId, headers, resHeaders) {
|
|
1195
|
+
const destination = await this.twoFactorDelivery.describeDestination(userId);
|
|
1196
|
+
if (!destination) {
|
|
1197
|
+
throw new ORPCError('BAD_REQUEST', {
|
|
1198
|
+
message: 'This account does not receive two-factor codes by email or SMS',
|
|
1199
|
+
});
|
|
1200
|
+
}
|
|
1201
|
+
const res = await this.api.sendTwoFactorOTP({ body: {}, headers, asResponse: true });
|
|
1202
|
+
await ensureOk(res);
|
|
1203
|
+
// A 200 here means the code was minted, not that it left the building: the send
|
|
1204
|
+
// hook is wrapped in `.catch(logger.error)` upstream. Telling the player a code is
|
|
1205
|
+
// on its way when the transport just failed strands them on a screen waiting for
|
|
1206
|
+
// something that is never coming.
|
|
1207
|
+
const failure = this.twoFactorDelivery.takeFailure(userId);
|
|
1208
|
+
if (failure) {
|
|
1209
|
+
throw new ORPCError('SERVICE_UNAVAILABLE', {
|
|
1210
|
+
message: 'Could not send your verification code. Please try again.',
|
|
1211
|
+
cause: failure,
|
|
1212
|
+
});
|
|
1213
|
+
}
|
|
1214
|
+
this.forwardCookies(res, resHeaders);
|
|
1215
|
+
return destination.masked;
|
|
1216
|
+
}
|
|
1217
|
+
/**
|
|
1218
|
+
* Whether the account insists on a second factor every login. Read off the row rather
|
|
1219
|
+
* than passed in: mid-challenge there is no session yet, so the only handle on the
|
|
1220
|
+
* account is the id the pending cookie resolved to.
|
|
1221
|
+
*/
|
|
1222
|
+
async requiresTwoFactorEveryLogin(userId) {
|
|
1223
|
+
if (!userId) {
|
|
1224
|
+
return false;
|
|
1225
|
+
}
|
|
1226
|
+
const [row] = await this.drizzle.db
|
|
1227
|
+
.select({ requireTwoFactorOnLogin: user.requireTwoFactorOnLogin })
|
|
1228
|
+
.from(user)
|
|
1229
|
+
.where(eq(user.id, userId))
|
|
1230
|
+
.limit(1);
|
|
1231
|
+
return row?.requireTwoFactorOnLogin ?? false;
|
|
368
1232
|
}
|
|
369
1233
|
async verifyTwoFactor(input, reqHeaders, resHeaders) {
|
|
1234
|
+
const { ip, userAgent } = extractClientMeta(reqHeaders);
|
|
370
1235
|
const headers = nodeHeadersToHeaders(reqHeaders);
|
|
371
|
-
const
|
|
1236
|
+
const pendingCookie = twoFactorPendingCookieValue(headers);
|
|
1237
|
+
const sessionUserId = await this.currentUserId(headers);
|
|
1238
|
+
const twoFactorKey = sessionUserId ?? pendingCookie ?? 'anonymous';
|
|
372
1239
|
await assertRateLimit(this.limiter, `verify2fa:${twoFactorKey}`, VERIFY_2FA_RATE_LIMIT);
|
|
373
|
-
const
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
1240
|
+
const challengedUserId = sessionUserId ?? (await this.twoFactorLockout?.resolvePendingUserId(pendingCookie));
|
|
1241
|
+
if (challengedUserId) {
|
|
1242
|
+
await this.twoFactorLockout?.assertNotLocked(challengedUserId);
|
|
1243
|
+
}
|
|
1244
|
+
// A backup code is a single-use recovery credential, not a second factor to bind a
|
|
1245
|
+
// browser to: it clears the challenge but never buys the trust window. A pushed
|
|
1246
|
+
// `otp` is a real factor and does, the same as a live authenticator code.
|
|
1247
|
+
const trustDevice = input.trustDevice &&
|
|
1248
|
+
input.method !== 'backup_code' &&
|
|
1249
|
+
this.trustedDevices !== undefined &&
|
|
1250
|
+
!(await this.requiresTwoFactorEveryLogin(challengedUserId));
|
|
1251
|
+
const body = { code: input.code, trustDevice };
|
|
1252
|
+
const res = await this.verifyChallengeCode(input.method, body, headers);
|
|
1253
|
+
if (!res.ok && challengedUserId) {
|
|
1254
|
+
await this.twoFactorLockout?.recordFailure(challengedUserId, { ip, userAgent });
|
|
1255
|
+
}
|
|
378
1256
|
await ensureOk(res);
|
|
379
|
-
|
|
380
|
-
|
|
1257
|
+
if (challengedUserId) {
|
|
1258
|
+
await this.twoFactorLockout?.reset(challengedUserId);
|
|
1259
|
+
}
|
|
1260
|
+
this.forwardCookies(res, resHeaders);
|
|
1261
|
+
// better-auth rotates the session on a successful challenge, so the request cookie is
|
|
1262
|
+
// already dead here - the actor is the identity resolved before the call.
|
|
1263
|
+
const userId = challengedUserId ?? (await this.currentUserId(headers));
|
|
1264
|
+
// Ground truth for the caller: `trustDevice` already reflects backup-code and
|
|
1265
|
+
// require-2fa-every-login refusals, but only actually buys the cookie below, and
|
|
1266
|
+
// only when `userId` resolved. The client asked to trust this device and deserves to
|
|
1267
|
+
// know whether that request was honoured rather than silently dropped.
|
|
1268
|
+
let trustGranted = false;
|
|
381
1269
|
if (userId) {
|
|
382
|
-
this.
|
|
1270
|
+
const playerId = await this.identityReader.getPlayerIdByUserIdSafe(userId);
|
|
1271
|
+
// A challenge answered from a live session is the enrolment step: better-auth only
|
|
1272
|
+
// flips twoFactorEnabled once the first code clears. Every later verification is a
|
|
1273
|
+
// sign-in, which carries the pending cookie instead and must not re-announce setup.
|
|
1274
|
+
if (sessionUserId) {
|
|
1275
|
+
this.events.emit('identity.2fa.enabled', {
|
|
1276
|
+
userId,
|
|
1277
|
+
playerId,
|
|
1278
|
+
method: input.method,
|
|
1279
|
+
ip,
|
|
1280
|
+
userAgent,
|
|
1281
|
+
});
|
|
1282
|
+
}
|
|
1283
|
+
this.events.emit('identity.2fa.verified', {
|
|
1284
|
+
userId,
|
|
1285
|
+
playerId,
|
|
1286
|
+
method: input.method,
|
|
1287
|
+
trustedDevice: trustDevice,
|
|
1288
|
+
ip,
|
|
1289
|
+
userAgent,
|
|
1290
|
+
});
|
|
1291
|
+
if (!sessionUserId) {
|
|
1292
|
+
this.events.emit('identity.authentication.succeeded', {
|
|
1293
|
+
userId,
|
|
1294
|
+
playerId,
|
|
1295
|
+
method: input.method,
|
|
1296
|
+
ip,
|
|
1297
|
+
userAgent,
|
|
1298
|
+
});
|
|
1299
|
+
}
|
|
1300
|
+
if (trustDevice) {
|
|
1301
|
+
await this.trustedDevices?.trust(userId, { ip, userAgent });
|
|
1302
|
+
trustGranted = true;
|
|
1303
|
+
}
|
|
1304
|
+
await captureTimezone(this.playerProvisioning, userId, input.timezone);
|
|
1305
|
+
}
|
|
1306
|
+
return { ...SUCCESS, trustGranted };
|
|
1307
|
+
}
|
|
1308
|
+
/**
|
|
1309
|
+
* Grants this browser its trust window without a sign-out. better-auth issues the
|
|
1310
|
+
* trust cookie only on the sign-in leg of a challenge, so the grant has to replay
|
|
1311
|
+
* that leg: the account proves its password and a fresh second factor, and the
|
|
1312
|
+
* cookies better-auth returns are the ones the browser keeps.
|
|
1313
|
+
*/
|
|
1314
|
+
async trustCurrentDevice(input, reqHeaders, resHeaders) {
|
|
1315
|
+
const { ip, userAgent } = extractClientMeta(reqHeaders);
|
|
1316
|
+
const headers = nodeHeadersToHeaders(reqHeaders);
|
|
1317
|
+
const userId = await this.currentUserId(headers);
|
|
1318
|
+
if (!userId) {
|
|
1319
|
+
throw new ORPCError('UNAUTHORIZED', { message: 'Not signed in' });
|
|
383
1320
|
}
|
|
1321
|
+
await assertRateLimit(this.limiter, `trustDevice:${userId}`, TWO_FACTOR_PASSWORD_RATE_LIMIT);
|
|
1322
|
+
// Granting trust the login path is contractually going to ignore would leave the
|
|
1323
|
+
// player with a device listed as trusted that still gets challenged every time.
|
|
1324
|
+
if (await this.requiresTwoFactorEveryLogin(userId)) {
|
|
1325
|
+
throw new ORPCError('UNPROCESSABLE_CONTENT', {
|
|
1326
|
+
message: 'Turn off two-factor on every login before trusting this device.',
|
|
1327
|
+
});
|
|
1328
|
+
}
|
|
1329
|
+
const [account] = await this.drizzle.db
|
|
1330
|
+
.select({ email: user.email })
|
|
1331
|
+
.from(user)
|
|
1332
|
+
.where(eq(user.id, userId))
|
|
1333
|
+
.limit(1);
|
|
1334
|
+
if (!account) {
|
|
1335
|
+
throw new UserNotFoundError(userId);
|
|
1336
|
+
}
|
|
1337
|
+
const signIn = await this.auth.api.signInEmail({
|
|
1338
|
+
body: { email: account.email, password: input.password },
|
|
1339
|
+
headers: withoutTrustDeviceCookie(headers),
|
|
1340
|
+
asResponse: true,
|
|
1341
|
+
});
|
|
1342
|
+
await ensureOk(signIn);
|
|
1343
|
+
const signInBody = (await signIn.json());
|
|
1344
|
+
if (signInBody.twoFactorRedirect !== true) {
|
|
1345
|
+
throw new ORPCError('BAD_REQUEST', {
|
|
1346
|
+
message: 'Two-factor authentication is not enabled for this account',
|
|
1347
|
+
});
|
|
1348
|
+
}
|
|
1349
|
+
// Only the cookies the challenge just issued: leaving the live session cookie in
|
|
1350
|
+
// place makes better-auth treat the call as a settings change and skip the trust.
|
|
1351
|
+
const challengeHeaders = new Headers(headers);
|
|
1352
|
+
challengeHeaders.set('cookie', requestCookieHeader(signIn));
|
|
1353
|
+
await this.twoFactorLockout?.assertNotLocked(userId);
|
|
1354
|
+
// Authenticator accounts only. This route replays a fresh sign-in leg, and
|
|
1355
|
+
// better-auth keys a pushed code by the pending-challenge cookie that leg mints -
|
|
1356
|
+
// so an `email`/`sms` account has no code that can answer this challenge, and
|
|
1357
|
+
// letting the call through would only spend its lockout budget on a credential it
|
|
1358
|
+
// is impossible to present. Refusing says so instead of failing as a wrong code.
|
|
1359
|
+
const challengeMethod = await resolveChallengeMethod(this.drizzle, userId);
|
|
1360
|
+
if (challengeMethod !== 'totp') {
|
|
1361
|
+
throw new ORPCError('CONFLICT', {
|
|
1362
|
+
message: 'Trusting this device requires an authenticator app.',
|
|
1363
|
+
});
|
|
1364
|
+
}
|
|
1365
|
+
const verified = await this.verifyChallengeCode(challengeMethod, { code: input.code, trustDevice: true }, challengeHeaders);
|
|
1366
|
+
if (!verified.ok) {
|
|
1367
|
+
await this.twoFactorLockout?.recordFailure(userId, { ip, userAgent });
|
|
1368
|
+
}
|
|
1369
|
+
await ensureOk(verified);
|
|
1370
|
+
await this.twoFactorLockout?.reset(userId);
|
|
1371
|
+
this.forwardCookies(verified, resHeaders);
|
|
1372
|
+
await this.trustedDevices?.trust(userId, { ip, userAgent });
|
|
1373
|
+
const playerId = await this.identityReader.getPlayerIdByUserIdSafe(userId);
|
|
1374
|
+
this.events.emit('identity.2fa.verified', {
|
|
1375
|
+
userId,
|
|
1376
|
+
playerId,
|
|
1377
|
+
method: challengeMethod,
|
|
1378
|
+
trustedDevice: true,
|
|
1379
|
+
ip,
|
|
1380
|
+
userAgent,
|
|
1381
|
+
});
|
|
1382
|
+
// The challenge leg above ran without a session cookie, so better-auth minted a new
|
|
1383
|
+
// session and this response carries it. That is a new authenticated session like any
|
|
1384
|
+
// other, and the security alert has to see it.
|
|
1385
|
+
this.events.emit('identity.authentication.succeeded', {
|
|
1386
|
+
userId,
|
|
1387
|
+
playerId,
|
|
1388
|
+
method: 'totp',
|
|
1389
|
+
ip,
|
|
1390
|
+
userAgent,
|
|
1391
|
+
});
|
|
384
1392
|
return SUCCESS;
|
|
385
1393
|
}
|
|
1394
|
+
/**
|
|
1395
|
+
* A step-up gate for the self-service routes that change standing 2FA state: the
|
|
1396
|
+
* caller has to clear a live authenticator code, not just the account password.
|
|
1397
|
+
* Routed through TwoFactorLockoutService so a hijacked session plus a reused
|
|
1398
|
+
* password cannot grind the second factor here the way the password-only paths let it.
|
|
1399
|
+
*/
|
|
1400
|
+
async assertFreshSecondFactor(userId, headers, meta, code) {
|
|
1401
|
+
await this.twoFactorLockout?.assertNotLocked(userId);
|
|
1402
|
+
const res = await this.verifyChallengeCode(await resolveChallengeMethod(this.drizzle, userId), { code, trustDevice: false }, headers);
|
|
1403
|
+
if (!res.ok) {
|
|
1404
|
+
await this.twoFactorLockout?.recordFailure(userId, meta);
|
|
1405
|
+
}
|
|
1406
|
+
await ensureOk(res, { genericMessage: 'Invalid authenticator code' });
|
|
1407
|
+
await this.twoFactorLockout?.reset(userId);
|
|
1408
|
+
}
|
|
1409
|
+
async regenerateBackupCodes(input, reqHeaders, resHeaders) {
|
|
1410
|
+
const { ip, userAgent } = extractClientMeta(reqHeaders);
|
|
1411
|
+
const headers = nodeHeadersToHeaders(reqHeaders);
|
|
1412
|
+
const userId = await this.currentUserId(headers);
|
|
1413
|
+
await assertRateLimit(this.limiter, `backupCodes:${userId ?? 'anonymous'}`, TWO_FACTOR_PASSWORD_RATE_LIMIT);
|
|
1414
|
+
if (!userId) {
|
|
1415
|
+
throw new ORPCError('UNAUTHORIZED', { message: 'Not signed in' });
|
|
1416
|
+
}
|
|
1417
|
+
await this.assertFreshSecondFactor(userId, headers, { ip, userAgent }, input.code);
|
|
1418
|
+
const res = await this.api.generateBackupCodes({
|
|
1419
|
+
body: { password: input.password },
|
|
1420
|
+
headers,
|
|
1421
|
+
asResponse: true,
|
|
1422
|
+
});
|
|
1423
|
+
await ensureOk(res);
|
|
1424
|
+
this.forwardCookies(res, resHeaders);
|
|
1425
|
+
const body = (await res.json());
|
|
1426
|
+
// The old set is void the moment a new one is minted, so any device still trusted
|
|
1427
|
+
// off the old recovery flow re-verifies on its next login.
|
|
1428
|
+
await this.trustedDevices?.revokeAllForUser(userId, userId);
|
|
1429
|
+
this.events.emit('identity.2fa.backup_codes_regenerated', {
|
|
1430
|
+
userId,
|
|
1431
|
+
playerId: await this.identityReader.getPlayerIdByUserIdSafe(userId),
|
|
1432
|
+
ip,
|
|
1433
|
+
userAgent,
|
|
1434
|
+
});
|
|
1435
|
+
return { backupCodes: body.backupCodes };
|
|
1436
|
+
}
|
|
386
1437
|
async disableTwoFactor(input, reqHeaders, resHeaders) {
|
|
1438
|
+
const { ip, userAgent } = extractClientMeta(reqHeaders);
|
|
387
1439
|
const headers = nodeHeadersToHeaders(reqHeaders);
|
|
388
1440
|
const userId = await this.currentUserId(headers);
|
|
389
1441
|
await assertRateLimit(this.limiter, `disable2fa:${userId ?? 'anonymous'}`, TWO_FACTOR_PASSWORD_RATE_LIMIT);
|
|
1442
|
+
if (!userId) {
|
|
1443
|
+
throw new ORPCError('UNAUTHORIZED', { message: 'Not signed in' });
|
|
1444
|
+
}
|
|
1445
|
+
await this.assertFreshSecondFactor(userId, headers, { ip, userAgent }, input.code);
|
|
1446
|
+
// Read before the teardown clears it, so the audit trail records which method the
|
|
1447
|
+
// account was actually protected by rather than a blank.
|
|
1448
|
+
const disabledMethod = await resolveChallengeMethod(this.drizzle, userId);
|
|
390
1449
|
const res = await this.api.disableTwoFactor({
|
|
391
1450
|
body: { password: input.password },
|
|
392
1451
|
headers,
|
|
393
1452
|
asResponse: true,
|
|
394
1453
|
});
|
|
395
1454
|
await ensureOk(res);
|
|
396
|
-
forwardCookies(res, resHeaders);
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
1455
|
+
this.forwardCookies(res, resHeaders);
|
|
1456
|
+
await this.setTwoFactorMethod(userId, null);
|
|
1457
|
+
// Dropping the second factor takes every standing bypass with it, the same teardown
|
|
1458
|
+
// a Super Admin reset performs - a browser must not keep the access 2FA was guarding.
|
|
1459
|
+
await this.trustedDevices?.revokeAllForUser(userId, userId);
|
|
1460
|
+
await this.sessions?.revokeAllSessions(userId, userId, { ip, userAgent });
|
|
1461
|
+
// Must clear alongside the method: leaving it set strands the account with
|
|
1462
|
+
// `twoFactorEnabled: false, requireTwoFactorOnLogin: true` - a state `trustCurrentDevice`
|
|
1463
|
+
// reads as "still enforced" while `setRequireTwoFactorOnLogin` itself refuses to turn it
|
|
1464
|
+
// off without `twoFactorEnabled`, so nothing in the product could ever escape it again.
|
|
1465
|
+
await this.drizzle.db
|
|
1466
|
+
.update(user)
|
|
1467
|
+
.set({ requireTwoFactorOnLogin: false })
|
|
1468
|
+
.where(eq(user.id, userId));
|
|
1469
|
+
this.events.emit('identity.2fa.disabled', {
|
|
1470
|
+
userId,
|
|
1471
|
+
playerId: await this.identityReader.getPlayerIdByUserIdSafe(userId),
|
|
1472
|
+
method: disabledMethod,
|
|
1473
|
+
ip,
|
|
1474
|
+
userAgent,
|
|
1475
|
+
});
|
|
400
1476
|
return SUCCESS;
|
|
401
1477
|
}
|
|
402
1478
|
async requestPasswordReset(input) {
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
//
|
|
406
|
-
//
|
|
1479
|
+
const email = input.email.toLowerCase();
|
|
1480
|
+
await assertRateLimit(this.limiter, makeRateLimitKey(RATE_LIMIT_KEYS.PASSWORD_RESET_REQUEST, email), PASSWORD_RESET_REQUEST_RATE_LIMIT);
|
|
1481
|
+
// Always returns success - never reveal whether the email exists. The reset OTP
|
|
1482
|
+
// (if any) is enqueued through better-auth's emailOTP hook -> MAIL_DISPATCH. Any
|
|
1483
|
+
// underlying error is swallowed for the same anti-enumeration reason.
|
|
407
1484
|
try {
|
|
408
|
-
await this.api.
|
|
409
|
-
body: { email
|
|
1485
|
+
await this.api.requestPasswordResetEmailOTP({
|
|
1486
|
+
body: { email },
|
|
410
1487
|
headers: new Headers(),
|
|
411
1488
|
asResponse: true,
|
|
412
1489
|
});
|
|
@@ -416,77 +1493,504 @@ export class IdentityService {
|
|
|
416
1493
|
}
|
|
417
1494
|
return SUCCESS;
|
|
418
1495
|
}
|
|
1496
|
+
async verifyPasswordResetOtp(input) {
|
|
1497
|
+
const email = input.email.toLowerCase();
|
|
1498
|
+
await assertRateLimit(this.limiter, makeRateLimitKey(RATE_LIMIT_KEYS.PASSWORD_RESET_VERIFY, email), PASSWORD_RESET_VERIFY_RATE_LIMIT);
|
|
1499
|
+
const res = await this.api.checkVerificationOTP({
|
|
1500
|
+
body: { email, type: 'forget-password', otp: input.otp },
|
|
1501
|
+
headers: new Headers(),
|
|
1502
|
+
asResponse: true,
|
|
1503
|
+
});
|
|
1504
|
+
await ensureOk(res, { genericMessage: 'Invalid or expired verification code' });
|
|
1505
|
+
return SUCCESS;
|
|
1506
|
+
}
|
|
419
1507
|
async resetPassword(input) {
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
await
|
|
423
|
-
|
|
424
|
-
body: { newPassword: input.newPassword, token: input.token },
|
|
1508
|
+
const email = input.email.toLowerCase();
|
|
1509
|
+
await assertRateLimit(this.limiter, makeRateLimitKey(RATE_LIMIT_KEYS.PASSWORD_RESET, email), PASSWORD_RESET_RATE_LIMIT);
|
|
1510
|
+
const res = await this.api.resetPasswordEmailOTP({
|
|
1511
|
+
body: { email, otp: input.otp, password: input.newPassword },
|
|
425
1512
|
headers: new Headers(),
|
|
426
1513
|
asResponse: true,
|
|
427
1514
|
});
|
|
428
|
-
await ensureOk(res);
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
await this.clearLockout(body.user.id);
|
|
434
|
-
}
|
|
1515
|
+
await ensureOk(res, { genericMessage: 'Invalid or expired verification code' });
|
|
1516
|
+
// better-auth's resetPasswordEmailOTP internally invokes the onPasswordReset hook
|
|
1517
|
+
// (wired in the constructor above), which emits `identity.password.reset` and
|
|
1518
|
+
// clears the lockout - do not duplicate that here (was double-emitting/double-
|
|
1519
|
+
// clearing on every real reset).
|
|
435
1520
|
return SUCCESS;
|
|
436
1521
|
}
|
|
437
|
-
async changePassword(input, reqHeaders, resHeaders) {
|
|
1522
|
+
async changePassword(input, reqHeaders, resHeaders, caller) {
|
|
438
1523
|
const headers = nodeHeadersToHeaders(reqHeaders);
|
|
439
|
-
const userId =
|
|
440
|
-
await assertRateLimit(this.limiter, `change-password:${userId
|
|
1524
|
+
const { userId, sessionId } = caller;
|
|
1525
|
+
await assertRateLimit(this.limiter, `change-password:${userId}`, CHANGE_PASSWORD_RATE_LIMIT);
|
|
441
1526
|
const res = await this.api.changePassword({
|
|
442
|
-
|
|
1527
|
+
// revokeOtherSessions: better-auth deletes every session for this user and
|
|
1528
|
+
// mints a fresh one for the caller; forwardCookies below ships that cookie.
|
|
1529
|
+
body: {
|
|
1530
|
+
currentPassword: input.currentPassword,
|
|
1531
|
+
newPassword: input.newPassword,
|
|
1532
|
+
revokeOtherSessions: true,
|
|
1533
|
+
},
|
|
443
1534
|
headers,
|
|
444
1535
|
asResponse: true,
|
|
445
1536
|
});
|
|
446
1537
|
await ensureOk(res);
|
|
447
|
-
forwardCookies(res, resHeaders);
|
|
1538
|
+
this.forwardCookies(res, resHeaders);
|
|
1539
|
+
// Captured once the rotation is known committed - the deferred sweep below deletes
|
|
1540
|
+
// any session row created at or before this instant (i.e. one a concurrent
|
|
1541
|
+
// old-password sign-in raced in), sparing anything created afterwards.
|
|
1542
|
+
const sweepDeadline = new Date();
|
|
1543
|
+
// The token of the session better-auth just minted for the caller. `ensureOk` only
|
|
1544
|
+
// reads the body on failure, so this read is safe here.
|
|
1545
|
+
// Library boundary: `Response.json()` resolves to `any`, and better-auth publishes no
|
|
1546
|
+
// response type for this route, so its shape is asserted once here.
|
|
1547
|
+
const rotatedToken = (await res.json().catch(() => ({}))).token ?? null;
|
|
1548
|
+
// better-auth's response only carries the token, not the row id - look the row up
|
|
1549
|
+
// once here and reuse its id both to clamp the dontRememberMe TTL below and to
|
|
1550
|
+
// spare this (legitimate) session from the sweep's own revoke push further down.
|
|
1551
|
+
const rotated = rotatedToken
|
|
1552
|
+
? (await this.drizzle.db
|
|
1553
|
+
.select({ id: session.id })
|
|
1554
|
+
.from(session)
|
|
1555
|
+
.where(eq(session.token, rotatedToken))
|
|
1556
|
+
.limit(1))[0]
|
|
1557
|
+
: undefined;
|
|
1558
|
+
// `revokeOtherSessions` makes better-auth mint the replacement session via
|
|
1559
|
+
// `createSession(userId)` with no `dontRememberMe` argument, so a caller who signed
|
|
1560
|
+
// in with `rememberMe: false` silently gets a full-TTL row. better-auth's own
|
|
1561
|
+
// `setSessionCookie` still honours the `dont_remember` cookie for the cookie maxAge,
|
|
1562
|
+
// but not the DB row - clamp it back to the non-remembered TTL to match.
|
|
1563
|
+
if (rotated && hasDontRememberCookie(headers)) {
|
|
1564
|
+
await this.drizzle.db
|
|
1565
|
+
.update(session)
|
|
1566
|
+
.set({ expiresAt: new Date(Date.now() + DONT_REMEMBER_SESSION_TTL_MS) })
|
|
1567
|
+
.where(eq(session.id, rotated.id));
|
|
1568
|
+
}
|
|
1569
|
+
const { ip, userAgent } = extractClientMeta(reqHeaders);
|
|
1570
|
+
// Independent of each other and of `rotated` - one round trip instead of two on a
|
|
1571
|
+
// user-facing endpoint. (The TTL clamp above does depend on `rotated`, so it stays
|
|
1572
|
+
// sequential.)
|
|
1573
|
+
const [, playerId] = await Promise.all([
|
|
1574
|
+
this.drizzle.db.update(user).set({ passwordMeetsPolicy: true }).where(eq(user.id, userId)),
|
|
1575
|
+
this.identityReader.getPlayerIdByUserIdSafe(userId),
|
|
1576
|
+
]);
|
|
1577
|
+
// Dedicated, non-sensitive record that the login credential itself changed -
|
|
1578
|
+
// the audit mapper keys the action off the topic, so a plain
|
|
1579
|
+
// `identity.sessions.revoked_all` alone would read as "revoked all sessions",
|
|
1580
|
+
// not "changed password". Every state-changing credential action needs its own
|
|
1581
|
+
// accurately named audit record.
|
|
1582
|
+
this.events.emit('identity.password.changed', {
|
|
1583
|
+
userId,
|
|
1584
|
+
playerId,
|
|
1585
|
+
ip: ip ?? null,
|
|
1586
|
+
userAgent: userAgent ?? null,
|
|
1587
|
+
});
|
|
1588
|
+
// Same event the admin "revoke all sessions" path emits, so the streamSession
|
|
1589
|
+
// SSE handler pushes { type: 'revoked' } to this user's OTHER tabs.
|
|
1590
|
+
// exceptSessionId is the caller's PRE-rotation session id - it's the id the
|
|
1591
|
+
// caller's already-open streamSession connection captured at stream-open, and the
|
|
1592
|
+
// only value its SSE compare can ever match, so this is what spares the
|
|
1593
|
+
// initiating tab.
|
|
1594
|
+
this.events.emit('identity.sessions.revoked_all', {
|
|
1595
|
+
userId,
|
|
1596
|
+
playerId,
|
|
1597
|
+
actorId: userId,
|
|
1598
|
+
ip: ip ?? null,
|
|
1599
|
+
userAgent: userAgent ?? null,
|
|
1600
|
+
exceptSessionId: sessionId,
|
|
1601
|
+
});
|
|
1602
|
+
// better-auth rotates the password hash and deletes sessions in separate,
|
|
1603
|
+
// untransacted statements; a sign-in that verified the OLD password just before
|
|
1604
|
+
// the rotation can still insert its session row right after. Re-sweep shortly
|
|
1605
|
+
// after to delete it, sparing the caller's fresh session by token. Skipped when
|
|
1606
|
+
// the rotated token is unknown - without it the sweep cannot tell the caller's
|
|
1607
|
+
// own new session apart. Residual exposure: RACED_SESSION_SWEEP_DELAY_MS.
|
|
1608
|
+
if (rotatedToken) {
|
|
1609
|
+
const timer = setTimeout(() => {
|
|
1610
|
+
void sweepRacedSessionsAfterPasswordChange(this.drizzle.db, {
|
|
1611
|
+
userId,
|
|
1612
|
+
sparedToken: rotatedToken,
|
|
1613
|
+
deadline: sweepDeadline,
|
|
1614
|
+
})
|
|
1615
|
+
.then((deletedIds) => {
|
|
1616
|
+
// A session the sweep just force-deleted got no push and no audit record
|
|
1617
|
+
// otherwise: it raced in after the primary revoked_all above already
|
|
1618
|
+
// fired, so this is the only notice it gets of either.
|
|
1619
|
+
if (deletedIds.length === 0) {
|
|
1620
|
+
return;
|
|
1621
|
+
}
|
|
1622
|
+
this.events.emit('identity.sessions.revoked_all', {
|
|
1623
|
+
userId,
|
|
1624
|
+
playerId,
|
|
1625
|
+
actorId: userId,
|
|
1626
|
+
ip: ip ?? null,
|
|
1627
|
+
userAgent: userAgent ?? null,
|
|
1628
|
+
// The caller's PRE-rotation session id, same as the primary emit above -
|
|
1629
|
+
// it's what the initiating tab's already-open streamSession connection
|
|
1630
|
+
// captured at stream-open, and the only value its SSE compare can match.
|
|
1631
|
+
// `rotated.id` (the NEW row) can never match that, so using it here would
|
|
1632
|
+
// force-revoke the legitimate acting tab the moment the sweep actually
|
|
1633
|
+
// deletes a raced session.
|
|
1634
|
+
exceptSessionId: sessionId,
|
|
1635
|
+
});
|
|
1636
|
+
})
|
|
1637
|
+
.catch((err) => {
|
|
1638
|
+
identityLogger.warn({ err, userId }, 'post-password-change session sweep failed');
|
|
1639
|
+
});
|
|
1640
|
+
}, RACED_SESSION_SWEEP_DELAY_MS);
|
|
1641
|
+
timer.unref?.();
|
|
1642
|
+
}
|
|
448
1643
|
return SUCCESS;
|
|
449
1644
|
}
|
|
450
|
-
async
|
|
451
|
-
const
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
1645
|
+
async getSecurityControls(reqHeaders) {
|
|
1646
|
+
const userId = await this.currentUserId(nodeHeadersToHeaders(reqHeaders));
|
|
1647
|
+
if (!userId) {
|
|
1648
|
+
throw new ORPCError('UNAUTHORIZED', { message: 'Not signed in.' });
|
|
1649
|
+
}
|
|
1650
|
+
return this.securityControlsFor(userId);
|
|
1651
|
+
}
|
|
1652
|
+
/**
|
|
1653
|
+
* Resolves the caller of a security-preference setter and refuses anyone who is not a
|
|
1654
|
+
* player. These setters reject before any shared guard runs, so a denial still owes the
|
|
1655
|
+
* audit log the same signal AdminGuard emits (docs/standards/audit.md) - `resource`
|
|
1656
|
+
* names which preference was attempted.
|
|
1657
|
+
*/
|
|
1658
|
+
async assertPlayerPreferenceCaller(reqHeaders, resource) {
|
|
1659
|
+
const { ip, userAgent } = extractClientMeta(reqHeaders);
|
|
1660
|
+
const userId = await this.currentUserId(nodeHeadersToHeaders(reqHeaders));
|
|
1661
|
+
if (!userId) {
|
|
1662
|
+
throw new ORPCError('UNAUTHORIZED', { message: 'Not signed in.' });
|
|
1663
|
+
}
|
|
1664
|
+
const [caller] = await this.drizzle.db
|
|
1665
|
+
.select({ role: user.role })
|
|
1666
|
+
.from(user)
|
|
1667
|
+
.where(eq(user.id, userId))
|
|
1668
|
+
.limit(1);
|
|
1669
|
+
if (caller?.role !== 'player') {
|
|
1670
|
+
this.events.emit('identity.user.unauthorized_access', {
|
|
1671
|
+
userId,
|
|
1672
|
+
playerId: null,
|
|
1673
|
+
resource,
|
|
1674
|
+
action: 'set',
|
|
1675
|
+
...(caller?.role ? { role: caller.role } : {}),
|
|
1676
|
+
ip,
|
|
1677
|
+
userAgent,
|
|
1678
|
+
});
|
|
1679
|
+
throw new ORPCError('FORBIDDEN', {
|
|
1680
|
+
message: 'Only players can set this preference.',
|
|
1681
|
+
});
|
|
1682
|
+
}
|
|
1683
|
+
return { userId, ip, userAgent };
|
|
1684
|
+
}
|
|
1685
|
+
async setLoginWithdrawalAlerts(input, reqHeaders) {
|
|
1686
|
+
const { userId, ip, userAgent } = await this.assertPlayerPreferenceCaller(reqHeaders, 'identity.security.login_withdrawal_alerts');
|
|
1687
|
+
const before = await this.securityControlsFor(userId);
|
|
1688
|
+
if (input.enabled && !before.emailVerified) {
|
|
1689
|
+
throw new ORPCError('UNPROCESSABLE_CONTENT', {
|
|
1690
|
+
message: 'Verify your email before enabling security alerts.',
|
|
1691
|
+
});
|
|
1692
|
+
}
|
|
1693
|
+
if (before.loginWithdrawalAlertsEnabled === input.enabled) {
|
|
1694
|
+
return before;
|
|
1695
|
+
}
|
|
1696
|
+
await this.drizzle.db
|
|
1697
|
+
.update(user)
|
|
1698
|
+
.set({ loginWithdrawalAlertsEnabled: input.enabled })
|
|
1699
|
+
.where(eq(user.id, userId));
|
|
1700
|
+
this.events.emit('identity.security.login_withdrawal_alerts.updated', {
|
|
1701
|
+
userId,
|
|
1702
|
+
playerId: await this.identityReader.getPlayerIdByUserIdSafe(userId),
|
|
1703
|
+
previousEnabled: before.loginWithdrawalAlertsEnabled,
|
|
1704
|
+
enabled: input.enabled,
|
|
1705
|
+
ip,
|
|
1706
|
+
userAgent,
|
|
1707
|
+
});
|
|
1708
|
+
return { ...before, loginWithdrawalAlertsEnabled: input.enabled };
|
|
1709
|
+
}
|
|
1710
|
+
async setAutoLogoutDuration(input, reqHeaders) {
|
|
1711
|
+
const { userId, ip, userAgent } = await this.assertPlayerPreferenceCaller(reqHeaders, 'identity.security.auto_logout');
|
|
1712
|
+
const before = await this.securityControlsFor(userId);
|
|
1713
|
+
if (before.autoLogoutDuration === input.duration) {
|
|
1714
|
+
return before;
|
|
1715
|
+
}
|
|
1716
|
+
await this.drizzle.db
|
|
1717
|
+
.update(user)
|
|
1718
|
+
.set({ autoLogoutDuration: input.duration })
|
|
1719
|
+
.where(eq(user.id, userId));
|
|
1720
|
+
this.events.emit('identity.security.auto_logout.updated', {
|
|
1721
|
+
userId,
|
|
1722
|
+
playerId: await this.identityReader.getPlayerIdByUserIdSafe(userId),
|
|
1723
|
+
previousDuration: before.autoLogoutDuration,
|
|
1724
|
+
duration: input.duration,
|
|
1725
|
+
ip,
|
|
1726
|
+
userAgent,
|
|
1727
|
+
});
|
|
1728
|
+
return { ...before, autoLogoutDuration: input.duration };
|
|
1729
|
+
}
|
|
1730
|
+
/**
|
|
1731
|
+
* Turning this on also tears down the devices already trusted: stripping the trust
|
|
1732
|
+
* cookie at login is enough to force the challenge, but leaving live rows behind would
|
|
1733
|
+
* show a player devices that no longer buy anything, and hand them straight back the
|
|
1734
|
+
* moment the toggle goes off again.
|
|
1735
|
+
*/
|
|
1736
|
+
async setRequireTwoFactorOnLogin(input, reqHeaders) {
|
|
1737
|
+
const { userId, ip, userAgent } = await this.assertPlayerPreferenceCaller(reqHeaders, 'identity.security.require_two_factor');
|
|
1738
|
+
const before = await this.securityControlsFor(userId);
|
|
1739
|
+
if (input.enabled && !before.twoFactorEnabled) {
|
|
1740
|
+
throw new ORPCError('UNPROCESSABLE_CONTENT', {
|
|
1741
|
+
message: 'Enable two-factor authentication before requiring it on every login.',
|
|
1742
|
+
});
|
|
1743
|
+
}
|
|
1744
|
+
if (before.requireTwoFactorOnLogin === input.enabled) {
|
|
1745
|
+
return before;
|
|
1746
|
+
}
|
|
1747
|
+
await this.drizzle.db
|
|
1748
|
+
.update(user)
|
|
1749
|
+
.set({ requireTwoFactorOnLogin: input.enabled })
|
|
1750
|
+
.where(eq(user.id, userId));
|
|
1751
|
+
if (input.enabled) {
|
|
1752
|
+
await this.trustedDevices?.revokeAllForUser(userId, userId);
|
|
1753
|
+
}
|
|
1754
|
+
this.events.emit('identity.security.require_two_factor.updated', {
|
|
1755
|
+
userId,
|
|
1756
|
+
playerId: await this.identityReader.getPlayerIdByUserIdSafe(userId),
|
|
1757
|
+
previousEnabled: before.requireTwoFactorOnLogin,
|
|
1758
|
+
enabled: input.enabled,
|
|
1759
|
+
ip,
|
|
1760
|
+
userAgent,
|
|
1761
|
+
});
|
|
1762
|
+
return { ...before, requireTwoFactorOnLogin: input.enabled };
|
|
1763
|
+
}
|
|
1764
|
+
/**
|
|
1765
|
+
* Sets (or overwrites) the player's anti-phishing code: a free-text, case-sensitive
|
|
1766
|
+
* recognition phrase stamped into every outgoing platform email so the player can tell a
|
|
1767
|
+
* genuine email from a phishing attempt. Unlike the withdrawal PIN this authorizes nothing,
|
|
1768
|
+
* so - like `setLoginWithdrawalAlerts` - it takes no reauth and there is no remove route;
|
|
1769
|
+
* calling it again with a new value just changes the code.
|
|
1770
|
+
*/
|
|
1771
|
+
async setAntiPhishingCode(input, reqHeaders) {
|
|
1772
|
+
const { ip, userAgent } = extractClientMeta(reqHeaders);
|
|
1773
|
+
const userId = await this.currentUserId(nodeHeadersToHeaders(reqHeaders));
|
|
1774
|
+
if (!userId) {
|
|
1775
|
+
throw new ORPCError('UNAUTHORIZED', { message: 'Not signed in.' });
|
|
1776
|
+
}
|
|
1777
|
+
const [caller] = await this.drizzle.db
|
|
1778
|
+
.select({ role: user.role, email: user.email, language: user.language })
|
|
1779
|
+
.from(user)
|
|
1780
|
+
.where(eq(user.id, userId))
|
|
1781
|
+
.limit(1);
|
|
1782
|
+
if (caller?.role !== 'player') {
|
|
1783
|
+
// A service-level denial still owes the audit log the same signal AdminGuard emits,
|
|
1784
|
+
// since this check rejects before any shared guard runs (docs/standards/audit.md).
|
|
1785
|
+
this.events.emit('identity.user.unauthorized_access', {
|
|
1786
|
+
userId,
|
|
1787
|
+
playerId: null,
|
|
1788
|
+
resource: 'identity.security.anti_phishing_code',
|
|
1789
|
+
action: 'set',
|
|
1790
|
+
...(caller?.role ? { role: caller.role } : {}),
|
|
1791
|
+
ip,
|
|
1792
|
+
userAgent,
|
|
1793
|
+
});
|
|
1794
|
+
throw new ORPCError('FORBIDDEN', {
|
|
1795
|
+
message: 'Only players can set this preference.',
|
|
1796
|
+
});
|
|
1797
|
+
}
|
|
1798
|
+
const before = await this.securityControlsFor(userId);
|
|
1799
|
+
if (before.antiPhishingCode === input.code) {
|
|
1800
|
+
return before;
|
|
1801
|
+
}
|
|
1802
|
+
await assertRateLimit(this.limiter, makeRateLimitKey(RATE_LIMIT_KEYS.ANTI_PHISHING_CODE_MUTATION, userId), ANTI_PHISHING_CODE_RATE_LIMIT);
|
|
1803
|
+
await this.drizzle.db
|
|
1804
|
+
.update(user)
|
|
1805
|
+
.set({ antiPhishingCode: input.code })
|
|
1806
|
+
.where(eq(user.id, userId));
|
|
1807
|
+
this.events.emit('identity.security.anti_phishing_code.set', {
|
|
1808
|
+
userId,
|
|
1809
|
+
playerId: await this.identityReader.getPlayerIdByUserIdSafe(userId),
|
|
1810
|
+
wasAlreadySet: before.antiPhishingCode !== null,
|
|
1811
|
+
ip,
|
|
1812
|
+
userAgent,
|
|
1813
|
+
});
|
|
1814
|
+
// Deliberately address-only: resolving a user recipient later would stamp the email with
|
|
1815
|
+
// the replacement code. This notice instead carries the prior code, which lets the owner
|
|
1816
|
+
// recognise it even if a stolen session changed the current value.
|
|
1817
|
+
// The row is already committed, so a failed enqueue must not fail the mutation: the
|
|
1818
|
+
// caller would see an error for a change that landed, and retrying the same value exits
|
|
1819
|
+
// at the no-op branch above without ever re-sending the notice.
|
|
1820
|
+
try {
|
|
1821
|
+
await this.mailDispatch?.toAddress({
|
|
1822
|
+
email: caller.email,
|
|
1823
|
+
locale: caller.language,
|
|
1824
|
+
template: {
|
|
1825
|
+
key: 'securityAntiPhishingCodeChanged',
|
|
1826
|
+
data: { previousAntiPhishingCode: before.antiPhishingCode },
|
|
1827
|
+
},
|
|
1828
|
+
idempotencyKey: `anti-phishing-code-changed:${userId}:${randomUUID()}`,
|
|
1829
|
+
});
|
|
1830
|
+
}
|
|
1831
|
+
catch (err) {
|
|
1832
|
+
identityLogger.error({ err, userId }, 'anti-phishing code change notice enqueue failed');
|
|
1833
|
+
}
|
|
1834
|
+
return { ...before, antiPhishingCode: input.code };
|
|
1835
|
+
}
|
|
1836
|
+
/**
|
|
1837
|
+
* Resends the registration code. Unauthenticated by design - the player has no session
|
|
1838
|
+
* until the code is verified - so it answers SUCCESS for every address and only mails a
|
|
1839
|
+
* code to an account that exists and is still unverified. Verified accounts are skipped
|
|
1840
|
+
* deliberately: `verifyEmail` signs the code's bearer in, so resending to a verified
|
|
1841
|
+
* address would turn this into passwordless sign-in for anyone who can read that inbox.
|
|
1842
|
+
*/
|
|
1843
|
+
async sendEmailVerification(input, reqHeaders) {
|
|
1844
|
+
const { ip } = extractClientMeta(reqHeaders);
|
|
1845
|
+
const email = input.email.toLowerCase();
|
|
1846
|
+
await assertRateLimit(this.limiter, `email-verify:${email}`, EMAIL_VERIFICATION_RATE_LIMIT);
|
|
1847
|
+
if (ip) {
|
|
1848
|
+
await assertRateLimit(this.limiter, `email-verify-ip:${ip}`, EMAIL_VERIFICATION_RATE_LIMIT);
|
|
1849
|
+
}
|
|
1850
|
+
const [row] = await this.drizzle.db
|
|
1851
|
+
.select({ emailVerified: user.emailVerified })
|
|
1852
|
+
.from(user)
|
|
1853
|
+
.where(eq(user.email, email))
|
|
1854
|
+
.limit(1);
|
|
1855
|
+
if (row && !row.emailVerified) {
|
|
1856
|
+
await this.api.sendVerificationOTP({
|
|
1857
|
+
body: { email, type: 'email-verification' },
|
|
1858
|
+
headers: nodeHeadersToHeaders(reqHeaders),
|
|
1859
|
+
asResponse: true,
|
|
1860
|
+
});
|
|
457
1861
|
}
|
|
458
1862
|
return SUCCESS;
|
|
459
1863
|
}
|
|
460
|
-
|
|
1864
|
+
/**
|
|
1865
|
+
* Consumes the 6-digit code mailed by `register()` and signs the player in -
|
|
1866
|
+
* better-auth's `autoSignInAfterVerification` mints the session here rather than at
|
|
1867
|
+
* sign-up, which is what lets sign-up stay sessionless and therefore keep its
|
|
1868
|
+
* duplicate-email response indistinguishable. Same post-credential gates as `login`:
|
|
1869
|
+
* a code is proof of address ownership, not a bypass for an RG or backoffice block.
|
|
1870
|
+
*/
|
|
1871
|
+
async verifyEmail(input, reqHeaders, resHeaders) {
|
|
1872
|
+
const { ip, userAgent } = extractClientMeta(reqHeaders);
|
|
461
1873
|
const headers = nodeHeadersToHeaders(reqHeaders);
|
|
462
|
-
const
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
1874
|
+
const email = input.email.toLowerCase();
|
|
1875
|
+
// Keyed on the address under attack (six digits are guessable) and on the caller, so
|
|
1876
|
+
// one client can neither grind a single account nor sweep many.
|
|
1877
|
+
await assertRateLimit(this.limiter, `verify-email:${email}`, VERIFY_EMAIL_RATE_LIMIT);
|
|
1878
|
+
// Only when the caller's IP is actually known: an `unknown` bucket would be shared by
|
|
1879
|
+
// every anonymous caller, letting one client stall everyone else's sign-up.
|
|
1880
|
+
if (ip) {
|
|
1881
|
+
await assertRateLimit(this.limiter, `verify-email-ip:${ip}`, VERIFY_EMAIL_RATE_LIMIT);
|
|
1882
|
+
}
|
|
1883
|
+
const res = await this.api.verifyEmailOTP({
|
|
1884
|
+
body: { email, otp: input.otp },
|
|
466
1885
|
headers,
|
|
467
1886
|
asResponse: true,
|
|
468
1887
|
});
|
|
469
|
-
await ensureOk(res);
|
|
470
|
-
|
|
471
|
-
|
|
1888
|
+
await ensureOk(res, { genericMessage: 'Invalid or expired verification code' });
|
|
1889
|
+
const body = (await res.json());
|
|
1890
|
+
// better-auth has already committed `emailVerified` by now, so the audit record is
|
|
1891
|
+
// emitted before any gate below can throw - a state change that leaves no trail is a
|
|
1892
|
+
// compliance gap, see docs/standards/audit.md.
|
|
1893
|
+
const playerId = await this.identityReader.getPlayerIdByUserIdSafe(body.user.id);
|
|
1894
|
+
this.events.emit('identity.email.verified', { userId: body.user.id, playerId, ip, userAgent });
|
|
1895
|
+
const [account] = await this.drizzle.db
|
|
1896
|
+
.select({
|
|
1897
|
+
id: user.id,
|
|
1898
|
+
rgBlocked: user.rgBlocked,
|
|
1899
|
+
rgBlockedUntil: user.rgBlockedUntil,
|
|
1900
|
+
twoFactorEnabled: user.twoFactorEnabled,
|
|
1901
|
+
})
|
|
1902
|
+
.from(user)
|
|
1903
|
+
.where(eq(user.id, body.user.id))
|
|
1904
|
+
.limit(1);
|
|
1905
|
+
if (account) {
|
|
1906
|
+
await this.assertAccountNotBlocked(account, { ip, userAgent });
|
|
472
1907
|
}
|
|
473
|
-
|
|
1908
|
+
// Before the 2FA branch below: that path ends the session it just minted, but the zone
|
|
1909
|
+
// the browser reported is good either way.
|
|
1910
|
+
await captureTimezone(this.playerProvisioning, body.user.id, input.timezone);
|
|
1911
|
+
// better-auth mints this session with `createSession`, which its twoFactor plugin only
|
|
1912
|
+
// hooks on the sign-in routes - so an enrolled account would get a full session from
|
|
1913
|
+
// the emailed code alone, bypassing its second factor. Verification still stands; the
|
|
1914
|
+
// session does not, and the player signs in through `login` to face the challenge.
|
|
1915
|
+
if (account?.twoFactorEnabled) {
|
|
1916
|
+
// Scoped to the token this call just minted: the player's other devices did nothing
|
|
1917
|
+
// wrong, and an unrelated sign-out here would be indistinguishable from a session
|
|
1918
|
+
// hijack. The RG/backoffice branch above is the one that revokes everything.
|
|
1919
|
+
if (body.token) {
|
|
1920
|
+
await this.drizzle.db
|
|
1921
|
+
.update(session)
|
|
1922
|
+
.set({ expiresAt: new Date() })
|
|
1923
|
+
.where(eq(session.token, body.token));
|
|
1924
|
+
}
|
|
1925
|
+
return { twoFactorRedirect: true };
|
|
1926
|
+
}
|
|
1927
|
+
if (!body.token) {
|
|
1928
|
+
throw new ORPCError('INTERNAL_SERVER_ERROR', { message: 'Verification did not sign you in' });
|
|
1929
|
+
}
|
|
1930
|
+
this.forwardCookies(res, resHeaders);
|
|
1931
|
+
await this.drizzle.db
|
|
1932
|
+
.update(session)
|
|
1933
|
+
.set({ ipAddress: ip, userAgent })
|
|
1934
|
+
.where(eq(session.token, body.token));
|
|
1935
|
+
this.events.emit('identity.user.login', { userId: body.user.id, playerId, ip, userAgent });
|
|
1936
|
+
this.events.emit('identity.authentication.succeeded', {
|
|
1937
|
+
userId: body.user.id,
|
|
1938
|
+
playerId,
|
|
1939
|
+
method: 'email_verification',
|
|
1940
|
+
ip,
|
|
1941
|
+
userAgent,
|
|
1942
|
+
});
|
|
1943
|
+
const sessionDurationSeconds = this.auth.options.session?.expiresIn ?? SESSION_DURATION_IN_SECONDS;
|
|
1944
|
+
return {
|
|
1945
|
+
user: toUser(body.user),
|
|
1946
|
+
session: {
|
|
1947
|
+
token: body.token,
|
|
1948
|
+
expiresAt: new Date(Date.now() + sessionDurationSeconds * 1000).toISOString(),
|
|
1949
|
+
},
|
|
1950
|
+
};
|
|
474
1951
|
}
|
|
475
1952
|
async changeEmail(input, reqHeaders, resHeaders) {
|
|
476
1953
|
const headers = nodeHeadersToHeaders(reqHeaders);
|
|
1954
|
+
const userId = await this.currentUserId(headers);
|
|
1955
|
+
const newEmail = input.newEmail.toLowerCase();
|
|
477
1956
|
const res = await this.api.changeEmail({
|
|
478
1957
|
body: { newEmail: input.newEmail },
|
|
479
1958
|
headers,
|
|
480
1959
|
asResponse: true,
|
|
481
1960
|
});
|
|
482
1961
|
await ensureOk(res);
|
|
483
|
-
forwardCookies(res, resHeaders);
|
|
1962
|
+
this.forwardCookies(res, resHeaders);
|
|
1963
|
+
if (userId) {
|
|
1964
|
+
// better-auth's `/change-email` returns the same `{ status: true }` shape for the
|
|
1965
|
+
// anti-enumeration no-op (target already owned by someone else) and for a deferred
|
|
1966
|
+
// confirmation-email flow, where the address only actually changes once the
|
|
1967
|
+
// confirmation link is clicked - neither of which touched this row yet. Requiring
|
|
1968
|
+
// `user.email` to already equal the requested address scopes the disable to the
|
|
1969
|
+
// one branch (`updateEmailWithoutVerification`) that updates it synchronously.
|
|
1970
|
+
const [disabled] = await this.drizzle.db
|
|
1971
|
+
.update(user)
|
|
1972
|
+
.set({ loginWithdrawalAlertsEnabled: false })
|
|
1973
|
+
.where(and(eq(user.id, userId), eq(user.loginWithdrawalAlertsEnabled, true), eq(user.email, newEmail)))
|
|
1974
|
+
.returning({ id: user.id });
|
|
1975
|
+
if (disabled) {
|
|
1976
|
+
const { ip, userAgent } = extractClientMeta(reqHeaders);
|
|
1977
|
+
this.events.emit('identity.security.login_withdrawal_alerts.updated', {
|
|
1978
|
+
userId,
|
|
1979
|
+
playerId: await this.identityReader.getPlayerIdByUserIdSafe(userId),
|
|
1980
|
+
previousEnabled: true,
|
|
1981
|
+
enabled: false,
|
|
1982
|
+
ip,
|
|
1983
|
+
userAgent,
|
|
1984
|
+
});
|
|
1985
|
+
}
|
|
1986
|
+
}
|
|
484
1987
|
return SUCCESS;
|
|
485
1988
|
}
|
|
486
1989
|
async updateProfile(input, reqHeaders, resHeaders) {
|
|
487
1990
|
if (input.language !== undefined) {
|
|
488
1991
|
assertSupportedLanguage(input.language, this.platformConfig);
|
|
489
1992
|
}
|
|
1993
|
+
const { ip, userAgent } = extractClientMeta(reqHeaders);
|
|
490
1994
|
const headers = nodeHeadersToHeaders(reqHeaders);
|
|
491
1995
|
// better-auth's field parser and drizzle's mapUpdateSet both drop `undefined`
|
|
492
1996
|
// values before the SQL SET clause, so omitted fields are safely no-ops here.
|
|
@@ -497,12 +2001,17 @@ export class IdentityService {
|
|
|
497
2001
|
asResponse: true,
|
|
498
2002
|
});
|
|
499
2003
|
await ensureOk(res);
|
|
500
|
-
forwardCookies(res, resHeaders);
|
|
2004
|
+
this.forwardCookies(res, resHeaders);
|
|
501
2005
|
// updateUser returns { status } only - re-read from session to get the full user.
|
|
502
2006
|
const session = await this.auth.api.getSession({ headers });
|
|
503
2007
|
const current = session?.user;
|
|
504
2008
|
if (current) {
|
|
505
|
-
this.events.emit('identity.profile.updated', {
|
|
2009
|
+
this.events.emit('identity.profile.updated', {
|
|
2010
|
+
userId: current.id,
|
|
2011
|
+
playerId: await this.identityReader.getPlayerIdByUserIdSafe(current.id),
|
|
2012
|
+
ip,
|
|
2013
|
+
userAgent,
|
|
2014
|
+
});
|
|
506
2015
|
}
|
|
507
2016
|
if (!current) {
|
|
508
2017
|
throw new Error('Profile update succeeded but session could not be re-read');
|