@raybase/core 0.0.1 → 0.3.3
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/dist/.admin-build/AdminApp.css +2 -0
- package/dist/.admin-build/AdminApp.js +77 -0
- package/dist/.admin-docs-build/AdminDocsApp.css +2 -0
- package/dist/.admin-docs-build/AdminDocsApp.js +45 -0
- package/dist/actions.d.ts +347 -0
- package/dist/actions.d.ts.map +1 -0
- package/dist/actions.js +661 -0
- package/dist/actions.js.map +1 -0
- package/dist/admin-assets/admin.7738f50720a8ed7b.css +2 -0
- package/dist/admin-assets/admin.8678cb61db34dc81.js +77 -0
- package/dist/admin-boot.d.ts +94 -0
- package/dist/admin-boot.d.ts.map +1 -0
- package/dist/admin-boot.js +139 -0
- package/dist/admin-boot.js.map +1 -0
- package/dist/admin-docs-content.d.ts +95 -0
- package/dist/admin-docs-content.d.ts.map +1 -0
- package/dist/admin-docs-content.js +463 -0
- package/dist/admin-docs-content.js.map +1 -0
- package/dist/admin-docs-ui.d.ts +11 -0
- package/dist/admin-docs-ui.d.ts.map +1 -0
- package/dist/admin-docs-ui.js +23 -0
- package/dist/admin-docs-ui.js.map +1 -0
- package/dist/admin-kit.d.ts +29 -0
- package/dist/admin-kit.js +1557 -0
- package/dist/admin-role.d.ts +8 -0
- package/dist/admin-role.d.ts.map +1 -0
- package/dist/admin-role.js +22 -0
- package/dist/admin-role.js.map +1 -0
- package/dist/admin-ui.d.ts +3 -0
- package/dist/admin-ui.d.ts.map +1 -0
- package/dist/admin-ui.js +16 -0
- package/dist/admin-ui.js.map +1 -0
- package/dist/agent-ai-chat.d.ts +127 -0
- package/dist/agent-ai-chat.d.ts.map +1 -0
- package/dist/agent-ai-chat.js +5975 -0
- package/dist/agent-ai-chat.js.map +1 -0
- package/dist/agent-chapter-archive.d.ts +214 -0
- package/dist/agent-chapter-archive.d.ts.map +1 -0
- package/dist/agent-chapter-archive.js +696 -0
- package/dist/agent-chapter-archive.js.map +1 -0
- package/dist/agent-chapter-search.d.ts +116 -0
- package/dist/agent-chapter-search.d.ts.map +1 -0
- package/dist/agent-chapter-search.js +605 -0
- package/dist/agent-chapter-search.js.map +1 -0
- package/dist/agent-chapter-tools.d.ts +45 -0
- package/dist/agent-chapter-tools.d.ts.map +1 -0
- package/dist/agent-chapter-tools.js +344 -0
- package/dist/agent-chapter-tools.js.map +1 -0
- package/dist/agent-chapters.d.ts +228 -0
- package/dist/agent-chapters.d.ts.map +1 -0
- package/dist/agent-chapters.js +737 -0
- package/dist/agent-chapters.js.map +1 -0
- package/dist/agent-data-parts.d.ts +167 -0
- package/dist/agent-data-parts.d.ts.map +1 -0
- package/dist/agent-data-parts.js +68 -0
- package/dist/agent-data-parts.js.map +1 -0
- package/dist/agent-errors.d.ts +41 -0
- package/dist/agent-errors.d.ts.map +1 -0
- package/dist/agent-errors.js +191 -0
- package/dist/agent-errors.js.map +1 -0
- package/dist/agent-follow-up-store.d.ts +273 -0
- package/dist/agent-follow-up-store.d.ts.map +1 -0
- package/dist/agent-follow-up-store.js +703 -0
- package/dist/agent-follow-up-store.js.map +1 -0
- package/dist/agent-follow-ups.d.ts +314 -0
- package/dist/agent-follow-ups.d.ts.map +1 -0
- package/dist/agent-follow-ups.js +840 -0
- package/dist/agent-follow-ups.js.map +1 -0
- package/dist/agent-memory.d.ts +323 -0
- package/dist/agent-memory.d.ts.map +1 -0
- package/dist/agent-memory.js +1270 -0
- package/dist/agent-memory.js.map +1 -0
- package/dist/agent-message-parts.d.ts +58 -0
- package/dist/agent-message-parts.d.ts.map +1 -0
- package/dist/agent-message-parts.js +163 -0
- package/dist/agent-message-parts.js.map +1 -0
- package/dist/agent-remote-mcp-credentials.d.ts +154 -0
- package/dist/agent-remote-mcp-credentials.d.ts.map +1 -0
- package/dist/agent-remote-mcp-credentials.js +287 -0
- package/dist/agent-remote-mcp-credentials.js.map +1 -0
- package/dist/agent-remote-mcp-crypto.d.ts +32 -0
- package/dist/agent-remote-mcp-crypto.d.ts.map +1 -0
- package/dist/agent-remote-mcp-crypto.js +101 -0
- package/dist/agent-remote-mcp-crypto.js.map +1 -0
- package/dist/agent-remote-mcp-install.d.ts +299 -0
- package/dist/agent-remote-mcp-install.d.ts.map +1 -0
- package/dist/agent-remote-mcp-install.js +785 -0
- package/dist/agent-remote-mcp-install.js.map +1 -0
- package/dist/agent-remote-mcp-oauth.d.ts +73 -0
- package/dist/agent-remote-mcp-oauth.d.ts.map +1 -0
- package/dist/agent-remote-mcp-oauth.js +344 -0
- package/dist/agent-remote-mcp-oauth.js.map +1 -0
- package/dist/agent-remote-mcp-transport.d.ts +46 -0
- package/dist/agent-remote-mcp-transport.d.ts.map +1 -0
- package/dist/agent-remote-mcp-transport.js +225 -0
- package/dist/agent-remote-mcp-transport.js.map +1 -0
- package/dist/agent-remote-mcp.d.ts +147 -0
- package/dist/agent-remote-mcp.d.ts.map +1 -0
- package/dist/agent-remote-mcp.js +681 -0
- package/dist/agent-remote-mcp.js.map +1 -0
- package/dist/agent-room-redaction.d.ts +66 -0
- package/dist/agent-room-redaction.d.ts.map +1 -0
- package/dist/agent-room-redaction.js +264 -0
- package/dist/agent-room-redaction.js.map +1 -0
- package/dist/agent-rooms.d.ts +209 -0
- package/dist/agent-rooms.d.ts.map +1 -0
- package/dist/agent-rooms.js +244 -0
- package/dist/agent-rooms.js.map +1 -0
- package/dist/agent-runtime.d.ts +541 -0
- package/dist/agent-runtime.d.ts.map +1 -0
- package/dist/agent-runtime.js +4260 -0
- package/dist/agent-runtime.js.map +1 -0
- package/dist/agent-skill-archive.d.ts +20 -0
- package/dist/agent-skill-archive.d.ts.map +1 -0
- package/dist/agent-skill-archive.js +316 -0
- package/dist/agent-skill-archive.js.map +1 -0
- package/dist/agent-skill-discovery.d.ts +96 -0
- package/dist/agent-skill-discovery.d.ts.map +1 -0
- package/dist/agent-skill-discovery.js +464 -0
- package/dist/agent-skill-discovery.js.map +1 -0
- package/dist/agent-skill-format.d.ts +57 -0
- package/dist/agent-skill-format.d.ts.map +1 -0
- package/dist/agent-skill-format.js +238 -0
- package/dist/agent-skill-format.js.map +1 -0
- package/dist/agent-skill-import.d.ts +64 -0
- package/dist/agent-skill-import.d.ts.map +1 -0
- package/dist/agent-skill-import.js +295 -0
- package/dist/agent-skill-import.js.map +1 -0
- package/dist/agent-skill-publish.d.ts +51 -0
- package/dist/agent-skill-publish.d.ts.map +1 -0
- package/dist/agent-skill-publish.js +136 -0
- package/dist/agent-skill-publish.js.map +1 -0
- package/dist/agent-skill-store.d.ts +252 -0
- package/dist/agent-skill-store.d.ts.map +1 -0
- package/dist/agent-skill-store.js +514 -0
- package/dist/agent-skill-store.js.map +1 -0
- package/dist/agent-skills.d.ts +85 -0
- package/dist/agent-skills.d.ts.map +1 -0
- package/dist/agent-skills.js +291 -0
- package/dist/agent-skills.js.map +1 -0
- package/dist/agent-transcript-pager.d.ts +77 -0
- package/dist/agent-transcript-pager.d.ts.map +1 -0
- package/dist/agent-transcript-pager.js +210 -0
- package/dist/agent-transcript-pager.js.map +1 -0
- package/dist/agent-user-data-parts.d.ts +20 -0
- package/dist/agent-user-data-parts.d.ts.map +1 -0
- package/dist/agent-user-data-parts.js +161 -0
- package/dist/agent-user-data-parts.js.map +1 -0
- package/dist/agent-user-transcript.d.ts +46 -0
- package/dist/agent-user-transcript.d.ts.map +1 -0
- package/dist/agent-user-transcript.js +106 -0
- package/dist/agent-user-transcript.js.map +1 -0
- package/dist/agent-voice-notes.d.ts +15 -0
- package/dist/agent-voice-notes.d.ts.map +1 -0
- package/dist/agent-voice-notes.js +17 -0
- package/dist/agent-voice-notes.js.map +1 -0
- package/dist/agent-wakes.d.ts +213 -0
- package/dist/agent-wakes.d.ts.map +1 -0
- package/dist/agent-wakes.js +534 -0
- package/dist/agent-wakes.js.map +1 -0
- package/dist/agent.d.ts +1780 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +3123 -0
- package/dist/agent.js.map +1 -0
- package/dist/ai.d.ts +583 -0
- package/dist/ai.d.ts.map +1 -0
- package/dist/ai.js +1858 -0
- package/dist/ai.js.map +1 -0
- package/dist/app-manifest.d.ts +255 -0
- package/dist/app-manifest.d.ts.map +1 -0
- package/dist/app-manifest.js +372 -0
- package/dist/app-manifest.js.map +1 -0
- package/dist/app-users.d.ts +30 -0
- package/dist/app-users.d.ts.map +1 -0
- package/dist/app-users.js +91 -0
- package/dist/app-users.js.map +1 -0
- package/dist/audit-archive.d.ts +85 -0
- package/dist/audit-archive.d.ts.map +1 -0
- package/dist/audit-archive.js +178 -0
- package/dist/audit-archive.js.map +1 -0
- package/dist/audit.d.ts +54 -0
- package/dist/audit.d.ts.map +1 -0
- package/dist/audit.js +95 -0
- package/dist/audit.js.map +1 -0
- package/dist/auth-logger.d.ts +28 -0
- package/dist/auth-logger.d.ts.map +1 -0
- package/dist/auth-logger.js +53 -0
- package/dist/auth-logger.js.map +1 -0
- package/dist/auth-password-secret.d.ts +59 -0
- package/dist/auth-password-secret.d.ts.map +1 -0
- package/dist/auth-password-secret.js +409 -0
- package/dist/auth-password-secret.js.map +1 -0
- package/dist/auth-schema.d.ts +120 -0
- package/dist/auth-schema.d.ts.map +1 -0
- package/dist/auth-schema.js +285 -0
- package/dist/auth-schema.js.map +1 -0
- package/dist/auth.d.ts +321 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +1562 -0
- package/dist/auth.js.map +1 -0
- package/dist/backup-archive.d.ts +257 -0
- package/dist/backup-archive.d.ts.map +1 -0
- package/dist/backup-archive.js +2068 -0
- package/dist/backup-archive.js.map +1 -0
- package/dist/backup-crypto.d.ts +313 -0
- package/dist/backup-crypto.d.ts.map +1 -0
- package/dist/backup-crypto.js +693 -0
- package/dist/backup-crypto.js.map +1 -0
- package/dist/backup-format.d.ts +200 -0
- package/dist/backup-format.d.ts.map +1 -0
- package/dist/backup-format.js +1247 -0
- package/dist/backup-format.js.map +1 -0
- package/dist/cli.d.ts +9 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +15 -0
- package/dist/cli.js.map +1 -0
- package/dist/clock.d.ts +35 -0
- package/dist/clock.d.ts.map +1 -0
- package/dist/clock.js +83 -0
- package/dist/clock.js.map +1 -0
- package/dist/data-client.d.ts +187 -0
- package/dist/data-client.d.ts.map +1 -0
- package/dist/data-client.js +590 -0
- package/dist/data-client.js.map +1 -0
- package/dist/data-secrets.d.ts +164 -0
- package/dist/data-secrets.d.ts.map +1 -0
- package/dist/data-secrets.js +383 -0
- package/dist/data-secrets.js.map +1 -0
- package/dist/db.d.ts +453 -0
- package/dist/db.d.ts.map +1 -0
- package/dist/db.js +324 -0
- package/dist/db.js.map +1 -0
- package/dist/dev-activity.d.ts +48 -0
- package/dist/dev-activity.d.ts.map +1 -0
- package/dist/dev-activity.js +50 -0
- package/dist/dev-activity.js.map +1 -0
- package/dist/do.d.ts +429 -0
- package/dist/do.d.ts.map +1 -0
- package/dist/do.js +4526 -0
- package/dist/do.js.map +1 -0
- package/dist/email.d.ts +137 -0
- package/dist/email.d.ts.map +1 -0
- package/dist/email.js +527 -0
- package/dist/email.js.map +1 -0
- package/dist/generated/admin-assets.d.ts +16 -0
- package/dist/generated/admin-assets.d.ts.map +1 -0
- package/dist/generated/admin-assets.js +16 -0
- package/dist/generated/admin-assets.js.map +1 -0
- package/dist/generated/admin-docs-assets.d.ts +3 -0
- package/dist/generated/admin-docs-assets.d.ts.map +1 -0
- package/dist/generated/admin-docs-assets.js +3 -0
- package/dist/generated/admin-docs-assets.js.map +1 -0
- package/dist/handoff-consumer.d.ts +79 -0
- package/dist/handoff-consumer.d.ts.map +1 -0
- package/dist/handoff-consumer.js +300 -0
- package/dist/handoff-consumer.js.map +1 -0
- package/dist/handoff.d.ts +70 -0
- package/dist/handoff.d.ts.map +1 -0
- package/dist/handoff.js +228 -0
- package/dist/handoff.js.map +1 -0
- package/dist/host-auth.d.ts +47 -0
- package/dist/host-auth.d.ts.map +1 -0
- package/dist/host-auth.js +59 -0
- package/dist/host-auth.js.map +1 -0
- package/dist/host-user.d.ts +15 -0
- package/dist/host-user.d.ts.map +1 -0
- package/dist/host-user.js +23 -0
- package/dist/host-user.js.map +1 -0
- package/dist/html.d.ts +35 -0
- package/dist/html.d.ts.map +1 -0
- package/dist/html.js +634 -0
- package/dist/html.js.map +1 -0
- package/dist/http-error.d.ts +13 -0
- package/dist/http-error.d.ts.map +1 -0
- package/dist/http-error.js +15 -0
- package/dist/http-error.js.map +1 -0
- package/dist/imports.d.ts +219 -0
- package/dist/imports.d.ts.map +1 -0
- package/dist/imports.js +571 -0
- package/dist/imports.js.map +1 -0
- package/dist/index.d.ts +78 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +76 -0
- package/dist/index.js.map +1 -0
- package/dist/inference-tape.d.ts +64 -0
- package/dist/inference-tape.d.ts.map +1 -0
- package/dist/inference-tape.js +278 -0
- package/dist/inference-tape.js.map +1 -0
- package/dist/internal.d.ts +15 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +48 -0
- package/dist/internal.js.map +1 -0
- package/dist/jobs.d.ts +796 -0
- package/dist/jobs.d.ts.map +1 -0
- package/dist/jobs.js +538 -0
- package/dist/jobs.js.map +1 -0
- package/dist/json-schema.d.ts +91 -0
- package/dist/json-schema.d.ts.map +1 -0
- package/dist/json-schema.js +884 -0
- package/dist/json-schema.js.map +1 -0
- package/dist/knowledge.d.ts +33 -0
- package/dist/knowledge.d.ts.map +1 -0
- package/dist/knowledge.js +348 -0
- package/dist/knowledge.js.map +1 -0
- package/dist/local-dev-chrome.d.ts +29 -0
- package/dist/local-dev-chrome.d.ts.map +1 -0
- package/dist/local-dev-chrome.js +514 -0
- package/dist/local-dev-chrome.js.map +1 -0
- package/dist/local-dev-personas.d.ts +15 -0
- package/dist/local-dev-personas.d.ts.map +1 -0
- package/dist/local-dev-personas.js +46 -0
- package/dist/local-dev-personas.js.map +1 -0
- package/dist/mcp.d.ts +567 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +2480 -0
- package/dist/mcp.js.map +1 -0
- package/dist/modules.d.ts +145 -0
- package/dist/modules.d.ts.map +1 -0
- package/dist/modules.js +164 -0
- package/dist/modules.js.map +1 -0
- package/dist/notification-client.d.ts +94 -0
- package/dist/notification-client.d.ts.map +1 -0
- package/dist/notification-client.js +127 -0
- package/dist/notification-client.js.map +1 -0
- package/dist/notifications.d.ts +447 -0
- package/dist/notifications.d.ts.map +1 -0
- package/dist/notifications.js +1625 -0
- package/dist/notifications.js.map +1 -0
- package/dist/operator-data-query.d.ts +117 -0
- package/dist/operator-data-query.d.ts.map +1 -0
- package/dist/operator-data-query.js +431 -0
- package/dist/operator-data-query.js.map +1 -0
- package/dist/operator-mcp.d.ts +63 -0
- package/dist/operator-mcp.d.ts.map +1 -0
- package/dist/operator-mcp.js +2828 -0
- package/dist/operator-mcp.js.map +1 -0
- package/dist/outbound-https.d.ts +24 -0
- package/dist/outbound-https.d.ts.map +1 -0
- package/dist/outbound-https.js +172 -0
- package/dist/outbound-https.js.map +1 -0
- package/dist/pitr.d.ts +60 -0
- package/dist/pitr.d.ts.map +1 -0
- package/dist/pitr.js +94 -0
- package/dist/pitr.js.map +1 -0
- package/dist/platform.d.ts +199 -0
- package/dist/platform.d.ts.map +1 -0
- package/dist/platform.js +196 -0
- package/dist/platform.js.map +1 -0
- package/dist/policies.d.ts +115 -0
- package/dist/policies.d.ts.map +1 -0
- package/dist/policies.js +158 -0
- package/dist/policies.js.map +1 -0
- package/dist/principal.d.ts +143 -0
- package/dist/principal.d.ts.map +1 -0
- package/dist/principal.js +174 -0
- package/dist/principal.js.map +1 -0
- package/dist/realtime.d.ts +280 -0
- package/dist/realtime.d.ts.map +1 -0
- package/dist/realtime.js +578 -0
- package/dist/realtime.js.map +1 -0
- package/dist/retrieval.d.ts +263 -0
- package/dist/retrieval.d.ts.map +1 -0
- package/dist/retrieval.js +602 -0
- package/dist/retrieval.js.map +1 -0
- package/dist/runtime-error-client.d.ts +10 -0
- package/dist/runtime-error-client.d.ts.map +1 -0
- package/dist/runtime-error-client.js +70 -0
- package/dist/runtime-error-client.js.map +1 -0
- package/dist/runtime-errors.d.ts +180 -0
- package/dist/runtime-errors.d.ts.map +1 -0
- package/dist/runtime-errors.js +572 -0
- package/dist/runtime-errors.js.map +1 -0
- package/dist/schema.d.ts +434 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +232 -0
- package/dist/schema.js.map +1 -0
- package/dist/search.d.ts +216 -0
- package/dist/search.d.ts.map +1 -0
- package/dist/search.js +785 -0
- package/dist/search.js.map +1 -0
- package/dist/settings.d.ts +191 -0
- package/dist/settings.d.ts.map +1 -0
- package/dist/settings.js +478 -0
- package/dist/settings.js.map +1 -0
- package/dist/sql.d.ts +7 -0
- package/dist/sql.d.ts.map +1 -0
- package/dist/sql.js +30 -0
- package/dist/sql.js.map +1 -0
- package/dist/storage-client.d.ts +69 -0
- package/dist/storage-client.d.ts.map +1 -0
- package/dist/storage-client.js +469 -0
- package/dist/storage-client.js.map +1 -0
- package/dist/storage.d.ts +21 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +82 -0
- package/dist/storage.js.map +1 -0
- package/dist/subject-domains.d.ts +15 -0
- package/dist/subject-domains.d.ts.map +1 -0
- package/dist/subject-domains.js +38 -0
- package/dist/subject-domains.js.map +1 -0
- package/dist/support.d.ts +132 -0
- package/dist/support.d.ts.map +1 -0
- package/dist/support.js +483 -0
- package/dist/support.js.map +1 -0
- package/dist/system-tables.d.ts +12 -0
- package/dist/system-tables.d.ts.map +1 -0
- package/dist/system-tables.js +225 -0
- package/dist/system-tables.js.map +1 -0
- package/dist/test.d.ts +57 -0
- package/dist/test.d.ts.map +1 -0
- package/dist/test.js +454 -0
- package/dist/test.js.map +1 -0
- package/dist/vite.d.ts +82 -0
- package/dist/vite.d.ts.map +1 -0
- package/dist/vite.js +82 -0
- package/dist/vite.js.map +1 -0
- package/dist/webpush-crypto.d.ts +39 -0
- package/dist/webpush-crypto.d.ts.map +1 -0
- package/dist/webpush-crypto.js +213 -0
- package/dist/webpush-crypto.js.map +1 -0
- package/dist/webpush-private.d.ts +11 -0
- package/dist/webpush-private.d.ts.map +1 -0
- package/dist/webpush-private.js +11 -0
- package/dist/webpush-private.js.map +1 -0
- package/dist/webpush.d.ts +86 -0
- package/dist/webpush.d.ts.map +1 -0
- package/dist/webpush.js +375 -0
- package/dist/webpush.js.map +1 -0
- package/dist/worker.d.ts +185 -0
- package/dist/worker.d.ts.map +1 -0
- package/dist/worker.js +13021 -0
- package/dist/worker.js.map +1 -0
- package/package.json +161 -8
- package/README.md +0 -3
package/dist/handoff.js
ADDED
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import { randomId } from "./sql.js";
|
|
2
|
+
import { wallNowMs } from "./clock.js";
|
|
3
|
+
import { sha256Hex } from "./internal.js";
|
|
4
|
+
const textEncoder = new TextEncoder();
|
|
5
|
+
const defaultConsumePath = "/_raybase/handoff/consume";
|
|
6
|
+
const defaultTokenTtlSeconds = 5 * 60;
|
|
7
|
+
const maxTokenTtlSeconds = 15 * 60;
|
|
8
|
+
const localOriginHosts = new Set(["localhost", "127.0.0.1", "::1", "[::1]"]);
|
|
9
|
+
export function handoffEnabled(config) {
|
|
10
|
+
return config.handoff?.enabled === true;
|
|
11
|
+
}
|
|
12
|
+
export function handoffTokenTtlSeconds(config) {
|
|
13
|
+
const configured = config.handoff?.tokenTtlSeconds;
|
|
14
|
+
return Number.isInteger(configured) && configured > 0 ? Math.min(configured, maxTokenTtlSeconds) : defaultTokenTtlSeconds;
|
|
15
|
+
}
|
|
16
|
+
export function handoffResourceById(config, id) {
|
|
17
|
+
return config.handoff?.resources?.find((resource) => resource.id === id) ?? null;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* The `iss` the hub signs with. Configure `handoff.issuer` when the hub is
|
|
21
|
+
* reachable under more than one hostname: consumers pin one issuer string, so
|
|
22
|
+
* whichever hostname a visitor arrived on, the token must say the same thing.
|
|
23
|
+
*/
|
|
24
|
+
export function handoffIssuer(config, requestOrigin) {
|
|
25
|
+
const configured = config.handoff?.issuer?.trim();
|
|
26
|
+
return (configured || requestOrigin).replace(/\/$/, "");
|
|
27
|
+
}
|
|
28
|
+
export function handoffResourceConsumePath(resource) {
|
|
29
|
+
return sanitizeHandoffReturnTo(resource.consumePath, defaultConsumePath);
|
|
30
|
+
}
|
|
31
|
+
export function handoffResourceOriginForEnv(config, resource, env) {
|
|
32
|
+
// The worker env is the only origin channel that tracks the actually running
|
|
33
|
+
// resource (local dev writes it to .dev.vars after picking a free port;
|
|
34
|
+
// deployments set it as a var). The config value is baked in at build time
|
|
35
|
+
// and cannot see runtime port drift. RAYBASE_SITE_ORIGIN is a single value,
|
|
36
|
+
// so it only overrides an unambiguous single-resource config.
|
|
37
|
+
const override = env.RAYBASE_SITE_ORIGIN?.trim();
|
|
38
|
+
if (override && config.handoff?.resources?.length === 1) {
|
|
39
|
+
try {
|
|
40
|
+
const parsed = new URL(override);
|
|
41
|
+
if (parsed.protocol === "http:" || parsed.protocol === "https:")
|
|
42
|
+
return parsed.origin;
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return resource.origin;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return resource.origin;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Every issue that would make the registry unusable at runtime. Called by the
|
|
52
|
+
* worker factory (so a bad registry fails loudly at startup) and by
|
|
53
|
+
* `raybase doctor`.
|
|
54
|
+
*/
|
|
55
|
+
export function validateHandoffConfig(config) {
|
|
56
|
+
const issues = [];
|
|
57
|
+
if (!handoffEnabled(config))
|
|
58
|
+
return issues;
|
|
59
|
+
const resources = config.handoff?.resources ?? [];
|
|
60
|
+
if (!resources.length)
|
|
61
|
+
issues.push("handoff.enabled requires at least one handoff resource.");
|
|
62
|
+
const issuer = config.handoff?.issuer;
|
|
63
|
+
if (issuer !== undefined && !isHandoffIssuerOrigin(issuer)) {
|
|
64
|
+
issues.push("handoff.issuer must be an https origin with no path (http is allowed for localhost only).");
|
|
65
|
+
}
|
|
66
|
+
const ttl = config.handoff?.tokenTtlSeconds;
|
|
67
|
+
if (ttl !== undefined && (!Number.isInteger(ttl) || ttl <= 0 || ttl > maxTokenTtlSeconds)) {
|
|
68
|
+
issues.push(`handoff.tokenTtlSeconds must be a whole number of seconds between 1 and ${maxTokenTtlSeconds}.`);
|
|
69
|
+
}
|
|
70
|
+
const ids = new Set();
|
|
71
|
+
for (const resource of resources) {
|
|
72
|
+
if (!/^[a-z0-9][a-z0-9-]{0,62}$/.test(resource.id ?? ""))
|
|
73
|
+
issues.push(`Handoff resource id "${resource.id}" must be a stable lowercase slug.`);
|
|
74
|
+
if (ids.has(resource.id))
|
|
75
|
+
issues.push(`Handoff resource id "${resource.id}" is duplicated.`);
|
|
76
|
+
ids.add(resource.id);
|
|
77
|
+
if (!resource.label?.trim())
|
|
78
|
+
issues.push(`Handoff resource "${resource.id}" needs a label.`);
|
|
79
|
+
if (!isHandoffOrigin(resource.origin))
|
|
80
|
+
issues.push(`Handoff resource "${resource.id}" needs an https origin (http is allowed for localhost only).`);
|
|
81
|
+
if (resource.kind !== "sso" && resource.kind !== "pass")
|
|
82
|
+
issues.push(`Handoff resource "${resource.id}" must have kind "sso" or "pass".`);
|
|
83
|
+
if (resource.kind === "pass" && resource.app)
|
|
84
|
+
issues.push(`Handoff resource "${resource.id}" is a pass resource and must not name an app; a pass never carries roles.`);
|
|
85
|
+
if (resource.consumePath !== undefined && !isHandoffPath(resource.consumePath))
|
|
86
|
+
issues.push(`Handoff resource "${resource.id}" consumePath must be a path starting with "/".`);
|
|
87
|
+
if (resource.returnTo !== undefined && !isHandoffPath(resource.returnTo))
|
|
88
|
+
issues.push(`Handoff resource "${resource.id}" returnTo must be a path starting with "/".`);
|
|
89
|
+
}
|
|
90
|
+
return issues;
|
|
91
|
+
}
|
|
92
|
+
/** An origin and nothing else: a path or query here would silently change `iss`. */
|
|
93
|
+
function isHandoffIssuerOrigin(value) {
|
|
94
|
+
if (!isHandoffOrigin(value))
|
|
95
|
+
return false;
|
|
96
|
+
const trimmed = value.trim().replace(/\/$/, "");
|
|
97
|
+
return new URL(trimmed).origin === trimmed;
|
|
98
|
+
}
|
|
99
|
+
function isHandoffOrigin(value) {
|
|
100
|
+
if (typeof value !== "string" || !value.trim())
|
|
101
|
+
return false;
|
|
102
|
+
let parsed;
|
|
103
|
+
try {
|
|
104
|
+
parsed = new URL(value);
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
if (parsed.protocol === "https:")
|
|
110
|
+
return true;
|
|
111
|
+
return parsed.protocol === "http:" && localOriginHosts.has(parsed.hostname);
|
|
112
|
+
}
|
|
113
|
+
// The same rule as handoff-consumer.ts's safeHandoffPath, which owns the
|
|
114
|
+
// explanation: one leading slash, no backslash, no control character (the URL
|
|
115
|
+
// parser strips TAB/CR/LF, which would turn "/\t//evil.example" into a
|
|
116
|
+
// protocol-relative URL). Duplicated rather than shared because the consumer
|
|
117
|
+
// imports nothing from Core.
|
|
118
|
+
const handoffPathPattern = /^\/(?!\/)[^\\\x00-\x1f\x7f]*$/;
|
|
119
|
+
function isHandoffPath(value) {
|
|
120
|
+
return typeof value === "string" && handoffPathPattern.test(value);
|
|
121
|
+
}
|
|
122
|
+
export function parseHandoffPrivateJwk(raw) {
|
|
123
|
+
if (!raw?.trim())
|
|
124
|
+
throw new Error("RAYBASE_HANDOFF_PRIVATE_JWK is required when handoff is enabled.");
|
|
125
|
+
let jwk;
|
|
126
|
+
try {
|
|
127
|
+
jwk = JSON.parse(raw);
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
throw new Error("RAYBASE_HANDOFF_PRIVATE_JWK must be a JSON Web Key.");
|
|
131
|
+
}
|
|
132
|
+
if (jwk.kty !== "EC" || jwk.crv !== "P-256" || typeof jwk.d !== "string") {
|
|
133
|
+
throw new Error("RAYBASE_HANDOFF_PRIVATE_JWK must be an ES256 private JWK.");
|
|
134
|
+
}
|
|
135
|
+
return jwk;
|
|
136
|
+
}
|
|
137
|
+
export async function publicJwkFromPrivate(raw) {
|
|
138
|
+
const privateJwk = parseHandoffPrivateJwk(raw);
|
|
139
|
+
const publicJwk = { ...privateJwk };
|
|
140
|
+
delete publicJwk.d;
|
|
141
|
+
delete publicJwk.key_ops;
|
|
142
|
+
publicJwk.use = "sig";
|
|
143
|
+
publicJwk.alg = "ES256";
|
|
144
|
+
publicJwk.kid = typeof privateJwk.kid === "string" && privateJwk.kid ? privateJwk.kid : await handoffJwkKid(publicJwk);
|
|
145
|
+
return publicJwk;
|
|
146
|
+
}
|
|
147
|
+
export async function handoffJwks(raw) {
|
|
148
|
+
return { keys: [await publicJwkFromPrivate(raw)] };
|
|
149
|
+
}
|
|
150
|
+
async function handoffJwkKid(jwk) {
|
|
151
|
+
return `raybase-handoff-${(await sha256Hex(JSON.stringify({ crv: jwk.crv, kty: jwk.kty, x: jwk.x, y: jwk.y }))).slice(0, 16)}`;
|
|
152
|
+
}
|
|
153
|
+
function base64url(bytes) {
|
|
154
|
+
let binary = "";
|
|
155
|
+
for (const byte of bytes)
|
|
156
|
+
binary += String.fromCharCode(byte);
|
|
157
|
+
return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
|
|
158
|
+
}
|
|
159
|
+
async function importHandoffSigningKey(jwk) {
|
|
160
|
+
return crypto.subtle.importKey("jwk", jwk, { name: "ECDSA", namedCurve: "P-256" }, false, ["sign"]);
|
|
161
|
+
}
|
|
162
|
+
export async function signHandoffToken(input) {
|
|
163
|
+
const privateJwk = parseHandoffPrivateJwk(input.privateJwk);
|
|
164
|
+
const now = Math.floor(wallNowMs() / 1000);
|
|
165
|
+
const exp = now + input.ttlSeconds;
|
|
166
|
+
const payload = {
|
|
167
|
+
iss: input.issuer.replace(/\/$/, ""),
|
|
168
|
+
aud: `raybase-handoff:${input.resource.id}`,
|
|
169
|
+
sub: input.user.id,
|
|
170
|
+
email: input.user.email,
|
|
171
|
+
email_verified: input.user.emailVerified === true,
|
|
172
|
+
name: input.user.name,
|
|
173
|
+
// appId says which app's membership the roles belong to, so it belongs to
|
|
174
|
+
// the same handoff the roles do and to no other.
|
|
175
|
+
...(input.appId && input.resource.kind === "sso" ? { appId: input.appId } : {}),
|
|
176
|
+
resource: input.resource.id,
|
|
177
|
+
kind: input.resource.kind,
|
|
178
|
+
// A pass names a resource and a person, never a role: the claim is absent
|
|
179
|
+
// rather than empty so a consumer cannot mistake one for a membership.
|
|
180
|
+
...(input.resource.kind === "sso" ? { roles: input.user.appRoles ?? [] } : {}),
|
|
181
|
+
iat: now,
|
|
182
|
+
exp,
|
|
183
|
+
jti: randomId("handoff")
|
|
184
|
+
};
|
|
185
|
+
const publicJwk = await publicJwkFromPrivate(input.privateJwk);
|
|
186
|
+
const header = { alg: "ES256", typ: "JWT", kid: publicJwk.kid };
|
|
187
|
+
const signingInput = `${base64url(textEncoder.encode(JSON.stringify(header)))}.${base64url(textEncoder.encode(JSON.stringify(payload)))}`;
|
|
188
|
+
const signature = new Uint8Array(await crypto.subtle.sign({ name: "ECDSA", hash: "SHA-256" }, await importHandoffSigningKey(privateJwk), textEncoder.encode(signingInput)));
|
|
189
|
+
return {
|
|
190
|
+
token: `${signingInput}.${base64url(signature)}`,
|
|
191
|
+
payload,
|
|
192
|
+
expiresAt: new Date(exp * 1000).toISOString()
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
export function handoffConsumeUrl(resource, origin, token, returnTo, state) {
|
|
196
|
+
const url = new URL(handoffResourceConsumePath(resource), origin);
|
|
197
|
+
url.searchParams.set("token", token);
|
|
198
|
+
url.searchParams.set("return", returnTo);
|
|
199
|
+
// Echoed verbatim: the resource minted it and only the resource checks it.
|
|
200
|
+
if (state)
|
|
201
|
+
url.searchParams.set("state", state);
|
|
202
|
+
return url.toString();
|
|
203
|
+
}
|
|
204
|
+
/** Path-only, so a return value can never send a browser off the resource. */
|
|
205
|
+
export function sanitizeHandoffReturnTo(value, fallback) {
|
|
206
|
+
return isHandoffPath(value) ? value : fallback;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Reduce a caller-supplied return target to a path on the resource. An absolute
|
|
210
|
+
* URL is accepted only when it is on the resource's own origin, so the bounce
|
|
211
|
+
* can hand back the URL the visitor actually asked for.
|
|
212
|
+
*/
|
|
213
|
+
export function handoffReturnPath(resource, origin, value) {
|
|
214
|
+
const fallback = sanitizeHandoffReturnTo(resource.returnTo, "/");
|
|
215
|
+
if (typeof value === "string" && /^https?:\/\//i.test(value)) {
|
|
216
|
+
try {
|
|
217
|
+
const requested = new URL(value);
|
|
218
|
+
if (requested.origin !== new URL(origin).origin)
|
|
219
|
+
return fallback;
|
|
220
|
+
return sanitizeHandoffReturnTo(`${requested.pathname}${requested.search}`, fallback);
|
|
221
|
+
}
|
|
222
|
+
catch {
|
|
223
|
+
return fallback;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
return sanitizeHandoffReturnTo(value, fallback);
|
|
227
|
+
}
|
|
228
|
+
//# sourceMappingURL=handoff.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handoff.js","sourceRoot":"","sources":["../src/handoff.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { SqlExecutor } from "./db.js";
|
|
2
|
+
import type { RaybaseUser } from "./policies.js";
|
|
3
|
+
export { hostUserIdPrefix, isHostUserId } from "./host-user.js";
|
|
4
|
+
/**
|
|
5
|
+
* A person the host platform has already signed in, as the host vouches for
|
|
6
|
+
* them on one request. `subject` must be stable for that person and unique
|
|
7
|
+
* within the provider (for example: the host account plus the host's own user id).
|
|
8
|
+
*/
|
|
9
|
+
export type RaybaseHostIdentity = {
|
|
10
|
+
subject: string;
|
|
11
|
+
/** Display name for the admin panel and audit; defaults to "<provider> user". */
|
|
12
|
+
name?: string;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Lets an app that runs inside another platform's signed-in surface (an
|
|
16
|
+
* app embedded in that platform's admin, for example) let its users reach
|
|
17
|
+
* Raybase agent routes (the Guide and other agents) without a Raybase
|
|
18
|
+
* session.
|
|
19
|
+
*
|
|
20
|
+
* Raybase calls `resolve` only on agent routes and only when the request has
|
|
21
|
+
* no Raybase session. A non-null identity becomes a Raybase user row
|
|
22
|
+
* (`hostuser_<provider>_…`, appRoles ["user"], no password, no sign-in
|
|
23
|
+
* method, an undeliverable `.invalid` email) created on first use, so
|
|
24
|
+
* conversations, memory and audit entries have a real user to point at.
|
|
25
|
+
* The host can never grant admin or operator roles; an admin who bans that
|
|
26
|
+
* user in /admin cuts off their access. A layered runtime with its own
|
|
27
|
+
* session resolver (Raybase Pro) makes its own users from the identity
|
|
28
|
+
* through its profile's `session.host`, and ignores this hook without one.
|
|
29
|
+
*/
|
|
30
|
+
export type RaybaseHostAuth<Env = unknown> = {
|
|
31
|
+
/** Short lowercase id for the host platform, e.g. "acme". */
|
|
32
|
+
provider: string;
|
|
33
|
+
resolve(input: {
|
|
34
|
+
request: Request;
|
|
35
|
+
env: Env;
|
|
36
|
+
}): Promise<RaybaseHostIdentity | null> | RaybaseHostIdentity | null;
|
|
37
|
+
};
|
|
38
|
+
export declare function defineRaybaseHostAuth<Env = unknown>(hostAuth: RaybaseHostAuth<Env>): RaybaseHostAuth<Env>;
|
|
39
|
+
export declare function hostUserId(provider: string, subject: string): Promise<string>;
|
|
40
|
+
/**
|
|
41
|
+
* Returns the Raybase user for a host-vouched identity, creating the row on
|
|
42
|
+
* first use. Returns null when an admin has banned that user. Roles are
|
|
43
|
+
* always plain ["user"], whatever the row says, so a host user is never an
|
|
44
|
+
* admin even if someone edits the row.
|
|
45
|
+
*/
|
|
46
|
+
export declare function ensureHostUser(db: SqlExecutor, provider: string, identity: RaybaseHostIdentity): Promise<RaybaseUser | null>;
|
|
47
|
+
//# sourceMappingURL=host-auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host-auth.d.ts","sourceRoot":"","sources":["../src/host-auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAG3C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEhE;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,iFAAiF;IACjF,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,eAAe,CAAC,GAAG,GAAG,OAAO,IAAI;IAC3C,6DAA6D;IAC7D,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,KAAK,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,GAAG,EAAE,GAAG,CAAA;KAAE,GAAG,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,GAAG,mBAAmB,GAAG,IAAI,CAAC;CAClH,CAAC;AAEF,wBAAgB,qBAAqB,CAAC,GAAG,GAAG,OAAO,EAAE,QAAQ,EAAE,eAAe,CAAC,GAAG,CAAC,GAAG,eAAe,CAAC,GAAG,CAAC,CAGzG;AAcD,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAGnF;AAID;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,EAAE,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,mBAAmB,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CA4BlI"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { authUserTableName } from "./auth-schema.js";
|
|
2
|
+
import { hostUserIdPrefix } from "./host-user.js";
|
|
3
|
+
export { hostUserIdPrefix, isHostUserId } from "./host-user.js";
|
|
4
|
+
export function defineRaybaseHostAuth(hostAuth) {
|
|
5
|
+
assertHostProvider(hostAuth.provider);
|
|
6
|
+
return hostAuth;
|
|
7
|
+
}
|
|
8
|
+
function assertHostProvider(provider) {
|
|
9
|
+
if (!/^[a-z][a-z0-9-]{0,31}$/.test(provider)) {
|
|
10
|
+
throw new Error(`Host auth provider must be a short lowercase id (got ${JSON.stringify(provider)})`);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
async function subjectDigest(provider, subject) {
|
|
14
|
+
const bytes = new TextEncoder().encode(`${provider}\u0000${subject}`);
|
|
15
|
+
const digest = new Uint8Array(await crypto.subtle.digest("SHA-256", bytes));
|
|
16
|
+
return Array.from(digest.slice(0, 12), (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
17
|
+
}
|
|
18
|
+
export async function hostUserId(provider, subject) {
|
|
19
|
+
assertHostProvider(provider);
|
|
20
|
+
return `${hostUserIdPrefix}${provider}_${await subjectDigest(provider, subject)}`;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Returns the Raybase user for a host-vouched identity, creating the row on
|
|
24
|
+
* first use. Returns null when an admin has banned that user. Roles are
|
|
25
|
+
* always plain ["user"], whatever the row says, so a host user is never an
|
|
26
|
+
* admin even if someone edits the row.
|
|
27
|
+
*/
|
|
28
|
+
export async function ensureHostUser(db, provider, identity) {
|
|
29
|
+
const subject = identity.subject.trim();
|
|
30
|
+
if (!subject)
|
|
31
|
+
throw new Error("Host identity subject is required");
|
|
32
|
+
const id = await hostUserId(provider, subject);
|
|
33
|
+
const name = (identity.name?.trim() || `${provider} user`).slice(0, 200);
|
|
34
|
+
const now = Date.now();
|
|
35
|
+
// The email column is unique, so a guessable address could be registered
|
|
36
|
+
// first by someone else and block this person's row. A random part set on
|
|
37
|
+
// first insert (and never changed after) makes it unguessable.
|
|
38
|
+
const email = `${randomHex(16)}@${provider}.host.invalid`;
|
|
39
|
+
await db.run(`INSERT INTO "${authUserTableName}" ("id", "name", "email", "emailVerified", "createdAt", "updatedAt", "operatorRole", "appRoles", "banned")
|
|
40
|
+
VALUES (?, ?, ?, 0, ?, ?, NULL, ?, 0)
|
|
41
|
+
ON CONFLICT ("id") DO UPDATE SET "name" = excluded."name", "updatedAt" = excluded."updatedAt"
|
|
42
|
+
WHERE "${authUserTableName}"."name" <> excluded."name"`, [id, name, email, now, now, JSON.stringify(["user"])]);
|
|
43
|
+
const row = await db.first(`SELECT "id", "email", "name", "banned" FROM "${authUserTableName}" WHERE "id" = ?`, [id]);
|
|
44
|
+
if (!row || row.banned === true || row.banned === 1)
|
|
45
|
+
return null;
|
|
46
|
+
return {
|
|
47
|
+
id: row.id,
|
|
48
|
+
email: row.email,
|
|
49
|
+
name: row.name,
|
|
50
|
+
operatorRole: null,
|
|
51
|
+
appRoles: ["user"],
|
|
52
|
+
emailVerified: false,
|
|
53
|
+
disabled: false
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function randomHex(bytes) {
|
|
57
|
+
return Array.from(crypto.getRandomValues(new Uint8Array(bytes)), (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=host-auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host-auth.js","sourceRoot":"","sources":["../src/host-auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Host users (see RaybaseHostAuth) are Raybase user rows that a host platform
|
|
3
|
+
* vouches for on agent routes. They are plain users by construction: these
|
|
4
|
+
* helpers keep them that way wherever Core turns a stored row into a user,
|
|
5
|
+
* so an edited row (or a role granted by mistake) never takes effect.
|
|
6
|
+
* Dependency-free so every user reader can import it.
|
|
7
|
+
*/
|
|
8
|
+
export declare const hostUserIdPrefix = "hostuser_";
|
|
9
|
+
export declare function isHostUserId(id: unknown): boolean;
|
|
10
|
+
/** Caps a host user at the plain "user" role; any other user passes through unchanged. */
|
|
11
|
+
export declare function withHostUserRoleCeiling<T extends {
|
|
12
|
+
id: string;
|
|
13
|
+
}>(user: T): T;
|
|
14
|
+
export declare function assertNotHostUser(userId: string, change: string): void;
|
|
15
|
+
//# sourceMappingURL=host-user.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host-user.d.ts","sourceRoot":"","sources":["../src/host-user.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,cAAc,CAAC;AAE5C,wBAAgB,YAAY,CAAC,EAAE,EAAE,OAAO,GAAG,OAAO,CAEjD;AAED,0FAA0F;AAC1F,wBAAgB,uBAAuB,CAAC,CAAC,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,CAG5E;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAItE"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Host users (see RaybaseHostAuth) are Raybase user rows that a host platform
|
|
3
|
+
* vouches for on agent routes. They are plain users by construction: these
|
|
4
|
+
* helpers keep them that way wherever Core turns a stored row into a user,
|
|
5
|
+
* so an edited row (or a role granted by mistake) never takes effect.
|
|
6
|
+
* Dependency-free so every user reader can import it.
|
|
7
|
+
*/
|
|
8
|
+
export const hostUserIdPrefix = "hostuser_";
|
|
9
|
+
export function isHostUserId(id) {
|
|
10
|
+
return typeof id === "string" && id.startsWith(hostUserIdPrefix);
|
|
11
|
+
}
|
|
12
|
+
/** Caps a host user at the plain "user" role; any other user passes through unchanged. */
|
|
13
|
+
export function withHostUserRoleCeiling(user) {
|
|
14
|
+
if (!isHostUserId(user.id))
|
|
15
|
+
return user;
|
|
16
|
+
return { ...user, operatorRole: null, appRoles: ["user"] };
|
|
17
|
+
}
|
|
18
|
+
export function assertNotHostUser(userId, change) {
|
|
19
|
+
if (isHostUserId(userId)) {
|
|
20
|
+
throw new Error(`${change} is not available for host users: they are signed in by the host platform and always hold the plain user role`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=host-user.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host-user.js","sourceRoot":"","sources":["../src/host-user.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,WAAW,CAAC;AAE5C,MAAM,UAAU,YAAY,CAAC,EAAW;IACtC,OAAO,OAAO,EAAE,KAAK,QAAQ,IAAI,EAAE,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;AACnE,CAAC;AAED,0FAA0F;AAC1F,MAAM,UAAU,uBAAuB,CAA2B,IAAO;IACvE,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;QAAE,OAAO,IAAI,CAAC;IACxC,OAAO,EAAE,GAAG,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC;AAC7D,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,MAAc,EAAE,MAAc;IAC9D,IAAI,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,+GAA+G,CAAC,CAAC;IAC5I,CAAC;AACH,CAAC"}
|
package/dist/html.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type RaybaseConfig } from "./schema.js";
|
|
2
|
+
export type AuthPageExternalProvider = {
|
|
3
|
+
id: string;
|
|
4
|
+
label: string;
|
|
5
|
+
};
|
|
6
|
+
export declare function escapeHtml(value: unknown): string;
|
|
7
|
+
export declare function jsonScript(value: unknown): string;
|
|
8
|
+
export type PageAsset = {
|
|
9
|
+
href?: string;
|
|
10
|
+
src?: string;
|
|
11
|
+
integrity?: string;
|
|
12
|
+
};
|
|
13
|
+
export declare function faviconDataUri(appName?: string): string;
|
|
14
|
+
export declare function page(title: string, body: string, options?: {
|
|
15
|
+
appName?: string;
|
|
16
|
+
headScript?: string;
|
|
17
|
+
script?: string;
|
|
18
|
+
style?: string;
|
|
19
|
+
assets?: PageAsset[];
|
|
20
|
+
}): string;
|
|
21
|
+
export declare function loginPage(config: RaybaseConfig, message?: string, options?: {
|
|
22
|
+
local?: boolean;
|
|
23
|
+
externalProviders?: AuthPageExternalProvider[];
|
|
24
|
+
}): string;
|
|
25
|
+
export declare function forgotPasswordPage(config: RaybaseConfig, message?: string): string;
|
|
26
|
+
export declare function resetPasswordPage(config: RaybaseConfig, token?: string, message?: string): string;
|
|
27
|
+
export declare function verifyEmailPage(config: RaybaseConfig, token?: string, email?: string, message?: string): string;
|
|
28
|
+
export declare function signupPage(config: RaybaseConfig, message?: string, options?: {
|
|
29
|
+
externalProviders?: AuthPageExternalProvider[];
|
|
30
|
+
}): string;
|
|
31
|
+
export declare function accessDeniedPage(config: RaybaseConfig): string;
|
|
32
|
+
export declare function setupPage(config: RaybaseConfig, token: string, purpose: "owner-setup" | "invite", email?: string, options?: {
|
|
33
|
+
externalProviders?: AuthPageExternalProvider[];
|
|
34
|
+
}): string;
|
|
35
|
+
//# sourceMappingURL=html.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../src/html.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0C,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAGzF,MAAM,MAAM,wBAAwB,GAAG;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAOjD;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEjD;AAED,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAKF,wBAAgB,cAAc,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAIvD;AAeD,wBAAgB,IAAI,CAClB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAA;CAAO,GAC7G,MAAM,CA+DR;AAgCD,wBAAgB,SAAS,CAAC,MAAM,EAAE,aAAa,EAAE,OAAO,SAAK,EAAE,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,iBAAiB,CAAC,EAAE,wBAAwB,EAAE,CAAA;CAAO,GAAG,MAAM,CA4CxJ;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,aAAa,EAAE,OAAO,SAAK,GAAG,MAAM,CAkB9E;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,SAAK,EAAE,OAAO,SAAK,GAAG,MAAM,CAmBzF;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,SAAK,EAAE,KAAK,SAAK,EAAE,OAAO,SAAK,GAAG,MAAM,CAoBnG;AAED,wBAAgB,UAAU,CACxB,MAAM,EAAE,aAAa,EACrB,OAAO,SAAK,EACZ,OAAO,GAAE;IAAE,iBAAiB,CAAC,EAAE,wBAAwB,EAAE,CAAA;CAAO,GAC/D,MAAM,CA4BR;AAID,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAa9D;AAED,wBAAgB,SAAS,CACvB,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,aAAa,GAAG,QAAQ,EACjC,KAAK,SAAK,EACV,OAAO,GAAE;IAAE,iBAAiB,CAAC,EAAE,wBAAwB,EAAE,CAAA;CAAO,GAC/D,MAAM,CAmCR"}
|