@antasphere/chassis-server 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +82 -0
- package/dist/accounts/deletion.d.ts +163 -0
- package/dist/accounts/deletion.d.ts.map +1 -0
- package/dist/accounts/deletion.js +360 -0
- package/dist/accounts/deletion.js.map +1 -0
- package/dist/accounts/erasure-log.d.ts +66 -0
- package/dist/accounts/erasure-log.d.ts.map +1 -0
- package/dist/accounts/erasure-log.js +117 -0
- package/dist/accounts/erasure-log.js.map +1 -0
- package/dist/accounts/index.d.ts +6 -0
- package/dist/accounts/index.d.ts.map +1 -0
- package/dist/accounts/index.js +6 -0
- package/dist/accounts/index.js.map +1 -0
- package/dist/accounts/mint-refusal.d.ts +47 -0
- package/dist/accounts/mint-refusal.d.ts.map +1 -0
- package/dist/accounts/mint-refusal.js +59 -0
- package/dist/accounts/mint-refusal.js.map +1 -0
- package/dist/accounts/signup-duplicate.d.ts +14 -0
- package/dist/accounts/signup-duplicate.d.ts.map +1 -0
- package/dist/accounts/signup-duplicate.js +25 -0
- package/dist/accounts/signup-duplicate.js.map +1 -0
- package/dist/accounts/superadmin.d.ts +27 -0
- package/dist/accounts/superadmin.d.ts.map +1 -0
- package/dist/accounts/superadmin.js +46 -0
- package/dist/accounts/superadmin.js.map +1 -0
- package/dist/api/apikeys.d.ts +14 -0
- package/dist/api/apikeys.d.ts.map +1 -0
- package/dist/api/apikeys.js +124 -0
- package/dist/api/apikeys.js.map +1 -0
- package/dist/api/audit.d.ts +4 -0
- package/dist/api/audit.d.ts.map +1 -0
- package/dist/api/audit.js +75 -0
- package/dist/api/audit.js.map +1 -0
- package/dist/api/break-glass.d.ts +48 -0
- package/dist/api/break-glass.d.ts.map +1 -0
- package/dist/api/break-glass.js +217 -0
- package/dist/api/break-glass.js.map +1 -0
- package/dist/api/cli-auth.d.ts +84 -0
- package/dist/api/cli-auth.d.ts.map +1 -0
- package/dist/api/cli-auth.js +177 -0
- package/dist/api/cli-auth.js.map +1 -0
- package/dist/api/create-api.d.ts +123 -0
- package/dist/api/create-api.d.ts.map +1 -0
- package/dist/api/create-api.js +1165 -0
- package/dist/api/create-api.js.map +1 -0
- package/dist/api/demo-passes.d.ts +45 -0
- package/dist/api/demo-passes.d.ts.map +1 -0
- package/dist/api/demo-passes.js +143 -0
- package/dist/api/demo-passes.js.map +1 -0
- package/dist/api/errors.d.ts +5 -0
- package/dist/api/errors.d.ts.map +1 -0
- package/dist/api/errors.js +5 -0
- package/dist/api/errors.js.map +1 -0
- package/dist/api/export.d.ts +63 -0
- package/dist/api/export.d.ts.map +1 -0
- package/dist/api/export.js +393 -0
- package/dist/api/export.js.map +1 -0
- package/dist/api/files.d.ts +40 -0
- package/dist/api/files.d.ts.map +1 -0
- package/dist/api/files.js +150 -0
- package/dist/api/files.js.map +1 -0
- package/dist/api/index.d.ts +17 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +17 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/invitations.d.ts +50 -0
- package/dist/api/invitations.d.ts.map +1 -0
- package/dist/api/invitations.js +313 -0
- package/dist/api/invitations.js.map +1 -0
- package/dist/api/members.d.ts +25 -0
- package/dist/api/members.d.ts.map +1 -0
- package/dist/api/members.js +522 -0
- package/dist/api/members.js.map +1 -0
- package/dist/api/onboarding.d.ts +26 -0
- package/dist/api/onboarding.d.ts.map +1 -0
- package/dist/api/onboarding.js +23 -0
- package/dist/api/onboarding.js.map +1 -0
- package/dist/api/openapi-doc.d.ts +21 -0
- package/dist/api/openapi-doc.d.ts.map +1 -0
- package/dist/api/openapi-doc.js +25 -0
- package/dist/api/openapi-doc.js.map +1 -0
- package/dist/api/projects.d.ts +24 -0
- package/dist/api/projects.d.ts.map +1 -0
- package/dist/api/projects.js +624 -0
- package/dist/api/projects.js.map +1 -0
- package/dist/api/scope-routes.d.ts +12 -0
- package/dist/api/scope-routes.d.ts.map +1 -0
- package/dist/api/scope-routes.js +2 -0
- package/dist/api/scope-routes.js.map +1 -0
- package/dist/api/sso-connect.d.ts +70 -0
- package/dist/api/sso-connect.d.ts.map +1 -0
- package/dist/api/sso-connect.js +164 -0
- package/dist/api/sso-connect.js.map +1 -0
- package/dist/api/sso-logout.d.ts +41 -0
- package/dist/api/sso-logout.d.ts.map +1 -0
- package/dist/api/sso-logout.js +34 -0
- package/dist/api/sso-logout.js.map +1 -0
- package/dist/api/teams.d.ts +43 -0
- package/dist/api/teams.d.ts.map +1 -0
- package/dist/api/teams.js +447 -0
- package/dist/api/teams.js.map +1 -0
- package/dist/api/workspaces.d.ts +114 -0
- package/dist/api/workspaces.d.ts.map +1 -0
- package/dist/api/workspaces.js +462 -0
- package/dist/api/workspaces.js.map +1 -0
- package/dist/apikeys/index.d.ts +3 -0
- package/dist/apikeys/index.d.ts.map +1 -0
- package/dist/apikeys/index.js +3 -0
- package/dist/apikeys/index.js.map +1 -0
- package/dist/apikeys/peppers.d.ts +53 -0
- package/dist/apikeys/peppers.d.ts.map +1 -0
- package/dist/apikeys/peppers.js +97 -0
- package/dist/apikeys/peppers.js.map +1 -0
- package/dist/apikeys/service.d.ts +56 -0
- package/dist/apikeys/service.d.ts.map +1 -0
- package/dist/apikeys/service.js +196 -0
- package/dist/apikeys/service.js.map +1 -0
- package/dist/app.d.ts +65 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +142 -0
- package/dist/app.js.map +1 -0
- package/dist/audit/filters.d.ts +38 -0
- package/dist/audit/filters.d.ts.map +1 -0
- package/dist/audit/filters.js +97 -0
- package/dist/audit/filters.js.map +1 -0
- package/dist/audit/index.d.ts +3 -0
- package/dist/audit/index.d.ts.map +1 -0
- package/dist/audit/index.js +3 -0
- package/dist/audit/index.js.map +1 -0
- package/dist/audit/service.d.ts +65 -0
- package/dist/audit/service.d.ts.map +1 -0
- package/dist/audit/service.js +103 -0
- package/dist/audit/service.js.map +1 -0
- package/dist/boot.d.ts +8 -0
- package/dist/boot.d.ts.map +1 -0
- package/dist/boot.js +822 -0
- package/dist/boot.js.map +1 -0
- package/dist/constant-time.d.ts +3 -0
- package/dist/constant-time.d.ts.map +1 -0
- package/dist/constant-time.js +10 -0
- package/dist/constant-time.js.map +1 -0
- package/dist/email/driver.d.ts +16 -0
- package/dist/email/driver.d.ts.map +1 -0
- package/dist/email/driver.js +136 -0
- package/dist/email/driver.js.map +1 -0
- package/dist/email/index.d.ts +4 -0
- package/dist/email/index.d.ts.map +1 -0
- package/dist/email/index.js +4 -0
- package/dist/email/index.js.map +1 -0
- package/dist/email/shell.d.ts +72 -0
- package/dist/email/shell.d.ts.map +1 -0
- package/dist/email/shell.js +146 -0
- package/dist/email/shell.js.map +1 -0
- package/dist/email/templates.d.ts +83 -0
- package/dist/email/templates.d.ts.map +1 -0
- package/dist/email/templates.js +96 -0
- package/dist/email/templates.js.map +1 -0
- package/dist/entitlements/check.d.ts +140 -0
- package/dist/entitlements/check.d.ts.map +1 -0
- package/dist/entitlements/check.js +276 -0
- package/dist/entitlements/check.js.map +1 -0
- package/dist/entitlements/clock-skew.d.ts +27 -0
- package/dist/entitlements/clock-skew.d.ts.map +1 -0
- package/dist/entitlements/clock-skew.js +58 -0
- package/dist/entitlements/clock-skew.js.map +1 -0
- package/dist/entitlements/gate.d.ts +113 -0
- package/dist/entitlements/gate.d.ts.map +1 -0
- package/dist/entitlements/gate.js +430 -0
- package/dist/entitlements/gate.js.map +1 -0
- package/dist/entitlements/hub-machine-token.d.ts +83 -0
- package/dist/entitlements/hub-machine-token.d.ts.map +1 -0
- package/dist/entitlements/hub-machine-token.js +175 -0
- package/dist/entitlements/hub-machine-token.js.map +1 -0
- package/dist/entitlements/hub-subject.d.ts +32 -0
- package/dist/entitlements/hub-subject.d.ts.map +1 -0
- package/dist/entitlements/hub-subject.js +68 -0
- package/dist/entitlements/hub-subject.js.map +1 -0
- package/dist/entitlements/index.d.ts +9 -0
- package/dist/entitlements/index.d.ts.map +1 -0
- package/dist/entitlements/index.js +9 -0
- package/dist/entitlements/index.js.map +1 -0
- package/dist/entitlements/poster.d.ts +81 -0
- package/dist/entitlements/poster.d.ts.map +1 -0
- package/dist/entitlements/poster.js +169 -0
- package/dist/entitlements/poster.js.map +1 -0
- package/dist/entitlements/profiles.d.ts +121 -0
- package/dist/entitlements/profiles.d.ts.map +1 -0
- package/dist/entitlements/profiles.js +212 -0
- package/dist/entitlements/profiles.js.map +1 -0
- package/dist/entitlements/slot.d.ts +33 -0
- package/dist/entitlements/slot.d.ts.map +1 -0
- package/dist/entitlements/slot.js +75 -0
- package/dist/entitlements/slot.js.map +1 -0
- package/dist/env.d.ts +293 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +383 -0
- package/dist/env.js.map +1 -0
- package/dist/files/http.d.ts +23 -0
- package/dist/files/http.d.ts.map +1 -0
- package/dist/files/http.js +66 -0
- package/dist/files/http.js.map +1 -0
- package/dist/files/index.d.ts +5 -0
- package/dist/files/index.d.ts.map +1 -0
- package/dist/files/index.js +5 -0
- package/dist/files/index.js.map +1 -0
- package/dist/files/serve.d.ts +43 -0
- package/dist/files/serve.d.ts.map +1 -0
- package/dist/files/serve.js +71 -0
- package/dist/files/serve.js.map +1 -0
- package/dist/files/service.d.ts +69 -0
- package/dist/files/service.d.ts.map +1 -0
- package/dist/files/service.js +188 -0
- package/dist/files/service.js.map +1 -0
- package/dist/files/spool.d.ts +21 -0
- package/dist/files/spool.d.ts.map +1 -0
- package/dist/files/spool.js +47 -0
- package/dist/files/spool.js.map +1 -0
- package/dist/identity/better-auth.d.ts +3927 -0
- package/dist/identity/better-auth.d.ts.map +1 -0
- package/dist/identity/better-auth.js +896 -0
- package/dist/identity/better-auth.js.map +1 -0
- package/dist/identity/demo-pass-plugin.d.ts +29 -0
- package/dist/identity/demo-pass-plugin.d.ts.map +1 -0
- package/dist/identity/demo-pass-plugin.js +88 -0
- package/dist/identity/demo-pass-plugin.js.map +1 -0
- package/dist/identity/demo-pass-rules.d.ts +84 -0
- package/dist/identity/demo-pass-rules.d.ts.map +1 -0
- package/dist/identity/demo-pass-rules.js +223 -0
- package/dist/identity/demo-pass-rules.js.map +1 -0
- package/dist/identity/demo-pass.d.ts +159 -0
- package/dist/identity/demo-pass.d.ts.map +1 -0
- package/dist/identity/demo-pass.js +319 -0
- package/dist/identity/demo-pass.js.map +1 -0
- package/dist/identity/hub-grant.d.ts +182 -0
- package/dist/identity/hub-grant.d.ts.map +1 -0
- package/dist/identity/hub-grant.js +594 -0
- package/dist/identity/hub-grant.js.map +1 -0
- package/dist/identity/hub-jwt.d.ts +22 -0
- package/dist/identity/hub-jwt.d.ts.map +1 -0
- package/dist/identity/hub-jwt.js +77 -0
- package/dist/identity/hub-jwt.js.map +1 -0
- package/dist/identity/hub-live-gate.d.ts +17 -0
- package/dist/identity/hub-live-gate.d.ts.map +1 -0
- package/dist/identity/hub-live-gate.js +146 -0
- package/dist/identity/hub-live-gate.js.map +1 -0
- package/dist/identity/hub-logout.d.ts +88 -0
- package/dist/identity/hub-logout.d.ts.map +1 -0
- package/dist/identity/hub-logout.js +158 -0
- package/dist/identity/hub-logout.js.map +1 -0
- package/dist/identity/hub-projection.d.ts +103 -0
- package/dist/identity/hub-projection.d.ts.map +1 -0
- package/dist/identity/hub-projection.js +130 -0
- package/dist/identity/hub-projection.js.map +1 -0
- package/dist/identity/hub-reconcile.d.ts +151 -0
- package/dist/identity/hub-reconcile.d.ts.map +1 -0
- package/dist/identity/hub-reconcile.js +400 -0
- package/dist/identity/hub-reconcile.js.map +1 -0
- package/dist/identity/hub-sso.d.ts +363 -0
- package/dist/identity/hub-sso.d.ts.map +1 -0
- package/dist/identity/hub-sso.js +536 -0
- package/dist/identity/hub-sso.js.map +1 -0
- package/dist/identity/hub-user-client.d.ts +222 -0
- package/dist/identity/hub-user-client.d.ts.map +1 -0
- package/dist/identity/hub-user-client.js +406 -0
- package/dist/identity/hub-user-client.js.map +1 -0
- package/dist/identity/index.d.ts +13 -0
- package/dist/identity/index.d.ts.map +1 -0
- package/dist/identity/index.js +13 -0
- package/dist/identity/index.js.map +1 -0
- package/dist/identity/oauth-jwt.d.ts +32 -0
- package/dist/identity/oauth-jwt.d.ts.map +1 -0
- package/dist/identity/oauth-jwt.js +122 -0
- package/dist/identity/oauth-jwt.js.map +1 -0
- package/dist/identity/resolve-membership.d.ts +28 -0
- package/dist/identity/resolve-membership.d.ts.map +1 -0
- package/dist/identity/resolve-membership.js +69 -0
- package/dist/identity/resolve-membership.js.map +1 -0
- package/dist/identity/signing-key.d.ts +49 -0
- package/dist/identity/signing-key.d.ts.map +1 -0
- package/dist/identity/signing-key.js +144 -0
- package/dist/identity/signing-key.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/invitations/index.d.ts +2 -0
- package/dist/invitations/index.d.ts.map +1 -0
- package/dist/invitations/index.js +2 -0
- package/dist/invitations/index.js.map +1 -0
- package/dist/invitations/service.d.ts +36 -0
- package/dist/invitations/service.d.ts.map +1 -0
- package/dist/invitations/service.js +122 -0
- package/dist/invitations/service.js.map +1 -0
- package/dist/jobs/index.d.ts +3 -0
- package/dist/jobs/index.d.ts.map +1 -0
- package/dist/jobs/index.js +3 -0
- package/dist/jobs/index.js.map +1 -0
- package/dist/jobs/pgboss.d.ts +119 -0
- package/dist/jobs/pgboss.d.ts.map +1 -0
- package/dist/jobs/pgboss.js +521 -0
- package/dist/jobs/pgboss.js.map +1 -0
- package/dist/jobs/timers.d.ts +127 -0
- package/dist/jobs/timers.d.ts.map +1 -0
- package/dist/jobs/timers.js +228 -0
- package/dist/jobs/timers.js.map +1 -0
- package/dist/logger.d.ts +17 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +64 -0
- package/dist/logger.js.map +1 -0
- package/dist/mcp/errors.d.ts +37 -0
- package/dist/mcp/errors.d.ts.map +1 -0
- package/dist/mcp/errors.js +77 -0
- package/dist/mcp/errors.js.map +1 -0
- package/dist/mcp/http.d.ts +35 -0
- package/dist/mcp/http.d.ts.map +1 -0
- package/dist/mcp/http.js +80 -0
- package/dist/mcp/http.js.map +1 -0
- package/dist/mcp/index.d.ts +8 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +8 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/inputs.d.ts +19 -0
- package/dist/mcp/inputs.d.ts.map +1 -0
- package/dist/mcp/inputs.js +28 -0
- package/dist/mcp/inputs.js.map +1 -0
- package/dist/mcp/projects.d.ts +31 -0
- package/dist/mcp/projects.d.ts.map +1 -0
- package/dist/mcp/projects.js +315 -0
- package/dist/mcp/projects.js.map +1 -0
- package/dist/mcp/server.d.ts +52 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +93 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/teams.d.ts +7 -0
- package/dist/mcp/teams.d.ts.map +1 -0
- package/dist/mcp/teams.js +62 -0
- package/dist/mcp/teams.js.map +1 -0
- package/dist/mcp/tool-kit.d.ts +67 -0
- package/dist/mcp/tool-kit.d.ts.map +1 -0
- package/dist/mcp/tool-kit.js +74 -0
- package/dist/mcp/tool-kit.js.map +1 -0
- package/dist/members/removal.d.ts +95 -0
- package/dist/members/removal.d.ts.map +1 -0
- package/dist/members/removal.js +143 -0
- package/dist/members/removal.js.map +1 -0
- package/dist/middleware/auth-body.d.ts +25 -0
- package/dist/middleware/auth-body.d.ts.map +1 -0
- package/dist/middleware/auth-body.js +55 -0
- package/dist/middleware/auth-body.js.map +1 -0
- package/dist/middleware/auth-context.d.ts +170 -0
- package/dist/middleware/auth-context.d.ts.map +1 -0
- package/dist/middleware/auth-context.js +251 -0
- package/dist/middleware/auth-context.js.map +1 -0
- package/dist/middleware/body-cap.d.ts +17 -0
- package/dist/middleware/body-cap.d.ts.map +1 -0
- package/dist/middleware/body-cap.js +31 -0
- package/dist/middleware/body-cap.js.map +1 -0
- package/dist/middleware/body-refusal.d.ts +20 -0
- package/dist/middleware/body-refusal.d.ts.map +1 -0
- package/dist/middleware/body-refusal.js +5 -0
- package/dist/middleware/body-refusal.js.map +1 -0
- package/dist/middleware/cross-site.d.ts +61 -0
- package/dist/middleware/cross-site.d.ts.map +1 -0
- package/dist/middleware/cross-site.js +59 -0
- package/dist/middleware/cross-site.js.map +1 -0
- package/dist/middleware/hub-managed.d.ts +45 -0
- package/dist/middleware/hub-managed.d.ts.map +1 -0
- package/dist/middleware/hub-managed.js +56 -0
- package/dist/middleware/hub-managed.js.map +1 -0
- package/dist/middleware/idempotency.d.ts +14 -0
- package/dist/middleware/idempotency.d.ts.map +1 -0
- package/dist/middleware/idempotency.js +222 -0
- package/dist/middleware/idempotency.js.map +1 -0
- package/dist/middleware/index.d.ts +12 -0
- package/dist/middleware/index.d.ts.map +1 -0
- package/dist/middleware/index.js +12 -0
- package/dist/middleware/index.js.map +1 -0
- package/dist/middleware/json-depth.d.ts +32 -0
- package/dist/middleware/json-depth.d.ts.map +1 -0
- package/dist/middleware/json-depth.js +80 -0
- package/dist/middleware/json-depth.js.map +1 -0
- package/dist/middleware/no-store.d.ts +21 -0
- package/dist/middleware/no-store.d.ts.map +1 -0
- package/dist/middleware/no-store.js +32 -0
- package/dist/middleware/no-store.js.map +1 -0
- package/dist/middleware/oauth-public.d.ts +16 -0
- package/dist/middleware/oauth-public.d.ts.map +1 -0
- package/dist/middleware/oauth-public.js +50 -0
- package/dist/middleware/oauth-public.js.map +1 -0
- package/dist/middleware/rate-limit.d.ts +182 -0
- package/dist/middleware/rate-limit.d.ts.map +1 -0
- package/dist/middleware/rate-limit.js +277 -0
- package/dist/middleware/rate-limit.js.map +1 -0
- package/dist/middleware/request-id.d.ts +10 -0
- package/dist/middleware/request-id.d.ts.map +1 -0
- package/dist/middleware/request-id.js +42 -0
- package/dist/middleware/request-id.js.map +1 -0
- package/dist/middleware/scopes.d.ts +33 -0
- package/dist/middleware/scopes.d.ts.map +1 -0
- package/dist/middleware/scopes.js +139 -0
- package/dist/middleware/scopes.js.map +1 -0
- package/dist/middleware/security-headers.d.ts +53 -0
- package/dist/middleware/security-headers.d.ts.map +1 -0
- package/dist/middleware/security-headers.js +96 -0
- package/dist/middleware/security-headers.js.map +1 -0
- package/dist/observability/index.d.ts +3 -0
- package/dist/observability/index.d.ts.map +1 -0
- package/dist/observability/index.js +3 -0
- package/dist/observability/index.js.map +1 -0
- package/dist/observability/metrics.d.ts +17 -0
- package/dist/observability/metrics.d.ts.map +1 -0
- package/dist/observability/metrics.js +82 -0
- package/dist/observability/metrics.js.map +1 -0
- package/dist/observability/otel.d.ts +20 -0
- package/dist/observability/otel.d.ts.map +1 -0
- package/dist/observability/otel.js +54 -0
- package/dist/observability/otel.js.map +1 -0
- package/dist/pagination.d.ts +57 -0
- package/dist/pagination.d.ts.map +1 -0
- package/dist/pagination.js +90 -0
- package/dist/pagination.js.map +1 -0
- package/dist/platform/edition.d.ts +57 -0
- package/dist/platform/edition.d.ts.map +1 -0
- package/dist/platform/edition.js +90 -0
- package/dist/platform/edition.js.map +1 -0
- package/dist/platform/entitlements.d.ts +26 -0
- package/dist/platform/entitlements.d.ts.map +1 -0
- package/dist/platform/entitlements.js +28 -0
- package/dist/platform/entitlements.js.map +1 -0
- package/dist/platform/events.d.ts +87 -0
- package/dist/platform/events.d.ts.map +1 -0
- package/dist/platform/events.js +32 -0
- package/dist/platform/events.js.map +1 -0
- package/dist/platform/index.d.ts +8 -0
- package/dist/platform/index.d.ts.map +1 -0
- package/dist/platform/index.js +8 -0
- package/dist/platform/index.js.map +1 -0
- package/dist/platform/local-identity.d.ts +39 -0
- package/dist/platform/local-identity.d.ts.map +1 -0
- package/dist/platform/local-identity.js +87 -0
- package/dist/platform/local-identity.js.map +1 -0
- package/dist/platform/registry.d.ts +23 -0
- package/dist/platform/registry.d.ts.map +1 -0
- package/dist/platform/registry.js +5 -0
- package/dist/platform/registry.js.map +1 -0
- package/dist/platform/usage.d.ts +11 -0
- package/dist/platform/usage.d.ts.map +1 -0
- package/dist/platform/usage.js +12 -0
- package/dist/platform/usage.js.map +1 -0
- package/dist/platform/workspaces.d.ts +25 -0
- package/dist/platform/workspaces.d.ts.map +1 -0
- package/dist/platform/workspaces.js +44 -0
- package/dist/platform/workspaces.js.map +1 -0
- package/dist/projects/access.d.ts +40 -0
- package/dist/projects/access.d.ts.map +1 -0
- package/dist/projects/access.js +133 -0
- package/dist/projects/access.js.map +1 -0
- package/dist/projects/index.d.ts +2 -0
- package/dist/projects/index.d.ts.map +1 -0
- package/dist/projects/index.js +2 -0
- package/dist/projects/index.js.map +1 -0
- package/dist/route-label.d.ts +23 -0
- package/dist/route-label.d.ts.map +1 -0
- package/dist/route-label.js +29 -0
- package/dist/route-label.js.map +1 -0
- package/dist/routes/health.d.ts +30 -0
- package/dist/routes/health.d.ts.map +1 -0
- package/dist/routes/health.js +54 -0
- package/dist/routes/health.js.map +1 -0
- package/dist/routes/index.d.ts +3 -0
- package/dist/routes/index.d.ts.map +1 -0
- package/dist/routes/index.js +3 -0
- package/dist/routes/index.js.map +1 -0
- package/dist/routes/wellknown.d.ts +11 -0
- package/dist/routes/wellknown.d.ts.map +1 -0
- package/dist/routes/wellknown.js +45 -0
- package/dist/routes/wellknown.js.map +1 -0
- package/dist/secret.d.ts +30 -0
- package/dist/secret.d.ts.map +1 -0
- package/dist/secret.js +97 -0
- package/dist/secret.js.map +1 -0
- package/dist/setup-transport.d.ts +23 -0
- package/dist/setup-transport.d.ts.map +1 -0
- package/dist/setup-transport.js +52 -0
- package/dist/setup-transport.js.map +1 -0
- package/dist/state.d.ts +21 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/state.js +4 -0
- package/dist/state.js.map +1 -0
- package/dist/storage/driver.d.ts +38 -0
- package/dist/storage/driver.d.ts.map +1 -0
- package/dist/storage/driver.js +14 -0
- package/dist/storage/driver.js.map +1 -0
- package/dist/storage/factory.d.ts +4 -0
- package/dist/storage/factory.d.ts.map +1 -0
- package/dist/storage/factory.js +20 -0
- package/dist/storage/factory.js.map +1 -0
- package/dist/storage/index.d.ts +4 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +4 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/local.d.ts +21 -0
- package/dist/storage/local.d.ts.map +1 -0
- package/dist/storage/local.js +88 -0
- package/dist/storage/local.js.map +1 -0
- package/dist/storage/s3.d.ts +29 -0
- package/dist/storage/s3.d.ts.map +1 -0
- package/dist/storage/s3.js +82 -0
- package/dist/storage/s3.js.map +1 -0
- package/dist/testing/fake-hub.d.ts +425 -0
- package/dist/testing/fake-hub.d.ts.map +1 -0
- package/dist/testing/fake-hub.js +1074 -0
- package/dist/testing/fake-hub.js.map +1 -0
- package/dist/testing/helpers.d.ts +124 -0
- package/dist/testing/helpers.d.ts.map +1 -0
- package/dist/testing/helpers.js +174 -0
- package/dist/testing/helpers.js.map +1 -0
- package/dist/testing/index.d.ts +12 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +12 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/setup-origins.d.ts +21 -0
- package/dist/testing/setup-origins.d.ts.map +1 -0
- package/dist/testing/setup-origins.js +57 -0
- package/dist/testing/setup-origins.js.map +1 -0
- package/dist/testing/sso-helpers.d.ts +43 -0
- package/dist/testing/sso-helpers.d.ts.map +1 -0
- package/dist/testing/sso-helpers.js +159 -0
- package/dist/testing/sso-helpers.js.map +1 -0
- package/dist/tool-definition.d.ts +382 -0
- package/dist/tool-definition.d.ts.map +1 -0
- package/dist/tool-definition.js +46 -0
- package/dist/tool-definition.js.map +1 -0
- package/dist/util/index.d.ts +8 -0
- package/dist/util/index.d.ts.map +1 -0
- package/dist/util/index.js +8 -0
- package/dist/util/index.js.map +1 -0
- package/package.json +161 -0
- package/src/accounts/deletion.ts +389 -0
- package/src/accounts/erasure-log.ts +140 -0
- package/src/accounts/index.ts +5 -0
- package/src/accounts/mint-refusal.ts +67 -0
- package/src/accounts/signup-duplicate.ts +21 -0
- package/src/accounts/superadmin.ts +46 -0
- package/src/api/apikeys.ts +147 -0
- package/src/api/audit.ts +83 -0
- package/src/api/break-glass.ts +294 -0
- package/src/api/cli-auth.ts +308 -0
- package/src/api/create-api.ts +1403 -0
- package/src/api/demo-passes.ts +207 -0
- package/src/api/errors.ts +13 -0
- package/src/api/export.ts +482 -0
- package/src/api/files.ts +200 -0
- package/src/api/index.ts +29 -0
- package/src/api/invitations.ts +396 -0
- package/src/api/members.ts +617 -0
- package/src/api/onboarding.ts +50 -0
- package/src/api/openapi-doc.ts +34 -0
- package/src/api/projects.ts +788 -0
- package/src/api/scope-routes.ts +12 -0
- package/src/api/sso-connect.ts +246 -0
- package/src/api/sso-logout.ts +76 -0
- package/src/api/teams.ts +575 -0
- package/src/api/workspaces.ts +649 -0
- package/src/apikeys/index.ts +2 -0
- package/src/apikeys/peppers.ts +118 -0
- package/src/apikeys/service.ts +223 -0
- package/src/app.ts +228 -0
- package/src/audit/filters.ts +101 -0
- package/src/audit/index.ts +9 -0
- package/src/audit/service.ts +154 -0
- package/src/boot.ts +953 -0
- package/src/constant-time.ts +9 -0
- package/src/email/driver.ts +139 -0
- package/src/email/index.ts +26 -0
- package/src/email/shell.ts +201 -0
- package/src/email/templates.ts +184 -0
- package/src/entitlements/check.ts +435 -0
- package/src/entitlements/clock-skew.ts +58 -0
- package/src/entitlements/gate.ts +636 -0
- package/src/entitlements/hub-machine-token.ts +205 -0
- package/src/entitlements/hub-subject.ts +77 -0
- package/src/entitlements/index.ts +37 -0
- package/src/entitlements/poster.ts +265 -0
- package/src/entitlements/profiles.ts +303 -0
- package/src/entitlements/slot.ts +105 -0
- package/src/env.ts +456 -0
- package/src/files/http.ts +77 -0
- package/src/files/index.ts +4 -0
- package/src/files/serve.ts +115 -0
- package/src/files/service.ts +209 -0
- package/src/files/spool.ts +58 -0
- package/src/identity/better-auth.ts +1103 -0
- package/src/identity/demo-pass-plugin.ts +121 -0
- package/src/identity/demo-pass-rules.ts +229 -0
- package/src/identity/demo-pass.ts +390 -0
- package/src/identity/hub-grant.ts +704 -0
- package/src/identity/hub-jwt.ts +78 -0
- package/src/identity/hub-live-gate.ts +167 -0
- package/src/identity/hub-logout.ts +174 -0
- package/src/identity/hub-projection.ts +251 -0
- package/src/identity/hub-reconcile.ts +572 -0
- package/src/identity/hub-sso.ts +696 -0
- package/src/identity/hub-user-client.ts +554 -0
- package/src/identity/index.ts +56 -0
- package/src/identity/oauth-jwt.ts +128 -0
- package/src/identity/resolve-membership.ts +104 -0
- package/src/identity/signing-key.ts +164 -0
- package/src/index.ts +65 -0
- package/src/invitations/index.ts +1 -0
- package/src/invitations/service.ts +171 -0
- package/src/jobs/index.ts +25 -0
- package/src/jobs/pgboss.ts +594 -0
- package/src/jobs/timers.ts +287 -0
- package/src/logger.ts +67 -0
- package/src/mcp/errors.ts +111 -0
- package/src/mcp/http.ts +129 -0
- package/src/mcp/index.ts +28 -0
- package/src/mcp/inputs.ts +33 -0
- package/src/mcp/projects.ts +480 -0
- package/src/mcp/server.ts +174 -0
- package/src/mcp/teams.ts +97 -0
- package/src/mcp/tool-kit.ts +148 -0
- package/src/members/removal.ts +216 -0
- package/src/middleware/auth-body.ts +58 -0
- package/src/middleware/auth-context.ts +384 -0
- package/src/middleware/body-cap.ts +33 -0
- package/src/middleware/body-refusal.ts +23 -0
- package/src/middleware/cross-site.ts +122 -0
- package/src/middleware/hub-managed.ts +61 -0
- package/src/middleware/idempotency.ts +264 -0
- package/src/middleware/index.ts +33 -0
- package/src/middleware/json-depth.ts +74 -0
- package/src/middleware/no-store.ts +30 -0
- package/src/middleware/oauth-public.ts +54 -0
- package/src/middleware/rate-limit.ts +432 -0
- package/src/middleware/request-id.ts +54 -0
- package/src/middleware/scopes.ts +150 -0
- package/src/middleware/security-headers.ts +129 -0
- package/src/observability/index.ts +2 -0
- package/src/observability/metrics.ts +102 -0
- package/src/observability/otel.ts +79 -0
- package/src/pagination.ts +118 -0
- package/src/platform/edition.ts +140 -0
- package/src/platform/entitlements.ts +47 -0
- package/src/platform/events.ts +71 -0
- package/src/platform/index.ts +7 -0
- package/src/platform/local-identity.ts +90 -0
- package/src/platform/registry.ts +28 -0
- package/src/platform/usage.ts +13 -0
- package/src/platform/workspaces.ts +41 -0
- package/src/projects/access.ts +160 -0
- package/src/projects/index.ts +7 -0
- package/src/route-label.ts +29 -0
- package/src/routes/health.ts +79 -0
- package/src/routes/index.ts +2 -0
- package/src/routes/wellknown.ts +67 -0
- package/src/secret.ts +115 -0
- package/src/setup-transport.ts +46 -0
- package/src/state.ts +23 -0
- package/src/storage/driver.ts +48 -0
- package/src/storage/factory.ts +34 -0
- package/src/storage/index.ts +3 -0
- package/src/storage/local.ts +93 -0
- package/src/storage/s3.ts +109 -0
- package/src/testing/fake-hub.ts +1316 -0
- package/src/testing/helpers.ts +254 -0
- package/src/testing/index.ts +11 -0
- package/src/testing/setup-origins.ts +58 -0
- package/src/testing/sso-helpers.ts +178 -0
- package/src/tool-definition.ts +463 -0
- package/src/util/index.ts +17 -0
- package/test/fixtures/onboarding-backfill.sql +13 -0
- package/test/fixtures/operator-user-id-backfill.sql +18 -0
- package/test/host/dr-lib.sh +253 -0
- package/test/host/drizzle/0000_chassis_baseline.sql +438 -0
- package/test/host/drizzle/0001_last_owner_guard.sql +42 -0
- package/test/host/drizzle/meta/0000_snapshot.json +3566 -0
- package/test/host/drizzle/meta/_journal.json +20 -0
- package/test/host/drizzle.config.ts +17 -0
- package/test/host/identity.ts +41 -0
- package/test/host/minimal-host.ts +35 -0
- package/test/host/minimal-tool.ts +123 -0
- package/test/integration/account-oracle-uniformity.test.ts +284 -0
- package/test/integration/account-recovery.test.ts +236 -0
- package/test/integration/account.test.ts +120 -0
- package/test/integration/api-quota.test.ts +208 -0
- package/test/integration/apikey-expiry.test.ts +178 -0
- package/test/integration/apikey-pepper-rotation.test.ts +190 -0
- package/test/integration/boot-posture.test.ts +169 -0
- package/test/integration/break-glass.test.ts +484 -0
- package/test/integration/cloud-lifecycle.test.ts +233 -0
- package/test/integration/credential-boundaries.test.ts +195 -0
- package/test/integration/default-workspace.test.ts +414 -0
- package/test/integration/demo-pass-rules.test.ts +332 -0
- package/test/integration/demo-pass.test.ts +1222 -0
- package/test/integration/dr-verify-real-dump.test.ts +154 -0
- package/test/integration/edition.test.ts +868 -0
- package/test/integration/email-change.test.ts +394 -0
- package/test/integration/empty-tool.test.ts +267 -0
- package/test/integration/entitlements-null-hook.test.ts +187 -0
- package/test/integration/entitlements.test.ts +693 -0
- package/test/integration/export-entries.test.ts +321 -0
- package/test/integration/files.test.ts +320 -0
- package/test/integration/first-boot-claim.test.ts +131 -0
- package/test/integration/gdpr.test.ts +532 -0
- package/test/integration/helpers.ts +29 -0
- package/test/integration/hub-grant.test.ts +505 -0
- package/test/integration/hub-live-gate.test.ts +612 -0
- package/test/integration/hub-managed-membership.test.ts +559 -0
- package/test/integration/hub-org-selector.test.ts +281 -0
- package/test/integration/hub-reconcile.test.ts +646 -0
- package/test/integration/hub-sso.test.ts +704 -0
- package/test/integration/hub-teams.test.ts +771 -0
- package/test/integration/idempotency.test.ts +261 -0
- package/test/integration/invite-verification.test.ts +210 -0
- package/test/integration/last-owner-race.test.ts +263 -0
- package/test/integration/m9-fixes.test.ts +290 -0
- package/test/integration/mcp-projects.test.ts +463 -0
- package/test/integration/member-removal-race.test.ts +466 -0
- package/test/integration/member-removal.test.ts +794 -0
- package/test/integration/oauth-mcp.test.ts +477 -0
- package/test/integration/oauth-workspace.test.ts +371 -0
- package/test/integration/observability.test.ts +183 -0
- package/test/integration/onboarding.test.ts +268 -0
- package/test/integration/orphan-purge.test.ts +451 -0
- package/test/integration/pagination.test.ts +344 -0
- package/test/integration/platform-core.test.ts +305 -0
- package/test/integration/platform.test.ts +246 -0
- package/test/integration/pool-survives-restart.test.ts +80 -0
- package/test/integration/projects-cloud.test.ts +193 -0
- package/test/integration/projects.test.ts +1310 -0
- package/test/integration/security-fixes.test.ts +190 -0
- package/test/integration/setup-transport.test.ts +118 -0
- package/test/integration/signin-wall.test.ts +103 -0
- package/test/integration/signing-key-rotation.test.ts +349 -0
- package/test/integration/sso-helpers.ts +15 -0
- package/test/integration/sso-logout.test.ts +283 -0
- package/test/integration/teams-cloud.test.ts +194 -0
- package/test/integration/teams.test.ts +551 -0
- package/test/integration/timers.test.ts +377 -0
- package/test/integration/two-factor.test.ts +301 -0
- package/test/integration/usage-window.test.ts +161 -0
- package/test/integration/workspace-create-cloud.test.ts +523 -0
- package/test/integration/workspace-create.test.ts +510 -0
- package/test/integration/workspace-scoping.test.ts +530 -0
- package/test/integration/zz-adv-replay-owner.test.ts +205 -0
- package/test/unit/apikey-peppers.test.ts +110 -0
- package/test/unit/apikey-prefix.test.ts +34 -0
- package/test/unit/audit-filters.test.ts +135 -0
- package/test/unit/auth-origins.test.ts +92 -0
- package/test/unit/body-cap.test.ts +84 -0
- package/test/unit/clock-skew.test.ts +68 -0
- package/test/unit/cross-site.test.ts +166 -0
- package/test/unit/declared-credits.test.ts +13 -0
- package/test/unit/demo-pass-rules.test.ts +192 -0
- package/test/unit/email-driver.test.ts +127 -0
- package/test/unit/end-pool.test.ts +181 -0
- package/test/unit/entitlement-check.test.ts +492 -0
- package/test/unit/entitlement-gate.test.ts +1333 -0
- package/test/unit/entitlement-profiles.test.ts +289 -0
- package/test/unit/erasure-log.test.ts +72 -0
- package/test/unit/error-mapping.test.ts +89 -0
- package/test/unit/export-entries.test.ts +85 -0
- package/test/unit/export-sanitize.test.ts +27 -0
- package/test/unit/files-head-route.test.ts +155 -0
- package/test/unit/files-http.test.ts +97 -0
- package/test/unit/head-rewrite.test.ts +72 -0
- package/test/unit/hub-create-org.test.ts +181 -0
- package/test/unit/hub-jwt.test.ts +93 -0
- package/test/unit/hub-sso-params.test.ts +39 -0
- package/test/unit/hub-subject.test.ts +83 -0
- package/test/unit/idempotency-crypto.test.ts +45 -0
- package/test/unit/json-depth.test.ts +88 -0
- package/test/unit/logger-redaction.test.ts +66 -0
- package/test/unit/mcp-errors.test.ts +110 -0
- package/test/unit/mcp-inputs.test.ts +106 -0
- package/test/unit/mcp-project-hints.test.ts +26 -0
- package/test/unit/no-store.test.ts +49 -0
- package/test/unit/no-tool-migration-filename.test.ts +70 -0
- package/test/unit/observability.test.ts +64 -0
- package/test/unit/openapi-doc.test.ts +93 -0
- package/test/unit/rate-limit-consume-on.test.ts +76 -0
- package/test/unit/rate-limit.test.ts +39 -0
- package/test/unit/readyz-storage.test.ts +157 -0
- package/test/unit/request-quota.test.ts +146 -0
- package/test/unit/scopes.test.ts +66 -0
- package/test/unit/security-headers.test.ts +131 -0
- package/test/unit/serve-content-type.test.ts +74 -0
- package/test/unit/setup-transport.test.ts +29 -0
- package/test/unit/storage-local.test.ts +53 -0
- package/test/unit/superadmin.test.ts +32 -0
- package/test/unit/timers.test.ts +287 -0
- package/test/unit/tool-definition-guards.test.ts +166 -0
- package/test/unit/tool-entitlements-guard.test.ts +168 -0
- package/test/unit/usage-poster.test.ts +542 -0
- package/test/unit/usage-window.test.ts +48 -0
- package/test/unit/workspace-create-audit.test.ts +48 -0
|
@@ -0,0 +1,594 @@
|
|
|
1
|
+
import pg from 'pg';
|
|
2
|
+
import { Counter } from 'prom-client';
|
|
3
|
+
import { and, eq } from 'drizzle-orm';
|
|
4
|
+
import { symmetricDecrypt, symmetricEncrypt } from 'better-auth/crypto';
|
|
5
|
+
import { account, hubGrantPresentations } from '@antasphere/chassis-db';
|
|
6
|
+
import { HUB_SSO_PROVIDER_ID } from './hub-sso.js';
|
|
7
|
+
/**
|
|
8
|
+
* The per-user hub grant (internal/federation.md, live user-scoped federation):
|
|
9
|
+
* a cloud tool holds each user's OWN `offline_access account:read` grant
|
|
10
|
+
* (plus `orgs:create` since PRDCT-2443 — hub-sso.ts HUB_SSO_SCOPES)
|
|
11
|
+
* — obtained at SSO login, persisted by Better Auth on the `account` row —
|
|
12
|
+
* and refreshes it against the hub's token endpoint to mint HUB-audienced
|
|
13
|
+
* access tokens (`resource=<hub>/mcp`, RFC 8707) that the hub's own
|
|
14
|
+
* `/api/v1` accepts. Everything the tool reads from the hub between logins
|
|
15
|
+
* is read AS THE USER with this grant; no service key exists anywhere in
|
|
16
|
+
* the user-facing path.
|
|
17
|
+
*
|
|
18
|
+
* Storage: the `account` row is the ONLY durable store (Better Auth already
|
|
19
|
+
* re-writes both tokens at every browser SSO login — the self-healing
|
|
20
|
+
* `hub_grant_expired` recovery path). With `account.encryptOAuthTokens: true`
|
|
21
|
+
* (identity/better-auth.ts) Better Auth encrypts what IT writes; this
|
|
22
|
+
* service encrypts/decrypts with the SAME primitive and the SAME key
|
|
23
|
+
* (`(await auth.$context).secretConfig` — with our string-secret config that
|
|
24
|
+
* is exactly the boot AUTH_SECRET), so the two writers are byte-compatible.
|
|
25
|
+
* Legacy plaintext rows pass through decrypt untouched (the 1.6.15
|
|
26
|
+
* `isLikelyEncrypted` rule, mirrored below).
|
|
27
|
+
*
|
|
28
|
+
* ── SECURITY-CRITICAL: refresh serialization ─────────────────────────────
|
|
29
|
+
* The hub rotates refresh tokens on EVERY use with RFC 9700 reuse
|
|
30
|
+
* detection: presenting a rotated-out token tears down the user's whole
|
|
31
|
+
* (client,user) grant family. A cross-replica double-refresh is therefore
|
|
32
|
+
* not a race, it is a GRANT-KILLING event. Discipline, in layers:
|
|
33
|
+
*
|
|
34
|
+
* 1. in-process single-flight per user (Map<userId, Promise>);
|
|
35
|
+
* 2. a cross-replica session-scoped `pg_advisory_lock(7432004,
|
|
36
|
+
* hashtext(userId))` on a DEDICATED pg client (the accounts/deletion.ts
|
|
37
|
+
* OWNER_GUARD_LOCK pattern). The two-int form keys a DIFFERENT advisory
|
|
38
|
+
* lock space than pg-boss's single-int `pg_advisory_lock(7432004)`
|
|
39
|
+
* (classid 7432004/objsubid 2 vs classid 0/objsubid 1) — no collision;
|
|
40
|
+
* 3. RE-READ AFTER LOCK: another replica may have refreshed while we
|
|
41
|
+
* waited — a changed refresh token (or a now-fresh stored access token)
|
|
42
|
+
* means we consume ITS result instead of presenting the stale token;
|
|
43
|
+
* 4. a ~10 s watchdog cuts the dedicated connection so a wedged refresh
|
|
44
|
+
* can never park the lock forever (a session lock dies with its
|
|
45
|
+
* session);
|
|
46
|
+
* 5. AMBIGUOUS OUTCOMES NEVER RE-PRESENT BLINDLY (PRDCT-1370). The hub
|
|
47
|
+
* rotates BEFORE it answers and cannot roll back, so a client-side
|
|
48
|
+
* timeout (or a lost response, or a 5xx after the commit) leaves us
|
|
49
|
+
* holding a token the hub may already have rotated out — and presenting
|
|
50
|
+
* it again is exactly the reuse-detection teardown above, reachable
|
|
51
|
+
* with no attacker, only a hub that is slow but alive. Every
|
|
52
|
+
* presentation is therefore recorded FIRST (`hub_grant_presentations`,
|
|
53
|
+
* keyed by the account row, carrying the ciphertext presented) and the
|
|
54
|
+
* record is cleared only once the hub's answer is known. A surviving
|
|
55
|
+
* record makes the next refresh PROBE the token through the hub's
|
|
56
|
+
* RFC 7662 introspection endpoint (`token_type_hint=refresh_token`,
|
|
57
|
+
* read-only: the pinned plugin answers `active:false` for a rotated-out
|
|
58
|
+
* token WITHOUT tearing the family down) and present it only when the
|
|
59
|
+
* hub still calls it active; an inactive answer marks the grant dead
|
|
60
|
+
* without ever presenting — the family, the CLI grant included, lives
|
|
61
|
+
* on at the hub and a browser SSO login heals this user.
|
|
62
|
+
*
|
|
63
|
+
* Failure taxonomy (the token endpoint's answer decides):
|
|
64
|
+
* - `invalid_grant` (expired / revoked / reuse-detected) → the grant is
|
|
65
|
+
* DEAD: tokens on the row are nulled (dead marker = refreshToken IS
|
|
66
|
+
* NULL); callers surface 401 `hub_grant_expired`; the next browser SSO
|
|
67
|
+
* login re-seeds the row and heals it.
|
|
68
|
+
* - `invalid_client` (broken client secret = OUR misconfiguration) →
|
|
69
|
+
* transient, logged LOUD, and it never kills grants — a config mistake
|
|
70
|
+
* must not mass-destroy every user's grant.
|
|
71
|
+
* - network / timeout / 5xx / malformed → transient (inconclusive).
|
|
72
|
+
*
|
|
73
|
+
* Access tokens are cached in-memory to exp − accessSkewMs; the account
|
|
74
|
+
* row's stored access token is trusted while fresh (it was minted with the
|
|
75
|
+
* same `resource` by either the login exchange or a sibling replica's
|
|
76
|
+
* refresh). An oss boot never constructs this class.
|
|
77
|
+
*/
|
|
78
|
+
/** Advisory-lock classid for the per-user refresh lock (two-int form). */
|
|
79
|
+
const GRANT_REFRESH_LOCK_KEY = 7_432_004;
|
|
80
|
+
/** Headroom the lock watchdog keeps beyond probe + presentation (row reads/writes, lock latency). */
|
|
81
|
+
export const LOCK_WATCHDOG_HEADROOM_MS = 2_000;
|
|
82
|
+
export const DEFAULT_GRANT_DIALS = {
|
|
83
|
+
accessSkewMs: 60_000,
|
|
84
|
+
tokenTimeoutMs: 5_000,
|
|
85
|
+
introspectTimeoutMs: 5_000,
|
|
86
|
+
// ≥ tokenTimeoutMs + introspectTimeoutMs + LOCK_WATCHDOG_HEADROOM_MS; the
|
|
87
|
+
// constructor clamps anything smaller (see there).
|
|
88
|
+
lockWatchdogMs: 12_000
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* Mirror of Better Auth 1.6.15's `isLikelyEncrypted` (dist/oauth2/utils.mjs):
|
|
92
|
+
* its decrypt path passes LEGACY PLAINTEXT tokens through untouched, and so
|
|
93
|
+
* must ours — enabling encryption must never brick pre-existing grants.
|
|
94
|
+
* Exported for hub-logout.ts, whose id_token read mirrors the same
|
|
95
|
+
* tolerant rule. Re-verify on any Better Auth bump.
|
|
96
|
+
*/
|
|
97
|
+
export function isLikelyEncrypted(token) {
|
|
98
|
+
if (token.startsWith('$ba$'))
|
|
99
|
+
return true;
|
|
100
|
+
return token.length % 2 === 0 && /^[0-9a-f]+$/i.test(token);
|
|
101
|
+
}
|
|
102
|
+
export class HubGrantService {
|
|
103
|
+
opts;
|
|
104
|
+
/** userId → fresh access token (in-memory only; the row is the durable store). */
|
|
105
|
+
cache = new Map();
|
|
106
|
+
inFlight = new Map();
|
|
107
|
+
tokenUrl;
|
|
108
|
+
introspectUrl;
|
|
109
|
+
fetchImpl;
|
|
110
|
+
now;
|
|
111
|
+
dials;
|
|
112
|
+
/** Registered into the Prometheus registry by boot (cloud only). */
|
|
113
|
+
promMetrics;
|
|
114
|
+
refreshes;
|
|
115
|
+
constructor(opts) {
|
|
116
|
+
this.opts = opts;
|
|
117
|
+
this.tokenUrl = opts.issuerUrl.replace(/\/+$/, '') + '/api/v1/auth/oauth2/token';
|
|
118
|
+
this.introspectUrl = opts.issuerUrl.replace(/\/+$/, '') + '/api/v1/auth/oauth2/introspect';
|
|
119
|
+
this.fetchImpl = opts.fetchImpl ?? fetch;
|
|
120
|
+
this.now = opts.now ?? Date.now;
|
|
121
|
+
// THE WATCHDOG MUST OUTLIVE THE LONGEST HOLD (PRDCT-1370 verifier
|
|
122
|
+
// finding): under the lock a refresh may now run the probe AND the
|
|
123
|
+
// presentation back to back, each up to its own timeout, plus the
|
|
124
|
+
// row reads and writes around them. A watchdog shorter than that cuts
|
|
125
|
+
// the lock mid-refresh, a sibling replica takes it and presents the
|
|
126
|
+
// SAME token — the double presentation the lock exists to prevent, and
|
|
127
|
+
// a family teardown at the hub. Clamped here, at the one place the
|
|
128
|
+
// dials are read, so no caller can under-size it.
|
|
129
|
+
const floor = opts.dials.tokenTimeoutMs + opts.dials.introspectTimeoutMs + LOCK_WATCHDOG_HEADROOM_MS;
|
|
130
|
+
this.dials = opts.dials.lockWatchdogMs >= floor ? opts.dials : { ...opts.dials, lockWatchdogMs: floor };
|
|
131
|
+
if (this.dials !== opts.dials) {
|
|
132
|
+
opts.logger.warn({ requested: opts.dials.lockWatchdogMs, effective: floor }, 'hub grant: lockWatchdogMs raised to cover probe + presentation under the lock');
|
|
133
|
+
}
|
|
134
|
+
// registers: [] — boot attaches this to the app registry on cloud; an
|
|
135
|
+
// oss boot never constructs this class, so the metric never exists there.
|
|
136
|
+
this.refreshes = new Counter({
|
|
137
|
+
name: 'hub_grant_refreshes_total',
|
|
138
|
+
help: 'Hub user-grant refresh attempts by outcome',
|
|
139
|
+
labelNames: ['outcome'],
|
|
140
|
+
registers: []
|
|
141
|
+
});
|
|
142
|
+
this.promMetrics = [this.refreshes];
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Store the H3 offline grant — the raw one-time `hubRefreshToken` from
|
|
146
|
+
* the hub's `POST /sso/tool-token` response, delivered through
|
|
147
|
+
* `/sso/cli-connect` — on the user's `antasphere` account row, encrypted
|
|
148
|
+
* with the SAME primitive + key as every Better Auth write, so the
|
|
149
|
+
* ordinary refresh path consumes it exactly like a browser-SSO grant.
|
|
150
|
+
* This is what gives a HEADLESS CLI user live as-the-user org reads
|
|
151
|
+
* between browser logins (and replaces the Stage E interim, where a
|
|
152
|
+
* connect-minted key answered 401 hub_grant_expired until one browser
|
|
153
|
+
* SSO).
|
|
154
|
+
*
|
|
155
|
+
* Overwrites any previous grant unconditionally: the H3 mint is the
|
|
156
|
+
* NEWEST valid credential, and the replaced family simply idles to expiry
|
|
157
|
+
* at the hub. The stored access token is cleared (the new grant has none
|
|
158
|
+
* yet); the caller VALIDATES the grant end-to-end by running the
|
|
159
|
+
* fail-closed connect reconcile right after — a garbage token surfaces as
|
|
160
|
+
* `grant_dead` there and no key is minted.
|
|
161
|
+
*
|
|
162
|
+
* Throws when the user holds no `antasphere` account row — the connect
|
|
163
|
+
* flow provisions the link BEFORE acquiring the grant, so that is a
|
|
164
|
+
* wiring bug, never a user state.
|
|
165
|
+
*/
|
|
166
|
+
async acquireFromConnect(userId, rawRefreshToken) {
|
|
167
|
+
const key = await this.opts.key();
|
|
168
|
+
const encrypted = await symmetricEncrypt({ key, data: rawRefreshToken });
|
|
169
|
+
const updated = await this.opts.db
|
|
170
|
+
.update(account)
|
|
171
|
+
.set({
|
|
172
|
+
accessToken: null,
|
|
173
|
+
accessTokenExpiresAt: null,
|
|
174
|
+
refreshToken: encrypted,
|
|
175
|
+
refreshTokenExpiresAt: null,
|
|
176
|
+
updatedAt: new Date()
|
|
177
|
+
})
|
|
178
|
+
.where(and(eq(account.userId, userId), eq(account.providerId, HUB_SSO_PROVIDER_ID)))
|
|
179
|
+
.returning({ id: account.id });
|
|
180
|
+
if (updated.length === 0) {
|
|
181
|
+
throw new Error('acquireFromConnect: no antasphere account row to store the grant on');
|
|
182
|
+
}
|
|
183
|
+
this.cache.delete(userId);
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Whether a stored (possibly stale) grant exists — the connect route's
|
|
187
|
+
* born-dead guard for requests that carry no hubRefreshToken: with no
|
|
188
|
+
* stored grant either, minting a key would strand it on
|
|
189
|
+
* hub_grant_expired, so the connect refuses with steering instead.
|
|
190
|
+
*/
|
|
191
|
+
async hasStoredGrant(userId) {
|
|
192
|
+
const row = await this.readRow(userId);
|
|
193
|
+
return Boolean(row?.refreshToken);
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Seed the in-memory cache with the SSO callback's access token (already
|
|
197
|
+
* hub-audienced — the code exchange sends the same `resource`), so the
|
|
198
|
+
* login-path reads and the first post-login requests need no refresh.
|
|
199
|
+
*/
|
|
200
|
+
prime(userId, accessToken, expiresAt) {
|
|
201
|
+
// Without a stated expiry, assume a conservative slice of the hub's
|
|
202
|
+
// 15-minute access tokens.
|
|
203
|
+
const expiresAtMs = expiresAt?.getTime() ?? this.now() + 5 * 60_000;
|
|
204
|
+
this.cache.set(userId, { token: accessToken, expiresAtMs });
|
|
205
|
+
}
|
|
206
|
+
/** Drop the cached access token (e.g. the hub just refused it). */
|
|
207
|
+
invalidateAccess(userId) {
|
|
208
|
+
this.cache.delete(userId);
|
|
209
|
+
}
|
|
210
|
+
/** A hub-callable access token for the user, refresh-on-demand. */
|
|
211
|
+
async accessToken(userId) {
|
|
212
|
+
const cached = this.cache.get(userId);
|
|
213
|
+
if (cached && cached.expiresAtMs - this.now() > this.dials.accessSkewMs) {
|
|
214
|
+
return { kind: 'ok', accessToken: cached.token };
|
|
215
|
+
}
|
|
216
|
+
return this.acquire(userId, false);
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Force a refresh (the caller saw the hub refuse the current token).
|
|
220
|
+
* Serialized behind any in-flight acquisition; the advisory lock +
|
|
221
|
+
* re-read-after-lock still guarantee at most one live rotation.
|
|
222
|
+
*/
|
|
223
|
+
async refresh(userId) {
|
|
224
|
+
this.cache.delete(userId);
|
|
225
|
+
const existing = this.inFlight.get(userId);
|
|
226
|
+
if (existing)
|
|
227
|
+
await existing.catch(() => { });
|
|
228
|
+
return this.acquire(userId, true);
|
|
229
|
+
}
|
|
230
|
+
acquire(userId, force) {
|
|
231
|
+
let flight = this.inFlight.get(userId);
|
|
232
|
+
if (!flight) {
|
|
233
|
+
flight = this.doAcquire(userId, force).finally(() => {
|
|
234
|
+
if (this.inFlight.get(userId) === flight)
|
|
235
|
+
this.inFlight.delete(userId);
|
|
236
|
+
});
|
|
237
|
+
this.inFlight.set(userId, flight);
|
|
238
|
+
}
|
|
239
|
+
return flight;
|
|
240
|
+
}
|
|
241
|
+
async doAcquire(userId, force) {
|
|
242
|
+
try {
|
|
243
|
+
const first = await this.readRow(userId);
|
|
244
|
+
if (!first)
|
|
245
|
+
return { kind: 'no_link' };
|
|
246
|
+
if (!first.refreshToken)
|
|
247
|
+
return { kind: 'grant_dead' };
|
|
248
|
+
if (!force) {
|
|
249
|
+
const stored = await this.storedAccess(userId, first);
|
|
250
|
+
if (stored)
|
|
251
|
+
return { kind: 'ok', accessToken: stored };
|
|
252
|
+
}
|
|
253
|
+
// Slow path: rotate under the cross-replica lock.
|
|
254
|
+
const lock = await this.acquireLock(userId);
|
|
255
|
+
try {
|
|
256
|
+
// RE-READ AFTER LOCK: a sibling replica (or a concurrent browser
|
|
257
|
+
// login) may have rotated while we waited. A changed refresh token
|
|
258
|
+
// means ITS access token is brand new — consume that instead of
|
|
259
|
+
// presenting our stale copy (which reuse detection would treat as
|
|
260
|
+
// an attack and kill the whole family).
|
|
261
|
+
const row = await this.readRow(userId);
|
|
262
|
+
if (!row)
|
|
263
|
+
return { kind: 'no_link' };
|
|
264
|
+
if (!row.refreshToken)
|
|
265
|
+
return { kind: 'grant_dead' };
|
|
266
|
+
if (!force || row.refreshToken !== first.refreshToken) {
|
|
267
|
+
const stored = await this.storedAccess(userId, row);
|
|
268
|
+
if (stored)
|
|
269
|
+
return { kind: 'ok', accessToken: stored };
|
|
270
|
+
}
|
|
271
|
+
let refreshToken;
|
|
272
|
+
try {
|
|
273
|
+
refreshToken = await this.decrypt(row.refreshToken);
|
|
274
|
+
}
|
|
275
|
+
catch (err) {
|
|
276
|
+
// Undecryptable ≠ revoked: a key/config problem must never null
|
|
277
|
+
// the row (the invalid_client stance). Loud, transient.
|
|
278
|
+
this.refreshes.inc({ outcome: 'error' });
|
|
279
|
+
this.opts.logger.error({ err, userId }, 'hub grant: stored refresh token failed to decrypt — check AUTH_SECRET continuity; failing transient');
|
|
280
|
+
return { kind: 'inconclusive' };
|
|
281
|
+
}
|
|
282
|
+
// An UNANSWERED earlier presentation of this very ciphertext (layer
|
|
283
|
+
// 5): the hub may have rotated it out already. Probe, never guess.
|
|
284
|
+
if (await this.hasUnansweredPresentation(row)) {
|
|
285
|
+
const probe = await this.introspect(refreshToken);
|
|
286
|
+
if (probe === 'inactive') {
|
|
287
|
+
await this.markDead(row);
|
|
288
|
+
await this.clearPresentation(row.id);
|
|
289
|
+
this.cache.delete(userId);
|
|
290
|
+
this.refreshes.inc({ outcome: 'probe_dead' });
|
|
291
|
+
this.opts.logger.warn({ userId }, 'hub grant: an earlier refresh went unanswered and the hub now reports the token inactive — ' +
|
|
292
|
+
'grant marked dead WITHOUT re-presenting (the family survives at the hub); a browser SSO login heals it');
|
|
293
|
+
return { kind: 'grant_dead' };
|
|
294
|
+
}
|
|
295
|
+
if (probe === 'transient') {
|
|
296
|
+
this.refreshes.inc({ outcome: 'probe_transient' });
|
|
297
|
+
return { kind: 'inconclusive' };
|
|
298
|
+
}
|
|
299
|
+
this.refreshes.inc({ outcome: 'probe_live' });
|
|
300
|
+
// active: the unanswered presentation never reached the hub —
|
|
301
|
+
// presenting again is safe, and the record below is renewed.
|
|
302
|
+
}
|
|
303
|
+
// Record the presentation BEFORE the fetch: if the answer never
|
|
304
|
+
// arrives, this row is what makes the next attempt probe first.
|
|
305
|
+
await this.recordPresentation(row);
|
|
306
|
+
const outcome = await this.postRefresh(refreshToken);
|
|
307
|
+
if (outcome.kind === 'ok') {
|
|
308
|
+
await this.writeRotation(row, outcome);
|
|
309
|
+
await this.clearPresentation(row.id);
|
|
310
|
+
this.cache.set(userId, { token: outcome.accessToken, expiresAtMs: outcome.expiresAt.getTime() });
|
|
311
|
+
this.refreshes.inc({ outcome: 'ok' });
|
|
312
|
+
return { kind: 'ok', accessToken: outcome.accessToken };
|
|
313
|
+
}
|
|
314
|
+
if (outcome.kind === 'invalid_grant') {
|
|
315
|
+
// Definitive: expired, revoked, or reuse-torn-down.
|
|
316
|
+
await this.markDead(row);
|
|
317
|
+
await this.clearPresentation(row.id);
|
|
318
|
+
this.cache.delete(userId);
|
|
319
|
+
this.refreshes.inc({ outcome: 'invalid_grant' });
|
|
320
|
+
this.opts.logger.warn({ userId }, 'hub grant: token endpoint answered invalid_grant — grant marked dead; a browser SSO login heals it');
|
|
321
|
+
return { kind: 'grant_dead' };
|
|
322
|
+
}
|
|
323
|
+
if (outcome.kind === 'invalid_client') {
|
|
324
|
+
// The hub answered, and it refused the CLIENT before touching the
|
|
325
|
+
// token (the pinned plugin validates client credentials before it
|
|
326
|
+
// rotates), so the presented token was not consumed: the record
|
|
327
|
+
// is cleared, not kept.
|
|
328
|
+
await this.clearPresentation(row.id);
|
|
329
|
+
this.refreshes.inc({ outcome: 'invalid_client' });
|
|
330
|
+
this.opts.logger.error('hub grant: token endpoint answered invalid_client — HUB_CLIENT_ID/HUB_CLIENT_SECRET are broken; ' +
|
|
331
|
+
'refreshes are failing transient (grants are NOT being killed); fix the client credentials');
|
|
332
|
+
return { kind: 'inconclusive' };
|
|
333
|
+
}
|
|
334
|
+
// Transient (timeout / network / 5xx / malformed): the answer is
|
|
335
|
+
// UNKNOWN, so the presentation record deliberately survives — the
|
|
336
|
+
// next attempt probes before it presents.
|
|
337
|
+
this.refreshes.inc({ outcome: 'error' });
|
|
338
|
+
return { kind: 'inconclusive' };
|
|
339
|
+
}
|
|
340
|
+
finally {
|
|
341
|
+
await this.releaseLock(lock);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
catch (err) {
|
|
345
|
+
this.refreshes.inc({ outcome: 'error' });
|
|
346
|
+
this.opts.logger.warn({ err, userId }, 'hub grant: refresh attempt failed — failing transient');
|
|
347
|
+
return { kind: 'inconclusive' };
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
/** The user's hub account link, tokens as stored (possibly encrypted). */
|
|
351
|
+
/**
|
|
352
|
+
* Null the tokens (dead marker = refreshToken IS NULL) — CONDITIONAL on
|
|
353
|
+
* the ciphertext we hold, so a browser login that re-seeded the row
|
|
354
|
+
* mid-flight is never wiped.
|
|
355
|
+
*/
|
|
356
|
+
async markDead(row) {
|
|
357
|
+
await this.opts.db
|
|
358
|
+
.update(account)
|
|
359
|
+
.set({
|
|
360
|
+
accessToken: null,
|
|
361
|
+
refreshToken: null,
|
|
362
|
+
accessTokenExpiresAt: null,
|
|
363
|
+
refreshTokenExpiresAt: null,
|
|
364
|
+
updatedAt: new Date()
|
|
365
|
+
})
|
|
366
|
+
.where(and(eq(account.id, row.id), eq(account.refreshToken, row.refreshToken)));
|
|
367
|
+
}
|
|
368
|
+
/** Whether an earlier presentation of THIS ciphertext is still unanswered. */
|
|
369
|
+
async hasUnansweredPresentation(row) {
|
|
370
|
+
const [marker] = await this.opts.db
|
|
371
|
+
.select({ refreshToken: hubGrantPresentations.refreshToken })
|
|
372
|
+
.from(hubGrantPresentations)
|
|
373
|
+
.where(eq(hubGrantPresentations.accountId, row.id))
|
|
374
|
+
.limit(1);
|
|
375
|
+
// A marker for a DIFFERENT ciphertext is stale by construction (a
|
|
376
|
+
// browser login re-seeded the row): the token it names is gone.
|
|
377
|
+
return marker !== undefined && marker.refreshToken === row.refreshToken;
|
|
378
|
+
}
|
|
379
|
+
async recordPresentation(row) {
|
|
380
|
+
await this.opts.db
|
|
381
|
+
.insert(hubGrantPresentations)
|
|
382
|
+
.values({ accountId: row.id, refreshToken: row.refreshToken, presentedAt: new Date() })
|
|
383
|
+
.onConflictDoUpdate({
|
|
384
|
+
target: hubGrantPresentations.accountId,
|
|
385
|
+
set: { refreshToken: row.refreshToken, presentedAt: new Date() }
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
async clearPresentation(accountId) {
|
|
389
|
+
await this.opts.db.delete(hubGrantPresentations).where(eq(hubGrantPresentations.accountId, accountId));
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* RFC 7662 probe of a refresh token whose last presentation went
|
|
393
|
+
* unanswered. Read-only at the hub: the pinned oauth-provider plugin's
|
|
394
|
+
* introspection answers `active:false` for a rotated-out, expired, or
|
|
395
|
+
* unknown refresh token and never touches the family. Anything but a
|
|
396
|
+
* definite answer is transient — a probe must never be the reason a
|
|
397
|
+
* grant dies.
|
|
398
|
+
*/
|
|
399
|
+
async introspect(refreshToken) {
|
|
400
|
+
const body = new URLSearchParams({
|
|
401
|
+
token: refreshToken,
|
|
402
|
+
token_type_hint: 'refresh_token',
|
|
403
|
+
client_id: this.opts.clientId,
|
|
404
|
+
client_secret: this.opts.clientSecret
|
|
405
|
+
});
|
|
406
|
+
let res;
|
|
407
|
+
try {
|
|
408
|
+
res = await this.fetchImpl(this.introspectUrl, {
|
|
409
|
+
method: 'POST',
|
|
410
|
+
headers: { 'content-type': 'application/x-www-form-urlencoded', accept: 'application/json' },
|
|
411
|
+
body: body.toString(),
|
|
412
|
+
signal: AbortSignal.timeout(this.dials.introspectTimeoutMs)
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
catch (err) {
|
|
416
|
+
this.opts.logger.warn({ err }, 'hub grant: introspection endpoint unreachable — probe inconclusive');
|
|
417
|
+
return 'transient';
|
|
418
|
+
}
|
|
419
|
+
let payload = null;
|
|
420
|
+
try {
|
|
421
|
+
payload = await res.json();
|
|
422
|
+
}
|
|
423
|
+
catch {
|
|
424
|
+
// classified below by status
|
|
425
|
+
}
|
|
426
|
+
if (res.ok) {
|
|
427
|
+
const active = payload?.active;
|
|
428
|
+
if (active === true)
|
|
429
|
+
return 'active';
|
|
430
|
+
if (active === false)
|
|
431
|
+
return 'inactive';
|
|
432
|
+
this.opts.logger.warn('hub grant: introspection 200 without a boolean `active` — malformed, probe inconclusive');
|
|
433
|
+
return 'transient';
|
|
434
|
+
}
|
|
435
|
+
if (res.status === 401) {
|
|
436
|
+
this.opts.logger.error('hub grant: introspection answered invalid_client — HUB_CLIENT_ID/HUB_CLIENT_SECRET are broken; probe inconclusive');
|
|
437
|
+
return 'transient';
|
|
438
|
+
}
|
|
439
|
+
this.opts.logger.warn({ status: res.status }, 'hub grant: introspection answered non-2xx — probe inconclusive');
|
|
440
|
+
return 'transient';
|
|
441
|
+
}
|
|
442
|
+
async readRow(userId) {
|
|
443
|
+
const [row] = await this.opts.db
|
|
444
|
+
.select({
|
|
445
|
+
id: account.id,
|
|
446
|
+
accessToken: account.accessToken,
|
|
447
|
+
refreshToken: account.refreshToken,
|
|
448
|
+
accessTokenExpiresAt: account.accessTokenExpiresAt
|
|
449
|
+
})
|
|
450
|
+
.from(account)
|
|
451
|
+
.where(and(eq(account.userId, userId), eq(account.providerId, HUB_SSO_PROVIDER_ID)))
|
|
452
|
+
.limit(1);
|
|
453
|
+
return row ?? null;
|
|
454
|
+
}
|
|
455
|
+
/** Decrypt-and-cache the row's access token when it is still fresh. */
|
|
456
|
+
async storedAccess(userId, row) {
|
|
457
|
+
if (!row.accessToken || !row.accessTokenExpiresAt)
|
|
458
|
+
return null;
|
|
459
|
+
const expiresAtMs = row.accessTokenExpiresAt.getTime();
|
|
460
|
+
if (expiresAtMs - this.now() <= this.dials.accessSkewMs)
|
|
461
|
+
return null;
|
|
462
|
+
try {
|
|
463
|
+
const token = await this.decrypt(row.accessToken);
|
|
464
|
+
this.cache.set(userId, { token, expiresAtMs });
|
|
465
|
+
return token;
|
|
466
|
+
}
|
|
467
|
+
catch (err) {
|
|
468
|
+
this.opts.logger.warn({ err, userId }, 'hub grant: stored access token failed to decrypt — refreshing');
|
|
469
|
+
return null;
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
/**
|
|
473
|
+
* Persist a rotation's result on the row, Better-Auth-compatible
|
|
474
|
+
* (encrypted with the same key + primitive setTokenUtil uses).
|
|
475
|
+
* Conditional on the ciphertext we rotated FROM: if a concurrent browser
|
|
476
|
+
* login re-wrote the row, its (equally valid, same-family) tokens win and
|
|
477
|
+
* our rotation is only served from memory.
|
|
478
|
+
*/
|
|
479
|
+
async writeRotation(row, outcome) {
|
|
480
|
+
const key = await this.opts.key();
|
|
481
|
+
const encryptedAccess = await symmetricEncrypt({ key, data: outcome.accessToken });
|
|
482
|
+
const encryptedRefresh = outcome.refreshToken
|
|
483
|
+
? await symmetricEncrypt({ key, data: outcome.refreshToken })
|
|
484
|
+
: row.refreshToken; // no rotation in the answer — keep the presented one
|
|
485
|
+
await this.opts.db
|
|
486
|
+
.update(account)
|
|
487
|
+
.set({
|
|
488
|
+
accessToken: encryptedAccess,
|
|
489
|
+
refreshToken: encryptedRefresh,
|
|
490
|
+
accessTokenExpiresAt: outcome.expiresAt,
|
|
491
|
+
updatedAt: new Date()
|
|
492
|
+
})
|
|
493
|
+
.where(and(eq(account.id, row.id), eq(account.refreshToken, row.refreshToken)));
|
|
494
|
+
}
|
|
495
|
+
async decrypt(stored) {
|
|
496
|
+
if (!isLikelyEncrypted(stored))
|
|
497
|
+
return stored; // legacy plaintext passthrough
|
|
498
|
+
return symmetricDecrypt({ key: await this.opts.key(), data: stored });
|
|
499
|
+
}
|
|
500
|
+
/** One refresh_token grant POST, classified per the failure taxonomy. */
|
|
501
|
+
async postRefresh(refreshToken) {
|
|
502
|
+
const body = new URLSearchParams({
|
|
503
|
+
grant_type: 'refresh_token',
|
|
504
|
+
refresh_token: refreshToken,
|
|
505
|
+
client_id: this.opts.clientId,
|
|
506
|
+
client_secret: this.opts.clientSecret
|
|
507
|
+
});
|
|
508
|
+
if (this.opts.tokenResource)
|
|
509
|
+
body.set('resource', this.opts.tokenResource);
|
|
510
|
+
let res;
|
|
511
|
+
try {
|
|
512
|
+
res = await this.fetchImpl(this.tokenUrl, {
|
|
513
|
+
method: 'POST',
|
|
514
|
+
headers: { 'content-type': 'application/x-www-form-urlencoded', accept: 'application/json' },
|
|
515
|
+
body: body.toString(),
|
|
516
|
+
signal: AbortSignal.timeout(this.dials.tokenTimeoutMs)
|
|
517
|
+
});
|
|
518
|
+
}
|
|
519
|
+
catch (err) {
|
|
520
|
+
this.opts.logger.warn({ err }, 'hub grant: token endpoint unreachable');
|
|
521
|
+
return { kind: 'transient' };
|
|
522
|
+
}
|
|
523
|
+
let payload = null;
|
|
524
|
+
try {
|
|
525
|
+
payload = await res.json();
|
|
526
|
+
}
|
|
527
|
+
catch {
|
|
528
|
+
// fall through — classified below by status
|
|
529
|
+
}
|
|
530
|
+
if (res.ok) {
|
|
531
|
+
const p = (payload ?? {});
|
|
532
|
+
if (typeof p.access_token !== 'string' || !p.access_token) {
|
|
533
|
+
this.opts.logger.warn('hub grant: token endpoint 200 without an access_token — malformed');
|
|
534
|
+
return { kind: 'transient' };
|
|
535
|
+
}
|
|
536
|
+
const expiresInS = typeof p.expires_in === 'number' && Number.isFinite(p.expires_in) && p.expires_in > 0
|
|
537
|
+
? p.expires_in
|
|
538
|
+
: 300; // conservative default when the hub omits it
|
|
539
|
+
return {
|
|
540
|
+
kind: 'ok',
|
|
541
|
+
accessToken: p.access_token,
|
|
542
|
+
expiresAt: new Date(this.now() + expiresInS * 1000),
|
|
543
|
+
refreshToken: typeof p.refresh_token === 'string' && p.refresh_token ? p.refresh_token : null
|
|
544
|
+
};
|
|
545
|
+
}
|
|
546
|
+
// RFC 6749 errors ride 400/401; anything else (5xx…) is transient.
|
|
547
|
+
if (res.status === 400 || res.status === 401) {
|
|
548
|
+
const error = payload?.error;
|
|
549
|
+
if (error === 'invalid_grant')
|
|
550
|
+
return { kind: 'invalid_grant' };
|
|
551
|
+
if (error === 'invalid_client')
|
|
552
|
+
return { kind: 'invalid_client' };
|
|
553
|
+
this.opts.logger.warn({ status: res.status, error }, 'hub grant: unrecognized token-endpoint error');
|
|
554
|
+
return { kind: 'transient' };
|
|
555
|
+
}
|
|
556
|
+
this.opts.logger.warn({ status: res.status }, 'hub grant: token endpoint answered non-2xx');
|
|
557
|
+
return { kind: 'transient' };
|
|
558
|
+
}
|
|
559
|
+
/**
|
|
560
|
+
* Session-scoped pg_advisory_lock on a dedicated client — never the pool
|
|
561
|
+
* (a session lock parked on a pooled connection would poison the pool).
|
|
562
|
+
* The watchdog cuts the connection after lockWatchdogMs; a session lock
|
|
563
|
+
* dies with its session, so a wedged refresh is strictly bounded.
|
|
564
|
+
*/
|
|
565
|
+
async acquireLock(userId) {
|
|
566
|
+
const client = new pg.Client({ connectionString: this.opts.connectionString });
|
|
567
|
+
await client.connect();
|
|
568
|
+
const lock = { client, released: false };
|
|
569
|
+
lock.watchdog = setTimeout(() => {
|
|
570
|
+
this.opts.logger.warn({ userId }, 'hub grant: refresh lock watchdog fired — cutting the dedicated connection');
|
|
571
|
+
lock.released = true;
|
|
572
|
+
void client.end().catch(() => { });
|
|
573
|
+
}, this.dials.lockWatchdogMs);
|
|
574
|
+
lock.watchdog.unref();
|
|
575
|
+
try {
|
|
576
|
+
await client.query('SELECT pg_advisory_lock($1, hashtext($2))', [GRANT_REFRESH_LOCK_KEY, userId]);
|
|
577
|
+
}
|
|
578
|
+
catch (cause) {
|
|
579
|
+
await this.releaseLock(lock);
|
|
580
|
+
throw cause;
|
|
581
|
+
}
|
|
582
|
+
return lock;
|
|
583
|
+
}
|
|
584
|
+
/** Idempotent; closing the client guarantees the session lock dies with it. */
|
|
585
|
+
async releaseLock(lock) {
|
|
586
|
+
if (lock.released)
|
|
587
|
+
return;
|
|
588
|
+
lock.released = true;
|
|
589
|
+
if (lock.watchdog)
|
|
590
|
+
clearTimeout(lock.watchdog);
|
|
591
|
+
await lock.client.end().catch(() => { });
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
//# sourceMappingURL=hub-grant.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hub-grant.js","sourceRoot":"","sources":["../../src/identity/hub-grant.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type JWTPayload } from 'jose';
|
|
2
|
+
/**
|
|
3
|
+
* Verifies hub-minted RS256 JWTs against the hub's REMOTE JWKS (discovered
|
|
4
|
+
* via OIDC discovery at the issuer root) — the cloud edition's trust anchor
|
|
5
|
+
* for "Sign in with Antasphere" (internal/federation.md). Same discipline as
|
|
6
|
+
* the local OauthJwtVerifier: hard issuer pinning, per-call audience
|
|
7
|
+
* pinning, RS256 allowlist (implicitly rejects none/HS256), small clock
|
|
8
|
+
* tolerance. jose's remote key set self-refreshes on an unknown `kid`; a
|
|
9
|
+
* signature failure on a KNOWN kid (rotation racing the cache) gets exactly
|
|
10
|
+
* one retry against a freshly created key set.
|
|
11
|
+
*/
|
|
12
|
+
export declare class HubJwtVerifier {
|
|
13
|
+
private readonly issuerUrl;
|
|
14
|
+
private discoveryCache;
|
|
15
|
+
private keySet;
|
|
16
|
+
constructor(issuerUrl: string);
|
|
17
|
+
private jwksUri;
|
|
18
|
+
private keys;
|
|
19
|
+
/** Verify a hub JWT with the given audience pin; throws on any failure. */
|
|
20
|
+
verify(token: string, audience: string): Promise<JWTPayload>;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=hub-jwt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hub-jwt.d.ts","sourceRoot":"","sources":["../../src/identity/hub-jwt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiC,KAAK,UAAU,EAAyB,MAAM,MAAM,CAAC;AAK7F;;;;;;;;;GASG;AACH,qBAAa,cAAc;IAIb,OAAO,CAAC,QAAQ,CAAC,SAAS;IAHtC,OAAO,CAAC,cAAc,CAAuD;IAC7E,OAAO,CAAC,MAAM,CAAsD;gBAEvC,SAAS,EAAE,MAAM;YAEhC,OAAO;YAqBP,IAAI;IAOlB,2EAA2E;IACrE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;CA2BnE"}
|