@runeditrun/rer 0.0.0-stage → 0.1.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 +21 -0
- package/README.md +154 -2
- package/bin/rer.mjs +3 -0
- package/cli/README.md +243 -0
- package/cli/adapter.mjs +10 -0
- package/cli/ai-local.mjs +65 -0
- package/cli/archive-path.mjs +52 -0
- package/cli/archive-vite.mjs +55 -0
- package/cli/archive.mjs +8 -0
- package/cli/auth-copy.mjs +80 -0
- package/cli/bounded.mjs +70 -0
- package/cli/cache-doctor.mjs +63 -0
- package/cli/container-transfer.mjs +35 -0
- package/cli/container.mjs +62 -0
- package/cli/contract.mjs +25 -0
- package/cli/dependencies.mjs +45 -0
- package/cli/dependency-approval.mjs +33 -0
- package/cli/dependency-doctor.mjs +34 -0
- package/cli/dependency-input.mjs +43 -0
- package/cli/deploy-config.mjs +118 -0
- package/cli/deploy.mjs +37 -0
- package/cli/dev-identity.mjs +80 -0
- package/cli/errors.mjs +14 -0
- package/cli/export.mjs +42 -0
- package/cli/font-cache.mjs +29 -0
- package/cli/hosted-output.mjs +110 -0
- package/cli/independent.mjs +29 -0
- package/cli/inspect.mjs +174 -0
- package/cli/jsonc.mjs +111 -0
- package/cli/lifecycle.mjs +148 -0
- package/cli/local.mjs +100 -0
- package/cli/main.mjs +57 -0
- package/cli/managed-server.mjs +143 -0
- package/cli/node-runtime-cache.mjs +68 -0
- package/cli/node-runtime-discovery.mjs +56 -0
- package/cli/node-runtime-download.mjs +59 -0
- package/cli/node-runtime.mjs +50 -0
- package/cli/output.mjs +22 -0
- package/cli/parse.mjs +77 -0
- package/cli/port.mjs +52 -0
- package/cli/portability-worker.mjs +56 -0
- package/cli/portability.mjs +66 -0
- package/cli/preview-cache.mjs +99 -0
- package/cli/project.mjs +48 -0
- package/cli/release.mjs +24 -0
- package/cli/runtime-front-door.mjs +46 -0
- package/cli/scheduled.mjs +81 -0
- package/cli/server-activity.mjs +12 -0
- package/cli/server-proxy.mjs +93 -0
- package/cli/server-registry.mjs +177 -0
- package/cli/server-resources.mjs +22 -0
- package/cli/settings.mjs +15 -0
- package/cli/setup-answers.mjs +29 -0
- package/cli/setup-input.mjs +113 -0
- package/cli/shared.mjs +7 -0
- package/cli/transfers.mjs +33 -0
- package/cli/version.mjs +36 -0
- package/composition/git-source.mjs +111 -0
- package/edition-authoring/files.mjs +81 -0
- package/edition-authoring/manifest.mjs +65 -0
- package/global/README.md +155 -0
- package/global/checkout.mjs +72 -0
- package/global/cli/command.mjs +13 -0
- package/global/cli/install.mjs +75 -0
- package/global/cli/layout.mjs +45 -0
- package/global/cli/status.mjs +54 -0
- package/global/cli/uninstall.mjs +36 -0
- package/global/delegate.mjs +13 -0
- package/global/launch/capacity.mjs +72 -0
- package/global/launch/dev.mjs +129 -0
- package/global/launch/facts.mjs +93 -0
- package/global/launch/failure.mjs +5 -0
- package/global/launch/local-defaults.mjs +4 -0
- package/global/launch/prepare.mjs +61 -0
- package/global/launch/render.mjs +44 -0
- package/global/launch/state.mjs +97 -0
- package/global/launch/steps.mjs +81 -0
- package/global/launch/worker.mjs +43 -0
- package/global/list.mjs +59 -0
- package/global/main.mjs +53 -0
- package/global/package-info.mjs +38 -0
- package/global/registry.mjs +24 -0
- package/global/rer.mjs +29 -0
- package/global/update/archive.mjs +89 -0
- package/global/update/command.mjs +90 -0
- package/global/update/latest.mjs +6 -0
- package/global/update/notice.mjs +58 -0
- package/global/update/registry.mjs +47 -0
- package/global/version.mjs +29 -0
- package/install.sh +144 -0
- package/modules/ai/LICENSE +21 -0
- package/modules/ai/README.md +90 -0
- package/modules/ai/client.mjs +71 -0
- package/modules/ai/config.mjs +39 -0
- package/modules/ai/dev/index.d.mts +6 -0
- package/modules/ai/dev/index.mjs +64 -0
- package/modules/ai/dev/outbox.mjs +33 -0
- package/modules/ai/errors.mjs +28 -0
- package/modules/ai/fake/index.d.mts +3 -0
- package/modules/ai/fake/index.mjs +82 -0
- package/modules/ai/index.d.mts +10 -0
- package/modules/ai/index.mjs +3 -0
- package/modules/ai/package.json +6 -0
- package/modules/container/README.md +156 -0
- package/modules/container/adapters/d1.mjs +34 -0
- package/modules/container/adapters/egress.mjs +40 -0
- package/modules/container/adapters/jobs.mjs +47 -0
- package/modules/container/adapters/objects.mjs +84 -0
- package/modules/container/adapters/retained.mjs +14 -0
- package/modules/container/adapters/sqlite-error.mjs +7 -0
- package/modules/container/adapters/sqlite-worker.mjs +26 -0
- package/modules/container/assets.mjs +14 -0
- package/modules/container/bindings.mjs +1 -0
- package/modules/container/boundary.mjs +38 -0
- package/modules/container/build.mjs +65 -0
- package/modules/container/deploy-input.mjs +17 -0
- package/modules/container/entrypoint.sh +5 -0
- package/modules/container/host.mjs +43 -0
- package/modules/container/ingress.mjs +23 -0
- package/modules/container/lock.mjs +11 -0
- package/modules/container/migrations.mjs +16 -0
- package/modules/container/node-engine.mjs +39 -0
- package/modules/container/portability-schema.mjs +14 -0
- package/modules/container/remote/deploy.py +76 -0
- package/modules/container/remote/files.py +275 -0
- package/modules/container/remote/resources.py +157 -0
- package/modules/container/runner.mjs +10 -0
- package/modules/container/ssh-plan.mjs +44 -0
- package/modules/container/ssh.mjs +63 -0
- package/modules/container/transfer.mjs +27 -0
- package/modules/container/worker-engine.mjs +32 -0
- package/modules/dependencies/README.md +211 -0
- package/modules/dependencies/approval.mjs +51 -0
- package/modules/dependencies/auth.mjs +40 -0
- package/modules/dependencies/authority.mjs +14 -0
- package/modules/dependencies/crypto.mjs +13 -0
- package/modules/dependencies/index.d.mts +23 -0
- package/modules/dependencies/index.mjs +113 -0
- package/modules/dependencies/logout.mjs +42 -0
- package/modules/dependencies/native.mjs +9 -0
- package/modules/dependencies/protocol.mjs +23 -0
- package/modules/dependencies/schema/approval-attempt.sql +3 -0
- package/modules/dependencies/schema/dependencies.sql +15 -0
- package/modules/dependencies/store.mjs +19 -0
- package/modules/deploy-kit/README.md +308 -0
- package/modules/deploy-kit/artifact.mjs +47 -0
- package/modules/deploy-kit/build-modules.mjs +21 -0
- package/modules/deploy-kit/check.mjs +13 -0
- package/modules/deploy-kit/cli.mjs +50 -0
- package/modules/deploy-kit/container-config.mjs +8 -0
- package/modules/deploy-kit/default-stage.mjs +14 -0
- package/modules/deploy-kit/deploy.mjs +80 -0
- package/modules/deploy-kit/health-request.mjs +86 -0
- package/modules/deploy-kit/health.mjs +99 -0
- package/modules/deploy-kit/index.mjs +12 -0
- package/modules/deploy-kit/local-only.mjs +10 -0
- package/modules/deploy-kit/migrations.mjs +48 -0
- package/modules/deploy-kit/owner-cli.mjs +63 -0
- package/modules/deploy-kit/owner.mjs +297 -0
- package/modules/deploy-kit/prepare.mjs +62 -0
- package/modules/deploy-kit/provider.mjs +99 -0
- package/modules/deploy-kit/queue-consumer.mjs +10 -0
- package/modules/deploy-kit/receipt.mjs +16 -0
- package/modules/deploy-kit/render.mjs +47 -0
- package/modules/deploy-kit/resources.mjs +106 -0
- package/modules/deploy-kit/service-grants.mjs +25 -0
- package/modules/deploy-kit/sql-safety.mjs +94 -0
- package/modules/deploy-kit/sql-tokens.mjs +49 -0
- package/modules/deploy-kit/teardown.mjs +100 -0
- package/modules/deploy-kit/templates.mjs +31 -0
- package/modules/deploy-kit/validation.mjs +58 -0
- package/modules/deploy-kit/worker.mjs +105 -0
- package/modules/erasure/CONTRACT.md +90 -0
- package/modules/erasure/README.md +221 -0
- package/modules/erasure/audit.mjs +23 -0
- package/modules/erasure/blobs.mjs +45 -0
- package/modules/erasure/cascade.mjs +91 -0
- package/modules/erasure/completion.mjs +62 -0
- package/modules/erasure/declaration.mjs +51 -0
- package/modules/erasure/fence.mjs +19 -0
- package/modules/erasure/index.d.mts +62 -0
- package/modules/erasure/index.mjs +85 -0
- package/modules/erasure/order.mjs +56 -0
- package/modules/erasure/plan.mjs +121 -0
- package/modules/erasure/rate.mjs +57 -0
- package/modules/erasure/receipt.mjs +32 -0
- package/modules/erasure/root.mjs +21 -0
- package/modules/erasure/schema/erasure-rates.sql +5 -0
- package/modules/erasure/schema/erasure.sql +27 -0
- package/modules/erasure/scope.mjs +29 -0
- package/modules/erasure/sql.mjs +23 -0
- package/modules/erasure/verification.mjs +69 -0
- package/modules/integrations/core/CONTRACT.md +50 -0
- package/modules/integrations/core/README.md +27 -0
- package/modules/integrations/core/crypto.ts +19 -0
- package/modules/integrations/core/database.ts +21 -0
- package/modules/integrations/core/delivery.ts +97 -0
- package/modules/integrations/core/destination.ts +13 -0
- package/modules/integrations/core/index.ts +7 -0
- package/modules/integrations/core/node-transport.ts +72 -0
- package/modules/integrations/core/public-address.ts +57 -0
- package/modules/integrations/core/repository.ts +74 -0
- package/modules/integrations/core/schema.sql +36 -0
- package/modules/integrations/core/sqlite.ts +20 -0
- package/modules/integrations/core/timestamped-body-signature.ts +38 -0
- package/modules/integrations/core/tokens.ts +71 -0
- package/modules/integrations/core/types.ts +52 -0
- package/modules/integrations/core/upgrade-token-usage-context.sql +5 -0
- package/modules/integrations/core/webhook.ts +73 -0
- package/modules/job-queue/README.md +173 -0
- package/modules/job-queue/cli.mjs +64 -0
- package/modules/job-queue/command.mjs +64 -0
- package/modules/job-queue/config.mjs +48 -0
- package/modules/job-queue/identity.mjs +48 -0
- package/modules/job-queue/index.mjs +135 -0
- package/modules/job-queue/membership.mjs +30 -0
- package/modules/job-queue/module.json +10 -0
- package/modules/job-queue/policy.mjs +29 -0
- package/modules/job-queue/processes.mjs +80 -0
- package/modules/job-queue/resources.mjs +37 -0
- package/modules/job-queue/storage.mjs +64 -0
- package/modules/job-queue/supervisor.mjs +30 -0
- package/modules/job-queue/waiting.mjs +16 -0
- package/modules/mail/LICENSE +21 -0
- package/modules/mail/README.md +336 -0
- package/modules/mail/doctor.mjs +81 -0
- package/modules/mail/index.mjs +8 -0
- package/modules/mail/live-proof/README.md +113 -0
- package/modules/mail/live-proof/run.mjs +55 -0
- package/modules/mail/package.json +19 -0
- package/modules/mail/pnpm-lock.yaml +537 -0
- package/modules/mail/src/adapters/cloudflare/README.md +84 -0
- package/modules/mail/src/adapters/cloudflare/headers.mjs +63 -0
- package/modules/mail/src/adapters/cloudflare/index.mjs +47 -0
- package/modules/mail/src/adapters/cloudflare/response.mjs +99 -0
- package/modules/mail/src/adapters/messaging/README.md +92 -0
- package/modules/mail/src/adapters/messaging/contract.mjs +66 -0
- package/modules/mail/src/adapters/messaging/event-schema.mjs +28 -0
- package/modules/mail/src/adapters/messaging/index.mjs +61 -0
- package/modules/mail/src/adapters/messaging/jws.mjs +68 -0
- package/modules/mail/src/adapters/messaging/request.mjs +52 -0
- package/modules/mail/src/adapters/messaging/serialize.mjs +21 -0
- package/modules/mail/src/adapters/resend/README.md +120 -0
- package/modules/mail/src/adapters/resend/index.mjs +22 -0
- package/modules/mail/src/adapters/resend/response.mjs +54 -0
- package/modules/mail/src/adapters/resend/serialize.mjs +46 -0
- package/modules/mail/src/adapters/resend/size.mjs +99 -0
- package/modules/mail/src/adapters/sendgrid/README.md +75 -0
- package/modules/mail/src/adapters/sendgrid/index.mjs +35 -0
- package/modules/mail/src/adapters/sendgrid/serialize.mjs +104 -0
- package/modules/mail/src/core/errors.mjs +9 -0
- package/modules/mail/src/core/transport.mjs +33 -0
- package/modules/mail/src/core/validation.mjs +172 -0
- package/modules/mail/src/development/index.d.mts +37 -0
- package/modules/mail/src/development/index.mjs +35 -0
- package/modules/mail/src/development/outbox.mjs +78 -0
- package/modules/mail/src/development/schema.sql +9 -0
- package/modules/mail/src/development/viewer-html.mjs +42 -0
- package/modules/mail/src/development/viewer.mjs +65 -0
- package/modules/mail/src/doctor/README.md +107 -0
- package/modules/mail/src/doctor/common.mjs +64 -0
- package/modules/mail/src/doctor/dns.mjs +102 -0
- package/modules/mail/src/doctor/index.mjs +28 -0
- package/modules/mail/src/doctor/probe.mjs +66 -0
- package/modules/mail/src/doctor/receive.mjs +81 -0
- package/modules/mail/src/doctor/records.mjs +45 -0
- package/modules/mail/src/events/README.md +268 -0
- package/modules/mail/src/events/d1-schema.sql +25 -0
- package/modules/mail/src/events/d1-storage.mjs +76 -0
- package/modules/mail/src/events/index.mjs +3 -0
- package/modules/mail/src/events/intake.mjs +201 -0
- package/modules/mail/src/events/storage.mjs +52 -0
- package/modules/mail/src/events/verify.mjs +92 -0
- package/modules/mail/src/inbound/README.md +137 -0
- package/modules/mail/src/inbound/bytes.mjs +91 -0
- package/modules/mail/src/inbound/headers.mjs +143 -0
- package/modules/mail/src/inbound/index.mjs +29 -0
- package/modules/mail/src/inbound/mime.mjs +36 -0
- package/modules/mail/src/inbound/multipart.mjs +27 -0
- package/modules/mail/src/inbound/resend-attachment.mjs +43 -0
- package/modules/mail/src/inbound/resend.mjs +54 -0
- package/modules/mail/src/inbound/sendgrid.mjs +60 -0
- package/modules/mail/src/sender.mjs +33 -0
- package/modules/mail/src/sendgrid-email/index.d.mts +33 -0
- package/modules/mail/src/sendgrid-email/index.mjs +86 -0
- package/modules/mail/src/unsubscribe/index.mjs +142 -0
- package/modules/operator-auth/README.md +599 -0
- package/modules/operator-auth/accounts/adapter.mjs +41 -0
- package/modules/operator-auth/accounts/admin.mjs +159 -0
- package/modules/operator-auth/accounts/credentials.mjs +27 -0
- package/modules/operator-auth/accounts/editor-owner.mjs +13 -0
- package/modules/operator-auth/accounts/index.d.mts +9 -0
- package/modules/operator-auth/accounts/index.mjs +9 -0
- package/modules/operator-auth/accounts/native.d.mts +38 -0
- package/modules/operator-auth/accounts/native.mjs +171 -0
- package/modules/operator-auth/accounts/oa.mjs +90 -0
- package/modules/operator-auth/accounts/provider-control.mjs +50 -0
- package/modules/operator-auth/accounts/provider-pin.mjs +14 -0
- package/modules/operator-auth/accounts/roles.mjs +26 -0
- package/modules/operator-auth/accounts/schema/dependency-setup.sql +17 -0
- package/modules/operator-auth/accounts/schema/dev-sessions.sql +22 -0
- package/modules/operator-auth/accounts/schema/domain-rules-step-up.sql +20 -0
- package/modules/operator-auth/accounts/schema/invitation-cancellation.sql +17 -0
- package/modules/operator-auth/accounts/schema/operator-auth.sql +142 -0
- package/modules/operator-auth/accounts/schema/provider-control.sql +30 -0
- package/modules/operator-auth/accounts/schema/provider-pins.sql +6 -0
- package/modules/operator-auth/accounts/settings-page.mjs +4 -0
- package/modules/operator-auth/accounts/store.mjs +246 -0
- package/modules/operator-auth/branding.mjs +66 -0
- package/modules/operator-auth/config.mjs +35 -0
- package/modules/operator-auth/conformance/README.md +81 -0
- package/modules/operator-auth/conformance/index.d.mts +43 -0
- package/modules/operator-auth/conformance/index.mjs +300 -0
- package/modules/operator-auth/conformance/presentation.mjs +57 -0
- package/modules/operator-auth/crypto.mjs +17 -0
- package/modules/operator-auth/dev/badge.mjs +62 -0
- package/modules/operator-auth/dev/index.d.mts +14 -0
- package/modules/operator-auth/dev/index.mjs +137 -0
- package/modules/operator-auth/dev/personas.mjs +17 -0
- package/modules/operator-auth/dev/sign-in-as.d.mts +3 -0
- package/modules/operator-auth/dev/sign-in-as.mjs +25 -0
- package/modules/operator-auth/dev-admission.d.mts +4 -0
- package/modules/operator-auth/dev-admission.mjs +10 -0
- package/modules/operator-auth/dev-gate.mjs +86 -0
- package/modules/operator-auth/docs/README.md +78 -0
- package/modules/operator-auth/docs/native-accounts.md +313 -0
- package/modules/operator-auth/docs/tanstack-start.md +218 -0
- package/modules/operator-auth/docs/vite-spa.md +144 -0
- package/modules/operator-auth/errors.mjs +9 -0
- package/modules/operator-auth/http.mjs +42 -0
- package/modules/operator-auth/identity/admission.mjs +105 -0
- package/modules/operator-auth/identity/after-confirm.mjs +18 -0
- package/modules/operator-auth/identity/email-link/confirmation.mjs +14 -0
- package/modules/operator-auth/identity/email-link/index.d.mts +48 -0
- package/modules/operator-auth/identity/email-link/index.mjs +128 -0
- package/modules/operator-auth/identity/email-link/message.mjs +16 -0
- package/modules/operator-auth/identity/index.d.mts +7 -0
- package/modules/operator-auth/identity/index.mjs +5 -0
- package/modules/operator-auth/identity/oidc/README.md +171 -0
- package/modules/operator-auth/identity/oidc/client-auth.mjs +16 -0
- package/modules/operator-auth/identity/oidc/config.mjs +102 -0
- package/modules/operator-auth/identity/oidc/crypto.mjs +29 -0
- package/modules/operator-auth/identity/oidc/errors.mjs +5 -0
- package/modules/operator-auth/identity/oidc/index.d.mts +33 -0
- package/modules/operator-auth/identity/oidc/index.mjs +287 -0
- package/modules/operator-auth/identity/oidc/jwt.mjs +102 -0
- package/modules/operator-auth/identity/oidc/network.mjs +93 -0
- package/modules/operator-auth/identity/oidc/presets.mjs +26 -0
- package/modules/operator-auth/identity/oidc/schema/oidc.sql +50 -0
- package/modules/operator-auth/identity/oidc/store.mjs +68 -0
- package/modules/operator-auth/identity/principal.mjs +28 -0
- package/modules/operator-auth/index.d.mts +223 -0
- package/modules/operator-auth/index.mjs +11 -0
- package/modules/operator-auth/input.mjs +55 -0
- package/modules/operator-auth/local-cli.mjs +16 -0
- package/modules/operator-auth/page.mjs +34 -0
- package/modules/operator-auth/policy.mjs +20 -0
- package/modules/operator-auth/routes.mjs +91 -0
- package/modules/operator-auth/service.mjs +152 -0
- package/modules/operator-auth/signin/index.mjs +67 -0
- package/modules/owner-claim/README.md +137 -0
- package/modules/owner-claim/idp.mjs +40 -0
- package/modules/owner-claim/index.d.mts +27 -0
- package/modules/owner-claim/index.mjs +39 -0
- package/modules/owner-claim/page.mjs +11 -0
- package/modules/owner-claim/schema/idp.sql +4 -0
- package/modules/owner-claim/schema/owner-claim.sql +18 -0
- package/modules/owner-claim/transaction.mjs +87 -0
- package/modules/owner-claim/verify.mjs +80 -0
- package/modules/portability/README.md +444 -0
- package/modules/portability/bridge.mjs +102 -0
- package/modules/portability/catalogue.mjs +118 -0
- package/modules/portability/cli-options.mjs +38 -0
- package/modules/portability/cli.mjs +56 -0
- package/modules/portability/copies.mjs +68 -0
- package/modules/portability/dev-data.mjs +32 -0
- package/modules/portability/diff.mjs +33 -0
- package/modules/portability/export.mjs +129 -0
- package/modules/portability/files.mjs +65 -0
- package/modules/portability/format.mjs +122 -0
- package/modules/portability/generated.mjs +60 -0
- package/modules/portability/hash.mjs +79 -0
- package/modules/portability/http.mjs +42 -0
- package/modules/portability/import.mjs +185 -0
- package/modules/portability/index.d.mts +58 -0
- package/modules/portability/index.mjs +22 -0
- package/modules/portability/journal.mjs +49 -0
- package/modules/portability/legacy-files.mjs +43 -0
- package/modules/portability/legacy-safety.mjs +27 -0
- package/modules/portability/lines.mjs +36 -0
- package/modules/portability/migration-history.mjs +18 -0
- package/modules/portability/migration-statements.mjs +23 -0
- package/modules/portability/payloads.mjs +52 -0
- package/modules/portability/provider-data.mjs +25 -0
- package/modules/portability/restore-safety.mjs +30 -0
- package/modules/portability/schema/portability.sql +25 -0
- package/modules/portability/storage.mjs +49 -0
- package/modules/release/README.md +212 -0
- package/modules/release/catalogue.mjs +79 -0
- package/modules/release/export.mjs +51 -0
- package/modules/release/produce.mjs +136 -0
- package/modules/release/public-child-transport-state.cjs +29 -0
- package/modules/release/public-child.mjs +71 -0
- package/modules/release/public-git.mjs +21 -0
- package/modules/release/publication-scan.mjs +22 -0
- package/modules/release/publish-handoff.mjs +37 -0
- package/modules/release/source.mjs +71 -0
- package/modules/release/test-summary.mjs +50 -0
- package/onboarding/README.md +163 -0
- package/onboarding/activity.mjs +31 -0
- package/onboarding/adapter-auth.mjs +88 -0
- package/onboarding/adapter-hosting.mjs +35 -0
- package/onboarding/adapter-labels.mjs +13 -0
- package/onboarding/adapter-settings.mjs +129 -0
- package/onboarding/adapter.mjs +238 -0
- package/onboarding/agent-handoff.mjs +9 -0
- package/onboarding/app-processes.mjs +21 -0
- package/onboarding/archive-output.d.mts +3 -0
- package/onboarding/archive-output.mjs +54 -0
- package/onboarding/command-custody.mjs +24 -0
- package/onboarding/command-recovery.mjs +8 -0
- package/onboarding/commands.mjs +166 -0
- package/onboarding/dependency-approval.mjs +36 -0
- package/onboarding/dev-identity.mjs +23 -0
- package/onboarding/email.mjs +24 -0
- package/onboarding/failures.mjs +42 -0
- package/onboarding/input-limits.mjs +7 -0
- package/onboarding/installer-inputs.mjs +24 -0
- package/onboarding/launcher.mjs +34 -0
- package/onboarding/local/build-files.mjs +64 -0
- package/onboarding/local/build.mjs +49 -0
- package/onboarding/local/environment.mjs +30 -0
- package/onboarding/local/files.mjs +35 -0
- package/onboarding/local/operation.mjs +166 -0
- package/onboarding/local/owner.mjs +34 -0
- package/onboarding/local/process-table.mjs +114 -0
- package/onboarding/local/recovery.mjs +79 -0
- package/onboarding/local/state.mjs +31 -0
- package/onboarding/metadata.mjs +7 -0
- package/onboarding/operator-install.mjs +45 -0
- package/onboarding/operator-installer.mjs +39 -0
- package/onboarding/operator-prerequisites.mjs +27 -0
- package/onboarding/package.json +6 -0
- package/onboarding/prefill.mjs +16 -0
- package/onboarding/private-files.mjs +97 -0
- package/onboarding/private.mjs +35 -0
- package/onboarding/process-cleanup.mjs +134 -0
- package/onboarding/process-diagnostics.mjs +91 -0
- package/onboarding/process-scope.mjs +118 -0
- package/onboarding/process-table.mjs +118 -0
- package/onboarding/process-tree.mjs +36 -0
- package/onboarding/production-modules.mjs +22 -0
- package/onboarding/production-options.mjs +40 -0
- package/onboarding/production-plan.mjs +8 -0
- package/onboarding/production-runtime.mjs +30 -0
- package/onboarding/project-vite.mjs +14 -0
- package/onboarding/providers.mjs +289 -0
- package/onboarding/queue.mjs +53 -0
- package/onboarding/queued-entry.mjs +34 -0
- package/onboarding/readiness.mjs +59 -0
- package/onboarding/redaction-jwt.mjs +32 -0
- package/onboarding/redaction.mjs +298 -0
- package/onboarding/schema/SETUP.schema.json +514 -0
- package/onboarding/schema/dependencies.mjs +35 -0
- package/onboarding/schema/json-schema.mjs +202 -0
- package/onboarding/schema/setup-validation.mjs +325 -0
- package/onboarding/secrets.mjs +21 -0
- package/onboarding/server.mjs +188 -0
- package/onboarding/setup-manifest.mjs +116 -0
- package/onboarding/state.mjs +46 -0
- package/onboarding/theme-files.mjs +37 -0
- package/onboarding/theme.mjs +118 -0
- package/onboarding/ui/activity.js +98 -0
- package/onboarding/ui/address-client.mjs +33 -0
- package/onboarding/ui/app.js +377 -0
- package/onboarding/ui/index.html +1 -0
- package/onboarding/ui/model-core.mjs +127 -0
- package/onboarding/ui/model.mjs +5 -0
- package/onboarding/ui/style.css +63 -0
- package/onboarding/ui/theme.css +37 -0
- package/onboarding/ui/workspace-art.js +30 -0
- package/onboarding/wrangler-auth.mjs +43 -0
- package/operations/README.md +246 -0
- package/operations/operations.mjs +168 -0
- package/operations/project-operations.mjs +157 -0
- package/package.json +11 -4
- package/scripts/publish-check/README.md +72 -0
- package/scripts/publish-check/checksum_maps.py +52 -0
- package/scripts/publish-check/cli.py +34 -0
- package/scripts/publish-check/command_arguments.py +51 -0
- package/scripts/publish-check/command_shell_quotes.py +41 -0
- package/scripts/publish-check/command_source_quotes.py +120 -0
- package/scripts/publish-check/content_identities.py +250 -0
- package/scripts/publish-check/copy_identities.py +41 -0
- package/scripts/publish-check/der.py +61 -0
- package/scripts/publish-check/destination.py +117 -0
- package/scripts/publish-check/env_values.py +74 -0
- package/scripts/publish-check/font_licence.py +23 -0
- package/scripts/publish-check/git_history.py +115 -0
- package/scripts/publish-check/github_refs.py +217 -0
- package/scripts/publish-check/gitleaks.py +72 -0
- package/scripts/publish-check/gitleaks.toml +40 -0
- package/scripts/publish-check/history_scan.py +176 -0
- package/scripts/publish-check/hit_location.py +18 -0
- package/scripts/publish-check/hygiene_config.py +42 -0
- package/scripts/publish-check/hygiene_text.py +11 -0
- package/scripts/publish-check/identity-recipe.mjs +54 -0
- package/scripts/publish-check/json_identity.py +79 -0
- package/scripts/publish-check/license-exceptions.json +11 -0
- package/scripts/publish-check/licenses.py +49 -0
- package/scripts/publish-check/policy.py +18 -0
- package/scripts/publish-check/project_identity.py +89 -0
- package/scripts/publish-check/provenance.py +91 -0
- package/scripts/publish-check/provenance_pins.py +33 -0
- package/scripts/publish-check/public_base.py +63 -0
- package/scripts/publish-check/public_hygiene.py +80 -0
- package/scripts/publish-check/publication-config.json +12 -0
- package/scripts/publish-check/publication_config.py +34 -0
- package/scripts/publish-check/report.py +52 -0
- package/scripts/publish-check/repository_commands.py +75 -0
- package/scripts/publish-check/repository_intent.py +52 -0
- package/scripts/publish-check/reviewed.py +41 -0
- package/scripts/publish-check/source_hashes.mjs +6 -0
- package/scripts/publish-check/tree_scan.py +88 -0
- package/scripts/publish-check/trust_bundle.py +87 -0
- package/scripts/publish-check.mjs +58 -0
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
# Native accounts and proof persistence
|
|
2
|
+
|
|
3
|
+
`createOperatorAuth({ db, config, accounts, proofs, ... })` selects native
|
|
4
|
+
composition for the **whole service**. Both adapters are required. Supplying
|
|
5
|
+
only one, `null`, `undefined`, missing methods or malformed optional methods
|
|
6
|
+
fails construction; it never selects OA as a fallback. Omit both options to
|
|
7
|
+
retain Base's existing OA composition and API.
|
|
8
|
+
|
|
9
|
+
The public declarations are `NativeAccountsAdapter<R>`, `NativePerson<R>`,
|
|
10
|
+
`NativeProofPersistence<R>` and `NativeOperatorAuth<R>` from
|
|
11
|
+
`modules/operator-auth/index.mjs`. `R` is the edition's own role union, for
|
|
12
|
+
example `'owner' | 'admin' | 'operator' | 'contact'`. IDs, roles, cookies and
|
|
13
|
+
existing sessions remain native. No role or tenant is taken from an OIDC claim,
|
|
14
|
+
request parameter or callback. Select the workspace/project tenant in the
|
|
15
|
+
server's adapter factory and scope every query and transaction to it.
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
const auth = createOperatorAuth({
|
|
19
|
+
db, config,
|
|
20
|
+
accounts: createNativeAccounts(db, { workspaceId }),
|
|
21
|
+
proofs: createNativeProofs(db, { workspaceId }),
|
|
22
|
+
mailSender, clientIp,
|
|
23
|
+
});
|
|
24
|
+
const handleAuth = createAuthHandler(auth);
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
`config` remains `AuthConfig`; the session secret keys email-token and rate-key
|
|
28
|
+
hashes, independently of the seed's native session-cookie digest. The OIDC
|
|
29
|
+
transaction secret remains separate. The accounts adapter reads the native
|
|
30
|
+
cookie in `getSession(request, { now })`, revokes its token and returns its
|
|
31
|
+
clearing cookie in `signOut`. The service never assumes the OA cookie name.
|
|
32
|
+
|
|
33
|
+
## Account contract
|
|
34
|
+
|
|
35
|
+
Retain the identity adapter methods (`findByEmail`, `findBinding`, `bind`,
|
|
36
|
+
`issueSession`, `revokeSession`, `owner`). Full native composition additionally
|
|
37
|
+
requires `findById`, `getSession`, `signOut`, `identityEnabled`, `policyVersion`,
|
|
38
|
+
`requiredProvider` and **atomic** `bindAndIssueSession`. The identity-only
|
|
39
|
+
`createAdmission` entry still accepts the earlier smaller interface. It does
|
|
40
|
+
not make an old adapter sufficient for the full service.
|
|
41
|
+
|
|
42
|
+
Project native account status into `active`, `invited` or `inactive`. Supply an
|
|
43
|
+
actual monotonic `version` (or an existing native authority revision) that
|
|
44
|
+
changes on email, status, role, ownership, credential fencing and any other
|
|
45
|
+
change that invalidates outstanding authority. A constant invented version
|
|
46
|
+
cannot meet this contract. `owner: boolean` is an authoritative projection, not
|
|
47
|
+
an inference that the native role string must be `'owner'`. `owner()` returns
|
|
48
|
+
the currently selected install owner. `findByEmail`/`findById` also expose the
|
|
49
|
+
native `role`, `displayName` and `createdAt` for the shared hook/session shape.
|
|
50
|
+
|
|
51
|
+
`getSession` rechecks current native account status/version, session expiry and
|
|
52
|
+
revocation. For new provider sessions it also checks current `(issuer, subject)`
|
|
53
|
+
binding, app policy generation, and the stored provider pin when issued through
|
|
54
|
+
the OIDC protocol. Server-verified identity seams carry no OIDC transaction pin. Preserve older native
|
|
55
|
+
sessions according to the seed's existing session contract; do not delete or
|
|
56
|
+
reinterpret them as provider sessions. The service strips the internal actor `hash` from public session responses and
|
|
57
|
+
normalizes completed/hook return paths before redirects. The service additionally enforces the
|
|
58
|
+
24-hour provider cap and disabled-provider setting, the dev gate, and loopback
|
|
59
|
+
review restrictions. Those outer checks are not a substitute for transactional
|
|
60
|
+
mutation fences.
|
|
61
|
+
|
|
62
|
+
`bindAndIssueSession` must commit all of the following together:
|
|
63
|
+
|
|
64
|
+
- Current tenant/account ID, email, status and version still match the admitted
|
|
65
|
+
person; the domain rule still permits this provider (owners are exempt).
|
|
66
|
+
- `principal.providerGeneration` equals the durable app generation, identity
|
|
67
|
+
sign-in is enabled. For protocol-issued principals, `principal.providerPin`
|
|
68
|
+
must still identify a linked issuer/client/pin generation in
|
|
69
|
+
`oa_identity_providers`. The server-verified seams below intentionally have no
|
|
70
|
+
pin; do not bind undefined values or invent one.
|
|
71
|
+
- `(issuer, subject)` is unbound or already bound to this same native person.
|
|
72
|
+
Never move a binding to another person. Revoke earlier password authority
|
|
73
|
+
in the same transaction, including native password credentials **and every
|
|
74
|
+
existing password session** for that person. Clearing a password field alone
|
|
75
|
+
does not revoke those sessions. Preserve ordinary native email sessions and
|
|
76
|
+
other people's password sessions.
|
|
77
|
+
- Insert a native session with issuer, subject, optional `sid`, pin, generation,
|
|
78
|
+
current account version and expiry no more than 24 hours after creation.
|
|
79
|
+
|
|
80
|
+
Return a `CompletedSession<R>` only after commit, or `null` on a refused race.
|
|
81
|
+
`acceptInvitation`, if supplied, must enforce the same conditions plus the
|
|
82
|
+
current invitation/issuer authority atomically. It is otherwise refused.
|
|
83
|
+
|
|
84
|
+
The server-only `admitVerifiedIdentity` and `createIdentityAdmission` seams
|
|
85
|
+
remain available with `config.externalIssuers`. The caller must already have
|
|
86
|
+
verified the identity cryptographically; association maps belong to server
|
|
87
|
+
configuration, never HTTP input. Native composition snapshots `policyVersion()`
|
|
88
|
+
before admission and supplies it as `principal.providerGeneration`. It strips
|
|
89
|
+
OIDC pin/generation fields from caller input. Both seams still enforce current
|
|
90
|
+
identity enablement, trusted email age, tenant/person status, immutable binding
|
|
91
|
+
and domain policy; only protocol-created principals carry a provider pin.
|
|
92
|
+
Adapters must apply the same generation, person and binding fences to these
|
|
93
|
+
sessions and allow pinless sessions in their step-up/owner mutation fences.
|
|
94
|
+
Do not add an HTTP endpoint accepting asserted identity JSON in a real app.
|
|
95
|
+
|
|
96
|
+
## Email-link lifecycle and atomic persistence
|
|
97
|
+
|
|
98
|
+
`identity/email-link/index.mjs` exports `createEmailLinkLifecycle`,
|
|
99
|
+
`STEP_UP_ACTIONS` and `STEP_UP_SECONDS`, with declarations beside it. It accepts
|
|
100
|
+
ordinary `AuthConfig` and normalizes defaults itself. Base's OA service and the
|
|
101
|
+
native service both use this implementation. For direct adoption supply
|
|
102
|
+
`EmailLinkPersistence<R>`: the native proof methods below plus account lookup,
|
|
103
|
+
authentication, required-provider lookup, authorized preview and atomic
|
|
104
|
+
consumption composition. The exported declaration gives every exact argument.
|
|
105
|
+
The full native service supplies that composition from `accounts` and `proofs`.
|
|
106
|
+
|
|
107
|
+
A direct `hooks.afterConfirm` runs exactly once after session issuance; return
|
|
108
|
+
paths are normalized and a throwing hook revokes the new session through
|
|
109
|
+
`persistence.revokeSession(id)` before returning refusal. Supply this durable
|
|
110
|
+
revocation capability with any direct completion hook; otherwise construction
|
|
111
|
+
fails before issuing authority. Composed services instead pass
|
|
112
|
+
`admission.afterConfirm`, which already owns hooks and account-store revocation.
|
|
113
|
+
The separate `afterConfirm` callback and `hooks.afterConfirm` are mutually
|
|
114
|
+
exclusive, so a callback cannot silently drop a supplied veto. Other hooks,
|
|
115
|
+
including `beforeMagicLink`, remain available with either composition.
|
|
116
|
+
|
|
117
|
+
`NativeProofPersistence` implements:
|
|
118
|
+
|
|
119
|
+
| Method | Required durable behavior |
|
|
120
|
+
| --- | --- |
|
|
121
|
+
| `limits(keys, now, windowMs)` | Atomically increment IP and email buckets; return each count. Keys are HMAC digests. |
|
|
122
|
+
| `token(record)` | Store only `hash`, never the raw bearer; bind current person ID/version/email, safe return, expiry. Recheck current authority and route; return whether inserted. |
|
|
123
|
+
| `preview(digest, now)` | Read a live magic proof and current authority; return the declared `NativeLinkPreview`. Never consume or create a session. |
|
|
124
|
+
| `consumeLink({ request, digest, person, now, returnTo })` | In one transaction recheck proof unused/not revoked/not expired, tenant, person ID/version/email/status and domain policy; consume once and issue a native session with a persisted fresh app-local proof. Return completed session after commit. Use the proof's stored safe return. |
|
|
125
|
+
| `revokeLink(id, now)` | Durably revoke even on uncertain delivery; errors propagate, never claim success. |
|
|
126
|
+
| `stepUpChallenge(record, actor)` | Store digest/action/return/expiry bound to this exact current session and person version. Recheck full current session authority atomically. |
|
|
127
|
+
| `stepUpPreview(digest, now)` | Inert read of the unconsumed live challenge. |
|
|
128
|
+
| `consumeStepUp(digest, actor, now)` | Recheck asking session ID, current person ID/version/email/status, revocation/expiry and provider authority; consume once and record local proof on that same session atomically. Issue no new session. |
|
|
129
|
+
| `revokeStepUp(id, now)` | Durably revoke the challenge after rejected, thrown or uncertain mail delivery. |
|
|
130
|
+
| `steppedUp(actor, since, now)` | Re-read current session/person authority and persisted local proof, with proof time between `since` and `now` and matching person version. Never infer proof from provider authentication. |
|
|
131
|
+
|
|
132
|
+
Use a database transaction such as D1 `batch` with an aborting guard and unique
|
|
133
|
+
proof digest. A preview/read followed by an unguarded consume and session insert
|
|
134
|
+
is **not** sufficient: restart, simultaneous confirmations and authority changes
|
|
135
|
+
must never yield a second or unauthorized session. A SQL update followed by a
|
|
136
|
+
`changes() = 1` abort guard in the same transaction is one workable approach.
|
|
137
|
+
All provider actor mutations repeat the stored generation, pin and 24-hour cap
|
|
138
|
+
inside the transaction, as well as person/session checks; an outer
|
|
139
|
+
`requireStepUp` read can race with revocation or a policy change.
|
|
140
|
+
|
|
141
|
+
GET/HEAD remain inert. Confirmation requires same-origin POST; unknown addresses
|
|
142
|
+
receive the same accepted response. Returned paths are stored after
|
|
143
|
+
`safeReturnTo`. Mail rejection, exception, rate-limit or uncertain status revokes
|
|
144
|
+
the issued proof. `development` mail counts only in configured local mode.
|
|
145
|
+
Step-up lasts ten minutes and only an app-local email proof can satisfy it.
|
|
146
|
+
The separate provider email-trust rule remains thirty days, including already
|
|
147
|
+
bound subjects and explicit associations with an asserted stale proof.
|
|
148
|
+
|
|
149
|
+
## Optional capabilities and refusals
|
|
150
|
+
|
|
151
|
+
There is no OA fallback for native account administration, invitations, role or
|
|
152
|
+
status mutations, listing/revoking arbitrary sessions, domain/provider owner
|
|
153
|
+
administration or credential minting. Those service methods return
|
|
154
|
+
`native_capability_unavailable` (501). Keep the native administration UI/routes;
|
|
155
|
+
use `requireStepUp` for owner-sensitive writes and repeat its proof/authority
|
|
156
|
+
conditions in that route's atomic mutation. This includes owner invitations,
|
|
157
|
+
reissue/cancellation, owner activation/deactivation, grants/removals, transfer
|
|
158
|
+
and owner dev provisioning.
|
|
159
|
+
|
|
160
|
+
Optional native methods are deliberately explicit:
|
|
161
|
+
|
|
162
|
+
- `issueLocalSession` enables server-verified password admission and loopback
|
|
163
|
+
review. It rechecks person/version/domain policy; password issuance additionally
|
|
164
|
+
requires no provider binding and a still-valid native password credential.
|
|
165
|
+
The caller owns real password verification and its rate limiting.
|
|
166
|
+
- `bootstrap` enables setup-token owner/session creation. It must claim exactly
|
|
167
|
+
one native owner atomically. The service verifies configured setup token,
|
|
168
|
+
origin, allow list and rate limits before invoking it. Without durable native
|
|
169
|
+
dependency setup provenance it must close first-setup identity eligibility in
|
|
170
|
+
that transaction. A stale `first_setup` flag is never permission to enable
|
|
171
|
+
provider sign-in on an ordinary owner-approved link.
|
|
172
|
+
- `completeLocalSetup` runs only behind the existing local CLI proof and with a
|
|
173
|
+
current owner. Its native mutation still owns its authority fence.
|
|
174
|
+
- `setIdentitySettings` fences the current owner/session, audits the setting,
|
|
175
|
+
increments the durable policy generation and revokes native provider sessions
|
|
176
|
+
on disable. Missing `identityEnabled` storage must mean off.
|
|
177
|
+
- `currentBoundSubject` is required for provider-session editor authority. No
|
|
178
|
+
method/no unique current subject means the editor grant is refused.
|
|
179
|
+
- `checkCredentialFence` enables fence checks for native minted credentials.
|
|
180
|
+
Missing/null fences, inactive people and old versions are refused. It is not a
|
|
181
|
+
native credential mint implementation; keep the edition's credential routes.
|
|
182
|
+
|
|
183
|
+
## Incumbent callback and legacy trust
|
|
184
|
+
|
|
185
|
+
Configure `redirectUri` explicitly for an incumbent callback, for example
|
|
186
|
+
`https://slate.example/api/auth/identity/callback`. Both exported HTTP handlers
|
|
187
|
+
own the selected callback even outside `/auth/oidc/`. The default remains
|
|
188
|
+
`/auth/oidc/<id>/callback`; once overridden that old path is unowned. The same
|
|
189
|
+
selected URI is used in authorization and token exchange. Foreign origins,
|
|
190
|
+
credentials, query/hash components, duplicate callback paths and conflicts with
|
|
191
|
+
shared auth/dependency routes are refused. Callback or policy changes invalidate
|
|
192
|
+
outstanding transactions; protocol state/cookie/issuer/audience/nonce/algorithm
|
|
193
|
+
and replay checks are unchanged.
|
|
194
|
+
|
|
195
|
+
The opt-in `preset: 'legacy-rs256'` trusts an incumbent issuer's signed
|
|
196
|
+
`email_verified: true`, with missing proof time counted at that sign-in. It
|
|
197
|
+
requires explicit exact `issuer` and `endpointPins: { authorization, token,
|
|
198
|
+
jwks }`, all HTTPS and allowed by `endpointOrigins`. Discovery must match these
|
|
199
|
+
pins, and the real RS256 signature must verify. Supplied malformed, stale or
|
|
200
|
+
future timestamps never become the current time. Normal Auth dated-email,
|
|
201
|
+
Google's gmail/hd rule, and subject-only Microsoft/Okta remain unchanged. This
|
|
202
|
+
preset is not a configurable bypass on those presets. Trust-preset/issuer/client
|
|
203
|
+
changes keep the existing pin pending an owner-approved re-link; endpoint
|
|
204
|
+
metadata changes refuse until the pin is explicitly re-linked. Any requested
|
|
205
|
+
trust/configuration change also changes the transaction fingerprint.
|
|
206
|
+
|
|
207
|
+
## Dependency reuse and migrations
|
|
208
|
+
|
|
209
|
+
Apply **only** `identity/oidc/schema/oidc.sql` for shared identity storage, and
|
|
210
|
+
`modules/dependencies/schema/dependencies.sql` followed by
|
|
211
|
+
`modules/dependencies/schema/approval-attempt.sql` if dependency linking is enabled.
|
|
212
|
+
Existing native adopters add `approval-attempt.sql` as a new numbered migration;
|
|
213
|
+
it invalidates old approvals, which must be renewed through local owner proof.
|
|
214
|
+
Their `oa_oidc_*`, `oa_identity_providers` and provider-health names are identity
|
|
215
|
+
storage, not account storage. Do not install any `accounts/schema/*.sql` for a
|
|
216
|
+
native seed, including `accounts/schema/dependency-setup.sql`. Add native
|
|
217
|
+
proof/rate/session authority columns/tables in new
|
|
218
|
+
numbered migrations; never edit applied migrations or copy OA people/sessions.
|
|
219
|
+
Preserve native roles, IDs, membership/workspace/project and existing sessions.
|
|
220
|
+
|
|
221
|
+
With `config.dependencies: true`, supply the complete
|
|
222
|
+
`accounts.dependencies: NativeDependencyAuthority<R>` capability. Missing or
|
|
223
|
+
partial capability refuses construction. `createDependencies({ auth, ... })`
|
|
224
|
+
and `linkedProviders` reuse the existing auth-6 pull/discovery/redemption/pinning
|
|
225
|
+
protocol; there is no second linking implementation. The native capability
|
|
226
|
+
contributes SQL fences and D1 statements to its **same** transaction:
|
|
227
|
+
|
|
228
|
+
- `unclaimed()` checks native ownership, never OA people. Optional `claimOwner`
|
|
229
|
+
accepts the verified owner claim using native durable claim semantics; without
|
|
230
|
+
it the claim is refused. A supplied native `bootstrap` is a separate setup-token
|
|
231
|
+
path and does not imply support for identity-provider owner claim.
|
|
232
|
+
- Every callback needs a fresh ten-minute app-local approval obtained through
|
|
233
|
+
`/auth/dependencies/relink` with the current owner's fresh local email proof.
|
|
234
|
+
Configured issuer, existing link and provider continuity never replace it.
|
|
235
|
+
- `ownerFence` and `approvalFence` repeat current tenant/owner/session/version,
|
|
236
|
+
fresh local proof and provider pin/generation/24h authority inside the shared
|
|
237
|
+
mutation transaction. Shared code always checks the captured `attempt_id`,
|
|
238
|
+
issuer/callback set, expiry and exact approving person/session/version both
|
|
239
|
+
before network I/O and at commit. `approvalFence` contributes native authority
|
|
240
|
+
for that snapshot; it does not need to duplicate the shared pending query.
|
|
241
|
+
Replacing an approval invalidates an in-flight callback without consuming the
|
|
242
|
+
replacement or changing the link, key, settings or audit.
|
|
243
|
+
- `linkedStatements` receives that `pending` snapshot, closes stale setup
|
|
244
|
+
eligibility, advances generation and revokes native sessions from changed
|
|
245
|
+
links. An ordinary existing-owner approval must preserve disabled identity;
|
|
246
|
+
never enable it from `first_setup` alone. Owner settings and setup eligibility
|
|
247
|
+
remain seed-owned. A provider move lifts native domain rules naming the old
|
|
248
|
+
provider.
|
|
249
|
+
- `unlinkStatements` revokes native sessions, lifts domain rules, advances
|
|
250
|
+
generation and records native audit rows. Shared code deletes the link,
|
|
251
|
+
private key and pending approval, preserves the sector, and updates the
|
|
252
|
+
identity pin in the same transaction. Native setup authority, if a seed later
|
|
253
|
+
supports it, must also be deleted by this native contribution.
|
|
254
|
+
- `consumeLogout` receives a cryptographically verified logout and pinned link.
|
|
255
|
+
Atomically recheck that exact dependency link and current native binding,
|
|
256
|
+
resolve/check `sub`/`sid`, claim the unique `(issuer,jti)` once, revoke the
|
|
257
|
+
intended native provider sessions, and bump the native person fence for a
|
|
258
|
+
fence event. The bump must invalidate **all** that person's fenced sessions
|
|
259
|
+
and minted credentials. Shared code retains the full signature/issuer/audience/
|
|
260
|
+
time/events/nonce validation. Return false for refused/replayed consumption.
|
|
261
|
+
|
|
262
|
+
Static incumbent providers remain visible beside linked Auth. `auth` and its
|
|
263
|
+
callback are reserved when the dependency is enabled. Shared owner-claim,
|
|
264
|
+
dev-entry, key-exchange and persona routes also refuse callback overrides.
|
|
265
|
+
|
|
266
|
+
Dependency setup before the first native owner is an **optional, currently
|
|
267
|
+
unsupported capability**. The composed service exposes `authorizeDependencySetup`
|
|
268
|
+
but explicitly refuses it with `native_capability_unavailable` (501).
|
|
269
|
+
`/auth/dependencies/setup` refuses before OA SQL, pending approval or key mutation,
|
|
270
|
+
even with a valid setup token or local CLI proof. No OA setup migration supplies
|
|
271
|
+
native authority, and `bootstrap` or `claimOwner` alone does not enable this route.
|
|
272
|
+
Existing native installs can link immediately after their owner's ordinary
|
|
273
|
+
email confirmation or step-up. New native installs must first claim an owner
|
|
274
|
+
through their supported native bootstrap, then obtain that same local proof.
|
|
275
|
+
An empty native install cannot use an initial dependency link for IdP owner
|
|
276
|
+
claim through this composition; seed integrations requiring that journey must
|
|
277
|
+
add and verify native setup provenance first.
|
|
278
|
+
|
|
279
|
+
Supporting that optional journey in future requires one atomic native setup
|
|
280
|
+
contribution to this same protocol: unclaimed/setup-token or loopback CLI
|
|
281
|
+
authority, unique attempt, native bootstrap owner/version/exact session/expiry,
|
|
282
|
+
current provider policy and pin where applicable, and completion/replacement
|
|
283
|
+
and unlink provenance. It must not create a parallel approval protocol or query
|
|
284
|
+
OA account/session/setup tables. Until supplied, refusal is deliberate.
|
|
285
|
+
|
|
286
|
+
## Slate and HappyToHelp continuation
|
|
287
|
+
|
|
288
|
+
`withDevIdentity` remains Base's OA-specific local persona wrapper; do not mount
|
|
289
|
+
it over a native seed. Native dev entry/persona provisioning remains the seed's
|
|
290
|
+
responsibility, with the shared dev key gate and owner-proof rules. The composed
|
|
291
|
+
native service reads already-issued native dev sessions only behind that gate.
|
|
292
|
+
|
|
293
|
+
Slate's prepared identity-only adapter is a starting point, not ready to mount:
|
|
294
|
+
add native session lookup/signout, durable person authority revisions, proof
|
|
295
|
+
persistence and atomic provider binding/issuance. Keep its server-selected
|
|
296
|
+
workspace, member IDs, groups/guest roles and native cookie; configure its exact
|
|
297
|
+
`/api/auth/identity/callback` and incumbent issuer/endpoints. Preserve historical
|
|
298
|
+
bindings and live native sessions. Retire the native identity engine only after
|
|
299
|
+
its real integration and previous-store fixture passes with the new migrations.
|
|
300
|
+
|
|
301
|
+
HappyToHelp supplies its owner/admin/operator/contact role union unchanged and
|
|
302
|
+
selects project/account scope server-side. End-customer widget sessions remain
|
|
303
|
+
outside this staff service. Keep password verification for unbound accounts;
|
|
304
|
+
provider binding must atomically revoke password authority. Its optional `idp`
|
|
305
|
+
claim needs its own atomic native owner claim adapter and may ask for a password
|
|
306
|
+
afterwards only if the product still offers passwords. Provider-issued editor
|
|
307
|
+
grants require the current native owner and current bound issuer/subject.
|
|
308
|
+
|
|
309
|
+
The real workerd/D1 native fixture in `tests/native/` demonstrates these
|
|
310
|
+
transactions with no OA account/session tables. It is test data, not a seed
|
|
311
|
+
schema to copy blindly. The declarations compile a different native role union
|
|
312
|
+
in `tests/native-types.check.mts`. Each seed still must prove its own native
|
|
313
|
+
adapter and applied migrations; Base verification does not certify a cutover.
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
# TanStack Start adoption
|
|
2
|
+
|
|
3
|
+
Keep auth, D1, mail construction and Worker bindings in server-owned modules.
|
|
4
|
+
The client-importable server-function wrapper may be a normal `.ts` file, but
|
|
5
|
+
load true server modules dynamically inside each handler, following
|
|
6
|
+
[`TANSTACK-START-MIGRATION.md`](../../../TANSTACK-START-MIGRATION.md). A route's
|
|
7
|
+
parent session check protects its document; every child server function that
|
|
8
|
+
reads or changes private data must check the session again before its first
|
|
9
|
+
private operation.
|
|
10
|
+
|
|
11
|
+
## Build the server instance
|
|
12
|
+
|
|
13
|
+
The following server module keeps a fixed canonical origin, accepts the actual
|
|
14
|
+
Worker bindings, uses the selected IF-056 mail sender, and never exports auth
|
|
15
|
+
configuration to route data:
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
// src/core/platform/operator-auth.server.ts
|
|
19
|
+
import { createMailSender } from '../../../modules/mail/index.mjs'
|
|
20
|
+
import { createOperatorAuth, createAuthHandler } from '../../../modules/operator-auth/index.mjs'
|
|
21
|
+
|
|
22
|
+
const appOrigin = 'https://app.example.com'
|
|
23
|
+
|
|
24
|
+
export interface OperatorBindings {
|
|
25
|
+
DB: D1Database
|
|
26
|
+
OWNER_EMAIL: string
|
|
27
|
+
SESSION_SECRET: string
|
|
28
|
+
SETUP_TOKEN?: string
|
|
29
|
+
MAIL_FROM?: string
|
|
30
|
+
MAIL_PROVIDER?: 'sendgrid' | 'resend' | 'cloudflare'
|
|
31
|
+
MAIL_API_KEY?: string
|
|
32
|
+
MAIL_ACCOUNT_ID?: string
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function operatorAuth(bindings: OperatorBindings) {
|
|
36
|
+
// Secrets are Worker secret bindings, never source text.
|
|
37
|
+
const { SESSION_SECRET, SETUP_TOKEN, MAIL_API_KEY: apiKey } = bindings
|
|
38
|
+
const mailSender = bindings.MAIL_PROVIDER && apiKey && bindings.MAIL_FROM
|
|
39
|
+
? createMailSender({
|
|
40
|
+
provider: bindings.MAIL_PROVIDER,
|
|
41
|
+
mode: 'production',
|
|
42
|
+
apiKey,
|
|
43
|
+
...(bindings.MAIL_ACCOUNT_ID ? { accountId: bindings.MAIL_ACCOUNT_ID } : {}),
|
|
44
|
+
})
|
|
45
|
+
: undefined
|
|
46
|
+
|
|
47
|
+
return createOperatorAuth({
|
|
48
|
+
db: bindings.DB,
|
|
49
|
+
config: {
|
|
50
|
+
origin: appOrigin,
|
|
51
|
+
OWNER_EMAIL: bindings.OWNER_EMAIL,
|
|
52
|
+
SESSION_SECRET,
|
|
53
|
+
...(SETUP_TOKEN ? { SETUP_TOKEN } : {}),
|
|
54
|
+
...(bindings.MAIL_FROM ? { MAIL_FROM: bindings.MAIL_FROM } : {}),
|
|
55
|
+
},
|
|
56
|
+
mailSender,
|
|
57
|
+
// Trust this header only when Cloudflare is the public Worker boundary.
|
|
58
|
+
clientIp: (request) => request.headers.get('CF-Connecting-IP') ?? '',
|
|
59
|
+
})
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function authHandler(bindings: OperatorBindings) {
|
|
63
|
+
return createAuthHandler(operatorAuth(bindings))
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
The optional mail construction is solely for the first-owner period: bootstrap
|
|
68
|
+
does not need it, while link and invitation requests return `503 mail_unavailable`
|
|
69
|
+
until a real sender and `MAIL_FROM` are configured. It does not select a test or
|
|
70
|
+
alternate provider. On other hosting boundaries, replace the IP resolver with a
|
|
71
|
+
server-verified address source; never use caller-controlled `X-Forwarded-For`.
|
|
72
|
+
|
|
73
|
+
## Mount auth before private APIs and Start
|
|
74
|
+
|
|
75
|
+
Mount the HTTP handler in Hono before protected namespaces and before dispatching
|
|
76
|
+
to Start. Forward the returned `Response` unchanged so its status, redirect and
|
|
77
|
+
`Set-Cookie` are retained. If OIDC is enabled, invoke its handler first at its
|
|
78
|
+
own exact paths, then invoke this core handler.
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
// src/core/app/hono.ts
|
|
82
|
+
import { Hono, type Context, type Next } from 'hono'
|
|
83
|
+
import start from '@tanstack/react-start/server-entry'
|
|
84
|
+
import { authHandler, operatorAuth, type OperatorBindings } from '../platform/operator-auth.server'
|
|
85
|
+
import type { Session } from '../../../modules/operator-auth/index.mjs'
|
|
86
|
+
|
|
87
|
+
const app = new Hono<{ Bindings: OperatorBindings; Variables: { operatorSession: Session } }>()
|
|
88
|
+
|
|
89
|
+
app.all('/auth/*', async (context) => {
|
|
90
|
+
const response = await authHandler(context.env)(context.req.raw)
|
|
91
|
+
return response ?? context.notFound()
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
const protectPrivate = async (context: Context<{ Bindings: OperatorBindings; Variables: { operatorSession: Session } }>, next: Next) => {
|
|
95
|
+
const session = await operatorAuth(context.env).getSession(context.req.raw)
|
|
96
|
+
if (!session) return context.json({ error: 'unauthenticated' }, 401)
|
|
97
|
+
context.set('operatorSession', session)
|
|
98
|
+
await next()
|
|
99
|
+
}
|
|
100
|
+
app.use('/api/private', protectPrivate)
|
|
101
|
+
app.use('/api/private/*', protectPrivate)
|
|
102
|
+
|
|
103
|
+
app.get('/api/private/profile', (context) => {
|
|
104
|
+
const session = context.get('operatorSession')
|
|
105
|
+
return context.json({ operator: { id: session.operator.id, role: session.operator.role } })
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
// Add every existing Hono-owned API path to this explicit predicate.
|
|
109
|
+
// Keep queue, scheduled, email and named Worker exports on this Worker.
|
|
110
|
+
function isHonoRequest(pathname: string) {
|
|
111
|
+
return pathname === '/auth' || pathname.startsWith('/auth/') ||
|
|
112
|
+
pathname === '/api/private' || pathname.startsWith('/api/private/')
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export default {
|
|
116
|
+
fetch(request: Request, bindings: OperatorBindings, execution: ExecutionContext) {
|
|
117
|
+
return isHonoRequest(new URL(request.url).pathname)
|
|
118
|
+
? app.fetch(request, bindings, execution)
|
|
119
|
+
: start.fetch(request)
|
|
120
|
+
},
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
For a private mutation, validate the application's normal exact-Origin and
|
|
125
|
+
Fetch-Metadata policy, validate the input, then call `getSession` on the actual
|
|
126
|
+
same-origin request before the first private read or write. The auth handler
|
|
127
|
+
already checks POST, exact configured Origin, Host, and Fetch Metadata for its
|
|
128
|
+
own mutation routes. Keep Start's default server-function CSRF middleware; if a
|
|
129
|
+
custom `src/start.ts` replaces it, preserve
|
|
130
|
+
`createCsrfMiddleware({ filter: (ctx) => ctx.handlerType === 'serverFn' })`.
|
|
131
|
+
|
|
132
|
+
## Protect documents and server functions
|
|
133
|
+
|
|
134
|
+
Keep the wrapper importable from routes, then dynamically load auth and bindings
|
|
135
|
+
inside the handler. The code below follows the repository's pinned Start 1.168.50
|
|
136
|
+
pattern. `requestBindings()` is the product's existing server-only binding
|
|
137
|
+
accessor.
|
|
138
|
+
|
|
139
|
+
```ts
|
|
140
|
+
// src/core/app/loaders.ts
|
|
141
|
+
import { createServerFn } from '@tanstack/react-start'
|
|
142
|
+
import { redirect } from '@tanstack/react-router'
|
|
143
|
+
|
|
144
|
+
export const requireOperator = createServerFn({ method: 'GET' }).handler(async () => {
|
|
145
|
+
const [{ operatorAuth }, { requestBindings }, { getRequestHeader }] = await Promise.all([
|
|
146
|
+
import('../platform/operator-auth.server'),
|
|
147
|
+
import('../platform/bindings.server'),
|
|
148
|
+
import('@tanstack/react-start/server'),
|
|
149
|
+
])
|
|
150
|
+
const bindings = requestBindings()
|
|
151
|
+
const auth = operatorAuth(bindings)
|
|
152
|
+
const headers = new Headers({ cookie: getRequestHeader('cookie') ?? '' })
|
|
153
|
+
const host = getRequestHeader('host')
|
|
154
|
+
if (host) headers.set('host', host)
|
|
155
|
+
const session = await auth.getSession(new Request('https://app.example.com/', { headers }))
|
|
156
|
+
if (!session) throw redirect({ to: '/signin' })
|
|
157
|
+
return { id: session.operator.id, email: session.operator.email, role: session.operator.role }
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
export const loadOperatorRoster = createServerFn({ method: 'GET' }).handler(async () => {
|
|
161
|
+
const [{ operatorAuth }, { requestBindings }, { getRequestHeader }] = await Promise.all([
|
|
162
|
+
import('../platform/operator-auth.server'),
|
|
163
|
+
import('../platform/bindings.server'),
|
|
164
|
+
import('@tanstack/react-start/server'),
|
|
165
|
+
])
|
|
166
|
+
const bindings = requestBindings()
|
|
167
|
+
const auth = operatorAuth(bindings)
|
|
168
|
+
const headers = new Headers({ cookie: getRequestHeader('cookie') ?? '' })
|
|
169
|
+
const host = getRequestHeader('host')
|
|
170
|
+
if (host) headers.set('host', host)
|
|
171
|
+
const session = await auth.getSession(new Request('https://app.example.com/', { headers }))
|
|
172
|
+
if (!session) throw redirect({ to: '/signin' })
|
|
173
|
+
return auth.listOperators(new Request('https://app.example.com/', { headers }))
|
|
174
|
+
})
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Replace the example origin and queue service with the product's fixed canonical
|
|
178
|
+
origin and real service. Never derive the configured origin from Host or forwarded
|
|
179
|
+
headers. Preserve the incoming Host header when available so the core can reject
|
|
180
|
+
an unexpected authority. Do not return `CompletedSession.cookie`, setup token,
|
|
181
|
+
mail configuration or D1 objects from a server function. Returning the small
|
|
182
|
+
operator record is safe; role checks still belong on each server-side action.
|
|
183
|
+
|
|
184
|
+
Mount `requireOperator()` at the private document boundary and call an equivalent
|
|
185
|
+
session check inside every private server-function handler. The roster example
|
|
186
|
+
then calls the module's real `listOperators` API, which applies its role policy
|
|
187
|
+
again. The browser-visible
|
|
188
|
+
generated RPC ID is not authorization; direct requests to a private server
|
|
189
|
+
function must reach the same session denial before any product data or mutation.
|
|
190
|
+
|
|
191
|
+
## One-time owner bootstrap
|
|
192
|
+
|
|
193
|
+
Provision `OWNER_EMAIL`, `SESSION_SECRET`, and `SETUP_TOKEN` in server bindings.
|
|
194
|
+
Generate independent high-entropy values (for example, two separate
|
|
195
|
+
`openssl rand -hex 32` invocations for the secrets). Keep `SETUP_TOKEN` out of
|
|
196
|
+
HTML, forms, `VITE_*`, and client RPC arguments. The owner-controlled setup
|
|
197
|
+
operation must invoke the actual POST `/auth/bootstrap` contract while keeping
|
|
198
|
+
the token in server-only input; it succeeds once, creates only the configured
|
|
199
|
+
owner and native session, and works with no mail sender. Verify the session, then
|
|
200
|
+
remove `SETUP_TOKEN`. A second setup call is rejected; changing the token does
|
|
201
|
+
not reset the bootstrap ledger. Do not seed an owner or demo product rows as a
|
|
202
|
+
side effect of a sign-in or OIDC request.
|
|
203
|
+
|
|
204
|
+
After setup, configure `MAIL_PROVIDER`, `MAIL_API_KEY`, optional Cloudflare
|
|
205
|
+
`MAIL_ACCOUNT_ID`, and `MAIL_FROM` as server bindings. IF-056 `accepted` means the
|
|
206
|
+
provider accepted the submission, not that the mailbox received it. `rejected`,
|
|
207
|
+
`rate_limited`, and `uncertain` results do not leave a usable auth link; callers
|
|
208
|
+
see a redacted `503`. Reconcile an uncertain send before deciding whether to
|
|
209
|
+
issue a new link. The auth module never retries or selects another sender.
|
|
210
|
+
|
|
211
|
+
## Optional local review
|
|
212
|
+
|
|
213
|
+
Enable `review:{enabled:true,operatorEmail}` only in a local review configuration
|
|
214
|
+
with an existing active operator. Bind the Worker to loopback. The issue request
|
|
215
|
+
must be POST with the exact local Origin and a matching literal loopback Host;
|
|
216
|
+
the cookie is local-only and each request is checked against the loopback
|
|
217
|
+
boundary. Forwarded headers do not make a public listener local. Disable review
|
|
218
|
+
in production and never create a fixture operator for it.
|