@geminixiang/mikan 1.0.0-beta.45 → 1.0.0-beta.47
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/CHANGELOG.md +47 -0
- package/README.md +12 -19
- package/dist/adapter.d.ts +1 -1
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js.map +1 -1
- package/dist/adapters/discord/bot.d.ts +6 -1
- package/dist/adapters/discord/bot.d.ts.map +1 -1
- package/dist/adapters/discord/bot.js +168 -144
- package/dist/adapters/discord/bot.js.map +1 -1
- package/dist/adapters/discord/context.d.ts +2 -8
- package/dist/adapters/discord/context.d.ts.map +1 -1
- package/dist/adapters/discord/context.js +1 -1
- package/dist/adapters/discord/context.js.map +1 -1
- package/dist/adapters/discord/format.d.ts.map +1 -1
- package/dist/adapters/discord/format.js +2 -4
- package/dist/adapters/discord/format.js.map +1 -1
- package/dist/adapters/github/bot.d.ts +6 -1
- package/dist/adapters/github/bot.d.ts.map +1 -1
- package/dist/adapters/github/bot.js +57 -25
- package/dist/adapters/github/bot.js.map +1 -1
- package/dist/adapters/github/context.d.ts +2 -9
- package/dist/adapters/github/context.d.ts.map +1 -1
- package/dist/adapters/github/context.js.map +1 -1
- package/dist/adapters/github/github-ops.d.ts +4 -17
- package/dist/adapters/github/github-ops.d.ts.map +1 -1
- package/dist/adapters/github/github-ops.js +17 -86
- package/dist/adapters/github/github-ops.js.map +1 -1
- package/dist/adapters/github/tool-pack.d.ts.map +1 -1
- package/dist/adapters/github/tool-pack.js +0 -1
- package/dist/adapters/github/tool-pack.js.map +1 -1
- package/dist/adapters/github/tools/checks.d.ts +0 -1
- package/dist/adapters/github/tools/checks.d.ts.map +1 -1
- package/dist/adapters/github/tools/checks.js +3 -22
- package/dist/adapters/github/tools/checks.js.map +1 -1
- package/dist/adapters/github/types.d.ts +0 -33
- package/dist/adapters/github/types.d.ts.map +1 -1
- package/dist/adapters/github/types.js.map +1 -1
- package/dist/adapters/progressive-renderer.d.ts.map +1 -1
- package/dist/adapters/progressive-renderer.js +311 -318
- package/dist/adapters/progressive-renderer.js.map +1 -1
- package/dist/adapters/shared.d.ts +12 -1
- package/dist/adapters/shared.d.ts.map +1 -1
- package/dist/adapters/shared.js +44 -1
- package/dist/adapters/shared.js.map +1 -1
- package/dist/adapters/slack/blocks.d.ts.map +1 -1
- package/dist/adapters/slack/blocks.js +1 -4
- package/dist/adapters/slack/blocks.js.map +1 -1
- package/dist/adapters/slack/bot.d.ts +15 -0
- package/dist/adapters/slack/bot.d.ts.map +1 -1
- package/dist/adapters/slack/bot.js +233 -206
- package/dist/adapters/slack/bot.js.map +1 -1
- package/dist/adapters/slack/context.d.ts +2 -8
- package/dist/adapters/slack/context.d.ts.map +1 -1
- package/dist/adapters/slack/context.js +1 -1
- package/dist/adapters/slack/context.js.map +1 -1
- package/dist/adapters/slack/response-lifecycle.d.ts.map +1 -1
- package/dist/adapters/slack/response-lifecycle.js +135 -123
- package/dist/adapters/slack/response-lifecycle.js.map +1 -1
- package/dist/adapters/slack/stream-limits.d.ts +1 -1
- package/dist/adapters/slack/stream-limits.js +1 -1
- package/dist/adapters/slack/stream-limits.js.map +1 -1
- package/dist/adapters/slack/types.d.ts +4 -0
- package/dist/adapters/slack/types.d.ts.map +1 -1
- package/dist/adapters/slack/types.js.map +1 -1
- package/dist/adapters/telegram/bot.d.ts +3 -0
- package/dist/adapters/telegram/bot.d.ts.map +1 -1
- package/dist/adapters/telegram/bot.js +23 -7
- package/dist/adapters/telegram/bot.js.map +1 -1
- package/dist/adapters/telegram/context.d.ts +2 -8
- package/dist/adapters/telegram/context.d.ts.map +1 -1
- package/dist/adapters/telegram/context.js +1 -2
- package/dist/adapters/telegram/context.js.map +1 -1
- package/dist/adapters/types.d.ts +11 -5
- package/dist/adapters/types.d.ts.map +1 -1
- package/dist/adapters/types.js.map +1 -1
- package/dist/agent/catalog.d.ts +6 -18
- package/dist/agent/catalog.d.ts.map +1 -1
- package/dist/agent/catalog.js +24 -156
- package/dist/agent/catalog.js.map +1 -1
- package/dist/agent/execution.d.ts +0 -7
- package/dist/agent/execution.d.ts.map +1 -1
- package/dist/agent/execution.js +23 -21
- package/dist/agent/execution.js.map +1 -1
- package/dist/agent/presenter.d.ts +7 -9
- package/dist/agent/presenter.d.ts.map +1 -1
- package/dist/agent/presenter.js +355 -357
- package/dist/agent/presenter.js.map +1 -1
- package/dist/agent/prompt.d.ts +5 -12
- package/dist/agent/prompt.d.ts.map +1 -1
- package/dist/agent/prompt.js +56 -81
- package/dist/agent/prompt.js.map +1 -1
- package/dist/agent/runner.d.ts +0 -7
- package/dist/agent/runner.d.ts.map +1 -1
- package/dist/agent/runner.js +335 -318
- package/dist/agent/runner.js.map +1 -1
- package/dist/agent/types.d.ts +21 -17
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js +0 -1
- package/dist/agent/types.js.map +1 -1
- package/dist/cli/boot.d.ts.map +1 -1
- package/dist/cli/boot.js +7 -10
- package/dist/cli/boot.js.map +1 -1
- package/dist/cli/onboard.d.ts +10 -0
- package/dist/cli/onboard.d.ts.map +1 -0
- package/dist/cli/onboard.js +237 -0
- package/dist/cli/onboard.js.map +1 -0
- package/dist/cli/types.d.ts +8 -3
- package/dist/cli/types.d.ts.map +1 -1
- package/dist/cli/types.js.map +1 -1
- package/dist/commands/auto-reply.d.ts.map +1 -1
- package/dist/commands/auto-reply.js +5 -12
- package/dist/commands/auto-reply.js.map +1 -1
- package/dist/commands/manifest.d.ts.map +1 -1
- package/dist/commands/manifest.js +9 -16
- package/dist/commands/manifest.js.map +1 -1
- package/dist/commands/new.d.ts.map +1 -1
- package/dist/commands/new.js +15 -10
- package/dist/commands/new.js.map +1 -1
- package/dist/commands/registry.d.ts.map +1 -1
- package/dist/commands/registry.js +0 -2
- package/dist/commands/registry.js.map +1 -1
- package/dist/commands/sandbox.d.ts.map +1 -1
- package/dist/commands/sandbox.js +89 -70
- package/dist/commands/sandbox.js.map +1 -1
- package/dist/commands/session-view.js +9 -2
- package/dist/commands/session-view.js.map +1 -1
- package/dist/commands/types.d.ts +4 -3
- package/dist/commands/types.d.ts.map +1 -1
- package/dist/commands/types.js.map +1 -1
- package/dist/config.d.ts +13 -17
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +39 -37
- package/dist/config.js.map +1 -1
- package/dist/dream/index.d.ts +20 -0
- package/dist/dream/index.d.ts.map +1 -0
- package/dist/dream/index.js +253 -0
- package/dist/dream/index.js.map +1 -0
- package/dist/dream/types.d.ts +30 -0
- package/dist/dream/types.d.ts.map +1 -0
- package/dist/dream/types.js.map +1 -0
- package/dist/env-manifest.d.ts.map +1 -1
- package/dist/env-manifest.js +12 -27
- package/dist/env-manifest.js.map +1 -1
- package/dist/execution-resolver.d.ts +9 -2
- package/dist/execution-resolver.d.ts.map +1 -1
- package/dist/execution-resolver.js +26 -27
- package/dist/execution-resolver.js.map +1 -1
- package/dist/harness/event-format.d.ts +1 -2
- package/dist/harness/event-format.d.ts.map +1 -1
- package/dist/harness/event-format.js +9 -15
- package/dist/harness/event-format.js.map +1 -1
- package/dist/harness/index.d.ts +1 -7
- package/dist/harness/index.d.ts.map +1 -1
- package/dist/harness/index.js +0 -4
- package/dist/harness/index.js.map +1 -1
- package/dist/harness/models.d.ts.map +1 -1
- package/dist/harness/models.js +15 -35
- package/dist/harness/models.js.map +1 -1
- package/dist/harness/runner.d.ts +7 -16
- package/dist/harness/runner.d.ts.map +1 -1
- package/dist/harness/runner.js +13 -131
- package/dist/harness/runner.js.map +1 -1
- package/dist/harness/session-store.d.ts +1 -1
- package/dist/harness/session-store.d.ts.map +1 -1
- package/dist/harness/session-store.js +1 -1
- package/dist/harness/session-store.js.map +1 -1
- package/dist/harness/subagent-runner.d.ts +2 -2
- package/dist/harness/subagent-runner.d.ts.map +1 -1
- package/dist/harness/subagent-runner.js +157 -162
- package/dist/harness/subagent-runner.js.map +1 -1
- package/dist/harness/types.d.ts +1 -13
- package/dist/harness/types.d.ts.map +1 -1
- package/dist/harness/types.js.map +1 -1
- package/dist/index.d.ts +3 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -5
- package/dist/index.js.map +1 -1
- package/dist/main.js +103 -222
- package/dist/main.js.map +1 -1
- package/dist/mcp/catalog.d.ts +5 -0
- package/dist/mcp/catalog.d.ts.map +1 -0
- package/dist/mcp/catalog.js +156 -0
- package/dist/mcp/catalog.js.map +1 -0
- package/dist/mcp/loader.d.ts +3 -2
- package/dist/mcp/loader.d.ts.map +1 -1
- package/dist/mcp/loader.js +54 -23
- package/dist/mcp/loader.js.map +1 -1
- package/dist/mcp/open-connector.d.ts +14 -0
- package/dist/mcp/open-connector.d.ts.map +1 -0
- package/dist/mcp/open-connector.js +203 -0
- package/dist/mcp/open-connector.js.map +1 -0
- package/dist/mcp/types.d.ts +28 -0
- package/dist/mcp/types.d.ts.map +1 -1
- package/dist/mcp/types.js.map +1 -1
- package/dist/office/index.d.ts +136 -8
- package/dist/office/index.d.ts.map +1 -1
- package/dist/office/index.js +1050 -9
- package/dist/office/index.js.map +1 -1
- package/dist/office/types.d.ts +19 -1
- package/dist/office/types.d.ts.map +1 -1
- package/dist/office/types.js.map +1 -1
- package/dist/packages/index.d.ts +168 -5
- package/dist/packages/index.d.ts.map +1 -1
- package/dist/packages/index.js +720 -5
- package/dist/packages/index.js.map +1 -1
- package/dist/packages/types.d.ts +1 -5
- package/dist/packages/types.d.ts.map +1 -1
- package/dist/packages/types.js.map +1 -1
- package/dist/process-lifecycle.d.ts +19 -0
- package/dist/process-lifecycle.d.ts.map +1 -0
- package/dist/process-lifecycle.js +60 -0
- package/dist/process-lifecycle.js.map +1 -0
- package/dist/provisioner.d.ts +2 -9
- package/dist/provisioner.d.ts.map +1 -1
- package/dist/provisioner.js +3 -12
- package/dist/provisioner.js.map +1 -1
- package/dist/runtime/conversation-runtime.d.ts.map +1 -1
- package/dist/runtime/conversation-runtime.js +124 -380
- package/dist/runtime/conversation-runtime.js.map +1 -1
- package/dist/runtime/session-lifecycle.d.ts +34 -18
- package/dist/runtime/session-lifecycle.d.ts.map +1 -1
- package/dist/runtime/session-lifecycle.js +179 -46
- package/dist/runtime/session-lifecycle.js.map +1 -1
- package/dist/runtime/types.d.ts +8 -26
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/runtime/types.js.map +1 -1
- package/dist/sandbox/cloudflare.d.ts.map +1 -1
- package/dist/sandbox/cloudflare.js +2 -3
- package/dist/sandbox/cloudflare.js.map +1 -1
- package/dist/sandbox/container.d.ts +0 -1
- package/dist/sandbox/container.d.ts.map +1 -1
- package/dist/sandbox/container.js +2 -3
- package/dist/sandbox/container.js.map +1 -1
- package/dist/sandbox/host.d.ts.map +1 -1
- package/dist/sandbox/host.js +4 -2
- package/dist/sandbox/host.js.map +1 -1
- package/dist/sandbox/identity.d.ts +10 -19
- package/dist/sandbox/identity.d.ts.map +1 -1
- package/dist/sandbox/identity.js +8 -8
- package/dist/sandbox/identity.js.map +1 -1
- package/dist/sandbox/index.d.ts +7 -10
- package/dist/sandbox/index.d.ts.map +1 -1
- package/dist/sandbox/index.js +45 -16
- package/dist/sandbox/index.js.map +1 -1
- package/dist/sandbox/types.d.ts +13 -45
- package/dist/sandbox/types.d.ts.map +1 -1
- package/dist/sandbox/types.js.map +1 -1
- package/dist/sandbox/utils.d.ts +5 -0
- package/dist/sandbox/utils.d.ts.map +1 -1
- package/dist/sandbox/utils.js +10 -0
- package/dist/sandbox/utils.js.map +1 -1
- package/dist/sessions/chat-history-sync.d.ts +1 -3
- package/dist/sessions/chat-history-sync.d.ts.map +1 -1
- package/dist/sessions/chat-history-sync.js +58 -11
- package/dist/sessions/chat-history-sync.js.map +1 -1
- package/dist/sessions/migrate-v3.d.ts +2 -5
- package/dist/sessions/migrate-v3.d.ts.map +1 -1
- package/dist/sessions/migrate-v3.js +17 -1
- package/dist/sessions/migrate-v3.js.map +1 -1
- package/dist/sessions/store.d.ts +5 -6
- package/dist/sessions/store.d.ts.map +1 -1
- package/dist/sessions/store.js +62 -2
- package/dist/sessions/store.js.map +1 -1
- package/dist/sessions/types.d.ts +9 -0
- package/dist/sessions/types.d.ts.map +1 -1
- package/dist/sessions/types.js.map +1 -1
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/bash.js +2 -10
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/read.js +2 -2
- package/dist/tools/read.js.map +1 -1
- package/dist/tools/sandbox.d.ts.map +1 -1
- package/dist/tools/sandbox.js +2 -3
- package/dist/tools/sandbox.js.map +1 -1
- package/dist/tools/subagent.d.ts +1 -1
- package/dist/tools/subagent.js.map +1 -1
- package/dist/types.d.ts +54 -130
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/vault/index.d.ts +9 -2
- package/dist/vault/index.d.ts.map +1 -1
- package/dist/vault/index.js +29 -5
- package/dist/vault/index.js.map +1 -1
- package/dist/web/admin/portal.d.ts +12 -1
- package/dist/web/admin/portal.d.ts.map +1 -1
- package/dist/web/admin/portal.js +437 -422
- package/dist/web/admin/portal.js.map +1 -1
- package/dist/web/admin/types.d.ts +2 -2
- package/dist/web/admin/types.d.ts.map +1 -1
- package/dist/web/admin/types.js.map +1 -1
- package/dist/web/login/portal.d.ts +7 -1
- package/dist/web/login/portal.d.ts.map +1 -1
- package/dist/web/login/portal.js +143 -78
- package/dist/web/login/portal.js.map +1 -1
- package/dist/web/portal-shell.d.ts +1 -0
- package/dist/web/portal-shell.d.ts.map +1 -1
- package/dist/web/portal-shell.js +12 -1
- package/dist/web/portal-shell.js.map +1 -1
- package/dist/web/server.d.ts +3 -3
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js.map +1 -1
- package/dist/web/session-view/portal.d.ts +8 -1
- package/dist/web/session-view/portal.d.ts.map +1 -1
- package/dist/web/session-view/portal.js +609 -132
- package/dist/web/session-view/portal.js.map +1 -1
- package/dist/web/session-view/types.d.ts +8 -0
- package/dist/web/session-view/types.d.ts.map +1 -1
- package/dist/web/session-view/types.js.map +1 -1
- package/dist/workspace-projection/index.d.ts +14 -2
- package/dist/workspace-projection/index.d.ts.map +1 -1
- package/dist/workspace-projection/index.js +102 -14
- package/dist/workspace-projection/index.js.map +1 -1
- package/dist/workspace-projection/types.d.ts +14 -1
- package/dist/workspace-projection/types.d.ts.map +1 -1
- package/dist/workspace-projection/types.js.map +1 -1
- package/package.json +3 -5
- package/dist/adapters/github/cloudbuild.d.ts +0 -19
- package/dist/adapters/github/cloudbuild.d.ts.map +0 -1
- package/dist/adapters/github/cloudbuild.js +0 -71
- package/dist/adapters/github/cloudbuild.js.map +0 -1
- package/dist/adapters/github/gcp-auth.d.ts +0 -28
- package/dist/adapters/github/gcp-auth.d.ts.map +0 -1
- package/dist/adapters/github/gcp-auth.js +0 -196
- package/dist/adapters/github/gcp-auth.js.map +0 -1
- package/dist/agent/index.d.ts +0 -9
- package/dist/agent/index.d.ts.map +0 -1
- package/dist/agent/index.js +0 -8
- package/dist/agent/index.js.map +0 -1
- package/dist/cli/ext-dev.d.ts +0 -2
- package/dist/cli/ext-dev.d.ts.map +0 -1
- package/dist/cli/ext-dev.js +0 -188
- package/dist/cli/ext-dev.js.map +0 -1
- package/dist/cli/ext.d.ts +0 -2
- package/dist/cli/ext.d.ts.map +0 -1
- package/dist/cli/ext.js +0 -324
- package/dist/cli/ext.js.map +0 -1
- package/dist/commands/extensions.d.ts +0 -26
- package/dist/commands/extensions.d.ts.map +0 -1
- package/dist/commands/extensions.js +0 -103
- package/dist/commands/extensions.js.map +0 -1
- package/dist/extension-schedules.d.ts +0 -31
- package/dist/extension-schedules.d.ts.map +0 -1
- package/dist/extension-schedules.js +0 -229
- package/dist/extension-schedules.js.map +0 -1
- package/dist/harness/auth.d.ts +0 -17
- package/dist/harness/auth.d.ts.map +0 -1
- package/dist/harness/auth.js +0 -92
- package/dist/harness/auth.js.map +0 -1
- package/dist/harness/extensions/loader.d.ts +0 -40
- package/dist/harness/extensions/loader.d.ts.map +0 -1
- package/dist/harness/extensions/loader.js +0 -723
- package/dist/harness/extensions/loader.js.map +0 -1
- package/dist/harness/extensions/registry.d.ts +0 -155
- package/dist/harness/extensions/registry.d.ts.map +0 -1
- package/dist/harness/extensions/registry.js +0 -420
- package/dist/harness/extensions/registry.js.map +0 -1
- package/dist/harness/extensions/types.d.ts +0 -665
- package/dist/harness/extensions/types.d.ts.map +0 -1
- package/dist/harness/extensions/types.js.map +0 -1
- package/dist/office/address.d.ts +0 -31
- package/dist/office/address.d.ts.map +0 -1
- package/dist/office/address.js +0 -113
- package/dist/office/address.js.map +0 -1
- package/dist/office/layout.d.ts +0 -27
- package/dist/office/layout.d.ts.map +0 -1
- package/dist/office/layout.js +0 -97
- package/dist/office/layout.js.map +0 -1
- package/dist/office/migration.d.ts +0 -44
- package/dist/office/migration.d.ts.map +0 -1
- package/dist/office/migration.js +0 -255
- package/dist/office/migration.js.map +0 -1
- package/dist/office/registry.d.ts +0 -75
- package/dist/office/registry.d.ts.map +0 -1
- package/dist/office/registry.js +0 -646
- package/dist/office/registry.js.map +0 -1
- package/dist/packages/admin.d.ts +0 -17
- package/dist/packages/admin.d.ts.map +0 -1
- package/dist/packages/admin.js +0 -98
- package/dist/packages/admin.js.map +0 -1
- package/dist/packages/inspect.d.ts +0 -11
- package/dist/packages/inspect.d.ts.map +0 -1
- package/dist/packages/inspect.js +0 -98
- package/dist/packages/inspect.js.map +0 -1
- package/dist/packages/materialize.d.ts +0 -40
- package/dist/packages/materialize.d.ts.map +0 -1
- package/dist/packages/materialize.js +0 -297
- package/dist/packages/materialize.js.map +0 -1
- package/dist/packages/resolve.d.ts +0 -25
- package/dist/packages/resolve.d.ts.map +0 -1
- package/dist/packages/resolve.js +0 -208
- package/dist/packages/resolve.js.map +0 -1
- package/dist/packages/source.d.ts +0 -39
- package/dist/packages/source.d.ts.map +0 -1
- package/dist/packages/source.js +0 -189
- package/dist/packages/source.js.map +0 -1
- package/dist/sandbox/errors.d.ts +0 -6
- package/dist/sandbox/errors.d.ts.map +0 -1
- package/dist/sandbox/errors.js +0 -11
- package/dist/sandbox/errors.js.map +0 -1
- package/dist/sandbox/firecracker.d.ts +0 -18
- package/dist/sandbox/firecracker.d.ts.map +0 -1
- package/dist/sandbox/firecracker.js +0 -223
- package/dist/sandbox/firecracker.js.map +0 -1
- package/dist/sandbox/gondolin.d.ts +0 -57
- package/dist/sandbox/gondolin.d.ts.map +0 -1
- package/dist/sandbox/gondolin.js +0 -764
- package/dist/sandbox/gondolin.js.map +0 -1
- package/dist/sandbox/image.d.ts +0 -3
- package/dist/sandbox/image.d.ts.map +0 -1
- package/dist/sandbox/image.js +0 -29
- package/dist/sandbox/image.js.map +0 -1
- package/dist/sessions/conversation-log.d.ts +0 -9
- package/dist/sessions/conversation-log.d.ts.map +0 -1
- package/dist/sessions/conversation-log.js +0 -50
- package/dist/sessions/conversation-log.js.map +0 -1
- package/dist/sessions/rotation.d.ts +0 -2
- package/dist/sessions/rotation.d.ts.map +0 -1
- package/dist/sessions/rotation.js +0 -41
- package/dist/sessions/rotation.js.map +0 -1
- package/dist/vault/disabled.d.ts +0 -9
- package/dist/vault/disabled.d.ts.map +0 -1
- package/dist/vault/disabled.js +0 -25
- package/dist/vault/disabled.js.map +0 -1
- package/dist/web/admin/store.d.ts +0 -13
- package/dist/web/admin/store.d.ts.map +0 -1
- package/dist/web/admin/store.js +0 -14
- package/dist/web/admin/store.js.map +0 -1
- package/dist/web/login/store.d.ts +0 -8
- package/dist/web/login/store.d.ts.map +0 -1
- package/dist/web/login/store.js +0 -15
- package/dist/web/login/store.js.map +0 -1
- package/dist/web/session-view/service.d.ts +0 -6
- package/dist/web/session-view/service.d.ts.map +0 -1
- package/dist/web/session-view/service.js +0 -517
- package/dist/web/session-view/service.js.map +0 -1
- package/dist/web/session-view/store.d.ts +0 -8
- package/dist/web/session-view/store.d.ts.map +0 -1
- package/dist/web/session-view/store.js +0 -15
- package/dist/web/session-view/store.js.map +0 -1
- /package/dist/{harness/extensions → dream}/types.js +0 -0
|
@@ -4,9 +4,9 @@ import type { LinkTokenStoreLike } from "../../commands/types.js";
|
|
|
4
4
|
import type { SandboxConfig } from "../../sandbox/index.js";
|
|
5
5
|
import type { EventStore } from "../../tools/types.js";
|
|
6
6
|
import type { VaultManager } from "../../vault/index.js";
|
|
7
|
-
import type { InMemorySessionViewTokenStore } from "../session-view/
|
|
7
|
+
import type { InMemorySessionViewTokenStore } from "../session-view/portal.js";
|
|
8
8
|
import type { TokenRecord } from "../types.js";
|
|
9
|
-
import type { InMemoryAdminTokenStore } from "./
|
|
9
|
+
import type { InMemoryAdminTokenStore } from "./portal.js";
|
|
10
10
|
export interface AdminRuntimeBridge {
|
|
11
11
|
getRunningSessions(): RunningSession[];
|
|
12
12
|
switchConversationModel(address: OfficeAddress, provider: string, model: string): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/web/admin/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClG,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/web/admin/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClG,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,2BAA2B,CAAC;AAC/E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAE3D,MAAM,WAAW,kBAAkB;IACjC,kBAAkB,IAAI,cAAc,EAAE,CAAC;IACvC,uBAAuB,CAAC,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IAC1F,8BAA8B,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC;IAChE,uBAAuB,IAAI;QAAE,IAAI,EAAE,aAAa,EAAE,CAAA;KAAE,CAAC;CACtD;AAED,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,YAAY,CAAC;IAC3B,cAAc,EAAE,kBAAkB,CAAC;IACnC,qBAAqB,CAAC,EAAE,6BAA6B,CAAC;IACtD,eAAe,EAAE,uBAAuB,CAAC;IACzC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,4EAA4E;IAC5E,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B,cAAc,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC,CAAC;CAC9D;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,UAAW,SAAQ,WAAW;IAC7C,QAAQ,EAAE,YAAY,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,oFAAoF;IACpF,cAAc,EAAE,MAAM,CAAC;CACxB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/web/admin/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { MessagingBot, OfficeAddress, PlatformName, RunningSession } from \"../../adapter.js\";\nimport type { Workspace } from \"../../office/index.js\";\nimport type { LinkTokenStoreLike } from \"../../commands/types.js\";\nimport type { SandboxConfig } from \"../../sandbox/index.js\";\nimport type { EventStore } from \"../../tools/types.js\";\nimport type { VaultManager } from \"../../vault/index.js\";\nimport type { InMemorySessionViewTokenStore } from \"../session-view/
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/web/admin/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { MessagingBot, OfficeAddress, PlatformName, RunningSession } from \"../../adapter.js\";\nimport type { Workspace } from \"../../office/index.js\";\nimport type { LinkTokenStoreLike } from \"../../commands/types.js\";\nimport type { SandboxConfig } from \"../../sandbox/index.js\";\nimport type { EventStore } from \"../../tools/types.js\";\nimport type { VaultManager } from \"../../vault/index.js\";\nimport type { InMemorySessionViewTokenStore } from \"../session-view/portal.js\";\nimport type { TokenRecord } from \"../types.js\";\nimport type { InMemoryAdminTokenStore } from \"./portal.js\";\n\nexport interface AdminRuntimeBridge {\n getRunningSessions(): RunningSession[];\n switchConversationModel(address: OfficeAddress, provider: string, model: string): boolean;\n refreshConversationEnvironment(address: OfficeAddress): boolean;\n refreshAllConversations(): { busy: OfficeAddress[] };\n}\n\nexport interface AdminServices {\n vaultManager: VaultManager;\n linkTokenStore: LinkTokenStoreLike;\n sessionViewTokenStore?: InMemorySessionViewTokenStore;\n adminTokenStore: InMemoryAdminTokenStore;\n portalBaseUrl?: string;\n workspace?: Workspace;\n /** Events read/delete go through the owning store, not raw disk parsing. */\n eventStore?: EventStore;\n sandbox?: SandboxConfig;\n runtime?: AdminRuntimeBridge;\n botsByPlatform?: Partial<Record<PlatformName, MessagingBot>>;\n}\n\nexport interface EventSummary {\n name: string;\n size: number;\n mtimeMs: number;\n type: string | null;\n platform: string | null;\n conversationId: string | null;\n text: string | null;\n at: string | null;\n schedule: string | null;\n timezone: string | null;\n}\n\nexport interface AdminToken extends TokenRecord {\n platform: PlatformName;\n platformUserId: string;\n platformUserName?: string;\n /** The conversation where /admin was invoked. Default scope for the 3 sub-pages. */\n conversationId: string;\n}\n"]}
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
2
|
-
import type {
|
|
2
|
+
import type { PlatformName } from "../../adapter.js";
|
|
3
|
+
import { InMemoryTokenStore } from "../token-store.js";
|
|
4
|
+
import type { LinkToken } from "./types.js";
|
|
5
|
+
export type { LinkToken } from "./types.js";
|
|
3
6
|
import { type VaultManager } from "../../vault/index.js";
|
|
4
7
|
export type { NotifyFn } from "./types.js";
|
|
8
|
+
export declare class InMemoryLinkTokenStore extends InMemoryTokenStore<LinkToken> {
|
|
9
|
+
create(platform: PlatformName, platformUserId: string, conversationId: string, vaultId: string, providerId: string): LinkToken;
|
|
10
|
+
}
|
|
5
11
|
import type { NotifyFn } from "./types.js";
|
|
6
12
|
/**
|
|
7
13
|
* Start a small HTTP server that receives credential onboarding callbacks from the web portal.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"portal.d.ts","sourceRoot":"","sources":["../../../src/web/login/portal.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"portal.d.ts","sourceRoot":"","sources":["../../../src/web/login/portal.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAIjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAU5C,OAAO,EAA0B,KAAK,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAIjF,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAI3C,qBAAa,sBAAuB,SAAQ,kBAAkB,CAAC,SAAS,CAAC;IACvE,MAAM,CACJ,QAAQ,EAAE,YAAY,EACtB,cAAc,EAAE,MAAM,EACtB,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,GACjB,SAAS,CAWX;CACF;AACD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAyN3C;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CACvC,cAAc,EAAE,sBAAsB,EACtC,YAAY,EAAE,YAAY,EAC1B,MAAM,EAAE,QAAQ,GACf,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAqGlE"}
|
package/dist/web/login/portal.js
CHANGED
|
@@ -1,11 +1,26 @@
|
|
|
1
1
|
import { createHash, randomBytes } from "node:crypto";
|
|
2
2
|
import { escapeHtml, readJsonBody, renderPortalShell, requestBaseUrl } from "../portal-shell.js";
|
|
3
3
|
import { resolveLinkBaseUrl } from "../../config.js";
|
|
4
|
+
import { readEnv } from "../../env-manifest.js";
|
|
5
|
+
import { InMemoryTokenStore } from "../token-store.js";
|
|
4
6
|
import { getOAuthServices, resolveOAuthService, } from "./oauth.js";
|
|
5
7
|
import * as log from "../../log.js";
|
|
6
8
|
import { reportUserFacingError } from "../../observability/sentry.js";
|
|
7
9
|
import { PRODUCT_NAME } from "../../platform-messages.js";
|
|
8
10
|
import { defaultVaultTargetPath } from "../../vault/index.js";
|
|
11
|
+
const TTL_MS = 15 * 60 * 1000;
|
|
12
|
+
export class InMemoryLinkTokenStore extends InMemoryTokenStore {
|
|
13
|
+
create(platform, platformUserId, conversationId, vaultId, providerId) {
|
|
14
|
+
this.deleteWhere((token) => token.platform === platform && token.platformUserId === platformUserId);
|
|
15
|
+
return this.createRecord(TTL_MS, {
|
|
16
|
+
platform,
|
|
17
|
+
platformUserId,
|
|
18
|
+
vaultId,
|
|
19
|
+
providerId,
|
|
20
|
+
conversationId,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
}
|
|
9
24
|
const OAUTH_STATE_TTL_MS = 10 * 60 * 1000;
|
|
10
25
|
const DEFAULT_SECRET_CONFIG_ID = "manual";
|
|
11
26
|
const SECRET_PRESETS = [
|
|
@@ -202,9 +217,20 @@ export function createLoginRequestHandler(linkTokenStore, vaultManager, notify)
|
|
|
202
217
|
const defaultMode = oauthServiceHint ? "oauth" : "api_key";
|
|
203
218
|
const existingSecrets = describeVaultSecrets(vaultManager, linkToken.vaultId);
|
|
204
219
|
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
205
|
-
res.end(renderCredentialPage(
|
|
206
|
-
|
|
207
|
-
:
|
|
220
|
+
res.end(renderCredentialPage({
|
|
221
|
+
token: rawToken,
|
|
222
|
+
title: oauthServiceHint ? `${oauthServiceHint.label} OAuth` : "Store Secret",
|
|
223
|
+
defaultMode,
|
|
224
|
+
initialEnvKey: "",
|
|
225
|
+
secretLabel: "Secret value",
|
|
226
|
+
placeholder: "sk-...",
|
|
227
|
+
helpText: oauthServiceHint
|
|
228
|
+
? `Authorize ${oauthServiceHint.label} and store tokens in your vault.`
|
|
229
|
+
: "Set any environment variable key/value pair in your vault.",
|
|
230
|
+
oauthServices,
|
|
231
|
+
oauthServiceIdHint: oauthServiceHint?.id,
|
|
232
|
+
existingSecrets,
|
|
233
|
+
}));
|
|
208
234
|
return true;
|
|
209
235
|
}
|
|
210
236
|
if (req.method === "POST" && url.pathname === "/api/link/complete") {
|
|
@@ -228,7 +254,15 @@ export function createLoginRequestHandler(linkTokenStore, vaultManager, notify)
|
|
|
228
254
|
return true;
|
|
229
255
|
}
|
|
230
256
|
if (req.method === "GET" && url.pathname === "/oauth/callback") {
|
|
231
|
-
void handleOAuthCallback(
|
|
257
|
+
void handleOAuthCallback({
|
|
258
|
+
url,
|
|
259
|
+
req,
|
|
260
|
+
linkTokenStore,
|
|
261
|
+
vaultManager,
|
|
262
|
+
notify,
|
|
263
|
+
oauthStates,
|
|
264
|
+
res,
|
|
265
|
+
}).catch((err) => {
|
|
232
266
|
log.logWarning("OAuth callback failed", err.message);
|
|
233
267
|
reportUserFacingError(err, {
|
|
234
268
|
domain: "login",
|
|
@@ -734,42 +768,8 @@ function renderManualProviderCard(initialEnvKey, secretLabel, placeholder) {
|
|
|
734
768
|
</div>
|
|
735
769
|
</section>`;
|
|
736
770
|
}
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
.map((service) => {
|
|
740
|
-
const selected = service.id === oauthServiceIdHint ? ' selected="selected"' : "";
|
|
741
|
-
return `<option value="${esc(service.id)}"${selected}>${esc(service.label)}</option>`;
|
|
742
|
-
})
|
|
743
|
-
.join("\n");
|
|
744
|
-
const presetCards = SECRET_PRESETS.map(renderPresetProviderCard).join("\n");
|
|
745
|
-
return renderHtmlDocument("Login", `<section class="card stack">
|
|
746
|
-
<p class="eyebrow">${PRODUCT_NAME}</p>
|
|
747
|
-
<h1 class="page-title">${esc(title)}</h1>
|
|
748
|
-
<p>Your personal sandbox is already provisioned automatically.</p>
|
|
749
|
-
<p>${esc(helpText)}</p>
|
|
750
|
-
${renderSecretsSummary(existingSecrets)}
|
|
751
|
-
<div class="mode">
|
|
752
|
-
<label><input type="radio" name="mode" value="api_key" ${defaultMode === "api_key" ? "checked" : ""}> Secrets / API tokens</label>
|
|
753
|
-
<label><input type="radio" name="mode" value="oauth" ${defaultMode === "oauth" ? "checked" : ""}> OAuth login</label>
|
|
754
|
-
</div>
|
|
755
|
-
</section>
|
|
756
|
-
|
|
757
|
-
<div id="api-panel" class="panel">
|
|
758
|
-
${presetCards}
|
|
759
|
-
${renderManualProviderCard(initialEnvKey, secretLabel, placeholder)}
|
|
760
|
-
</div>
|
|
761
|
-
|
|
762
|
-
<div id="oauth-panel" class="panel card stack">
|
|
763
|
-
<label for="oauthService">OAuth service</label>
|
|
764
|
-
<select id="oauthService" name="oauthService">${oauthOptions}</select>
|
|
765
|
-
<p class="panel-note">You'll be redirected to the selected service's authorization page.</p>
|
|
766
|
-
</div>
|
|
767
|
-
|
|
768
|
-
<div>
|
|
769
|
-
<button id="btn" class="primary-button" onclick="connect()">Continue</button>
|
|
770
|
-
<div id="result" class="result" aria-live="polite"></div>
|
|
771
|
-
</div>
|
|
772
|
-
<script>
|
|
771
|
+
const CREDENTIAL_PAGE_TOKEN = "__MIKAN_LOGIN_TOKEN__";
|
|
772
|
+
const CREDENTIAL_PAGE_SCRIPT = ` <script>
|
|
773
773
|
const envKeyPattern = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
774
774
|
|
|
775
775
|
function selectedMode() {
|
|
@@ -853,7 +853,7 @@ function renderCredentialPage(token, title, defaultMode, initialEnvKey, secretLa
|
|
|
853
853
|
const r = await fetch('/api/oauth/start', {
|
|
854
854
|
method: 'POST',
|
|
855
855
|
headers: { 'Content-Type': 'application/json' },
|
|
856
|
-
body: JSON.stringify({ token: '
|
|
856
|
+
body: JSON.stringify({ token: '__MIKAN_LOGIN_TOKEN__', serviceId }),
|
|
857
857
|
});
|
|
858
858
|
const data = await r.json();
|
|
859
859
|
if (!r.ok) {
|
|
@@ -875,7 +875,7 @@ function renderCredentialPage(token, title, defaultMode, initialEnvKey, secretLa
|
|
|
875
875
|
const r = await fetch('/api/link/complete', {
|
|
876
876
|
method: 'POST',
|
|
877
877
|
headers: { 'Content-Type': 'application/json' },
|
|
878
|
-
body: JSON.stringify({ token: '
|
|
878
|
+
body: JSON.stringify({ token: '__MIKAN_LOGIN_TOKEN__', mode: 'api_key', env: payload.env }),
|
|
879
879
|
});
|
|
880
880
|
const data = await r.json();
|
|
881
881
|
if (r.ok) {
|
|
@@ -936,7 +936,47 @@ function renderCredentialPage(token, title, defaultMode, initialEnvKey, secretLa
|
|
|
936
936
|
resetContinueButton();
|
|
937
937
|
}
|
|
938
938
|
}
|
|
939
|
-
</script
|
|
939
|
+
</script>`;
|
|
940
|
+
function renderCredentialPageScript(token) {
|
|
941
|
+
return CREDENTIAL_PAGE_SCRIPT.replaceAll(CREDENTIAL_PAGE_TOKEN, () => esc(token));
|
|
942
|
+
}
|
|
943
|
+
function renderCredentialPage(options) {
|
|
944
|
+
const { token, title, defaultMode, initialEnvKey, secretLabel, placeholder, helpText, oauthServices, oauthServiceIdHint, existingSecrets, } = options;
|
|
945
|
+
const oauthOptions = oauthServices
|
|
946
|
+
.map((service) => {
|
|
947
|
+
const selected = service.id === oauthServiceIdHint ? ' selected="selected"' : "";
|
|
948
|
+
return `<option value="${esc(service.id)}"${selected}>${esc(service.label)}</option>`;
|
|
949
|
+
})
|
|
950
|
+
.join("\n");
|
|
951
|
+
const presetCards = SECRET_PRESETS.map(renderPresetProviderCard).join("\n");
|
|
952
|
+
return renderHtmlDocument("Login", `<section class="card stack">
|
|
953
|
+
<p class="eyebrow">${PRODUCT_NAME}</p>
|
|
954
|
+
<h1 class="page-title">${esc(title)}</h1>
|
|
955
|
+
<p>Your personal sandbox is already provisioned automatically.</p>
|
|
956
|
+
<p>${esc(helpText)}</p>
|
|
957
|
+
${renderSecretsSummary(existingSecrets)}
|
|
958
|
+
<div class="mode">
|
|
959
|
+
<label><input type="radio" name="mode" value="api_key" ${defaultMode === "api_key" ? "checked" : ""}> Secrets / API tokens</label>
|
|
960
|
+
<label><input type="radio" name="mode" value="oauth" ${defaultMode === "oauth" ? "checked" : ""}> OAuth login</label>
|
|
961
|
+
</div>
|
|
962
|
+
</section>
|
|
963
|
+
|
|
964
|
+
<div id="api-panel" class="panel">
|
|
965
|
+
${presetCards}
|
|
966
|
+
${renderManualProviderCard(initialEnvKey, secretLabel, placeholder)}
|
|
967
|
+
</div>
|
|
968
|
+
|
|
969
|
+
<div id="oauth-panel" class="panel card stack">
|
|
970
|
+
<label for="oauthService">OAuth service</label>
|
|
971
|
+
<select id="oauthService" name="oauthService">${oauthOptions}</select>
|
|
972
|
+
<p class="panel-note">You'll be redirected to the selected service's authorization page.</p>
|
|
973
|
+
</div>
|
|
974
|
+
|
|
975
|
+
<div>
|
|
976
|
+
<button id="btn" class="primary-button" onclick="connect()">Continue</button>
|
|
977
|
+
<div id="result" class="result" aria-live="polite"></div>
|
|
978
|
+
</div>
|
|
979
|
+
${renderCredentialPageScript(token)}`);
|
|
940
980
|
}
|
|
941
981
|
function renderErrorPage(message) {
|
|
942
982
|
return renderStatusPage("Login Error", message, "err");
|
|
@@ -1090,8 +1130,8 @@ async function handleOAuthStart(data, req, linkTokenStore, oauthStates, res) {
|
|
|
1090
1130
|
res.end(JSON.stringify({ error: `Unsupported OAuth service: ${data.serviceId}` }));
|
|
1091
1131
|
return;
|
|
1092
1132
|
}
|
|
1093
|
-
const clientId =
|
|
1094
|
-
const clientSecret =
|
|
1133
|
+
const clientId = readEnv(service.clientIdEnvKey);
|
|
1134
|
+
const clientSecret = readEnv(service.clientSecretEnvKey);
|
|
1095
1135
|
if (!clientId || !clientSecret) {
|
|
1096
1136
|
res.writeHead(400, { "Content-Type": "application/json" });
|
|
1097
1137
|
res.end(JSON.stringify({
|
|
@@ -1130,69 +1170,66 @@ async function handleOAuthStart(data, req, linkTokenStore, oauthStates, res) {
|
|
|
1130
1170
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
1131
1171
|
res.end(JSON.stringify({ ok: true, redirectUrl: authorizeUrl.toString() }));
|
|
1132
1172
|
}
|
|
1133
|
-
|
|
1173
|
+
function resolveOAuthCallback(options) {
|
|
1174
|
+
const { url, oauthStates, linkTokenStore, res } = options;
|
|
1134
1175
|
const state = url.searchParams.get("state") ?? "";
|
|
1135
1176
|
const code = url.searchParams.get("code") ?? "";
|
|
1136
1177
|
const oauthError = url.searchParams.get("error");
|
|
1137
1178
|
// Atomic pop: whatever path we take from here, this state is spent.
|
|
1138
|
-
// Done before any `await` to close the TOCTOU window between the state
|
|
1139
|
-
// lookup and the final delete.
|
|
1140
1179
|
const pending = oauthStates.get(state);
|
|
1141
1180
|
if (pending)
|
|
1142
1181
|
oauthStates.delete(state);
|
|
1143
1182
|
if (oauthError) {
|
|
1144
1183
|
res.writeHead(400, { "Content-Type": "text/html; charset=utf-8" });
|
|
1145
1184
|
res.end(renderErrorPage(`OAuth authorization failed: ${oauthError}`));
|
|
1146
|
-
return;
|
|
1185
|
+
return undefined;
|
|
1147
1186
|
}
|
|
1148
1187
|
if (!pending || Date.now() > pending.expiresAt) {
|
|
1149
1188
|
res.writeHead(400, { "Content-Type": "text/html; charset=utf-8" });
|
|
1150
1189
|
res.end(renderErrorPage("OAuth state is invalid or expired. Please run /login again."));
|
|
1151
|
-
return;
|
|
1190
|
+
return undefined;
|
|
1152
1191
|
}
|
|
1153
1192
|
if (!code) {
|
|
1154
1193
|
res.writeHead(400, { "Content-Type": "text/html; charset=utf-8" });
|
|
1155
1194
|
res.end(renderErrorPage("Missing OAuth authorization code."));
|
|
1156
|
-
return;
|
|
1195
|
+
return undefined;
|
|
1157
1196
|
}
|
|
1158
1197
|
const service = resolveOAuthService(pending.serviceId);
|
|
1159
1198
|
if (!service) {
|
|
1160
1199
|
res.writeHead(400, { "Content-Type": "text/html; charset=utf-8" });
|
|
1161
1200
|
res.end(renderErrorPage("Unsupported OAuth service."));
|
|
1162
|
-
return;
|
|
1201
|
+
return undefined;
|
|
1163
1202
|
}
|
|
1164
|
-
const clientId =
|
|
1165
|
-
const clientSecret =
|
|
1203
|
+
const clientId = readEnv(service.clientIdEnvKey);
|
|
1204
|
+
const clientSecret = readEnv(service.clientSecretEnvKey);
|
|
1166
1205
|
if (!clientId || !clientSecret) {
|
|
1167
1206
|
res.writeHead(500, { "Content-Type": "text/html; charset=utf-8" });
|
|
1168
1207
|
res.end(renderErrorPage("OAuth service is not configured on server."));
|
|
1169
|
-
return;
|
|
1208
|
+
return undefined;
|
|
1170
1209
|
}
|
|
1171
|
-
// Atomic consume
|
|
1172
|
-
// callbacks for the same state would previously both pass `peek` and both
|
|
1173
|
-
// run `exchangeOAuthCode` across the await; only one reaches `consume`.
|
|
1210
|
+
// Atomic consume keeps the callback one-shot across the token exchange await.
|
|
1174
1211
|
const linkToken = linkTokenStore.consume(pending.linkToken);
|
|
1175
1212
|
if (!linkToken) {
|
|
1176
1213
|
res.writeHead(400, { "Content-Type": "text/html; charset=utf-8" });
|
|
1177
1214
|
res.end(renderErrorPage("Login link is invalid or expired. Please run /login again."));
|
|
1178
|
-
return;
|
|
1215
|
+
return undefined;
|
|
1179
1216
|
}
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
const
|
|
1217
|
+
return { code, codeVerifier: pending.codeVerifier, service, clientId, clientSecret, linkToken };
|
|
1218
|
+
}
|
|
1219
|
+
function storeOAuthCredentials(options) {
|
|
1220
|
+
const { tokenResponse, service, clientId, clientSecret, linkToken, vaultManager, res } = options;
|
|
1221
|
+
const accessToken = tokenResponse.access_token?.trim();
|
|
1222
|
+
const refreshToken = tokenResponse.refresh_token?.trim();
|
|
1184
1223
|
if (!accessToken) {
|
|
1185
1224
|
res.writeHead(400, { "Content-Type": "text/html; charset=utf-8" });
|
|
1186
1225
|
res.end(renderErrorPage("OAuth token exchange did not return an access_token."));
|
|
1187
|
-
return;
|
|
1226
|
+
return undefined;
|
|
1188
1227
|
}
|
|
1189
1228
|
const updates = {};
|
|
1190
|
-
for (const key of service.accessTokenEnvKeys ?? [])
|
|
1229
|
+
for (const key of service.accessTokenEnvKeys ?? [])
|
|
1191
1230
|
updates[key] = accessToken;
|
|
1192
|
-
|
|
1193
|
-
if (refreshToken && service.refreshTokenEnvKey) {
|
|
1231
|
+
if (refreshToken && service.refreshTokenEnvKey)
|
|
1194
1232
|
updates[service.refreshTokenEnvKey] = refreshToken;
|
|
1195
|
-
}
|
|
1196
1233
|
const fileOutput = service.fileOutput;
|
|
1197
1234
|
let mountedPath;
|
|
1198
1235
|
if (fileOutput?.type === "authorized_user") {
|
|
@@ -1200,15 +1237,13 @@ async function handleOAuthCallback(url, req, linkTokenStore, vaultManager, notif
|
|
|
1200
1237
|
res.writeHead(400, { "Content-Type": "text/html; charset=utf-8" });
|
|
1201
1238
|
res.end(renderErrorPage("OAuth token exchange did not return a refresh_token. " +
|
|
1202
1239
|
"Retry after revoking prior consent or ensure prompt=consent is applied."));
|
|
1203
|
-
return;
|
|
1240
|
+
return undefined;
|
|
1204
1241
|
}
|
|
1205
1242
|
mountedPath = fileOutput.targetPath ?? defaultVaultTargetPath(fileOutput.relativePath);
|
|
1206
|
-
if (fileOutput.envKey)
|
|
1243
|
+
if (fileOutput.envKey)
|
|
1207
1244
|
updates[fileOutput.envKey] = mountedPath;
|
|
1208
|
-
|
|
1209
|
-
for (const key of fileOutput.additionalEnvKeys ?? []) {
|
|
1245
|
+
for (const key of fileOutput.additionalEnvKeys ?? [])
|
|
1210
1246
|
updates[key] = mountedPath;
|
|
1211
|
-
}
|
|
1212
1247
|
}
|
|
1213
1248
|
const storedTargets = [];
|
|
1214
1249
|
try {
|
|
@@ -1240,10 +1275,39 @@ async function handleOAuthCallback(url, req, linkTokenStore, vaultManager, notif
|
|
|
1240
1275
|
});
|
|
1241
1276
|
res.writeHead(500, { "Content-Type": "text/html; charset=utf-8" });
|
|
1242
1277
|
res.end(renderErrorPage("OAuth tokens were received but could not be stored on the server. Fix the server issue and run /login again."));
|
|
1243
|
-
return;
|
|
1278
|
+
return undefined;
|
|
1244
1279
|
}
|
|
1280
|
+
return storedTargets;
|
|
1281
|
+
}
|
|
1282
|
+
async function handleOAuthCallback(options) {
|
|
1283
|
+
const resolved = resolveOAuthCallback(options);
|
|
1284
|
+
if (!resolved)
|
|
1285
|
+
return;
|
|
1286
|
+
const { service, code, clientId, clientSecret, codeVerifier, linkToken } = resolved;
|
|
1287
|
+
const redirectUri = `${requestBaseUrl(options.req)}/oauth/callback`;
|
|
1288
|
+
const tokenResponse = await exchangeOAuthCode({
|
|
1289
|
+
service,
|
|
1290
|
+
code,
|
|
1291
|
+
clientId,
|
|
1292
|
+
clientSecret,
|
|
1293
|
+
redirectUri,
|
|
1294
|
+
codeVerifier,
|
|
1295
|
+
});
|
|
1296
|
+
const storedTargets = storeOAuthCredentials({
|
|
1297
|
+
tokenResponse,
|
|
1298
|
+
service,
|
|
1299
|
+
clientId,
|
|
1300
|
+
clientSecret,
|
|
1301
|
+
linkToken,
|
|
1302
|
+
vaultManager: options.vaultManager,
|
|
1303
|
+
res: options.res,
|
|
1304
|
+
});
|
|
1305
|
+
if (!storedTargets)
|
|
1306
|
+
return;
|
|
1245
1307
|
log.logInfo(`Stored [${storedTargets.join(", ")}] for ${linkToken.platform}/${linkToken.platformUserId} in vault:${linkToken.vaultId}`);
|
|
1246
|
-
|
|
1308
|
+
options
|
|
1309
|
+
.notify(linkToken.platform, linkToken.conversationId, `${service.label} OAuth stored (${storedTargets.join(", ")}) in vault \`${linkToken.vaultId}\`.`)
|
|
1310
|
+
.catch((err) => {
|
|
1247
1311
|
log.logWarning("Failed to notify user after OAuth login", err.message);
|
|
1248
1312
|
reportUserFacingError(err, {
|
|
1249
1313
|
domain: "login",
|
|
@@ -1260,10 +1324,11 @@ async function handleOAuthCallback(url, req, linkTokenStore, vaultManager, notif
|
|
|
1260
1324
|
},
|
|
1261
1325
|
});
|
|
1262
1326
|
});
|
|
1263
|
-
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
1264
|
-
res.end(renderSuccessPage(`${service.label} OAuth connected successfully.`));
|
|
1327
|
+
options.res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
1328
|
+
options.res.end(renderSuccessPage(`${service.label} OAuth connected successfully.`));
|
|
1265
1329
|
}
|
|
1266
|
-
async function exchangeOAuthCode(
|
|
1330
|
+
async function exchangeOAuthCode(options) {
|
|
1331
|
+
const { service, code, clientId, clientSecret, redirectUri, codeVerifier } = options;
|
|
1267
1332
|
const params = new URLSearchParams();
|
|
1268
1333
|
params.set("grant_type", "authorization_code");
|
|
1269
1334
|
params.set("code", code);
|