studiograph 1.3.48-next.21 → 1.3.48-next.210
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -16
- package/dist/agent/agent-pool.d.ts +87 -3
- package/dist/agent/agent-pool.js +188 -15
- package/dist/agent/agent-pool.js.map +1 -1
- package/dist/agent/followups.d.ts +34 -0
- package/dist/agent/followups.js +52 -0
- package/dist/agent/followups.js.map +1 -0
- package/dist/agent/orchestrator.d.ts +101 -4
- package/dist/agent/orchestrator.js +464 -66
- package/dist/agent/orchestrator.js.map +1 -1
- package/dist/agent/prompts/entity-types-section.d.ts +34 -0
- package/dist/agent/prompts/entity-types-section.js +76 -0
- package/dist/agent/prompts/entity-types-section.js.map +1 -0
- package/dist/agent/prompts/system.md +112 -54
- package/dist/agent/skill-loader.d.ts +30 -17
- package/dist/agent/skill-loader.js +63 -30
- package/dist/agent/skill-loader.js.map +1 -1
- package/dist/agent/skills/artifact-canvas/skill.md +152 -0
- package/dist/agent/skills/entity-schema.md +75 -431
- package/dist/agent/skills/interview/entity-templates.md +38 -37
- package/dist/agent/skills/interview/question-domains.md +54 -49
- package/dist/agent/skills/interview/skill.md +84 -16
- package/dist/agent/skills/schema-rules.md +28 -28
- package/dist/agent/tools/artifact-tools.d.ts +124 -0
- package/dist/agent/tools/artifact-tools.js +207 -0
- package/dist/agent/tools/artifact-tools.js.map +1 -0
- package/dist/agent/tools/capture-tools.d.ts +31 -0
- package/dist/agent/tools/capture-tools.js +40 -0
- package/dist/agent/tools/capture-tools.js.map +1 -0
- package/dist/agent/tools/folder-tools.d.ts +47 -0
- package/dist/agent/tools/folder-tools.js +249 -0
- package/dist/agent/tools/folder-tools.js.map +1 -0
- package/dist/agent/tools/fs-tools.d.ts +6 -5
- package/dist/agent/tools/fs-tools.js +5 -5
- package/dist/agent/tools/fs-tools.js.map +1 -1
- package/dist/agent/tools/graph-tools.d.ts +48 -72
- package/dist/agent/tools/graph-tools.js +852 -329
- package/dist/agent/tools/graph-tools.js.map +1 -1
- package/dist/agent/tools/history-tools.d.ts +95 -0
- package/dist/agent/tools/history-tools.js +461 -0
- package/dist/agent/tools/history-tools.js.map +1 -0
- package/dist/agent/tools/load-skill.d.ts +6 -5
- package/dist/agent/tools/load-skill.js +3 -3
- package/dist/agent/tools/load-skill.js.map +1 -1
- package/dist/agent/tools/ops-tools.d.ts +5 -4
- package/dist/agent/tools/ops-tools.js +130 -236
- package/dist/agent/tools/ops-tools.js.map +1 -1
- package/dist/agent/tools/permission-tools.d.ts +87 -17
- package/dist/agent/tools/permission-tools.js +233 -43
- package/dist/agent/tools/permission-tools.js.map +1 -1
- package/dist/agent/tools/tool-loader.js +5 -4
- package/dist/agent/tools/tool-loader.js.map +1 -1
- package/dist/agent/tools/web-tools.js +58 -9
- package/dist/agent/tools/web-tools.js.map +1 -1
- package/dist/cli/commands/about.d.ts +1 -0
- package/dist/cli/commands/about.js +55 -3
- package/dist/cli/commands/about.js.map +1 -1
- package/dist/cli/commands/admin/audit-workspace.d.ts +23 -0
- package/dist/cli/commands/admin/audit-workspace.js +133 -0
- package/dist/cli/commands/admin/audit-workspace.js.map +1 -0
- package/dist/cli/commands/admin/audit.d.ts +21 -0
- package/dist/cli/commands/admin/audit.js +174 -0
- package/dist/cli/commands/admin/audit.js.map +1 -0
- package/dist/cli/commands/admin/backup.d.ts +54 -0
- package/dist/cli/commands/admin/backup.js +207 -0
- package/dist/cli/commands/admin/backup.js.map +1 -0
- package/dist/cli/commands/admin/folder.d.ts +11 -0
- package/dist/cli/commands/{collection.js → admin/folder.js} +33 -32
- package/dist/cli/commands/admin/folder.js.map +1 -0
- package/dist/cli/commands/admin/index.d.ts +16 -0
- package/dist/cli/commands/admin/index.js +46 -0
- package/dist/cli/commands/admin/index.js.map +1 -0
- package/dist/cli/commands/admin/migrate-assets.d.ts +53 -0
- package/dist/cli/commands/admin/migrate-assets.js +184 -0
- package/dist/cli/commands/admin/migrate-assets.js.map +1 -0
- package/dist/cli/commands/admin/migrate.d.ts +56 -0
- package/dist/cli/commands/admin/migrate.js +263 -0
- package/dist/cli/commands/admin/migrate.js.map +1 -0
- package/dist/cli/commands/admin/restore.d.ts +24 -0
- package/dist/cli/commands/admin/restore.js +228 -0
- package/dist/cli/commands/admin/restore.js.map +1 -0
- package/dist/cli/commands/admin/secrets.d.ts +23 -0
- package/dist/cli/commands/admin/secrets.js +256 -0
- package/dist/cli/commands/admin/secrets.js.map +1 -0
- package/dist/cli/commands/admin/settings.d.ts +28 -0
- package/dist/cli/commands/admin/settings.js +284 -0
- package/dist/cli/commands/admin/settings.js.map +1 -0
- package/dist/cli/commands/admin/token.d.ts +42 -0
- package/dist/cli/commands/admin/token.js +126 -0
- package/dist/cli/commands/admin/token.js.map +1 -0
- package/dist/cli/commands/admin/transfer-ownership.d.ts +15 -0
- package/dist/cli/commands/admin/transfer-ownership.js +106 -0
- package/dist/cli/commands/admin/transfer-ownership.js.map +1 -0
- package/dist/cli/commands/admin/user.d.ts +11 -0
- package/dist/cli/commands/admin/user.js +187 -0
- package/dist/cli/commands/admin/user.js.map +1 -0
- package/dist/cli/commands/clone.d.ts +25 -3
- package/dist/cli/commands/clone.js +142 -36
- package/dist/cli/commands/clone.js.map +1 -1
- package/dist/cli/commands/config.d.ts +23 -107
- package/dist/cli/commands/config.js +52 -260
- package/dist/cli/commands/config.js.map +1 -1
- package/dist/cli/commands/connector.d.ts +10 -13
- package/dist/cli/commands/connector.js +16 -58
- package/dist/cli/commands/connector.js.map +1 -1
- package/dist/cli/commands/deploy.js +215 -68
- package/dist/cli/commands/deploy.js.map +1 -1
- package/dist/cli/commands/index.js +5 -1
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/init.js +10 -30
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/mcp.js +54 -6
- package/dist/cli/commands/mcp.js.map +1 -1
- package/dist/cli/commands/r2.d.ts +3 -0
- package/dist/cli/commands/r2.js +223 -204
- package/dist/cli/commands/r2.js.map +1 -1
- package/dist/cli/commands/redeploy.js +65 -12
- package/dist/cli/commands/redeploy.js.map +1 -1
- package/dist/cli/commands/reset.d.ts +22 -6
- package/dist/cli/commands/reset.js +132 -34
- package/dist/cli/commands/reset.js.map +1 -1
- package/dist/cli/commands/serve.js +231 -26
- package/dist/cli/commands/serve.js.map +1 -1
- package/dist/cli/commands/sync.d.ts +1 -1
- package/dist/cli/commands/sync.js +237 -227
- package/dist/cli/commands/sync.js.map +1 -1
- package/dist/cli/crypto-bundle.d.ts +39 -0
- package/dist/cli/crypto-bundle.js +94 -0
- package/dist/cli/crypto-bundle.js.map +1 -0
- package/dist/cli/index.js +24 -26
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/railway-pin.d.ts +68 -0
- package/dist/cli/railway-pin.js +96 -0
- package/dist/cli/railway-pin.js.map +1 -0
- package/dist/cli/railway-provisioning.d.ts +53 -0
- package/dist/cli/railway-provisioning.js +85 -0
- package/dist/cli/railway-provisioning.js.map +1 -0
- package/dist/cli/setup-wizard.d.ts +30 -49
- package/dist/cli/setup-wizard.js +39 -40
- package/dist/cli/setup-wizard.js.map +1 -1
- package/dist/core/accent-palette.d.ts +22 -0
- package/dist/core/accent-palette.js +47 -0
- package/dist/core/accent-palette.js.map +1 -0
- package/dist/core/artifact-asset-urls.d.ts +51 -0
- package/dist/core/artifact-asset-urls.js +79 -0
- package/dist/core/artifact-asset-urls.js.map +1 -0
- package/dist/core/artifact-bundle.d.ts +69 -0
- package/dist/core/artifact-bundle.js +305 -0
- package/dist/core/artifact-bundle.js.map +1 -0
- package/dist/core/artifact-escape.d.ts +5 -0
- package/dist/core/artifact-escape.js +26 -0
- package/dist/core/artifact-escape.js.map +1 -0
- package/dist/core/artifact-export.d.ts +17 -0
- package/dist/core/artifact-export.js +529 -0
- package/dist/core/artifact-export.js.map +1 -0
- package/dist/core/cell-anchor.d.ts +29 -0
- package/dist/core/cell-anchor.js +53 -0
- package/dist/core/cell-anchor.js.map +1 -0
- package/dist/core/comment-anchor.d.ts +41 -0
- package/dist/core/comment-anchor.js +147 -0
- package/dist/core/comment-anchor.js.map +1 -0
- package/dist/core/commit-messages.d.ts +57 -0
- package/dist/core/commit-messages.js +85 -0
- package/dist/core/commit-messages.js.map +1 -0
- package/dist/core/embeds.d.ts +96 -0
- package/dist/core/embeds.js +187 -0
- package/dist/core/embeds.js.map +1 -0
- package/dist/core/entity-body-templates.d.ts +21 -0
- package/dist/core/entity-body-templates.js +67 -0
- package/dist/core/entity-body-templates.js.map +1 -0
- package/dist/core/entity-types-catalog.d.ts +65 -0
- package/dist/core/entity-types-catalog.js +142 -0
- package/dist/core/entity-types-catalog.js.map +1 -0
- package/dist/core/field-library.d.ts +62 -0
- package/dist/core/field-library.js +129 -0
- package/dist/core/field-library.js.map +1 -0
- package/dist/core/folder-paths.d.ts +41 -0
- package/dist/core/folder-paths.js +95 -0
- package/dist/core/folder-paths.js.map +1 -0
- package/dist/core/folder-sidecar.d.ts +36 -0
- package/dist/core/folder-sidecar.js +91 -0
- package/dist/core/folder-sidecar.js.map +1 -0
- package/dist/core/format-registry.d.ts +170 -0
- package/dist/core/format-registry.js +412 -0
- package/dist/core/format-registry.js.map +1 -0
- package/dist/core/graph.d.ts +773 -14
- package/dist/core/graph.js +2269 -308
- package/dist/core/graph.js.map +1 -1
- package/dist/core/history-diff.d.ts +35 -0
- package/dist/core/history-diff.js +114 -0
- package/dist/core/history-diff.js.map +1 -0
- package/dist/core/refs.d.ts +41 -0
- package/dist/core/refs.js +80 -0
- package/dist/core/refs.js.map +1 -0
- package/dist/core/schema-registry.d.ts +66 -0
- package/dist/core/schema-registry.js +198 -37
- package/dist/core/schema-registry.js.map +1 -1
- package/dist/core/schemas/connector.d.ts +67 -0
- package/dist/core/schemas/connector.js +100 -0
- package/dist/core/schemas/connector.js.map +1 -0
- package/dist/core/schemas/workspace.d.ts +122 -0
- package/dist/core/schemas/workspace.js +211 -0
- package/dist/core/schemas/workspace.js.map +1 -0
- package/dist/core/secrets/SecretStore.d.ts +77 -0
- package/dist/core/secrets/SecretStore.js +13 -0
- package/dist/core/secrets/SecretStore.js.map +1 -0
- package/dist/core/secrets/SettingsResolver.d.ts +54 -0
- package/dist/core/secrets/SettingsResolver.js +80 -0
- package/dist/core/secrets/SettingsResolver.js.map +1 -0
- package/dist/core/secrets/SettingsStore.d.ts +30 -0
- package/dist/core/secrets/SettingsStore.js +9 -0
- package/dist/core/secrets/SettingsStore.js.map +1 -0
- package/dist/core/secrets/SqliteEncryptedStore.d.ts +90 -0
- package/dist/core/secrets/SqliteEncryptedStore.js +598 -0
- package/dist/core/secrets/SqliteEncryptedStore.js.map +1 -0
- package/dist/core/secrets/audit.d.ts +36 -0
- package/dist/core/secrets/audit.js +60 -0
- package/dist/core/secrets/audit.js.map +1 -0
- package/dist/core/secrets/auth-db-migration.d.ts +129 -0
- package/dist/core/secrets/auth-db-migration.js +653 -0
- package/dist/core/secrets/auth-db-migration.js.map +1 -0
- package/dist/core/secrets/bundle.d.ts +141 -0
- package/dist/core/secrets/bundle.js +435 -0
- package/dist/core/secrets/bundle.js.map +1 -0
- package/dist/core/secrets/dual-write.d.ts +81 -0
- package/dist/core/secrets/dual-write.js +247 -0
- package/dist/core/secrets/dual-write.js.map +1 -0
- package/dist/core/secrets/encryption.d.ts +44 -0
- package/dist/core/secrets/encryption.js +97 -0
- package/dist/core/secrets/encryption.js.map +1 -0
- package/dist/core/secrets/index.d.ts +49 -0
- package/dist/core/secrets/index.js +74 -0
- package/dist/core/secrets/index.js.map +1 -0
- package/dist/core/secrets/master-key.d.ts +38 -0
- package/dist/core/secrets/master-key.js +122 -0
- package/dist/core/secrets/master-key.js.map +1 -0
- package/dist/core/secrets/probes/anthropic.d.ts +98 -0
- package/dist/core/secrets/probes/anthropic.js +300 -0
- package/dist/core/secrets/probes/anthropic.js.map +1 -0
- package/dist/core/secrets/probes/brave.d.ts +9 -0
- package/dist/core/secrets/probes/brave.js +15 -0
- package/dist/core/secrets/probes/brave.js.map +1 -0
- package/dist/core/secrets/probes/r2.d.ts +15 -0
- package/dist/core/secrets/probes/r2.js +14 -0
- package/dist/core/secrets/probes/r2.js.map +1 -0
- package/dist/core/secrets/probes/tavily.d.ts +18 -0
- package/dist/core/secrets/probes/tavily.js +58 -0
- package/dist/core/secrets/probes/tavily.js.map +1 -0
- package/dist/core/secrets/probes/voyage.d.ts +13 -0
- package/dist/core/secrets/probes/voyage.js +52 -0
- package/dist/core/secrets/probes/voyage.js.map +1 -0
- package/dist/core/secrets/r2-structural-migration.d.ts +39 -0
- package/dist/core/secrets/r2-structural-migration.js +109 -0
- package/dist/core/secrets/r2-structural-migration.js.map +1 -0
- package/dist/core/secrets/read-flip.d.ts +59 -0
- package/dist/core/secrets/read-flip.js +87 -0
- package/dist/core/secrets/read-flip.js.map +1 -0
- package/dist/core/secrets/registry.d.ts +188 -0
- package/dist/core/secrets/registry.js +616 -0
- package/dist/core/secrets/registry.js.map +1 -0
- package/dist/core/types.d.ts +77 -483
- package/dist/core/types.js +25 -3
- package/dist/core/types.js.map +1 -1
- package/dist/core/user-config.d.ts +75 -12
- package/dist/core/user-config.js +155 -14
- package/dist/core/user-config.js.map +1 -1
- package/dist/core/validation.d.ts +786 -1373
- package/dist/core/validation.js +458 -147
- package/dist/core/validation.js.map +1 -1
- package/dist/core/workspace-manager.d.ts +87 -14
- package/dist/core/workspace-manager.js +222 -94
- package/dist/core/workspace-manager.js.map +1 -1
- package/dist/core/workspace.d.ts +19 -5
- package/dist/core/workspace.js +67 -39
- package/dist/core/workspace.js.map +1 -1
- package/dist/mcp/comment-virtual-entity.d.ts +36 -0
- package/dist/mcp/comment-virtual-entity.js +71 -0
- package/dist/mcp/comment-virtual-entity.js.map +1 -0
- package/dist/mcp/connector-manager.d.ts +72 -2
- package/dist/mcp/connector-manager.js +211 -32
- package/dist/mcp/connector-manager.js.map +1 -1
- package/dist/mcp/oauth-provider.d.ts +0 -5
- package/dist/mcp/oauth-provider.js +10 -22
- package/dist/mcp/oauth-provider.js.map +1 -1
- package/dist/mcp/oauth-registry.d.ts +46 -8
- package/dist/mcp/oauth-registry.js +52 -13
- package/dist/mcp/oauth-registry.js.map +1 -1
- package/dist/mcp/server-discovery.d.ts +73 -0
- package/dist/mcp/server-discovery.js +164 -0
- package/dist/mcp/server-discovery.js.map +1 -0
- package/dist/mcp/server.d.ts +24 -3
- package/dist/mcp/server.js +53 -10
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/state-signer.d.ts +62 -0
- package/dist/mcp/state-signer.js +205 -0
- package/dist/mcp/state-signer.js.map +1 -0
- package/dist/mcp/stdio-proxy.d.ts +67 -0
- package/dist/mcp/stdio-proxy.js +149 -0
- package/dist/mcp/stdio-proxy.js.map +1 -0
- package/dist/mcp/tools.d.ts +65 -2
- package/dist/mcp/tools.js +1772 -124
- package/dist/mcp/tools.js.map +1 -1
- package/dist/server/__tests__/helpers/graph-api.d.ts +16 -0
- package/dist/server/__tests__/helpers/graph-api.js +16 -0
- package/dist/server/__tests__/helpers/graph-api.js.map +1 -0
- package/dist/server/artifact-asset-mint.d.ts +41 -0
- package/dist/server/artifact-asset-mint.js +59 -0
- package/dist/server/artifact-asset-mint.js.map +1 -0
- package/dist/server/asset-index-queue.d.ts +98 -0
- package/dist/server/asset-index-queue.js +193 -0
- package/dist/server/asset-index-queue.js.map +1 -0
- package/dist/server/body-write-coordinator.d.ts +161 -0
- package/dist/server/body-write-coordinator.js +182 -0
- package/dist/server/body-write-coordinator.js.map +1 -0
- package/dist/server/cloud-billing-flow.d.ts +32 -0
- package/dist/server/cloud-billing-flow.js +75 -0
- package/dist/server/cloud-billing-flow.js.map +1 -0
- package/dist/server/commit-audit.d.ts +26 -0
- package/dist/server/commit-audit.js +30 -0
- package/dist/server/commit-audit.js.map +1 -0
- package/dist/server/index.d.ts +29 -3
- package/dist/server/index.js +657 -269
- package/dist/server/index.js.map +1 -1
- package/dist/server/middleware/sanitize.d.ts +46 -0
- package/dist/server/middleware/sanitize.js +182 -0
- package/dist/server/middleware/sanitize.js.map +1 -0
- package/dist/server/routes/artifact-export-api.d.ts +11 -0
- package/dist/server/routes/artifact-export-api.js +159 -0
- package/dist/server/routes/artifact-export-api.js.map +1 -0
- package/dist/server/routes/asset-api.d.ts +76 -1
- package/dist/server/routes/asset-api.js +761 -61
- package/dist/server/routes/asset-api.js.map +1 -1
- package/dist/server/routes/audit-api.d.ts +24 -0
- package/dist/server/routes/audit-api.js +117 -0
- package/dist/server/routes/audit-api.js.map +1 -0
- package/dist/server/routes/auth-api.js +532 -63
- package/dist/server/routes/auth-api.js.map +1 -1
- package/dist/server/routes/capture-api.d.ts +10 -3
- package/dist/server/routes/capture-api.js +213 -25
- package/dist/server/routes/capture-api.js.map +1 -1
- package/dist/server/routes/chat-sessions-api.d.ts +13 -0
- package/dist/server/routes/chat-sessions-api.js +455 -0
- package/dist/server/routes/chat-sessions-api.js.map +1 -0
- package/dist/server/routes/chat.d.ts +35 -1
- package/dist/server/routes/chat.js +699 -54
- package/dist/server/routes/chat.js.map +1 -1
- package/dist/server/routes/comments-api.d.ts +15 -0
- package/dist/server/routes/comments-api.js +444 -0
- package/dist/server/routes/comments-api.js.map +1 -0
- package/dist/server/routes/config-api.d.ts +3 -2
- package/dist/server/routes/config-api.js +179 -49
- package/dist/server/routes/config-api.js.map +1 -1
- package/dist/server/routes/connectors-api.js +177 -42
- package/dist/server/routes/connectors-api.js.map +1 -1
- package/dist/server/routes/event-ingest-api.d.ts +15 -0
- package/dist/server/routes/{meeting-ingest-api.js → event-ingest-api.js} +35 -20
- package/dist/server/routes/event-ingest-api.js.map +1 -0
- package/dist/server/routes/field-library-api.d.ts +28 -0
- package/dist/server/routes/field-library-api.js +126 -0
- package/dist/server/routes/field-library-api.js.map +1 -0
- package/dist/server/routes/git-http.d.ts +2 -2
- package/dist/server/routes/git-http.js +86 -39
- package/dist/server/routes/git-http.js.map +1 -1
- package/dist/server/routes/graph-api-access.d.ts +57 -0
- package/dist/server/routes/graph-api-access.js +112 -0
- package/dist/server/routes/graph-api-access.js.map +1 -0
- package/dist/server/routes/graph-api.d.ts +1 -1
- package/dist/server/routes/graph-api.js +1455 -325
- package/dist/server/routes/graph-api.js.map +1 -1
- package/dist/server/routes/health.d.ts +18 -0
- package/dist/server/routes/health.js +74 -0
- package/dist/server/routes/health.js.map +1 -0
- package/dist/server/routes/import-batch.d.ts +24 -0
- package/dist/server/routes/import-batch.js +33 -0
- package/dist/server/routes/import-batch.js.map +1 -0
- package/dist/server/routes/insights-api.d.ts +9 -2
- package/dist/server/routes/insights-api.js +355 -61
- package/dist/server/routes/insights-api.js.map +1 -1
- package/dist/server/routes/mcp.d.ts +7 -3
- package/dist/server/routes/mcp.js +24 -8
- package/dist/server/routes/mcp.js.map +1 -1
- package/dist/server/routes/oauth-api.d.ts +67 -0
- package/dist/server/routes/oauth-api.js +421 -0
- package/dist/server/routes/oauth-api.js.map +1 -0
- package/dist/server/routes/permissions-api.d.ts +9 -2
- package/dist/server/routes/permissions-api.js +87 -31
- package/dist/server/routes/permissions-api.js.map +1 -1
- package/dist/server/routes/r2-api.d.ts +25 -0
- package/dist/server/routes/r2-api.js +276 -0
- package/dist/server/routes/r2-api.js.map +1 -0
- package/dist/server/routes/secrets-api.d.ts +36 -0
- package/dist/server/routes/secrets-api.js +308 -0
- package/dist/server/routes/secrets-api.js.map +1 -0
- package/dist/server/routes/settings-api.d.ts +29 -0
- package/dist/server/routes/settings-api.js +180 -0
- package/dist/server/routes/settings-api.js.map +1 -0
- package/dist/server/routes/share-api.d.ts +32 -0
- package/dist/server/routes/share-api.js +234 -0
- package/dist/server/routes/share-api.js.map +1 -0
- package/dist/server/routes/views-api.js +51 -0
- package/dist/server/routes/views-api.js.map +1 -1
- package/dist/server/routes/workspace-api.d.ts +2 -1
- package/dist/server/routes/workspace-api.js +142 -23
- package/dist/server/routes/workspace-api.js.map +1 -1
- package/dist/server/routes/ws.d.ts +3 -2
- package/dist/server/routes/ws.js +68 -17
- package/dist/server/routes/ws.js.map +1 -1
- package/dist/server/session-manager.d.ts +48 -5
- package/dist/server/session-manager.js +182 -14
- package/dist/server/session-manager.js.map +1 -1
- package/dist/server/ws-hub.d.ts +124 -37
- package/dist/server/ws-hub.js +0 -0
- package/dist/server/ws-hub.js.map +1 -1
- package/dist/server/yjs-manager.d.ts +278 -7
- package/dist/server/yjs-manager.js +830 -38
- package/dist/server/yjs-manager.js.map +1 -1
- package/dist/server/yjs-persistence.d.ts +165 -0
- package/dist/server/yjs-persistence.js +557 -0
- package/dist/server/yjs-persistence.js.map +1 -0
- package/dist/server/yjs-text-diff.d.ts +32 -0
- package/dist/server/yjs-text-diff.js +61 -0
- package/dist/server/yjs-text-diff.js.map +1 -0
- package/dist/services/access-control.d.ts +73 -0
- package/dist/services/access-control.js +165 -0
- package/dist/services/access-control.js.map +1 -0
- package/dist/services/artifact-asset-token.d.ts +69 -0
- package/dist/services/artifact-asset-token.js +94 -0
- package/dist/services/artifact-asset-token.js.map +1 -0
- package/dist/services/artifact-library-sources.d.ts +3 -0
- package/dist/services/artifact-library-sources.js +44 -0
- package/dist/services/artifact-library-sources.js.map +1 -0
- package/dist/services/artifact-render-export.d.ts +97 -0
- package/dist/services/artifact-render-export.js +467 -0
- package/dist/services/artifact-render-export.js.map +1 -0
- package/dist/services/asset-caption-service.d.ts +103 -0
- package/dist/services/asset-caption-service.js +186 -0
- package/dist/services/asset-caption-service.js.map +1 -0
- package/dist/services/asset-delete-authz.d.ts +31 -0
- package/dist/services/asset-delete-authz.js +61 -0
- package/dist/services/asset-delete-authz.js.map +1 -0
- package/dist/services/asset-finalize-service.d.ts +58 -0
- package/dist/services/asset-finalize-service.js +216 -0
- package/dist/services/asset-finalize-service.js.map +1 -0
- package/dist/services/asset-import-service.d.ts +111 -0
- package/dist/services/asset-import-service.js +394 -0
- package/dist/services/asset-import-service.js.map +1 -0
- package/dist/services/asset-index-sweep.d.ts +95 -0
- package/dist/services/asset-index-sweep.js +249 -0
- package/dist/services/asset-index-sweep.js.map +1 -0
- package/dist/services/asset-lifecycle-check.d.ts +22 -0
- package/dist/services/asset-lifecycle-check.js +80 -0
- package/dist/services/asset-lifecycle-check.js.map +1 -0
- package/dist/services/asset-listing.d.ts +72 -0
- package/dist/services/asset-listing.js +321 -0
- package/dist/services/asset-listing.js.map +1 -0
- package/dist/services/asset-presign-service.d.ts +68 -0
- package/dist/services/asset-presign-service.js +124 -0
- package/dist/services/asset-presign-service.js.map +1 -0
- package/dist/services/asset-sidecar-service.d.ts +28 -0
- package/dist/services/asset-sidecar-service.js +79 -0
- package/dist/services/asset-sidecar-service.js.map +1 -0
- package/dist/services/asset-upload-errors.d.ts +41 -0
- package/dist/services/asset-upload-errors.js +45 -0
- package/dist/services/asset-upload-errors.js.map +1 -0
- package/dist/services/asset-upload-service.d.ts +56 -0
- package/dist/services/asset-upload-service.js +200 -0
- package/dist/services/asset-upload-service.js.map +1 -0
- package/dist/services/asset-upload-token.d.ts +58 -0
- package/dist/services/asset-upload-token.js +75 -0
- package/dist/services/asset-upload-token.js.map +1 -0
- package/dist/services/assets/asset-index-service.d.ts +127 -0
- package/dist/services/assets/asset-index-service.js +227 -0
- package/dist/services/assets/asset-index-service.js.map +1 -0
- package/dist/services/assets/base.d.ts +128 -2
- package/dist/services/assets/base.js +98 -1
- package/dist/services/assets/base.js.map +1 -1
- package/dist/services/assets/index.d.ts +114 -1
- package/dist/services/assets/index.js +221 -0
- package/dist/services/assets/index.js.map +1 -1
- package/dist/services/assets/local.d.ts +16 -1
- package/dist/services/assets/local.js +110 -1
- package/dist/services/assets/local.js.map +1 -1
- package/dist/services/assets/r2-sync.d.ts +88 -0
- package/dist/services/assets/r2-sync.js +412 -0
- package/dist/services/assets/r2-sync.js.map +1 -0
- package/dist/services/assets/r2.d.ts +87 -1
- package/dist/services/assets/r2.js +203 -1
- package/dist/services/assets/r2.js.map +1 -1
- package/dist/services/auth-service.d.ts +312 -45
- package/dist/services/auth-service.js +1011 -195
- package/dist/services/auth-service.js.map +1 -1
- package/dist/services/chat-session-service.d.ts +188 -0
- package/dist/services/chat-session-service.js +512 -0
- package/dist/services/chat-session-service.js.map +1 -0
- package/dist/services/cloud-inference-billing.d.ts +64 -0
- package/dist/services/cloud-inference-billing.js +313 -0
- package/dist/services/cloud-inference-billing.js.map +1 -0
- package/dist/services/comment-service.d.ts +97 -0
- package/dist/services/comment-service.js +341 -0
- package/dist/services/comment-service.js.map +1 -0
- package/dist/services/comment-virtual-entity.d.ts +36 -0
- package/dist/services/comment-virtual-entity.js +71 -0
- package/dist/services/comment-virtual-entity.js.map +1 -0
- package/dist/services/convert-service.d.ts +64 -0
- package/dist/services/convert-service.js +68 -0
- package/dist/services/convert-service.js.map +1 -0
- package/dist/services/csv-service.d.ts +22 -17
- package/dist/services/csv-service.js +55 -92
- package/dist/services/csv-service.js.map +1 -1
- package/dist/services/entity-mutations.d.ts +213 -0
- package/dist/services/entity-mutations.js +380 -0
- package/dist/services/entity-mutations.js.map +1 -0
- package/dist/services/{meeting-processor.d.ts → event-processor.d.ts} +15 -8
- package/dist/services/{meeting-processor.js → event-processor.js} +124 -65
- package/dist/services/event-processor.js.map +1 -0
- package/dist/services/extract/docx.d.ts +1 -0
- package/dist/services/extract/docx.js +233 -0
- package/dist/services/extract/docx.js.map +1 -0
- package/dist/services/extract/index.d.ts +9 -0
- package/dist/services/extract/index.js +10 -0
- package/dist/services/extract/index.js.map +1 -0
- package/dist/services/extract/pdf.d.ts +13 -0
- package/dist/services/extract/pdf.js +69 -0
- package/dist/services/extract/pdf.js.map +1 -0
- package/dist/services/folder-creation.d.ts +33 -0
- package/dist/services/folder-creation.js +103 -0
- package/dist/services/folder-creation.js.map +1 -0
- package/dist/services/git.d.ts +58 -0
- package/dist/services/git.js +194 -55
- package/dist/services/git.js.map +1 -1
- package/dist/services/graph-maintenance.js +4 -4
- package/dist/services/graph-maintenance.js.map +1 -1
- package/dist/services/import-service.d.ts +51 -2
- package/dist/services/import-service.js +254 -107
- package/dist/services/import-service.js.map +1 -1
- package/dist/services/lint-service.js +10 -17
- package/dist/services/lint-service.js.map +1 -1
- package/dist/services/markdown.d.ts +12 -1
- package/dist/services/markdown.js +77 -9
- package/dist/services/markdown.js.map +1 -1
- package/dist/services/mention-detector.d.ts +23 -0
- package/dist/services/mention-detector.js +47 -0
- package/dist/services/mention-detector.js.map +1 -0
- package/dist/services/model-capabilities.d.ts +41 -0
- package/dist/services/model-capabilities.js +107 -0
- package/dist/services/model-capabilities.js.map +1 -0
- package/dist/services/notification-broadcast.d.ts +32 -0
- package/dist/services/notification-broadcast.js +38 -0
- package/dist/services/notification-broadcast.js.map +1 -0
- package/dist/services/notification-service.d.ts +41 -0
- package/dist/services/notification-service.js +100 -0
- package/dist/services/notification-service.js.map +1 -0
- package/dist/services/oauth-server-store.d.ts +147 -0
- package/dist/services/oauth-server-store.js +319 -0
- package/dist/services/oauth-server-store.js.map +1 -0
- package/dist/services/orphan-service.js +2 -2
- package/dist/services/orphan-service.js.map +1 -1
- package/dist/services/personal-folder.d.ts +40 -0
- package/dist/services/personal-folder.js +101 -0
- package/dist/services/personal-folder.js.map +1 -0
- package/dist/services/scratch-asset-promote.d.ts +57 -0
- package/dist/services/scratch-asset-promote.js +95 -0
- package/dist/services/scratch-asset-promote.js.map +1 -0
- package/dist/services/scratch-attachment-service.d.ts +196 -0
- package/dist/services/scratch-attachment-service.js +347 -0
- package/dist/services/scratch-attachment-service.js.map +1 -0
- package/dist/services/share-link-service.d.ts +57 -0
- package/dist/services/share-link-service.js +142 -0
- package/dist/services/share-link-service.js.map +1 -0
- package/dist/services/user-person-bridge.d.ts +136 -0
- package/dist/services/user-person-bridge.js +340 -0
- package/dist/services/user-person-bridge.js.map +1 -0
- package/dist/services/vector-service.d.ts +282 -5
- package/dist/services/vector-service.js +585 -29
- package/dist/services/vector-service.js.map +1 -1
- package/dist/services/workspace-access.d.ts +108 -0
- package/dist/services/workspace-access.js +149 -0
- package/dist/services/workspace-access.js.map +1 -0
- package/dist/services/workspace-assets-folder.d.ts +46 -0
- package/dist/services/workspace-assets-folder.js +75 -0
- package/dist/services/workspace-assets-folder.js.map +1 -0
- package/dist/utils/git.d.ts +17 -2
- package/dist/utils/git.js +23 -7
- package/dist/utils/git.js.map +1 -1
- package/dist/utils/log.d.ts +42 -0
- package/dist/utils/log.js +137 -0
- package/dist/utils/log.js.map +1 -0
- package/dist/utils/preflight.js +2 -2
- package/dist/utils/preflight.js.map +1 -1
- package/dist/utils/version-checker.d.ts +12 -19
- package/dist/utils/version-checker.js +14 -104
- package/dist/utils/version-checker.js.map +1 -1
- package/dist/web/_app/immutable/assets/0.Bs_z3Z86.css +2 -0
- package/dist/web/_app/immutable/assets/12.DlIf1mKh.css +1 -0
- package/dist/web/_app/immutable/assets/14.7d-Q37wc.css +1 -0
- package/dist/web/_app/immutable/assets/15.BwBFdc1D.css +1 -0
- package/dist/web/_app/immutable/assets/16.CmLrbzZp.css +1 -0
- package/dist/web/_app/immutable/assets/17.DcuK5ZVm.css +1 -0
- package/dist/web/_app/immutable/assets/2.DATnR31c.css +1 -0
- package/dist/web/_app/immutable/assets/3.Cz4H8n_O.css +1 -0
- package/dist/web/_app/immutable/assets/4.aDHteTDy.css +1 -0
- package/dist/web/_app/immutable/assets/6.CF1i5Bon.css +1 -0
- package/dist/web/_app/immutable/assets/ArtifactEntityView.C4ooklFD.css +1 -0
- package/dist/web/_app/immutable/assets/AssetLibraryPicker.BOFW0MvF.css +1 -0
- package/dist/web/_app/immutable/assets/BulkActionsBar.cmKvHzRK.css +1 -0
- package/dist/web/_app/immutable/assets/CalendarView.lBCvS3X5.css +1 -0
- package/dist/web/_app/immutable/assets/CodeMirrorEditor.D6hf2pNJ.css +1 -0
- package/dist/web/_app/immutable/assets/CopyField.DVGZtw4U.css +1 -0
- package/dist/web/_app/immutable/assets/FolderMembersPanel.kiYnDFHu.css +1 -0
- package/dist/web/_app/immutable/assets/FolderMutationDialogs.BMRF6Z3z.css +1 -0
- package/dist/web/_app/immutable/assets/FolderPicker.Cp46GHe2.css +1 -0
- package/dist/web/_app/immutable/assets/GalleryView.WBGxxUQc.css +1 -0
- package/dist/web/_app/immutable/assets/GraphView.BJtGL9py.css +1 -0
- package/dist/web/_app/immutable/assets/KanbanView.BOaI5KFL.css +1 -0
- package/dist/web/_app/immutable/assets/Link.vV0ne105.css +1 -0
- package/dist/web/_app/immutable/assets/Markdown.BZnsSOSf.css +1 -0
- package/dist/web/_app/immutable/assets/Rail.ilusFgD4.css +1 -0
- package/dist/web/_app/immutable/assets/SettingsDialog.D7-BO6S_.css +1 -0
- package/dist/web/_app/immutable/assets/Spinner.UBfl0pab.css +1 -0
- package/dist/web/_app/immutable/assets/StopFilledAlt.fNlDN65D.css +1 -0
- package/dist/web/_app/immutable/assets/TimelineView.xAZBJhHw.css +1 -0
- package/dist/web/_app/immutable/assets/WorkspaceView.C8ErUJAY.css +1 -0
- package/dist/web/_app/immutable/assets/button.BlLm4Dg1.css +1 -0
- package/dist/web/_app/immutable/assets/history-summary.LpmHXasl.css +1 -0
- package/dist/web/_app/immutable/assets/ibm-plex-mono-latin-400-normal.CvHOgSBP.woff +0 -0
- package/dist/web/_app/immutable/assets/ibm-plex-mono-latin-400-normal.DMJ8VG8y.woff2 +0 -0
- package/dist/web/_app/immutable/assets/ibm-plex-mono-latin-500-normal.CB9ihrfo.woff +0 -0
- package/dist/web/_app/immutable/assets/ibm-plex-mono-latin-500-normal.DSY6xOcd.woff2 +0 -0
- package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-400-italic.CZTNEAuW.woff2 +0 -0
- package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-400-italic.CsGl1sm0.woff +0 -0
- package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-400-normal.CDDApCn2.woff2 +0 -0
- package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-400-normal.CYLoc0-x.woff +0 -0
- package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-500-italic.BNK2_mGO.woff2 +0 -0
- package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-500-italic.DpEwFAQM.woff +0 -0
- package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-500-normal.6ng42L7E.woff2 +0 -0
- package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-500-normal.BgVn5rGT.woff +0 -0
- package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-600-normal.Cu4Hd6ag.woff +0 -0
- package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-600-normal.CuJfVYMP.woff2 +0 -0
- package/dist/web/_app/immutable/assets/inline-list.cqga56xT.css +1 -0
- package/dist/web/_app/immutable/assets/list-columns.BgnafZ4K.css +1 -0
- package/dist/web/_app/immutable/assets/realtime.DDCWxn3B.css +1 -0
- package/dist/web/_app/immutable/assets/select.B90KUqR4.css +1 -0
- package/dist/web/_app/immutable/assets/sheet.RF9RBmml.css +1 -0
- package/dist/web/_app/immutable/chunks/22qYtvr82.js +1 -0
- package/dist/web/_app/immutable/chunks/3anKjXOb.js +1 -0
- package/dist/web/_app/immutable/chunks/6S9WOky52.js +1 -0
- package/dist/web/_app/immutable/chunks/7xJ91z7d.js +2 -0
- package/dist/web/_app/immutable/chunks/9K8VREGP.js +1 -0
- package/dist/web/_app/immutable/chunks/B-TGZnCt2.js +1 -0
- package/dist/web/_app/immutable/chunks/B-n5q6ku.js +1 -0
- package/dist/web/_app/immutable/chunks/B0p2fSEV2.js +1 -0
- package/dist/web/_app/immutable/chunks/B2oi87jG.js +2 -0
- package/dist/web/_app/immutable/chunks/B4DG5QOL.js +1 -0
- package/dist/web/_app/immutable/chunks/B6Lt-qaJ.js +1 -0
- package/dist/web/_app/immutable/chunks/B6qeIQZz.js +2 -0
- package/dist/web/_app/immutable/chunks/B9KfEsQw2.js +1 -0
- package/dist/web/_app/immutable/chunks/B9VRF5aH2.js +1 -0
- package/dist/web/_app/immutable/chunks/BCQQzpbj.js +1 -0
- package/dist/web/_app/immutable/chunks/BF0vIqH9.js +1 -0
- package/dist/web/_app/immutable/chunks/BFp1K70l.js +8 -0
- package/dist/web/_app/immutable/chunks/BFr7Funh.js +1 -0
- package/dist/web/_app/immutable/chunks/BFx32D20.js +2 -0
- package/dist/web/_app/immutable/chunks/BLs1h0Rh2.js +1 -0
- package/dist/web/_app/immutable/chunks/BPzV_xOS2.js +1 -0
- package/dist/web/_app/immutable/chunks/BRvMjAzW.js +2 -0
- package/dist/web/_app/immutable/chunks/BV-iCKqa.js +1 -0
- package/dist/web/_app/immutable/chunks/BZi3uKF4.js +1 -0
- package/dist/web/_app/immutable/chunks/B_PyL87x.js +2 -0
- package/dist/web/_app/immutable/chunks/BbfHGU9n2.js +1 -0
- package/dist/web/_app/immutable/chunks/Bbqu2-5G2.js +1 -0
- package/dist/web/_app/immutable/chunks/BdWZJpmv.js +2 -0
- package/dist/web/_app/immutable/chunks/BfnFtsiY.js +1 -0
- package/dist/web/_app/immutable/chunks/BlgjVmFM2.js +14 -0
- package/dist/web/_app/immutable/chunks/BmgXvmIG.js +5 -0
- package/dist/web/_app/immutable/chunks/BpCG9m962.js +1 -0
- package/dist/web/_app/immutable/chunks/BrveeylZ.js +1 -0
- package/dist/web/_app/immutable/chunks/BsW72fyR2.js +1 -0
- package/dist/web/_app/immutable/chunks/Bti_XKwx.js +2692 -0
- package/dist/web/_app/immutable/chunks/BuhW5Fr0.js +689 -0
- package/dist/web/_app/immutable/chunks/Bx74EEyn2.js +1 -0
- package/dist/web/_app/immutable/chunks/BxPN0T61.js +1 -0
- package/dist/web/_app/immutable/chunks/Bxk27YWG.js +1 -0
- package/dist/web/_app/immutable/chunks/Bz9lrgGs.js +1 -0
- package/dist/web/_app/immutable/chunks/BzaxZ6j12.js +1 -0
- package/dist/web/_app/immutable/chunks/C1B4xDs0.js +1 -0
- package/dist/web/_app/immutable/chunks/C1trcC8M.js +7 -0
- package/dist/web/_app/immutable/chunks/C3F_NMTk.js +3 -0
- package/dist/web/_app/immutable/chunks/C4PZmGUQ.js +2 -0
- package/dist/web/_app/immutable/chunks/C6wYiSz8.js +1 -0
- package/dist/web/_app/immutable/chunks/C70saxIl.js +1 -0
- package/dist/web/_app/immutable/chunks/C9tvkk7Y2.js +22 -0
- package/dist/web/_app/immutable/chunks/CE1XZ5DE.js +1 -0
- package/dist/web/_app/immutable/chunks/CEahbtnP.js +1 -0
- package/dist/web/_app/immutable/chunks/CGkd0a-c2.js +2 -0
- package/dist/web/_app/immutable/chunks/CIoNEHQ82.js +184 -0
- package/dist/web/_app/immutable/chunks/CK4z74w5.js +1 -0
- package/dist/web/_app/immutable/chunks/COo3HgCZ.js +1 -0
- package/dist/web/_app/immutable/chunks/CP8_U450.js +1 -0
- package/dist/web/_app/immutable/chunks/CQ1eQ93t2.js +6 -0
- package/dist/web/_app/immutable/chunks/CQyBDccA.js +1 -0
- package/dist/web/_app/immutable/chunks/CUFQMEBn2.js +1 -0
- package/dist/web/_app/immutable/chunks/CV5OSCJc.js +1 -0
- package/dist/web/_app/immutable/chunks/CYEYDNwO2.js +1 -0
- package/dist/web/_app/immutable/chunks/CZgFaimi2.js +83 -0
- package/dist/web/_app/immutable/chunks/CZqvCTCv.js +1 -0
- package/dist/web/_app/immutable/chunks/CcWaWbrI2.js +1 -0
- package/dist/web/_app/immutable/chunks/CdtzRVZK.js +1 -0
- package/dist/web/_app/immutable/chunks/CfYG72Hc.js +1 -0
- package/dist/web/_app/immutable/chunks/Cg-ND0cl.js +1 -0
- package/dist/web/_app/immutable/chunks/Ch1kmm3J2.js +1 -0
- package/dist/web/_app/immutable/chunks/CjiMLTwX2.js +1 -0
- package/dist/web/_app/immutable/chunks/CkoeSJ8K.js +6 -0
- package/dist/web/_app/immutable/chunks/Cp87MaaW.js +1 -0
- package/dist/web/_app/immutable/chunks/Cqm5wAin.js +1 -0
- package/dist/web/_app/immutable/chunks/Ct1uesdW.js +2 -0
- package/dist/web/_app/immutable/chunks/CuYPXpWU.js +1 -0
- package/dist/web/_app/immutable/chunks/Cuq8J2Td.js +1 -0
- package/dist/web/_app/immutable/chunks/CvSEodTA.js +1 -0
- package/dist/web/_app/immutable/chunks/CvqqrTrj.js +1 -0
- package/dist/web/_app/immutable/chunks/CzXdOgVl2.js +7 -0
- package/dist/web/_app/immutable/chunks/D0W7c6Sg.js +185 -0
- package/dist/web/_app/immutable/chunks/D0rBhnqB2.js +1 -0
- package/dist/web/_app/immutable/chunks/D1-GZSN1.js +1 -0
- package/dist/web/_app/immutable/chunks/D1BLcNJ7.js +1 -0
- package/dist/web/_app/immutable/chunks/D1yvtriI.js +1 -0
- package/dist/web/_app/immutable/chunks/D25NMRpl.js +1 -0
- package/dist/web/_app/immutable/chunks/D3F675fu2.js +2 -0
- package/dist/web/_app/immutable/chunks/D4UrtGC1.js +1 -0
- package/dist/web/_app/immutable/chunks/D8wZ2xul.js +4 -0
- package/dist/web/_app/immutable/chunks/DA3HEX3X.js +1 -0
- package/dist/web/_app/immutable/chunks/DE2TCESD2.js +1 -0
- package/dist/web/_app/immutable/chunks/DN-gIRdd2.js +1 -0
- package/dist/web/_app/immutable/chunks/DPUVu0T0.js +1 -0
- package/dist/web/_app/immutable/chunks/DPcejqKZ.js +1 -0
- package/dist/web/_app/immutable/chunks/DQMWa2t7.js +1 -0
- package/dist/web/_app/immutable/chunks/DRPMJ-3M.js +2 -0
- package/dist/web/_app/immutable/chunks/DRPnwQAm.js +1 -0
- package/dist/web/_app/immutable/chunks/DXmfl4Hq2.js +1 -0
- package/dist/web/_app/immutable/chunks/DXsFrDer2.js +1 -0
- package/dist/web/_app/immutable/chunks/DYc5KW3F.js +1 -0
- package/dist/web/_app/immutable/chunks/DcPrzUMJ.js +1 -0
- package/dist/web/_app/immutable/chunks/DdQVGKgM.js +1 -0
- package/dist/web/_app/immutable/chunks/DiFfW--R2.js +2 -0
- package/dist/web/_app/immutable/chunks/DjIqa1_y.js +2 -0
- package/dist/web/_app/immutable/chunks/Dl63IUnH2.js +224 -0
- package/dist/web/_app/immutable/chunks/DmFdD6zT.js +1 -0
- package/dist/web/_app/immutable/chunks/Dn3R8S-U.js +1 -0
- package/dist/web/_app/immutable/chunks/DpNr1GQ2.js +1 -0
- package/dist/web/_app/immutable/chunks/DsFEd8vL2.js +1 -0
- package/dist/web/_app/immutable/chunks/DuxziNnw.js +1 -0
- package/dist/web/_app/immutable/chunks/FuiJnZG0.js +1 -0
- package/dist/web/_app/immutable/chunks/Izkulod7.js +1 -0
- package/dist/web/_app/immutable/chunks/LYL8znYR2.js +23 -0
- package/dist/web/_app/immutable/chunks/ON7Gta0d.js +1 -0
- package/dist/web/_app/immutable/chunks/PhN6tXuJ2.js +1 -0
- package/dist/web/_app/immutable/chunks/PyLyCpuL.js +1 -0
- package/dist/web/_app/immutable/chunks/RG7IUVLn2.js +2 -0
- package/dist/web/_app/immutable/chunks/RK4gCWN0.js +2 -0
- package/dist/web/_app/immutable/chunks/SnzlL4ZV.js +1 -0
- package/dist/web/_app/immutable/chunks/XcWejFm_.js +5 -0
- package/dist/web/_app/immutable/chunks/Xkp5hSA1.js +1 -0
- package/dist/web/_app/immutable/chunks/al_nidE9.js +1 -0
- package/dist/web/_app/immutable/chunks/e50-izZO2.js +1 -0
- package/dist/web/_app/immutable/chunks/golz20La2.js +2 -0
- package/dist/web/_app/immutable/chunks/hG-QCarB.js +1 -0
- package/dist/web/_app/immutable/chunks/kNaey6uv.js +1 -0
- package/dist/web/_app/immutable/chunks/nXReuy-5.js +3 -0
- package/dist/web/_app/immutable/chunks/o61aZZFZ2.js +66 -0
- package/dist/web/_app/immutable/chunks/qwr5boV8.js +1 -0
- package/dist/web/_app/immutable/chunks/rjjyuGhb.js +1 -0
- package/dist/web/_app/immutable/chunks/uBgoVlsx.js +3 -0
- package/dist/web/_app/immutable/chunks/xY0c-UfG.js +3 -0
- package/dist/web/_app/immutable/chunks/xeNvx4Bl2.js +1 -0
- package/dist/web/_app/immutable/chunks/xihTtKlq.js +1 -0
- package/dist/web/_app/immutable/entry/app.dqA31fjy.js +2 -0
- package/dist/web/_app/immutable/entry/start.BB1XrAea.js +1 -0
- package/dist/web/_app/immutable/nodes/0.dALEQAnu.js +2 -0
- package/dist/web/_app/immutable/nodes/1.aFU32Ukj.js +1 -0
- package/dist/web/_app/immutable/nodes/10.C2wB-OnW.js +1 -0
- package/dist/web/_app/immutable/nodes/11.CI3a8Rj5.js +1 -0
- package/dist/web/_app/immutable/nodes/12.CsTvsKzB.js +1 -0
- package/dist/web/_app/immutable/nodes/13.CYrHXCA8.js +1 -0
- package/dist/web/_app/immutable/nodes/14.B31HrQ26.js +1 -0
- package/dist/web/_app/immutable/nodes/15.DxgnZ61h.js +1 -0
- package/dist/web/_app/immutable/nodes/16.DAP8cwVb.js +1 -0
- package/dist/web/_app/immutable/nodes/17.CmwXtCDY.js +77 -0
- package/dist/web/_app/immutable/nodes/2.BuGXEIlN.js +122 -0
- package/dist/web/_app/immutable/nodes/3.CmhZJWHE.js +6 -0
- package/dist/web/_app/immutable/nodes/4.BRfoPTm-.js +11 -0
- package/dist/web/_app/immutable/nodes/5.C7gPuZM_.js +1 -0
- package/dist/web/_app/immutable/nodes/6.qKODVbya.js +6 -0
- package/dist/web/_app/immutable/nodes/7.BZO37zAJ.js +1 -0
- package/dist/web/_app/immutable/nodes/8.xF_Dd1BO.js +1 -0
- package/dist/web/_app/immutable/nodes/9.Bow4UyKV.js +1 -0
- package/dist/web/_app/version.json +1 -1
- package/dist/web/favicon-16.png +0 -0
- package/dist/web/favicon-180.png +0 -0
- package/dist/web/favicon-32.png +0 -0
- package/dist/web/favicon-48.png +0 -0
- package/dist/web/favicon-512.png +0 -0
- package/dist/web/favicon.ico +0 -0
- package/dist/web/favicon.svg +8 -0
- package/dist/web/index.html +56 -21
- package/dist/web/studiograph-logomark.svg +29 -0
- package/package.json +35 -14
- package/dist/agent/skills/enrich-entities.md +0 -136
- package/dist/agent/skills/sync-configuration.md +0 -119
- package/dist/agent/skills/sync-setup.md +0 -82
- package/dist/agent/tools/message-tools.d.ts +0 -42
- package/dist/agent/tools/message-tools.js +0 -106
- package/dist/agent/tools/message-tools.js.map +0 -1
- package/dist/cli/commands/app.d.ts +0 -7
- package/dist/cli/commands/app.js +0 -268
- package/dist/cli/commands/app.js.map +0 -1
- package/dist/cli/commands/clear.d.ts +0 -5
- package/dist/cli/commands/clear.js +0 -36
- package/dist/cli/commands/clear.js.map +0 -1
- package/dist/cli/commands/collection.d.ts +0 -10
- package/dist/cli/commands/collection.js.map +0 -1
- package/dist/cli/commands/join.d.ts +0 -9
- package/dist/cli/commands/join.js +0 -255
- package/dist/cli/commands/join.js.map +0 -1
- package/dist/cli/commands/start.d.ts +0 -7
- package/dist/cli/commands/start.js +0 -584
- package/dist/cli/commands/start.js.map +0 -1
- package/dist/cli/commands/update.d.ts +0 -8
- package/dist/cli/commands/update.js +0 -155
- package/dist/cli/commands/update.js.map +0 -1
- package/dist/cli/commands/user.d.ts +0 -7
- package/dist/cli/commands/user.js +0 -175
- package/dist/cli/commands/user.js.map +0 -1
- package/dist/cli/scaffolding.d.ts +0 -12
- package/dist/cli/scaffolding.js +0 -397
- package/dist/cli/scaffolding.js.map +0 -1
- package/dist/integrations/registry.d.ts +0 -8
- package/dist/integrations/registry.js +0 -7
- package/dist/integrations/registry.js.map +0 -1
- package/dist/integrations/types.d.ts +0 -43
- package/dist/integrations/types.js +0 -5
- package/dist/integrations/types.js.map +0 -1
- package/dist/lib/lib/utils.d.ts +0 -2
- package/dist/lib/lib/utils.js +0 -6
- package/dist/lib/lib/utils.js.map +0 -1
- package/dist/server/chrome/chrome.css +0 -691
- package/dist/server/chrome/chrome.js +0 -374
- package/dist/server/commit-scheduler.d.ts +0 -39
- package/dist/server/commit-scheduler.js +0 -113
- package/dist/server/commit-scheduler.js.map +0 -1
- package/dist/server/plugin-loader.d.ts +0 -53
- package/dist/server/plugin-loader.js +0 -155
- package/dist/server/plugin-loader.js.map +0 -1
- package/dist/server/routes/meeting-ingest-api.d.ts +0 -14
- package/dist/server/routes/meeting-ingest-api.js.map +0 -1
- package/dist/server/routes/messages-api.d.ts +0 -15
- package/dist/server/routes/messages-api.js +0 -385
- package/dist/server/routes/messages-api.js.map +0 -1
- package/dist/services/batch-processor.d.ts +0 -49
- package/dist/services/batch-processor.js +0 -166
- package/dist/services/batch-processor.js.map +0 -1
- package/dist/services/briefing.d.ts +0 -26
- package/dist/services/briefing.js +0 -230
- package/dist/services/briefing.js.map +0 -1
- package/dist/services/heartbeat.d.ts +0 -28
- package/dist/services/heartbeat.js +0 -183
- package/dist/services/heartbeat.js.map +0 -1
- package/dist/services/image-import-service.d.ts +0 -24
- package/dist/services/image-import-service.js +0 -108
- package/dist/services/image-import-service.js.map +0 -1
- package/dist/services/insights.d.ts +0 -38
- package/dist/services/insights.js +0 -269
- package/dist/services/insights.js.map +0 -1
- package/dist/services/meeting-processor.js.map +0 -1
- package/dist/services/message-service.d.ts +0 -68
- package/dist/services/message-service.js +0 -220
- package/dist/services/message-service.js.map +0 -1
- package/dist/utils/workspace-config.d.ts +0 -8
- package/dist/utils/workspace-config.js +0 -22
- package/dist/utils/workspace-config.js.map +0 -1
- package/dist/web/_app/immutable/assets/0.uPSqtsC5.css +0 -1
- package/dist/web/_app/immutable/assets/11.2jzI3cZY.css +0 -1
- package/dist/web/_app/immutable/assets/12.CT4xL4K3.css +0 -1
- package/dist/web/_app/immutable/assets/13.BUrHkYry.css +0 -1
- package/dist/web/_app/immutable/assets/2.DpQWr6q6.css +0 -1
- package/dist/web/_app/immutable/assets/3.BxdqT7zi.css +0 -1
- package/dist/web/_app/immutable/assets/4.DdNqjd0T.css +0 -1
- package/dist/web/_app/immutable/assets/5.DFeGxLYf.css +0 -1
- package/dist/web/_app/immutable/assets/6.DXZr_rI_.css +0 -1
- package/dist/web/_app/immutable/assets/GraphView.D9ePpZez.css +0 -1
- package/dist/web/_app/immutable/assets/Toaster.rN8r_Hzv.css +0 -1
- package/dist/web/_app/immutable/assets/ViewToolbar.BWE03S64.css +0 -1
- package/dist/web/_app/immutable/assets/WorkspaceView.CgGDi_Zb.css +0 -1
- package/dist/web/_app/immutable/assets/wikilinks.CzMBkUMB.css +0 -1
- package/dist/web/_app/immutable/chunks/-jG4Obyh.js +0 -4
- package/dist/web/_app/immutable/chunks/2nrc8f_O.js +0 -1
- package/dist/web/_app/immutable/chunks/7S2LGqoP.js +0 -2
- package/dist/web/_app/immutable/chunks/8Q3ZJIYu.js +0 -1
- package/dist/web/_app/immutable/chunks/B8ydT5xX.js +0 -2
- package/dist/web/_app/immutable/chunks/BB_5th5W.js +0 -3383
- package/dist/web/_app/immutable/chunks/BEn6N5c2.js +0 -1
- package/dist/web/_app/immutable/chunks/BFNNbCAM.js +0 -1
- package/dist/web/_app/immutable/chunks/BFZZEUd5.js +0 -1
- package/dist/web/_app/immutable/chunks/BGk8kfOE.js +0 -2
- package/dist/web/_app/immutable/chunks/BIBCr278.js +0 -1
- package/dist/web/_app/immutable/chunks/BPCkkwqe.js +0 -1
- package/dist/web/_app/immutable/chunks/BhlvzGQx.js +0 -1
- package/dist/web/_app/immutable/chunks/BlMknQeF.js +0 -1
- package/dist/web/_app/immutable/chunks/BpjqrlCg.js +0 -1
- package/dist/web/_app/immutable/chunks/BrebtJNG.js +0 -18
- package/dist/web/_app/immutable/chunks/ByBZ7JIT.js +0 -1
- package/dist/web/_app/immutable/chunks/Bz0ZjVQE.js +0 -2
- package/dist/web/_app/immutable/chunks/BzJTZOK2.js +0 -1
- package/dist/web/_app/immutable/chunks/C0LVZhvn.js +0 -1
- package/dist/web/_app/immutable/chunks/C3uBrOS5.js +0 -1
- package/dist/web/_app/immutable/chunks/C8R1sDpW.js +0 -1
- package/dist/web/_app/immutable/chunks/CDRHrs0g.js +0 -1
- package/dist/web/_app/immutable/chunks/CN5_py1I.js +0 -1
- package/dist/web/_app/immutable/chunks/CPne482a.js +0 -1
- package/dist/web/_app/immutable/chunks/CSVbGg_b.js +0 -5
- package/dist/web/_app/immutable/chunks/CWyU-seV.js +0 -1
- package/dist/web/_app/immutable/chunks/CX_61fY8.js +0 -5
- package/dist/web/_app/immutable/chunks/CYrVHOHA.js +0 -1
- package/dist/web/_app/immutable/chunks/ChsiIm-E.js +0 -1
- package/dist/web/_app/immutable/chunks/CojKppbh.js +0 -1
- package/dist/web/_app/immutable/chunks/CqkleIqs.js +0 -1
- package/dist/web/_app/immutable/chunks/CtYLtD7K.js +0 -1
- package/dist/web/_app/immutable/chunks/D-HDy5qS.js +0 -1
- package/dist/web/_app/immutable/chunks/D5aIYSkd.js +0 -1
- package/dist/web/_app/immutable/chunks/DBBXARVf.js +0 -1
- package/dist/web/_app/immutable/chunks/DFYOFE3o.js +0 -1
- package/dist/web/_app/immutable/chunks/DKaafS50.js +0 -1
- package/dist/web/_app/immutable/chunks/DUMOo1Pn.js +0 -1
- package/dist/web/_app/immutable/chunks/DWX9f6AF.js +0 -1
- package/dist/web/_app/immutable/chunks/DY8-EONP.js +0 -1
- package/dist/web/_app/immutable/chunks/DkoHPElM.js +0 -1
- package/dist/web/_app/immutable/chunks/DnL9f0lc.js +0 -7
- package/dist/web/_app/immutable/chunks/DsnmJJEf.js +0 -1
- package/dist/web/_app/immutable/chunks/DujahU3W.js +0 -1
- package/dist/web/_app/immutable/chunks/FBn-ES5k.js +0 -1
- package/dist/web/_app/immutable/chunks/HQpwSOb3.js +0 -1
- package/dist/web/_app/immutable/chunks/KyjzlWRN.js +0 -2
- package/dist/web/_app/immutable/chunks/PPVm8Dsz.js +0 -1
- package/dist/web/_app/immutable/chunks/UwYfmrPx.js +0 -2
- package/dist/web/_app/immutable/chunks/W25ZVI8L.js +0 -2
- package/dist/web/_app/immutable/chunks/WSUKABI_.js +0 -1
- package/dist/web/_app/immutable/chunks/XjsuEnNE.js +0 -5
- package/dist/web/_app/immutable/chunks/ZD6ARAtb.js +0 -1
- package/dist/web/_app/immutable/chunks/pBTf4stg.js +0 -2
- package/dist/web/_app/immutable/chunks/rGIarcnp.js +0 -1
- package/dist/web/_app/immutable/chunks/vxEtkL8z.js +0 -1
- package/dist/web/_app/immutable/chunks/wDIGUaoU.js +0 -3
- package/dist/web/_app/immutable/entry/app.ZHiTM8WS.js +0 -2
- package/dist/web/_app/immutable/entry/start.C9-FfAVc.js +0 -1
- package/dist/web/_app/immutable/nodes/0.D92Orz8k.js +0 -2
- package/dist/web/_app/immutable/nodes/1.BMdyglM_.js +0 -1
- package/dist/web/_app/immutable/nodes/10.BilVDHSL.js +0 -1
- package/dist/web/_app/immutable/nodes/11.CS9E0Hic.js +0 -1
- package/dist/web/_app/immutable/nodes/12.D3BOxYzG.js +0 -1
- package/dist/web/_app/immutable/nodes/13.CClMKYtN.js +0 -1
- package/dist/web/_app/immutable/nodes/2.C8KKElPL.js +0 -267
- package/dist/web/_app/immutable/nodes/3.C5n5uiWU.js +0 -5
- package/dist/web/_app/immutable/nodes/4.DcGVvgiL.js +0 -11
- package/dist/web/_app/immutable/nodes/5.DxIjnFQO.js +0 -4
- package/dist/web/_app/immutable/nodes/6.lkh6kKLj.js +0 -1
- package/dist/web/_app/immutable/nodes/7.Bg7SbfhA.js +0 -1
- package/dist/web/_app/immutable/nodes/8.DcXWCNBE.js +0 -1
- package/dist/web/_app/immutable/nodes/9.Cefi8Jfm.js +0 -1
|
@@ -0,0 +1,653 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phase 8 — auth.db column upgrades for per-user secret encryption.
|
|
3
|
+
*
|
|
4
|
+
* Two tables in `auth.db` carry per-user secrets:
|
|
5
|
+
*
|
|
6
|
+
* 1. `oauth_tokens.data_json` (TEXT NOT NULL) holds the full MCP OAuth
|
|
7
|
+
* payload (tokens + client info + code verifier) for a user+connector.
|
|
8
|
+
* Its value is a JSON blob containing the access/refresh tokens.
|
|
9
|
+
* 2. `user_preferences.settings_json` (TEXT NOT NULL DEFAULT '{}') holds
|
|
10
|
+
* a free-form per-user key/value map. Today the only secret it
|
|
11
|
+
* carries is the Deepgram key (meeting capture); the rest is
|
|
12
|
+
* non-secret prefs (default folder, calendar config). Discrimination
|
|
13
|
+
* is registry-driven — any key whose registry entry is
|
|
14
|
+
* `user-secret` moves to the new ciphertext column.
|
|
15
|
+
*
|
|
16
|
+
* Strategy:
|
|
17
|
+
*
|
|
18
|
+
* - `oauth_tokens`: SQLite cannot ALTER a TEXT NOT NULL column to be
|
|
19
|
+
* nullable. The standard pattern is a transactional table rebuild
|
|
20
|
+
* (CREATE NEW + INSERT...SELECT + DROP + RENAME). We do that, with
|
|
21
|
+
* the per-row encryption running in the Node loop between SELECT and
|
|
22
|
+
* INSERT.
|
|
23
|
+
* - `user_preferences`: column additions are easy (no constraints
|
|
24
|
+
* block us), so we just ALTER to add `settings_ciphertext` and
|
|
25
|
+
* `key_version`, then walk each row and partition keys by
|
|
26
|
+
* classification.
|
|
27
|
+
*
|
|
28
|
+
* Safety:
|
|
29
|
+
*
|
|
30
|
+
* - Before any DDL, `auth.db` is copied to
|
|
31
|
+
* `auth.db.backup.<unix-ts-ms>`. If the backup write fails, the
|
|
32
|
+
* migration aborts before touching the source DB.
|
|
33
|
+
* - The rebuild runs inside a single transaction. SQLite atomic
|
|
34
|
+
* semantics give us rollback on any per-row encryption failure.
|
|
35
|
+
* - A row-count integrity check fires before COMMIT; mismatch
|
|
36
|
+
* triggers ROLLBACK and a thrown error.
|
|
37
|
+
* - Idempotent: completion is recorded in a new `meta` table.
|
|
38
|
+
* Re-running is a fast no-op.
|
|
39
|
+
* - Half-state guard: at boot we refuse to start if we find
|
|
40
|
+
* `data_json IS NOT NULL AND data_ciphertext IS NOT NULL` on any
|
|
41
|
+
* row — that means a previous run committed partial state.
|
|
42
|
+
*
|
|
43
|
+
* AAD binding for every encrypted blob:
|
|
44
|
+
*
|
|
45
|
+
* `{ scope: 'user', scopeId: <user_id>, key: <column>, keyVersion: 'mk_v1' }`
|
|
46
|
+
*
|
|
47
|
+
* Swapping a ciphertext between users invalidates the AAD; tampering
|
|
48
|
+
* with the row triggers AEAD failure on decrypt.
|
|
49
|
+
*/
|
|
50
|
+
import Database from 'better-sqlite3';
|
|
51
|
+
import { chmodSync, copyFileSync, existsSync } from 'fs';
|
|
52
|
+
import { encrypt, decrypt } from './encryption.js';
|
|
53
|
+
import { getKeyDef } from './registry.js';
|
|
54
|
+
import { log } from '../../utils/log.js';
|
|
55
|
+
const DEFAULT_KEY_VERSION = 'mk_v1';
|
|
56
|
+
const MIGRATION_META_KEY = 'auth_db_phase8_migrated_at';
|
|
57
|
+
const PREFS_SECRET_BLOB_KEY = 'user_preferences.settings';
|
|
58
|
+
const OAUTH_TOKENS_KEY = 'oauth_token';
|
|
59
|
+
/**
|
|
60
|
+
* Run the Phase 8 auth.db migration. Idempotent; returns immediately
|
|
61
|
+
* with `skipped: true` once the meta row is present.
|
|
62
|
+
*
|
|
63
|
+
* Caller MUST hold the only open handle to auth.db while this runs —
|
|
64
|
+
* the migration opens its own Database connection internally so that
|
|
65
|
+
* AuthService's WAL/foreign-keys configuration doesn't bleed in.
|
|
66
|
+
* In `serve.ts` this runs before AuthService is constructed.
|
|
67
|
+
*/
|
|
68
|
+
export function migrateAuthDbPhase8(opts) {
|
|
69
|
+
if (!existsSync(opts.authDbPath)) {
|
|
70
|
+
// Fresh install — no DB to migrate. We still want the meta marker so
|
|
71
|
+
// a later AuthService construction doesn't redo migration on a DB
|
|
72
|
+
// that was created with the new schema from scratch. But at this
|
|
73
|
+
// point the DB doesn't exist, so we have nothing to write to.
|
|
74
|
+
// Defer: AuthService.constructor will create the DB with the new
|
|
75
|
+
// shape and write the meta row itself.
|
|
76
|
+
return { skipped: true, oauthRowsMigrated: 0, prefsRowsMigrated: 0 };
|
|
77
|
+
}
|
|
78
|
+
const keyVersion = opts.keyVersion ?? DEFAULT_KEY_VERSION;
|
|
79
|
+
// Open the DB. Brief connection lifecycle — we close before returning so
|
|
80
|
+
// the caller can open it fresh through AuthService.
|
|
81
|
+
const db = new Database(opts.authDbPath);
|
|
82
|
+
try {
|
|
83
|
+
ensureMetaTable(db);
|
|
84
|
+
if (alreadyMigrated(db)) {
|
|
85
|
+
return { skipped: true, oauthRowsMigrated: 0, prefsRowsMigrated: 0 };
|
|
86
|
+
}
|
|
87
|
+
// Belt-and-suspenders: a half-state from a previous crashed run should
|
|
88
|
+
// never reach this point (the migration runs inside a transaction), but
|
|
89
|
+
// if it somehow did, refuse to continue silently.
|
|
90
|
+
detectHalfState(db);
|
|
91
|
+
// Backup before any DDL. If this throws, the source DB is untouched.
|
|
92
|
+
const backupPath = backupDb(opts.authDbPath);
|
|
93
|
+
let oauthRowsMigrated = 0;
|
|
94
|
+
let prefsRowsMigrated = 0;
|
|
95
|
+
try {
|
|
96
|
+
// The whole migration runs in one transaction. If any step
|
|
97
|
+
// throws (encryption failure, row-count mismatch, anything),
|
|
98
|
+
// better-sqlite3 rolls back automatically.
|
|
99
|
+
db.transaction(() => {
|
|
100
|
+
oauthRowsMigrated = migrateOAuthTokens(db, opts.masterKey, keyVersion);
|
|
101
|
+
prefsRowsMigrated = migrateUserPreferences(db, opts.masterKey, keyVersion);
|
|
102
|
+
// Mark completion inside the same transaction so the meta row
|
|
103
|
+
// and the new schema commit atomically.
|
|
104
|
+
db.prepare(`INSERT INTO meta (key, value) VALUES (?, ?)
|
|
105
|
+
ON CONFLICT(key) DO UPDATE SET value = excluded.value`).run(MIGRATION_META_KEY, String(Date.now()));
|
|
106
|
+
})();
|
|
107
|
+
}
|
|
108
|
+
catch (err) {
|
|
109
|
+
// Re-throw after logging. The caller (serve.ts) refuses to start
|
|
110
|
+
// on migration error; the backup file is the recovery path.
|
|
111
|
+
log.error(`[secrets] auth.db Phase 8 migration FAILED: ${err instanceof Error ? err.message : String(err)}. ` +
|
|
112
|
+
`Restore from backup at ${backupPath} and investigate before retrying.`);
|
|
113
|
+
throw err;
|
|
114
|
+
}
|
|
115
|
+
return {
|
|
116
|
+
skipped: false,
|
|
117
|
+
oauthRowsMigrated,
|
|
118
|
+
prefsRowsMigrated,
|
|
119
|
+
backupPath,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
finally {
|
|
123
|
+
db.close();
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Public helper for AuthService to invoke at construction time once the
|
|
128
|
+
* migration is known to be complete (or didn't need to run on a fresh
|
|
129
|
+
* DB). On a freshly-created DB this writes the meta row so future
|
|
130
|
+
* `migrateAuthDbPhase8` calls short-circuit.
|
|
131
|
+
*/
|
|
132
|
+
export function markAuthDbPhase8Migrated(db) {
|
|
133
|
+
ensureMetaTable(db);
|
|
134
|
+
if (alreadyMigrated(db))
|
|
135
|
+
return;
|
|
136
|
+
db.prepare(`INSERT INTO meta (key, value) VALUES (?, ?)
|
|
137
|
+
ON CONFLICT(key) DO UPDATE SET value = excluded.value`).run(MIGRATION_META_KEY, String(Date.now()));
|
|
138
|
+
}
|
|
139
|
+
export function isAuthDbPhase8Migrated(db) {
|
|
140
|
+
ensureMetaTable(db);
|
|
141
|
+
return alreadyMigrated(db);
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Half-state detector for the live AuthService boot. Caller-friendly:
|
|
145
|
+
* returns true when migration appears complete-and-consistent. Throws
|
|
146
|
+
* on the corrupted shape (data_json non-null on a row that also has
|
|
147
|
+
* data_ciphertext) — that's evidence a previous run committed partial
|
|
148
|
+
* state and we'd rather refuse to start than serve corrupt OAuth data.
|
|
149
|
+
*/
|
|
150
|
+
export function assertAuthDbConsistent(db) {
|
|
151
|
+
if (!tableHasColumn(db, 'oauth_tokens', 'data_ciphertext'))
|
|
152
|
+
return;
|
|
153
|
+
detectHalfState(db);
|
|
154
|
+
}
|
|
155
|
+
// ─────────────────────────────────────────────────────────────────────
|
|
156
|
+
// Internals
|
|
157
|
+
// ─────────────────────────────────────────────────────────────────────
|
|
158
|
+
function ensureMetaTable(db) {
|
|
159
|
+
db.exec(`
|
|
160
|
+
CREATE TABLE IF NOT EXISTS meta (
|
|
161
|
+
key TEXT PRIMARY KEY,
|
|
162
|
+
value TEXT NOT NULL
|
|
163
|
+
)
|
|
164
|
+
`);
|
|
165
|
+
}
|
|
166
|
+
function alreadyMigrated(db) {
|
|
167
|
+
const row = db
|
|
168
|
+
.prepare('SELECT value FROM meta WHERE key = ?')
|
|
169
|
+
.get(MIGRATION_META_KEY);
|
|
170
|
+
return !!row;
|
|
171
|
+
}
|
|
172
|
+
function tableHasColumn(db, table, column) {
|
|
173
|
+
const cols = db
|
|
174
|
+
.prepare(`PRAGMA table_info(${table})`)
|
|
175
|
+
.all();
|
|
176
|
+
return cols.some((c) => c.name === column);
|
|
177
|
+
}
|
|
178
|
+
function detectHalfState(db) {
|
|
179
|
+
// Only meaningful when the new column already exists.
|
|
180
|
+
if (!tableHasColumn(db, 'oauth_tokens', 'data_ciphertext'))
|
|
181
|
+
return;
|
|
182
|
+
const row = db
|
|
183
|
+
.prepare(`SELECT COUNT(*) AS n FROM oauth_tokens
|
|
184
|
+
WHERE data_json IS NOT NULL AND data_ciphertext IS NOT NULL`)
|
|
185
|
+
.get();
|
|
186
|
+
if (row.n > 0) {
|
|
187
|
+
throw new Error(`auth.db Phase 8 half-state detected: ${row.n} row(s) in oauth_tokens have both ` +
|
|
188
|
+
`data_json and data_ciphertext populated. Restore from backup and investigate.`);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
function backupDb(authDbPath) {
|
|
192
|
+
const backupPath = `${authDbPath}.backup.${Date.now()}`;
|
|
193
|
+
// Codex M2: tighten the source file mode BEFORE copy so the backup
|
|
194
|
+
// can't inherit a wider 0644 than the running server would have set.
|
|
195
|
+
// The AuthService constructor chmods 0o600 on open, but the migration
|
|
196
|
+
// runs before AuthService is constructed — and a fresh-from-tarball
|
|
197
|
+
// or first-deploy auth.db can land as 0644 from `umask 022`. Setting
|
|
198
|
+
// both source and backup to 0o600 is defensive and idempotent.
|
|
199
|
+
// POSIX only; Windows ACLs differ and best-effort.
|
|
200
|
+
if (process.platform !== 'win32') {
|
|
201
|
+
try {
|
|
202
|
+
chmodSync(authDbPath, 0o600);
|
|
203
|
+
}
|
|
204
|
+
catch { /* non-fatal */ }
|
|
205
|
+
}
|
|
206
|
+
// copyFileSync copies the main DB file. WAL contents are flushed on the
|
|
207
|
+
// close that happens before we open here (auth.db is opened with WAL by
|
|
208
|
+
// AuthService), but we are running before AuthService starts. The DB
|
|
209
|
+
// file we copy here is the post-checkpoint snapshot from the previous
|
|
210
|
+
// session. Any not-yet-checkpointed WAL would belong to a write that
|
|
211
|
+
// happened in this process — and we haven't done any writes yet.
|
|
212
|
+
copyFileSync(authDbPath, backupPath);
|
|
213
|
+
// Backup carries credential-equivalent material (bcrypt hashes, OAuth
|
|
214
|
+
// payloads). Lock it down to the running user — copyFileSync mirrors
|
|
215
|
+
// the umask, not the source mode.
|
|
216
|
+
if (process.platform !== 'win32') {
|
|
217
|
+
try {
|
|
218
|
+
chmodSync(backupPath, 0o600);
|
|
219
|
+
}
|
|
220
|
+
catch { /* non-fatal */ }
|
|
221
|
+
}
|
|
222
|
+
return backupPath;
|
|
223
|
+
}
|
|
224
|
+
function migrateOAuthTokens(db, masterKey, keyVersion) {
|
|
225
|
+
// Snapshot the original table_info so we can preserve every existing
|
|
226
|
+
// column (the schema may have evolved beyond what we expect). The new
|
|
227
|
+
// table mirrors the original, except:
|
|
228
|
+
// - `data_json` drops the NOT NULL constraint (we'll write NULL).
|
|
229
|
+
// - Two new columns: `data_ciphertext` TEXT, `key_version` TEXT.
|
|
230
|
+
const origCols = db
|
|
231
|
+
.prepare('PRAGMA table_info(oauth_tokens)')
|
|
232
|
+
.all();
|
|
233
|
+
// Track the original primary-key columns so the rebuilt table keeps
|
|
234
|
+
// the same composite PK. Today this is (user_id, connector_name) but
|
|
235
|
+
// we mirror what PRAGMA reports rather than hardcode.
|
|
236
|
+
const pkCols = origCols
|
|
237
|
+
.filter((c) => c.pk > 0)
|
|
238
|
+
.sort((a, b) => a.pk - b.pk)
|
|
239
|
+
.map((c) => c.name);
|
|
240
|
+
// Tolerate pre-existing ciphertext columns. Non-serve construction paths
|
|
241
|
+
// (CLI `user`/`mcp`/`clone`/`sync` — anything that builds AuthService
|
|
242
|
+
// before the boot-time migration runs) add `data_ciphertext` and
|
|
243
|
+
// `key_version` idempotently in the constructor (auth-service.ts:378-387).
|
|
244
|
+
// If that happened first, the source table already has the new columns
|
|
245
|
+
// and pushing them again here would create a duplicate-column error in
|
|
246
|
+
// the rebuilt table. Detect and skip the re-add — the migration still
|
|
247
|
+
// needs to run to encrypt any rows that were left with `data_json`
|
|
248
|
+
// populated and `data_ciphertext` NULL (partial-state recovery).
|
|
249
|
+
const hasCiphertextCol = origCols.some((c) => c.name === 'data_ciphertext');
|
|
250
|
+
const hasKeyVersionCol = origCols.some((c) => c.name === 'key_version');
|
|
251
|
+
// Render each column in the same order/type as the original, except
|
|
252
|
+
// drop NOT NULL from `data_json` so we can write NULLs after encrypt.
|
|
253
|
+
// SQLite's PRAGMA returns `dflt_value` without surrounding parens for
|
|
254
|
+
// function expressions (e.g. `datetime('now')`), but the SQL grammar
|
|
255
|
+
// requires the parens — bare `DEFAULT datetime('now')` fails to parse.
|
|
256
|
+
// We wrap any non-literal default in parens.
|
|
257
|
+
const columnDefs = origCols.map((c) => {
|
|
258
|
+
const name = c.name;
|
|
259
|
+
const type = c.type || 'TEXT';
|
|
260
|
+
const notNull = c.notnull && name !== 'data_json' ? ' NOT NULL' : '';
|
|
261
|
+
const dflt = c.dflt_value !== null && c.dflt_value !== undefined
|
|
262
|
+
? ` DEFAULT ${renderDefault(c.dflt_value)}`
|
|
263
|
+
: '';
|
|
264
|
+
return `${name} ${type}${notNull}${dflt}`;
|
|
265
|
+
});
|
|
266
|
+
// Add the new columns ONLY if they're not already part of the source
|
|
267
|
+
// schema (see hasCiphertextCol / hasKeyVersionCol above).
|
|
268
|
+
if (!hasCiphertextCol)
|
|
269
|
+
columnDefs.push('data_ciphertext TEXT');
|
|
270
|
+
if (!hasKeyVersionCol)
|
|
271
|
+
columnDefs.push('key_version TEXT');
|
|
272
|
+
// Preserve foreign-key constraints from the original table.
|
|
273
|
+
// `PRAGMA foreign_key_list` reports each FK with its source column,
|
|
274
|
+
// target table+column, and ON UPDATE/DELETE actions. Multi-column FKs
|
|
275
|
+
// share an `id`; we group by id and emit one composite clause each.
|
|
276
|
+
const fkRows = db
|
|
277
|
+
.prepare('PRAGMA foreign_key_list(oauth_tokens)')
|
|
278
|
+
.all();
|
|
279
|
+
const fkGroups = new Map();
|
|
280
|
+
for (const fk of fkRows) {
|
|
281
|
+
if (!fkGroups.has(fk.id))
|
|
282
|
+
fkGroups.set(fk.id, []);
|
|
283
|
+
fkGroups.get(fk.id).push(fk);
|
|
284
|
+
}
|
|
285
|
+
const fkClauses = [];
|
|
286
|
+
for (const group of fkGroups.values()) {
|
|
287
|
+
group.sort((a, b) => a.seq - b.seq);
|
|
288
|
+
const cols = group.map((g) => g.from).join(', ');
|
|
289
|
+
const refCols = group.map((g) => g.to).join(', ');
|
|
290
|
+
const target = group[0].table;
|
|
291
|
+
const onDelete = group[0].on_delete && group[0].on_delete !== 'NO ACTION'
|
|
292
|
+
? ` ON DELETE ${group[0].on_delete}`
|
|
293
|
+
: '';
|
|
294
|
+
const onUpdate = group[0].on_update && group[0].on_update !== 'NO ACTION'
|
|
295
|
+
? ` ON UPDATE ${group[0].on_update}`
|
|
296
|
+
: '';
|
|
297
|
+
fkClauses.push(`FOREIGN KEY (${cols}) REFERENCES ${target}(${refCols})${onDelete}${onUpdate}`);
|
|
298
|
+
}
|
|
299
|
+
const pkClause = pkCols.length > 0 ? `, PRIMARY KEY (${pkCols.join(', ')})` : '';
|
|
300
|
+
const fkClause = fkClauses.length > 0 ? `, ${fkClauses.join(', ')}` : '';
|
|
301
|
+
// Drop any pre-existing v2 from a crashed prior attempt before we use the name.
|
|
302
|
+
db.exec('DROP TABLE IF EXISTS oauth_tokens_v2');
|
|
303
|
+
db.exec(`CREATE TABLE oauth_tokens_v2 (
|
|
304
|
+
${columnDefs.join(',\n ')}${pkClause}${fkClause}
|
|
305
|
+
)`);
|
|
306
|
+
// Snapshot any indexes/triggers on the original so we can recreate
|
|
307
|
+
// them on the rebuilt table. SQLite's sqlite_master lets us read the
|
|
308
|
+
// CREATE SQL verbatim; we'll have to rewrite "oauth_tokens" → "oauth_tokens"
|
|
309
|
+
// (the same name after rename) so the indexes apply correctly. Simplest
|
|
310
|
+
// path: capture them, drop them, recreate after rename. They reference
|
|
311
|
+
// the table by name, so they survive the rename automatically once we
|
|
312
|
+
// re-exec their original CREATE SQL.
|
|
313
|
+
const auxObjects = db
|
|
314
|
+
.prepare(`SELECT type, name, sql FROM sqlite_master
|
|
315
|
+
WHERE tbl_name = 'oauth_tokens' AND type IN ('index', 'trigger')
|
|
316
|
+
AND sql IS NOT NULL
|
|
317
|
+
AND name NOT LIKE 'sqlite_autoindex_%'`)
|
|
318
|
+
.all();
|
|
319
|
+
// Pre-count rows so we can verify integrity before committing.
|
|
320
|
+
const preCount = db.prepare('SELECT COUNT(*) AS n FROM oauth_tokens').get().n;
|
|
321
|
+
// Per-row encrypt + insert. We can't do this in a pure SQL
|
|
322
|
+
// INSERT...SELECT because encryption needs the Node-side cipher.
|
|
323
|
+
// The original columns SELECT is built from PRAGMA, so any future
|
|
324
|
+
// column additions flow through transparently.
|
|
325
|
+
const selectCols = origCols.map((c) => c.name);
|
|
326
|
+
const selectStmt = db.prepare(`SELECT ${selectCols.join(', ')} FROM oauth_tokens`);
|
|
327
|
+
// The INSERT shape depends on whether ciphertext columns pre-existed
|
|
328
|
+
// on the source table. When they did, they're already part of `selectCols`
|
|
329
|
+
// and we just rewrite the per-row values (encrypt rows where data_json
|
|
330
|
+
// is populated and ciphertext is missing — partial-state recovery).
|
|
331
|
+
// When they didn't, we append them after the original column list.
|
|
332
|
+
const insertCols = hasCiphertextCol && hasKeyVersionCol
|
|
333
|
+
? selectCols
|
|
334
|
+
: [...selectCols,
|
|
335
|
+
...(hasCiphertextCol ? [] : ['data_ciphertext']),
|
|
336
|
+
...(hasKeyVersionCol ? [] : ['key_version'])];
|
|
337
|
+
const insertPlaceholders = insertCols.map(() => '?').join(', ');
|
|
338
|
+
const insertStmt = db.prepare(`INSERT INTO oauth_tokens_v2 (${insertCols.join(', ')})
|
|
339
|
+
VALUES (${insertPlaceholders})`);
|
|
340
|
+
// Materialize rows before iterating + inserting — better-sqlite3 refuses
|
|
341
|
+
// to run another statement (the INSERT below) while a SELECT iterator is
|
|
342
|
+
// open. The oauth_tokens table is small (one row per user+connector), so
|
|
343
|
+
// the memory cost is trivial.
|
|
344
|
+
const rows = selectStmt.all();
|
|
345
|
+
let rowsMigrated = 0;
|
|
346
|
+
for (const row of rows) {
|
|
347
|
+
const userId = String(row['user_id'] ?? '');
|
|
348
|
+
const dataJson = row['data_json'];
|
|
349
|
+
const existingCiphertext = hasCiphertextCol ? row['data_ciphertext'] : null;
|
|
350
|
+
const existingKeyVersion = hasKeyVersionCol ? row['key_version'] : null;
|
|
351
|
+
// Decide the row's target state.
|
|
352
|
+
let nextDataJson;
|
|
353
|
+
let nextCiphertext;
|
|
354
|
+
let nextKeyVersion;
|
|
355
|
+
if (typeof dataJson === 'string') {
|
|
356
|
+
// data_json is populated → row needs encryption. detectHalfState()
|
|
357
|
+
// (run before this transaction) refuses to proceed when both
|
|
358
|
+
// data_json and data_ciphertext are populated, so reaching here
|
|
359
|
+
// with `existingCiphertext` non-null is impossible. Asserting
|
|
360
|
+
// defensively for future safety.
|
|
361
|
+
if (typeof existingCiphertext === 'string' && existingCiphertext.length > 0) {
|
|
362
|
+
throw new Error(`oauth_tokens row for user_id=${userId} has both data_json and ` +
|
|
363
|
+
`data_ciphertext populated; refusing to overwrite ciphertext`);
|
|
364
|
+
}
|
|
365
|
+
const enc = encrypt(masterKey, dataJson, {
|
|
366
|
+
scope: 'user',
|
|
367
|
+
scopeId: userId,
|
|
368
|
+
key: OAUTH_TOKENS_KEY,
|
|
369
|
+
keyVersion,
|
|
370
|
+
});
|
|
371
|
+
nextDataJson = null;
|
|
372
|
+
nextCiphertext = enc.ciphertext;
|
|
373
|
+
nextKeyVersion = enc.keyVersion;
|
|
374
|
+
}
|
|
375
|
+
else if (dataJson === null && typeof existingCiphertext === 'string' && existingCiphertext.length > 0) {
|
|
376
|
+
// Already encrypted (e.g. a previous Phase 8 pass on this DB whose
|
|
377
|
+
// meta marker got rolled back, or an out-of-band write). Pass
|
|
378
|
+
// through unchanged.
|
|
379
|
+
nextDataJson = null;
|
|
380
|
+
nextCiphertext = existingCiphertext;
|
|
381
|
+
nextKeyVersion = (typeof existingKeyVersion === 'string' && existingKeyVersion.length > 0)
|
|
382
|
+
? existingKeyVersion
|
|
383
|
+
: keyVersion;
|
|
384
|
+
}
|
|
385
|
+
else if (dataJson === null && (existingCiphertext === null || existingCiphertext === undefined)) {
|
|
386
|
+
// Neither column has data. Legal when the row got partway through
|
|
387
|
+
// some other path that nulled data_json but didn't write ciphertext.
|
|
388
|
+
// Migration can't recover a value that's gone — keep the row blank.
|
|
389
|
+
nextDataJson = null;
|
|
390
|
+
nextCiphertext = null;
|
|
391
|
+
nextKeyVersion = null;
|
|
392
|
+
}
|
|
393
|
+
else {
|
|
394
|
+
throw new Error(`oauth_tokens row for user_id=${userId} has unexpected data_json type ` +
|
|
395
|
+
`(${typeof dataJson}); aborting migration`);
|
|
396
|
+
}
|
|
397
|
+
// Build the insert payload in `insertCols` order. For pre-existing
|
|
398
|
+
// ciphertext columns, the new computed value replaces the source.
|
|
399
|
+
const values = insertCols.map((c) => {
|
|
400
|
+
if (c === 'data_json')
|
|
401
|
+
return nextDataJson;
|
|
402
|
+
if (c === 'data_ciphertext')
|
|
403
|
+
return nextCiphertext;
|
|
404
|
+
if (c === 'key_version')
|
|
405
|
+
return nextKeyVersion;
|
|
406
|
+
return row[c];
|
|
407
|
+
});
|
|
408
|
+
insertStmt.run(...values);
|
|
409
|
+
rowsMigrated++;
|
|
410
|
+
}
|
|
411
|
+
if (rowsMigrated !== preCount) {
|
|
412
|
+
throw new Error(`oauth_tokens migration row-count mismatch: pre=${preCount}, post=${rowsMigrated}`);
|
|
413
|
+
}
|
|
414
|
+
db.exec('DROP TABLE oauth_tokens');
|
|
415
|
+
db.exec('ALTER TABLE oauth_tokens_v2 RENAME TO oauth_tokens');
|
|
416
|
+
// Verify post-rename row count again, defensively.
|
|
417
|
+
const postCount = db.prepare('SELECT COUNT(*) AS n FROM oauth_tokens').get().n;
|
|
418
|
+
if (postCount !== preCount) {
|
|
419
|
+
throw new Error(`oauth_tokens post-rename row-count mismatch: pre=${preCount}, post=${postCount}`);
|
|
420
|
+
}
|
|
421
|
+
// Re-create any indexes/triggers. Their CREATE SQL referenced the
|
|
422
|
+
// original table by name; the rename means the same name now applies
|
|
423
|
+
// to the new table, so the original SQL works as-is.
|
|
424
|
+
for (const obj of auxObjects) {
|
|
425
|
+
// The old objects are dropped by `DROP TABLE oauth_tokens` (SQLite
|
|
426
|
+
// drops dependent indexes/triggers automatically). Re-create now.
|
|
427
|
+
try {
|
|
428
|
+
db.exec(obj.sql);
|
|
429
|
+
}
|
|
430
|
+
catch (err) {
|
|
431
|
+
throw new Error(`failed to recreate ${obj.type} ${obj.name} on rebuilt oauth_tokens: ` +
|
|
432
|
+
`${err instanceof Error ? err.message : String(err)}`);
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
return rowsMigrated;
|
|
436
|
+
}
|
|
437
|
+
function migrateUserPreferences(db, masterKey, keyVersion) {
|
|
438
|
+
// Add columns idempotently. Re-running after a partial crash should not
|
|
439
|
+
// fail on "duplicate column"; ALTER TABLE ADD COLUMN doesn't support
|
|
440
|
+
// IF NOT EXISTS in SQLite, so we check via PRAGMA.
|
|
441
|
+
if (!tableHasColumn(db, 'user_preferences', 'settings_ciphertext')) {
|
|
442
|
+
db.exec('ALTER TABLE user_preferences ADD COLUMN settings_ciphertext TEXT');
|
|
443
|
+
}
|
|
444
|
+
if (!tableHasColumn(db, 'user_preferences', 'key_version')) {
|
|
445
|
+
db.exec('ALTER TABLE user_preferences ADD COLUMN key_version TEXT');
|
|
446
|
+
}
|
|
447
|
+
// Walk every row that has a non-empty settings_json. Partition keys by
|
|
448
|
+
// registry classification: any key whose `user.*` registry entry is
|
|
449
|
+
// `user-secret` moves to ciphertext; the rest stay in settings_json.
|
|
450
|
+
// Each row gets ONE ciphertext blob covering the subset of secret keys.
|
|
451
|
+
const rows = db
|
|
452
|
+
.prepare(`SELECT user_id, settings_json, settings_ciphertext
|
|
453
|
+
FROM user_preferences
|
|
454
|
+
WHERE settings_json IS NOT NULL AND settings_json != ''`)
|
|
455
|
+
.all();
|
|
456
|
+
const updateStmt = db.prepare(`UPDATE user_preferences
|
|
457
|
+
SET settings_json = ?, settings_ciphertext = ?, key_version = ?, updated_at = datetime('now')
|
|
458
|
+
WHERE user_id = ?`);
|
|
459
|
+
let rowsMigrated = 0;
|
|
460
|
+
for (const row of rows) {
|
|
461
|
+
let parsed;
|
|
462
|
+
try {
|
|
463
|
+
parsed = JSON.parse(row.settings_json);
|
|
464
|
+
}
|
|
465
|
+
catch {
|
|
466
|
+
// Malformed JSON — leave it alone, don't write garbage to ciphertext.
|
|
467
|
+
// The read side already tolerates this (returns {}).
|
|
468
|
+
continue;
|
|
469
|
+
}
|
|
470
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed))
|
|
471
|
+
continue;
|
|
472
|
+
const secretEntries = {};
|
|
473
|
+
const plainEntries = {};
|
|
474
|
+
for (const [k, v] of Object.entries(parsed)) {
|
|
475
|
+
if (isUserSecretSettingsKey(k)) {
|
|
476
|
+
secretEntries[k] = v;
|
|
477
|
+
}
|
|
478
|
+
else {
|
|
479
|
+
plainEntries[k] = v;
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
// If there are no secret entries, leave the row alone — nothing to
|
|
483
|
+
// encrypt. The new columns stay NULL.
|
|
484
|
+
if (Object.keys(secretEntries).length === 0)
|
|
485
|
+
continue;
|
|
486
|
+
const enc = encrypt(masterKey, JSON.stringify(secretEntries), {
|
|
487
|
+
scope: 'user',
|
|
488
|
+
scopeId: String(row.user_id),
|
|
489
|
+
key: PREFS_SECRET_BLOB_KEY,
|
|
490
|
+
keyVersion,
|
|
491
|
+
});
|
|
492
|
+
updateStmt.run(JSON.stringify(plainEntries), enc.ciphertext, enc.keyVersion, row.user_id);
|
|
493
|
+
rowsMigrated++;
|
|
494
|
+
}
|
|
495
|
+
return rowsMigrated;
|
|
496
|
+
}
|
|
497
|
+
/**
|
|
498
|
+
* Map a key from `user_preferences.settings_json` to its registry entry,
|
|
499
|
+
* if any, and decide whether it's `user-secret`. The registry stores
|
|
500
|
+
* canonical names like `user.deepgram.api_key`; the raw JSON key in
|
|
501
|
+
* settings today is `deepgram_key`. We accept both forms (canonical
|
|
502
|
+
* registry name OR the legacy JSON key suffix) so the migration works
|
|
503
|
+
* against rows produced by the current code.
|
|
504
|
+
*/
|
|
505
|
+
function isUserSecretSettingsKey(rawKey) {
|
|
506
|
+
const direct = getKeyDef(rawKey);
|
|
507
|
+
if (direct?.classification === 'user-secret')
|
|
508
|
+
return true;
|
|
509
|
+
// Legacy short-form fallback: `deepgram_key` → `user.deepgram.api_key`.
|
|
510
|
+
// This mapping is a small lookup table; we only need it for keys that
|
|
511
|
+
// actually appear in pre-migration data.
|
|
512
|
+
const canonical = LEGACY_PREFS_KEY_TO_REGISTRY[rawKey];
|
|
513
|
+
if (canonical) {
|
|
514
|
+
const def = getKeyDef(canonical);
|
|
515
|
+
if (def?.classification === 'user-secret')
|
|
516
|
+
return true;
|
|
517
|
+
}
|
|
518
|
+
return false;
|
|
519
|
+
}
|
|
520
|
+
/**
|
|
521
|
+
* Map legacy `user_preferences.settings_json` keys to canonical registry
|
|
522
|
+
* names. The migration uses this to classify pre-existing rows; new
|
|
523
|
+
* writes through the API will use canonical names directly (Phase 8
|
|
524
|
+
* API update lands alongside the migration).
|
|
525
|
+
*/
|
|
526
|
+
export const LEGACY_PREFS_KEY_TO_REGISTRY = {
|
|
527
|
+
deepgram_key: 'user.deepgram.api_key',
|
|
528
|
+
};
|
|
529
|
+
/**
|
|
530
|
+
* Helper used by AuthService when reading user_preferences. Given a
|
|
531
|
+
* row's plaintext `settings_json` and optional `settings_ciphertext`,
|
|
532
|
+
* return the merged object. Decryption errors throw — the caller
|
|
533
|
+
* should let them propagate (corrupt or wrong-key data is a hard
|
|
534
|
+
* fail, not a silent empty object).
|
|
535
|
+
*/
|
|
536
|
+
export function decryptUserPreferencesSettings(masterKey, userId, settingsJson, settingsCiphertext, keyVersion) {
|
|
537
|
+
const plain = settingsJson && settingsJson.trim()
|
|
538
|
+
? safeJsonParseObject(settingsJson)
|
|
539
|
+
: {};
|
|
540
|
+
if (!settingsCiphertext)
|
|
541
|
+
return plain;
|
|
542
|
+
const decrypted = decrypt(masterKey, {
|
|
543
|
+
ciphertext: settingsCiphertext,
|
|
544
|
+
keyVersion: keyVersion ?? DEFAULT_KEY_VERSION,
|
|
545
|
+
}, {
|
|
546
|
+
scope: 'user',
|
|
547
|
+
scopeId: String(userId),
|
|
548
|
+
key: PREFS_SECRET_BLOB_KEY,
|
|
549
|
+
keyVersion: keyVersion ?? DEFAULT_KEY_VERSION,
|
|
550
|
+
});
|
|
551
|
+
const secret = safeJsonParseObject(decrypted);
|
|
552
|
+
// Plain and secret keys are partitioned at write time, so they should
|
|
553
|
+
// not collide. If they do (shouldn't happen), the secret wins — it
|
|
554
|
+
// was the value originally stored in the ciphertext-bound slot.
|
|
555
|
+
return { ...plain, ...secret };
|
|
556
|
+
}
|
|
557
|
+
/**
|
|
558
|
+
* Encrypt the secret subset of a user_preferences object for storage.
|
|
559
|
+
* Returns the pair (settings_json plaintext, settings_ciphertext) to
|
|
560
|
+
* write into the row. The caller (AuthService.setUserSettings) is
|
|
561
|
+
* responsible for the full merged write.
|
|
562
|
+
*/
|
|
563
|
+
export function encryptUserPreferencesSettings(masterKey, userId, merged, keyVersion = DEFAULT_KEY_VERSION) {
|
|
564
|
+
const secretEntries = {};
|
|
565
|
+
const plainEntries = {};
|
|
566
|
+
for (const [k, v] of Object.entries(merged)) {
|
|
567
|
+
if (isUserSecretSettingsKey(k)) {
|
|
568
|
+
secretEntries[k] = v;
|
|
569
|
+
}
|
|
570
|
+
else {
|
|
571
|
+
plainEntries[k] = v;
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
if (Object.keys(secretEntries).length === 0) {
|
|
575
|
+
return {
|
|
576
|
+
settingsJson: JSON.stringify(plainEntries),
|
|
577
|
+
settingsCiphertext: null,
|
|
578
|
+
keyVersion: null,
|
|
579
|
+
};
|
|
580
|
+
}
|
|
581
|
+
const enc = encrypt(masterKey, JSON.stringify(secretEntries), {
|
|
582
|
+
scope: 'user',
|
|
583
|
+
scopeId: String(userId),
|
|
584
|
+
key: PREFS_SECRET_BLOB_KEY,
|
|
585
|
+
keyVersion,
|
|
586
|
+
});
|
|
587
|
+
return {
|
|
588
|
+
settingsJson: JSON.stringify(plainEntries),
|
|
589
|
+
settingsCiphertext: enc.ciphertext,
|
|
590
|
+
keyVersion: enc.keyVersion,
|
|
591
|
+
};
|
|
592
|
+
}
|
|
593
|
+
/**
|
|
594
|
+
* Encrypt an oauth_tokens row's data payload for storage. The AAD is
|
|
595
|
+
* bound to the owning user_id so a row swap is detected on decrypt.
|
|
596
|
+
*/
|
|
597
|
+
export function encryptOAuthTokenData(masterKey, userId, dataJson, keyVersion = DEFAULT_KEY_VERSION) {
|
|
598
|
+
return encrypt(masterKey, dataJson, {
|
|
599
|
+
scope: 'user',
|
|
600
|
+
scopeId: String(userId),
|
|
601
|
+
key: OAUTH_TOKENS_KEY,
|
|
602
|
+
keyVersion,
|
|
603
|
+
});
|
|
604
|
+
}
|
|
605
|
+
/**
|
|
606
|
+
* Decrypt an oauth_tokens row's ciphertext. Throws on AAD mismatch,
|
|
607
|
+
* tampering, or wrong key — callers should let the error propagate.
|
|
608
|
+
*/
|
|
609
|
+
export function decryptOAuthTokenData(masterKey, userId, ciphertext, keyVersion) {
|
|
610
|
+
return decrypt(masterKey, { ciphertext, keyVersion: keyVersion ?? DEFAULT_KEY_VERSION }, {
|
|
611
|
+
scope: 'user',
|
|
612
|
+
scopeId: String(userId),
|
|
613
|
+
key: OAUTH_TOKENS_KEY,
|
|
614
|
+
keyVersion: keyVersion ?? DEFAULT_KEY_VERSION,
|
|
615
|
+
});
|
|
616
|
+
}
|
|
617
|
+
/**
|
|
618
|
+
* SQLite's PRAGMA emits column defaults verbatim from the source CREATE
|
|
619
|
+
* TABLE — but strips surrounding parens on function expressions. To round-
|
|
620
|
+
* trip safely we need to re-add parens for anything that doesn't look like
|
|
621
|
+
* a SQL literal (NULL, numeric, quoted string). Literals can pass through
|
|
622
|
+
* unchanged; the test for a literal is conservative — when in doubt, wrap.
|
|
623
|
+
*/
|
|
624
|
+
function renderDefault(dflt) {
|
|
625
|
+
const trimmed = dflt.trim();
|
|
626
|
+
// Quoted string literal — leave alone.
|
|
627
|
+
if (/^'(?:[^']|'')*'$/.test(trimmed))
|
|
628
|
+
return trimmed;
|
|
629
|
+
// NULL/TRUE/FALSE keywords.
|
|
630
|
+
if (/^(NULL|TRUE|FALSE)$/i.test(trimmed))
|
|
631
|
+
return trimmed;
|
|
632
|
+
// Numeric literal (integer or float, optionally signed).
|
|
633
|
+
if (/^-?\d+(?:\.\d+)?$/.test(trimmed))
|
|
634
|
+
return trimmed;
|
|
635
|
+
// Already parenthesised.
|
|
636
|
+
if (/^\(.*\)$/.test(trimmed))
|
|
637
|
+
return trimmed;
|
|
638
|
+
// Everything else (function calls, expressions) gets wrapped.
|
|
639
|
+
return `(${trimmed})`;
|
|
640
|
+
}
|
|
641
|
+
function safeJsonParseObject(text) {
|
|
642
|
+
try {
|
|
643
|
+
const v = JSON.parse(text);
|
|
644
|
+
if (v && typeof v === 'object' && !Array.isArray(v)) {
|
|
645
|
+
return v;
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
catch {
|
|
649
|
+
/* fall through */
|
|
650
|
+
}
|
|
651
|
+
return {};
|
|
652
|
+
}
|
|
653
|
+
//# sourceMappingURL=auth-db-migration.js.map
|