@withbuddi/buddi 0.1.0-pre.50 → 0.1.0-pre.52
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/extension/background.js +1604 -847
- package/extension/manifest.json +3 -3
- package/extension/popup.css +91 -3
- package/extension/popup.html +49 -32
- package/extension/popup.js +215 -123
- package/node_modules/@buddi/cli/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/cli/dist/commands.d.ts.map +1 -1
- package/node_modules/@buddi/cli/dist/commands.js +11 -1
- package/node_modules/@buddi/cli/dist/commands.js.map +1 -1
- package/node_modules/@buddi/core/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/core/dist/plugin/index.d.ts +1 -1
- package/node_modules/@buddi/core/dist/plugin/index.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/plugin/index.js.map +1 -1
- package/node_modules/@buddi/core/dist/questions/store.d.ts +3 -1
- package/node_modules/@buddi/core/dist/questions/store.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/questions/store.js +3 -3
- package/node_modules/@buddi/core/dist/questions/store.js.map +1 -1
- package/node_modules/@buddi/core/dist/questions/types.d.ts +46 -1
- package/node_modules/@buddi/core/dist/questions/types.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/questions/types.js +2 -1
- package/node_modules/@buddi/core/dist/questions/types.js.map +1 -1
- package/node_modules/@buddi/core/dist/registry.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/registry.js +11 -2
- package/node_modules/@buddi/core/dist/registry.js.map +1 -1
- package/node_modules/@buddi/core/dist/scheduler/index.d.ts +1 -0
- package/node_modules/@buddi/core/dist/scheduler/index.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/scheduler/index.js +1 -0
- package/node_modules/@buddi/core/dist/scheduler/index.js.map +1 -1
- package/node_modules/@buddi/core/dist/scheduler/manual.d.ts +50 -0
- package/node_modules/@buddi/core/dist/scheduler/manual.d.ts.map +1 -0
- package/node_modules/@buddi/core/dist/scheduler/manual.js +73 -0
- package/node_modules/@buddi/core/dist/scheduler/manual.js.map +1 -0
- package/node_modules/@buddi/core/dist/secrets/approval.d.ts +54 -0
- package/node_modules/@buddi/core/dist/secrets/approval.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/secrets/approval.js +58 -1
- package/node_modules/@buddi/core/dist/secrets/approval.js.map +1 -1
- package/node_modules/@buddi/core/dist/secrets/settings.d.ts +178 -0
- package/node_modules/@buddi/core/dist/secrets/settings.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/secrets/settings.js +63 -6
- package/node_modules/@buddi/core/dist/secrets/settings.js.map +1 -1
- package/node_modules/@buddi/core/dist/secrets/store.d.ts +31 -0
- package/node_modules/@buddi/core/dist/secrets/store.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/secrets/store.js +75 -0
- package/node_modules/@buddi/core/dist/secrets/store.js.map +1 -1
- package/node_modules/@buddi/core/dist/secrets/use.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/secrets/use.js +68 -3
- package/node_modules/@buddi/core/dist/secrets/use.js.map +1 -1
- package/node_modules/@buddi/core/dist/tools.d.ts +22 -0
- package/node_modules/@buddi/core/dist/tools.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/tools.js.map +1 -1
- package/node_modules/@buddi/core/migrations/080_secret_requests.sql +14 -0
- package/node_modules/@buddi/gateway/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/gateway/dist/chat/session.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/chat/session.js +2 -1
- package/node_modules/@buddi/gateway/dist/chat/session.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/mcp/requests.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/mcp/requests.js +9 -1
- package/node_modules/@buddi/gateway/dist/mcp/requests.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/missions/execute.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/missions/execute.js +3 -1
- package/node_modules/@buddi/gateway/dist/missions/execute.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/missions/reminders.d.ts +7 -2
- package/node_modules/@buddi/gateway/dist/missions/reminders.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/missions/reminders.js +27 -9
- package/node_modules/@buddi/gateway/dist/missions/reminders.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/missions/run-now.d.ts +38 -0
- package/node_modules/@buddi/gateway/dist/missions/run-now.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/missions/run-now.js +62 -0
- package/node_modules/@buddi/gateway/dist/missions/run-now.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/missions-cli.d.ts +1 -1
- package/node_modules/@buddi/gateway/dist/missions-cli.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/missions-cli.js +21 -10
- package/node_modules/@buddi/gateway/dist/missions-cli.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/serve.d.ts +3 -12
- package/node_modules/@buddi/gateway/dist/serve.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/serve.js +2 -21
- package/node_modules/@buddi/gateway/dist/serve.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/surfaces/browser-cards.d.ts +15 -3
- package/node_modules/@buddi/gateway/dist/surfaces/browser-cards.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/surfaces/browser-cards.js +34 -7
- package/node_modules/@buddi/gateway/dist/surfaces/browser-cards.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/surfaces/offered-actions.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/surfaces/offered-actions.js +8 -2
- package/node_modules/@buddi/gateway/dist/surfaces/offered-actions.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/surfaces/pending-question.d.ts +3 -1
- package/node_modules/@buddi/gateway/dist/surfaces/pending-question.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/surfaces/pending-question.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/surfaces/secret-request.d.ts +173 -0
- package/node_modules/@buddi/gateway/dist/surfaces/secret-request.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/surfaces/secret-request.js +332 -0
- package/node_modules/@buddi/gateway/dist/surfaces/secret-request.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/system-context.js +1 -1
- package/node_modules/@buddi/gateway/dist/system-context.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/main.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/main.js +14 -3
- package/node_modules/@buddi/gateway/dist/telegram/main.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/surface.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/surface.js +4 -1
- package/node_modules/@buddi/gateway/dist/telegram/surface.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/api-routes.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/api-routes.js +16 -1
- package/node_modules/@buddi/gateway/dist/web/api-routes.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/approval-ask.js +2 -2
- package/node_modules/@buddi/gateway/dist/web/approval-ask.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/browser-capture.d.ts +13 -0
- package/node_modules/@buddi/gateway/dist/web/browser-capture.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/browser-capture.js +24 -0
- package/node_modules/@buddi/gateway/dist/web/browser-capture.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/chat.d.ts +26 -0
- package/node_modules/@buddi/gateway/dist/web/chat.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/chat.js +87 -2
- package/node_modules/@buddi/gateway/dist/web/chat.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/extension.d.ts +30 -0
- package/node_modules/@buddi/gateway/dist/web/extension.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/extension.js +86 -6
- package/node_modules/@buddi/gateway/dist/web/extension.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/onboarding.js +1 -1
- package/node_modules/@buddi/gateway/dist/web/onboarding.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/read.d.ts +2 -0
- package/node_modules/@buddi/gateway/dist/web/read.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/read.js +2 -1
- package/node_modules/@buddi/gateway/dist/web/read.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/remote-hand.d.ts +26 -2
- package/node_modules/@buddi/gateway/dist/web/remote-hand.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/remote-hand.js +89 -28
- package/node_modules/@buddi/gateway/dist/web/remote-hand.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/secret-request.d.ts +54 -0
- package/node_modules/@buddi/gateway/dist/web/secret-request.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/secret-request.js +264 -0
- package/node_modules/@buddi/gateway/dist/web/secret-request.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/secrets.d.ts +1 -0
- package/node_modules/@buddi/gateway/dist/web/secrets.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/secrets.js +1 -1
- package/node_modules/@buddi/gateway/dist/web/secrets.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/server.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/server.js +76 -4
- package/node_modules/@buddi/gateway/dist/web/server.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/write.d.ts +14 -0
- package/node_modules/@buddi/gateway/dist/web/write.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/write.js +21 -0
- package/node_modules/@buddi/gateway/dist/web/write.js.map +1 -1
- package/node_modules/@buddi/install/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/runtime/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/runtime/dist/anthropic.d.ts +7 -0
- package/node_modules/@buddi/runtime/dist/anthropic.d.ts.map +1 -1
- package/node_modules/@buddi/runtime/dist/anthropic.js +19 -1
- package/node_modules/@buddi/runtime/dist/anthropic.js.map +1 -1
- package/node_modules/@buddi/runtime/dist/codex-direct.d.ts +1 -1
- package/node_modules/@buddi/runtime/dist/codex-direct.js +1 -1
- package/node_modules/@buddi/tool-artifacts/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/tool-browser/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/tool-browser/dist/controller.d.ts +16 -1
- package/node_modules/@buddi/tool-browser/dist/controller.d.ts.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/controller.js +59 -5
- package/node_modules/@buddi/tool-browser/dist/controller.js.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/driver.d.ts +12 -0
- package/node_modules/@buddi/tool-browser/dist/driver.d.ts.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/driver.js +41 -2
- package/node_modules/@buddi/tool-browser/dist/driver.js.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/extension.d.ts +49 -9
- package/node_modules/@buddi/tool-browser/dist/extension.d.ts.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/extension.js +145 -21
- package/node_modules/@buddi/tool-browser/dist/extension.js.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/index.d.ts +10 -6
- package/node_modules/@buddi/tool-browser/dist/index.d.ts.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/index.js +22 -8
- package/node_modules/@buddi/tool-browser/dist/index.js.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/routes.d.ts +10 -1
- package/node_modules/@buddi/tool-browser/dist/routes.d.ts.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/routes.js +24 -0
- package/node_modules/@buddi/tool-browser/dist/routes.js.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/service.d.ts +48 -1
- package/node_modules/@buddi/tool-browser/dist/service.d.ts.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/service.js +114 -11
- package/node_modules/@buddi/tool-browser/dist/service.js.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/types.d.ts +54 -3
- package/node_modules/@buddi/tool-browser/dist/types.d.ts.map +1 -1
- package/node_modules/@buddi/tool-browser/dist/types.js +17 -1
- package/node_modules/@buddi/tool-browser/dist/types.js.map +1 -1
- package/node_modules/@buddi/tool-email/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/tool-host/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/tool-mcp/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/tool-memory/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/tool-web/dist/.tsbuildinfo +1 -1
- package/node_modules/imapflow/CHANGELOG.md +30 -0
- package/node_modules/imapflow/dist/cjs/commands/authenticate.js +15 -4
- package/node_modules/imapflow/dist/cjs/commands/enable.js +6 -0
- package/node_modules/imapflow/dist/cjs/commands/fetch.js +22 -5
- package/node_modules/imapflow/dist/cjs/commands/select.d.ts +3 -14
- package/node_modules/imapflow/dist/cjs/commands/select.js +1 -4
- package/node_modules/imapflow/dist/cjs/commands/store.js +7 -6
- package/node_modules/imapflow/dist/cjs/download.js +139 -5
- package/node_modules/imapflow/dist/cjs/imap-flow.d.ts +2 -2
- package/node_modules/imapflow/dist/cjs/imap-flow.js +51 -12
- package/node_modules/imapflow/dist/cjs/package-info.d.ts +1 -1
- package/node_modules/imapflow/dist/cjs/package-info.js +1 -1
- package/node_modules/imapflow/dist/cjs/search-compiler.js +6 -3
- package/node_modules/imapflow/dist/cjs/tools.d.ts +14 -3
- package/node_modules/imapflow/dist/cjs/tools.js +68 -6
- package/node_modules/imapflow/dist/cjs/types.d.ts +9 -1
- package/node_modules/imapflow/dist/esm/commands/authenticate.js +15 -4
- package/node_modules/imapflow/dist/esm/commands/enable.js +6 -0
- package/node_modules/imapflow/dist/esm/commands/fetch.js +22 -5
- package/node_modules/imapflow/dist/esm/commands/select.d.ts +3 -14
- package/node_modules/imapflow/dist/esm/commands/select.js +1 -4
- package/node_modules/imapflow/dist/esm/commands/store.js +8 -7
- package/node_modules/imapflow/dist/esm/download.js +139 -5
- package/node_modules/imapflow/dist/esm/imap-flow.d.ts +2 -2
- package/node_modules/imapflow/dist/esm/imap-flow.js +52 -13
- package/node_modules/imapflow/dist/esm/package-info.d.ts +1 -1
- package/node_modules/imapflow/dist/esm/package-info.js +1 -1
- package/node_modules/imapflow/dist/esm/search-compiler.js +6 -3
- package/node_modules/imapflow/dist/esm/tools.d.ts +14 -3
- package/node_modules/imapflow/dist/esm/tools.js +67 -6
- package/node_modules/imapflow/dist/esm/types.d.ts +9 -1
- package/node_modules/imapflow/package.json +5 -3
- package/node_modules/playwright/README.md +4 -4
- package/node_modules/playwright/lib/agents/playwright-test-generator.agent.md +1 -1
- package/node_modules/playwright/lib/cli/testActions.js +8 -5
- package/node_modules/playwright/lib/common/index.js +37 -23
- package/node_modules/playwright/lib/common/index.js.txt +8 -9
- package/node_modules/playwright/lib/index.js +16 -4
- package/node_modules/playwright/lib/matchers/expect.js +13 -7
- package/node_modules/playwright/lib/matchers/expect.js.txt +4 -4
- package/node_modules/playwright/lib/program.js +2 -1
- package/node_modules/playwright/lib/runner/index.js +438 -244
- package/node_modules/playwright/lib/runner/index.js.txt +12 -11
- package/node_modules/playwright/lib/transform/babelBundle.js +2612 -2396
- package/node_modules/playwright/lib/transform/babelBundle.js.LICENSE +15 -15
- package/node_modules/playwright/lib/transform/babelBundle.js.txt +14 -11
- package/node_modules/playwright/lib/transform/esmLoader.js +17 -5
- package/node_modules/playwright/lib/transform/esmLoader.js.txt +3 -3
- package/node_modules/playwright/lib/worker/workerProcessEntry.js +17 -18
- package/node_modules/playwright/package.json +2 -7
- package/node_modules/playwright/types/test.d.ts +156 -39
- package/node_modules/playwright-core/browsers.json +9 -9
- package/node_modules/playwright-core/cli.js +1 -0
- package/node_modules/playwright-core/lib/bootstrap.js +61 -0
- package/node_modules/playwright-core/lib/coreBundle.js +6393 -4170
- package/node_modules/playwright-core/lib/server/electron/loader.js +4 -0
- package/node_modules/playwright-core/lib/tools/cli-client/cli.js +2 -1
- package/node_modules/playwright-core/lib/tools/cli-client/help.json +99 -12
- package/node_modules/playwright-core/lib/tools/cli-client/output.js +17 -16
- package/node_modules/playwright-core/lib/tools/cli-client/program.js +8 -4
- package/node_modules/playwright-core/lib/tools/cli-client/session.js +2 -0
- package/node_modules/playwright-core/lib/tools/skills/playwright-cli/SKILL.md +71 -3
- package/node_modules/playwright-core/lib/tools/skills/playwright-cli/references/pr-attachments.md +60 -0
- package/node_modules/playwright-core/lib/tools/skills/playwright-cli/references/running-code.md +4 -0
- package/node_modules/playwright-core/lib/tools/skills/playwright-cli/references/session-management.md +2 -0
- package/node_modules/playwright-core/lib/tools/skills/playwright-cli/references/test-generation.md +1 -1
- package/node_modules/playwright-core/lib/tools/skills/playwright-cli/references/video-recording.md +76 -3
- package/node_modules/playwright-core/lib/tools/skills/playwright-trace/SKILL.md +1 -1
- package/node_modules/playwright-core/lib/utilsBundle.js +948 -227
- package/node_modules/playwright-core/lib/utilsBundle.js.LICENSE +6 -6
- package/node_modules/playwright-core/lib/vite/htmlReport/report.js +1 -1
- package/node_modules/playwright-core/lib/vite/recorder/assets/{codeMirrorModule-CVQWJZAA.js → codeMirrorModule-DK72OMRi.js} +1 -1
- package/node_modules/playwright-core/lib/vite/recorder/assets/index-Cn0mmDuv.js +129 -0
- package/node_modules/playwright-core/lib/vite/recorder/index.html +1 -1
- package/node_modules/playwright-core/lib/vite/traceViewer/assets/{codeMirrorModule-BbkfBe3n.js → codeMirrorModule-BEB2e8M3.js} +1 -1
- package/node_modules/playwright-core/lib/vite/traceViewer/assets/defaultSettingsView-D-g2vrvf.js +184 -0
- package/node_modules/playwright-core/lib/vite/traceViewer/assets/{xtermModule-DywYcAf8.js → xtermModule-B794rD2Z.js} +1 -1
- package/node_modules/playwright-core/lib/vite/traceViewer/{defaultSettingsView.Bqk9acqE.css → defaultSettingsView.C8BeHuxd.css} +1 -1
- package/node_modules/playwright-core/lib/vite/traceViewer/{index.B4cLoZK3.js → index.7-c5LSTW.js} +1 -1
- package/node_modules/playwright-core/lib/vite/traceViewer/index.html +3 -3
- package/node_modules/playwright-core/lib/vite/traceViewer/sw.bundle.js +3 -3
- package/node_modules/playwright-core/lib/vite/traceViewer/{uiMode.CU5KtEkS.js → uiMode.CYwC_gH1.js} +4 -4
- package/node_modules/playwright-core/lib/vite/traceViewer/uiMode.html +3 -3
- package/node_modules/playwright-core/package.json +1 -1
- package/node_modules/playwright-core/types/protocol.d.ts +468 -337
- package/node_modules/playwright-core/types/types.d.ts +572 -37
- package/package.json +2 -2
- package/packages/cli/dist/.tsbuildinfo +1 -1
- package/packages/cli/dist/commands.d.ts.map +1 -1
- package/packages/cli/dist/commands.js +11 -1
- package/packages/cli/dist/commands.js.map +1 -1
- package/packages/core/dist/.tsbuildinfo +1 -1
- package/packages/core/dist/plugin/index.d.ts +1 -1
- package/packages/core/dist/plugin/index.d.ts.map +1 -1
- package/packages/core/dist/plugin/index.js.map +1 -1
- package/packages/core/dist/questions/store.d.ts +3 -1
- package/packages/core/dist/questions/store.d.ts.map +1 -1
- package/packages/core/dist/questions/store.js +3 -3
- package/packages/core/dist/questions/store.js.map +1 -1
- package/packages/core/dist/questions/types.d.ts +46 -1
- package/packages/core/dist/questions/types.d.ts.map +1 -1
- package/packages/core/dist/questions/types.js +2 -1
- package/packages/core/dist/questions/types.js.map +1 -1
- package/packages/core/dist/registry.d.ts.map +1 -1
- package/packages/core/dist/registry.js +11 -2
- package/packages/core/dist/registry.js.map +1 -1
- package/packages/core/dist/scheduler/index.d.ts +1 -0
- package/packages/core/dist/scheduler/index.d.ts.map +1 -1
- package/packages/core/dist/scheduler/index.js +1 -0
- package/packages/core/dist/scheduler/index.js.map +1 -1
- package/packages/core/dist/scheduler/manual.d.ts +50 -0
- package/packages/core/dist/scheduler/manual.d.ts.map +1 -0
- package/packages/core/dist/scheduler/manual.js +73 -0
- package/packages/core/dist/scheduler/manual.js.map +1 -0
- package/packages/core/dist/secrets/approval.d.ts +54 -0
- package/packages/core/dist/secrets/approval.d.ts.map +1 -1
- package/packages/core/dist/secrets/approval.js +58 -1
- package/packages/core/dist/secrets/approval.js.map +1 -1
- package/packages/core/dist/secrets/settings.d.ts +178 -0
- package/packages/core/dist/secrets/settings.d.ts.map +1 -1
- package/packages/core/dist/secrets/settings.js +63 -6
- package/packages/core/dist/secrets/settings.js.map +1 -1
- package/packages/core/dist/secrets/store.d.ts +31 -0
- package/packages/core/dist/secrets/store.d.ts.map +1 -1
- package/packages/core/dist/secrets/store.js +75 -0
- package/packages/core/dist/secrets/store.js.map +1 -1
- package/packages/core/dist/secrets/use.d.ts.map +1 -1
- package/packages/core/dist/secrets/use.js +68 -3
- package/packages/core/dist/secrets/use.js.map +1 -1
- package/packages/core/dist/tools.d.ts +22 -0
- package/packages/core/dist/tools.d.ts.map +1 -1
- package/packages/core/dist/tools.js.map +1 -1
- package/packages/core/migrations/080_secret_requests.sql +14 -0
- package/packages/gateway/dist/.tsbuildinfo +1 -1
- package/packages/gateway/dist/chat/session.d.ts.map +1 -1
- package/packages/gateway/dist/chat/session.js +2 -1
- package/packages/gateway/dist/chat/session.js.map +1 -1
- package/packages/gateway/dist/mcp/requests.d.ts.map +1 -1
- package/packages/gateway/dist/mcp/requests.js +9 -1
- package/packages/gateway/dist/mcp/requests.js.map +1 -1
- package/packages/gateway/dist/missions/execute.d.ts.map +1 -1
- package/packages/gateway/dist/missions/execute.js +3 -1
- package/packages/gateway/dist/missions/execute.js.map +1 -1
- package/packages/gateway/dist/missions/reminders.d.ts +7 -2
- package/packages/gateway/dist/missions/reminders.d.ts.map +1 -1
- package/packages/gateway/dist/missions/reminders.js +27 -9
- package/packages/gateway/dist/missions/reminders.js.map +1 -1
- package/packages/gateway/dist/missions/run-now.d.ts +38 -0
- package/packages/gateway/dist/missions/run-now.d.ts.map +1 -0
- package/packages/gateway/dist/missions/run-now.js +62 -0
- package/packages/gateway/dist/missions/run-now.js.map +1 -0
- package/packages/gateway/dist/missions-cli.d.ts +1 -1
- package/packages/gateway/dist/missions-cli.d.ts.map +1 -1
- package/packages/gateway/dist/missions-cli.js +21 -10
- package/packages/gateway/dist/missions-cli.js.map +1 -1
- package/packages/gateway/dist/serve.d.ts +3 -12
- package/packages/gateway/dist/serve.d.ts.map +1 -1
- package/packages/gateway/dist/serve.js +2 -21
- package/packages/gateway/dist/serve.js.map +1 -1
- package/packages/gateway/dist/surfaces/browser-cards.d.ts +15 -3
- package/packages/gateway/dist/surfaces/browser-cards.d.ts.map +1 -1
- package/packages/gateway/dist/surfaces/browser-cards.js +34 -7
- package/packages/gateway/dist/surfaces/browser-cards.js.map +1 -1
- package/packages/gateway/dist/surfaces/offered-actions.d.ts.map +1 -1
- package/packages/gateway/dist/surfaces/offered-actions.js +8 -2
- package/packages/gateway/dist/surfaces/offered-actions.js.map +1 -1
- package/packages/gateway/dist/surfaces/pending-question.d.ts +3 -1
- package/packages/gateway/dist/surfaces/pending-question.d.ts.map +1 -1
- package/packages/gateway/dist/surfaces/pending-question.js.map +1 -1
- package/packages/gateway/dist/surfaces/secret-request.d.ts +173 -0
- package/packages/gateway/dist/surfaces/secret-request.d.ts.map +1 -0
- package/packages/gateway/dist/surfaces/secret-request.js +332 -0
- package/packages/gateway/dist/surfaces/secret-request.js.map +1 -0
- package/packages/gateway/dist/system-context.js +1 -1
- package/packages/gateway/dist/system-context.js.map +1 -1
- package/packages/gateway/dist/telegram/main.d.ts.map +1 -1
- package/packages/gateway/dist/telegram/main.js +14 -3
- package/packages/gateway/dist/telegram/main.js.map +1 -1
- package/packages/gateway/dist/telegram/surface.d.ts.map +1 -1
- package/packages/gateway/dist/telegram/surface.js +4 -1
- package/packages/gateway/dist/telegram/surface.js.map +1 -1
- package/packages/gateway/dist/web/api-routes.d.ts.map +1 -1
- package/packages/gateway/dist/web/api-routes.js +16 -1
- package/packages/gateway/dist/web/api-routes.js.map +1 -1
- package/packages/gateway/dist/web/approval-ask.js +2 -2
- package/packages/gateway/dist/web/approval-ask.js.map +1 -1
- package/packages/gateway/dist/web/browser-capture.d.ts +13 -0
- package/packages/gateway/dist/web/browser-capture.d.ts.map +1 -0
- package/packages/gateway/dist/web/browser-capture.js +24 -0
- package/packages/gateway/dist/web/browser-capture.js.map +1 -0
- package/packages/gateway/dist/web/chat.d.ts +26 -0
- package/packages/gateway/dist/web/chat.d.ts.map +1 -1
- package/packages/gateway/dist/web/chat.js +87 -2
- package/packages/gateway/dist/web/chat.js.map +1 -1
- package/packages/gateway/dist/web/extension.d.ts +30 -0
- package/packages/gateway/dist/web/extension.d.ts.map +1 -1
- package/packages/gateway/dist/web/extension.js +86 -6
- package/packages/gateway/dist/web/extension.js.map +1 -1
- package/packages/gateway/dist/web/onboarding.js +1 -1
- package/packages/gateway/dist/web/onboarding.js.map +1 -1
- package/packages/gateway/dist/web/read.d.ts +2 -0
- package/packages/gateway/dist/web/read.d.ts.map +1 -1
- package/packages/gateway/dist/web/read.js +2 -1
- package/packages/gateway/dist/web/read.js.map +1 -1
- package/packages/gateway/dist/web/remote-hand.d.ts +26 -2
- package/packages/gateway/dist/web/remote-hand.d.ts.map +1 -1
- package/packages/gateway/dist/web/remote-hand.js +89 -28
- package/packages/gateway/dist/web/remote-hand.js.map +1 -1
- package/packages/gateway/dist/web/secret-request.d.ts +54 -0
- package/packages/gateway/dist/web/secret-request.d.ts.map +1 -0
- package/packages/gateway/dist/web/secret-request.js +264 -0
- package/packages/gateway/dist/web/secret-request.js.map +1 -0
- package/packages/gateway/dist/web/secrets.d.ts +1 -0
- package/packages/gateway/dist/web/secrets.d.ts.map +1 -1
- package/packages/gateway/dist/web/secrets.js +1 -1
- package/packages/gateway/dist/web/secrets.js.map +1 -1
- package/packages/gateway/dist/web/server.d.ts.map +1 -1
- package/packages/gateway/dist/web/server.js +76 -4
- package/packages/gateway/dist/web/server.js.map +1 -1
- package/packages/gateway/dist/web/write.d.ts +14 -0
- package/packages/gateway/dist/web/write.d.ts.map +1 -1
- package/packages/gateway/dist/web/write.js +21 -0
- package/packages/gateway/dist/web/write.js.map +1 -1
- package/packages/install/dist/.tsbuildinfo +1 -1
- package/packages/runtime/dist/.tsbuildinfo +1 -1
- package/packages/runtime/dist/anthropic.d.ts +7 -0
- package/packages/runtime/dist/anthropic.d.ts.map +1 -1
- package/packages/runtime/dist/anthropic.js +19 -1
- package/packages/runtime/dist/anthropic.js.map +1 -1
- package/packages/runtime/dist/codex-direct.d.ts +1 -1
- package/packages/runtime/dist/codex-direct.js +1 -1
- package/packages/tools/artifacts/dist/.tsbuildinfo +1 -1
- package/packages/tools/browser/dist/.tsbuildinfo +1 -1
- package/packages/tools/browser/dist/controller.d.ts +16 -1
- package/packages/tools/browser/dist/controller.d.ts.map +1 -1
- package/packages/tools/browser/dist/controller.js +59 -5
- package/packages/tools/browser/dist/controller.js.map +1 -1
- package/packages/tools/browser/dist/driver.d.ts +12 -0
- package/packages/tools/browser/dist/driver.d.ts.map +1 -1
- package/packages/tools/browser/dist/driver.js +41 -2
- package/packages/tools/browser/dist/driver.js.map +1 -1
- package/packages/tools/browser/dist/extension.d.ts +49 -9
- package/packages/tools/browser/dist/extension.d.ts.map +1 -1
- package/packages/tools/browser/dist/extension.js +145 -21
- package/packages/tools/browser/dist/extension.js.map +1 -1
- package/packages/tools/browser/dist/index.d.ts +10 -6
- package/packages/tools/browser/dist/index.d.ts.map +1 -1
- package/packages/tools/browser/dist/index.js +22 -8
- package/packages/tools/browser/dist/index.js.map +1 -1
- package/packages/tools/browser/dist/routes.d.ts +10 -1
- package/packages/tools/browser/dist/routes.d.ts.map +1 -1
- package/packages/tools/browser/dist/routes.js +24 -0
- package/packages/tools/browser/dist/routes.js.map +1 -1
- package/packages/tools/browser/dist/service.d.ts +48 -1
- package/packages/tools/browser/dist/service.d.ts.map +1 -1
- package/packages/tools/browser/dist/service.js +114 -11
- package/packages/tools/browser/dist/service.js.map +1 -1
- package/packages/tools/browser/dist/types.d.ts +54 -3
- package/packages/tools/browser/dist/types.d.ts.map +1 -1
- package/packages/tools/browser/dist/types.js +17 -1
- package/packages/tools/browser/dist/types.js.map +1 -1
- package/packages/tools/email/dist/.tsbuildinfo +1 -1
- package/packages/tools/host/dist/.tsbuildinfo +1 -1
- package/packages/tools/mcp/dist/.tsbuildinfo +1 -1
- package/packages/tools/memory/dist/.tsbuildinfo +1 -1
- package/packages/tools/web/dist/.tsbuildinfo +1 -1
- package/packages/web/dist/assets/index-oxmxR39o.js +155 -0
- package/packages/web/dist/assets/index-rMRjibNI.css +1 -0
- package/packages/web/dist/assets/{lottie_light-BJaxbmZQ.js → lottie_light-DROBTM6Y.js} +1 -1
- package/packages/web/dist/build.json +1 -1
- package/packages/web/dist/index.html +2 -2
- package/packages/web/dist/precache.json +4 -4
- package/node_modules/playwright/jsx-runtime.js +0 -42
- package/node_modules/playwright/jsx-runtime.mjs +0 -21
- package/node_modules/playwright-core/lib/vite/recorder/assets/index-hrlLqLtq.js +0 -129
- package/node_modules/playwright-core/lib/vite/traceViewer/assets/defaultSettingsView-Ds6CBOo0.js +0 -182
- package/packages/web/dist/assets/index-DBVZzTau.css +0 -1
- package/packages/web/dist/assets/index-DqoP9iYJ.js +0 -155
|
@@ -19,6 +19,113 @@ const limited_passthrough_js_1 = require("./limited-passthrough.js");
|
|
|
19
19
|
// away (a consumer destroying it closes it without a 'drain')
|
|
20
20
|
const DRAIN_WAIT_EVENTS = ['drain', 'error', 'close'];
|
|
21
21
|
const tools_js_1 = require("./tools.js");
|
|
22
|
+
const isEmptySection = (value) => !value?.length;
|
|
23
|
+
/**
|
|
24
|
+
* The section to ask again when exactly one of a part's MIME headers and content came back
|
|
25
|
+
* empty (see refetchDroppedSections()), undefined when both or neither did
|
|
26
|
+
*/
|
|
27
|
+
const droppedSection = (mime, content, mimeRequest, contentRequest) => {
|
|
28
|
+
if (isEmptySection(mime) === isEmptySection(content)) {
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
return isEmptySection(content) ? contentRequest : mimeRequest;
|
|
32
|
+
};
|
|
33
|
+
/** Start offset of every partial section among the requests, keyed by section */
|
|
34
|
+
const partialStarts = (requests) => {
|
|
35
|
+
let starts = new Map();
|
|
36
|
+
for (let request of requests) {
|
|
37
|
+
if (typeof request !== 'string') {
|
|
38
|
+
starts.set(request.key, Number(request.start) || 0);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return starts;
|
|
42
|
+
};
|
|
43
|
+
// How many times a request is repeated after answers that belong to another request
|
|
44
|
+
const MAX_FOREIGN_ANSWERS = 3;
|
|
45
|
+
const requestedUid = (range, options) => options.uid && /^\d+$/.test(String(range)) ? Number(range) : undefined;
|
|
46
|
+
const isForeignAnswer = (response, expected) => {
|
|
47
|
+
if (expected.uid && response.uid && response.uid !== expected.uid) {
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
for (let [key, start] of expected.origins) {
|
|
51
|
+
let origin = response.partialOrigins && response.partialOrigins.get(key);
|
|
52
|
+
// An answer without the origin is taken as is: some servers leave it out, and some
|
|
53
|
+
// ignore the partial specifier altogether
|
|
54
|
+
if (typeof origin === 'number' && origin !== start) {
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return false;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* fetchOne() that takes only an answer belonging to the request. Apache James now and then
|
|
62
|
+
* writes the head of a FETCH answer after its tagged OK, so the data of one request shows up
|
|
63
|
+
* within the answer to the next one. Taken at face value it would be the data of that next
|
|
64
|
+
* request, and a download would end without an error but with misplaced bytes. An answer for
|
|
65
|
+
* another UID, or with a partial section that starts at another offset than asked, is dropped
|
|
66
|
+
* and the request repeated.
|
|
67
|
+
*/
|
|
68
|
+
async function fetchExpected(client, range, query, options, expected) {
|
|
69
|
+
for (let attempt = 1;; attempt++) {
|
|
70
|
+
let response = await client.fetchOne(range, query, options);
|
|
71
|
+
if (!response || !isForeignAnswer(response, expected)) {
|
|
72
|
+
return response;
|
|
73
|
+
}
|
|
74
|
+
client.log.warn({
|
|
75
|
+
msg: 'Server answered with data of another request, asking again',
|
|
76
|
+
uid: response.uid,
|
|
77
|
+
origins: response.partialOrigins && Object.fromEntries(response.partialOrigins),
|
|
78
|
+
attempt,
|
|
79
|
+
cid: client.id
|
|
80
|
+
});
|
|
81
|
+
if (attempt >= MAX_FOREIGN_ANSWERS) {
|
|
82
|
+
let err = new Error('Server kept answering with data of another request');
|
|
83
|
+
err.code = 'DownloadIncomplete';
|
|
84
|
+
err.cid = client.id;
|
|
85
|
+
throw err;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Apache James (and the servers built on it, Twake Mail among them) answers only the first
|
|
91
|
+
* section it is asked for each MIME part of one FETCH and returns the other one empty:
|
|
92
|
+
* BODY[2.MIME] with BODY[2] yields the headers and a zero-length body, the reverse order loses
|
|
93
|
+
* the headers (FetchGroup.addPartContent() keeps the first descriptor for a part path). Asks the
|
|
94
|
+
* sections that came back empty again, in a FETCH of their own, and merges the answer into
|
|
95
|
+
* `response`. Callers only list a section whose companion did arrive, so a compliant server
|
|
96
|
+
* pays the extra round trip only for a part that really is empty.
|
|
97
|
+
*/
|
|
98
|
+
async function refetchDroppedSections(client, response, range, options, sections) {
|
|
99
|
+
if (!sections.length) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
client.log.debug({
|
|
103
|
+
msg: 'Server answered a body section empty while its companion section was not, asking it again separately',
|
|
104
|
+
sections: sections.map(section => (typeof section === 'string' ? section : section.key)),
|
|
105
|
+
cid: client.id
|
|
106
|
+
});
|
|
107
|
+
// the UID pins the message even when the first command addressed it by sequence number
|
|
108
|
+
let uid = response.uid;
|
|
109
|
+
let retry = await fetchExpected(client, uid || range, { uid: true, bodyParts: sections }, uid ? { ...options, uid: true } : options, {
|
|
110
|
+
uid,
|
|
111
|
+
origins: partialStarts(sections)
|
|
112
|
+
});
|
|
113
|
+
if (!retry) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (retry.headers) {
|
|
117
|
+
response.headers = retry.headers;
|
|
118
|
+
}
|
|
119
|
+
for (let [key, value] of retry.bodyParts || []) {
|
|
120
|
+
(response.bodyParts ??= new Map()).set(key, value);
|
|
121
|
+
if (retry.binaryParts && retry.binaryParts.has(key)) {
|
|
122
|
+
(response.binaryParts ??= new Set()).add(key);
|
|
123
|
+
}
|
|
124
|
+
else if (response.binaryParts) {
|
|
125
|
+
response.binaryParts.delete(key);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
22
129
|
/**
|
|
23
130
|
* Implements ImapFlow.download(), see its documentation
|
|
24
131
|
*
|
|
@@ -66,6 +173,7 @@ async function downloadMessage(client, range, part, options) {
|
|
|
66
173
|
let getNextPart = async (query) => {
|
|
67
174
|
query = query || {};
|
|
68
175
|
let mimeKey;
|
|
176
|
+
let contentRequest;
|
|
69
177
|
if (!part) {
|
|
70
178
|
query.source = {
|
|
71
179
|
start: processed,
|
|
@@ -88,13 +196,18 @@ async function downloadMessage(client, range, part, options) {
|
|
|
88
196
|
query.bodyParts.push(mimeKey);
|
|
89
197
|
}
|
|
90
198
|
}
|
|
91
|
-
|
|
199
|
+
contentRequest = {
|
|
92
200
|
key: part,
|
|
93
201
|
start: processed,
|
|
94
202
|
maxLength: chunkSize
|
|
95
|
-
}
|
|
203
|
+
};
|
|
204
|
+
query.bodyParts.push(contentRequest);
|
|
96
205
|
}
|
|
97
|
-
let
|
|
206
|
+
let expected = {
|
|
207
|
+
uid: uid || requestedUid(range, downloadOptions),
|
|
208
|
+
origins: new Map([[part || '', processed]])
|
|
209
|
+
};
|
|
210
|
+
let response = await fetchExpected(client, range, query, downloadOptions, expected);
|
|
98
211
|
if (!response) {
|
|
99
212
|
return { response: false, chunk: false };
|
|
100
213
|
}
|
|
@@ -104,6 +217,12 @@ async function downloadMessage(client, range, part, options) {
|
|
|
104
217
|
range = uid;
|
|
105
218
|
downloadOptions.uid = true;
|
|
106
219
|
}
|
|
220
|
+
if (mimeKey && contentRequest) {
|
|
221
|
+
let dropped = droppedSection(mimeKey === 'header' ? response.headers : response.bodyParts?.get(mimeKey), response.bodyParts?.get(part), mimeKey, contentRequest);
|
|
222
|
+
if (dropped) {
|
|
223
|
+
await refetchDroppedSections(client, response, range, downloadOptions, [dropped]);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
107
226
|
let chunk = !part ? response.source : response.bodyParts && response.bodyParts.get(part);
|
|
108
227
|
if (!chunk) {
|
|
109
228
|
return {};
|
|
@@ -458,16 +577,31 @@ async function downloadMessageParts(client, range, parts, options) {
|
|
|
458
577
|
// again on the answer for servers that ignore the partial specifier
|
|
459
578
|
let maxBytes = (0, limited_passthrough_js_1.normalizeByteLimit)(downloadOptions.maxBytes);
|
|
460
579
|
let query = { bodyParts: [] };
|
|
580
|
+
let contentRequests = new Map();
|
|
461
581
|
for (let part of parts) {
|
|
462
582
|
query.bodyParts.push(part + '.mime');
|
|
463
583
|
// The partial specifier carries a 32-bit length (RFC 9051 "number"), so a cap beyond
|
|
464
584
|
// that is applied on the answer alone
|
|
465
|
-
|
|
585
|
+
let contentRequest = maxBytes > 0xffffffff ? part : { key: part, start: 0, maxLength: maxBytes };
|
|
586
|
+
contentRequests.set(part, contentRequest);
|
|
587
|
+
query.bodyParts.push(contentRequest);
|
|
466
588
|
}
|
|
467
|
-
let response = await client
|
|
589
|
+
let response = await fetchExpected(client, range, query, downloadOptions, {
|
|
590
|
+
uid: requestedUid(range, downloadOptions),
|
|
591
|
+
origins: partialStarts(query.bodyParts)
|
|
592
|
+
});
|
|
468
593
|
if (!response || !response.bodyParts) {
|
|
469
594
|
return {};
|
|
470
595
|
}
|
|
596
|
+
let dropped = [];
|
|
597
|
+
for (let [part, contentRequest] of contentRequests) {
|
|
598
|
+
let section = droppedSection(response.bodyParts.get(part + '.mime'), response.bodyParts.get(part), part + '.mime', contentRequest);
|
|
599
|
+
if (section) {
|
|
600
|
+
dropped.push(section);
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
// Sections of different parts do not collide, so every dropped one fits in one FETCH
|
|
604
|
+
await refetchDroppedSections(client, response, range, downloadOptions, dropped);
|
|
471
605
|
let data = {};
|
|
472
606
|
for (let [part, content] of response.bodyParts) {
|
|
473
607
|
let keyParts = part.split('.mime');
|
|
@@ -122,8 +122,8 @@ export declare class ImapFlow extends EventEmitter {
|
|
|
122
122
|
*/
|
|
123
123
|
usable: boolean;
|
|
124
124
|
/**
|
|
125
|
-
*
|
|
126
|
-
*
|
|
125
|
+
* `true` once the connection is authenticated (by LOGIN, AUTHENTICATE or a PREAUTH greeting),
|
|
126
|
+
* `false` before that. The user name is in `options.auth.user`
|
|
127
127
|
*/
|
|
128
128
|
authenticated: string | boolean;
|
|
129
129
|
/**
|
|
@@ -1500,9 +1500,8 @@ class ImapFlow extends node_events_1.EventEmitter {
|
|
|
1500
1500
|
// of the IP - accepting any "localhost" certificate for any IP-hosted
|
|
1501
1501
|
// server, and rejecting legitimate IP-SAN certificates.
|
|
1502
1502
|
host: this.host,
|
|
1503
|
-
servername: this.servername,
|
|
1504
1503
|
port: this.port
|
|
1505
|
-
}, this.options.tls || {});
|
|
1504
|
+
}, this.tlsServername(), this.options.tls || {});
|
|
1506
1505
|
this.clearSocketHandlers();
|
|
1507
1506
|
let settled = false;
|
|
1508
1507
|
// Single settlement path for the upgrade. Every terminal outcome - handshake
|
|
@@ -1513,6 +1512,13 @@ class ImapFlow extends node_events_1.EventEmitter {
|
|
|
1513
1512
|
// socket event cannot re-enter an already settled upgrade or leave state behind.
|
|
1514
1513
|
const settle = (err, result) => {
|
|
1515
1514
|
if (settled) {
|
|
1515
|
+
// A failed handshake can produce more than one error (Bun emits ECONNRESET on
|
|
1516
|
+
// the TLS socket after the one that settled the upgrade). settle() stays the
|
|
1517
|
+
// error listener of both sockets until they are torn down, so later errors
|
|
1518
|
+
// end up here instead of being thrown as unhandled 'error' events.
|
|
1519
|
+
if (err) {
|
|
1520
|
+
this.log.debug({ msg: 'Socket error after the TLS upgrade was settled', err, cid: this.id });
|
|
1521
|
+
}
|
|
1516
1522
|
return;
|
|
1517
1523
|
}
|
|
1518
1524
|
settled = true;
|
|
@@ -1520,9 +1526,12 @@ class ImapFlow extends node_events_1.EventEmitter {
|
|
|
1520
1526
|
this.upgradeTimeout = null;
|
|
1521
1527
|
this.upgrading = false;
|
|
1522
1528
|
this._upgradeReject = null;
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1529
|
+
if (!err) {
|
|
1530
|
+
// the generic socket handlers took over in the success callback
|
|
1531
|
+
socketPlain.removeListener('error', settle);
|
|
1532
|
+
if (this.socket && this.socket !== socketPlain) {
|
|
1533
|
+
this.socket.removeListener('error', settle);
|
|
1534
|
+
}
|
|
1526
1535
|
}
|
|
1527
1536
|
if (err) {
|
|
1528
1537
|
(0, tools_js_1.clearTimer)(this.connectTimeout);
|
|
@@ -1540,7 +1549,7 @@ class ImapFlow extends node_events_1.EventEmitter {
|
|
|
1540
1549
|
// one function, one settlement, and removeListener() in settle() needs no separate
|
|
1541
1550
|
// handler references. A TLS handshake failure (bad certificate, protocol mismatch)
|
|
1542
1551
|
// is emitted on the new TLS socket rather than on the plain one, so both are covered.
|
|
1543
|
-
socketPlain.
|
|
1552
|
+
socketPlain.on('error', settle);
|
|
1544
1553
|
/* c8 ignore start */ // UPGRADE_TIMEOUT is 10s; firing it deterministically would make the test suite hang
|
|
1545
1554
|
this.upgradeTimeout = setTimeout(() => {
|
|
1546
1555
|
let err = new Error('Failed to upgrade connection in required time');
|
|
@@ -1618,7 +1627,7 @@ class ImapFlow extends node_events_1.EventEmitter {
|
|
|
1618
1627
|
// error listener during the handshake window; the generic handlers are installed
|
|
1619
1628
|
// by setSocketHandlers() inside the success callback above, so a handshake error
|
|
1620
1629
|
// has a single error path.
|
|
1621
|
-
tlsSocket.
|
|
1630
|
+
tlsSocket.on('error', settle);
|
|
1622
1631
|
this.writeSocket = tlsSocket;
|
|
1623
1632
|
});
|
|
1624
1633
|
if (upgraded) {
|
|
@@ -1892,12 +1901,18 @@ class ImapFlow extends node_events_1.EventEmitter {
|
|
|
1892
1901
|
uids = untagged.attributes[0].value;
|
|
1893
1902
|
}
|
|
1894
1903
|
let uidList = (0, tools_js_1.expandRange)(uids);
|
|
1904
|
+
let earlier = tags.includes('EARLIER');
|
|
1905
|
+
// RFC 7162 section 3.2.10: unlike VANISHED (EARLIER), a plain VANISHED reports messages the
|
|
1906
|
+
// client knows about and decrements the message count like the same number of EXPUNGEs would
|
|
1907
|
+
if (!earlier) {
|
|
1908
|
+
mailbox.exists = Math.max(0, mailbox.exists - uidList.length);
|
|
1909
|
+
}
|
|
1895
1910
|
for (let uid of uidList) {
|
|
1896
1911
|
let payload = {
|
|
1897
1912
|
path: mailbox.path,
|
|
1898
1913
|
uid,
|
|
1899
1914
|
vanished: true,
|
|
1900
|
-
earlier
|
|
1915
|
+
earlier
|
|
1901
1916
|
};
|
|
1902
1917
|
await this.notifyExpunge(payload);
|
|
1903
1918
|
}
|
|
@@ -1909,7 +1924,7 @@ class ImapFlow extends node_events_1.EventEmitter {
|
|
|
1909
1924
|
// mailbox closed, ignore
|
|
1910
1925
|
return;
|
|
1911
1926
|
}
|
|
1912
|
-
let message = await (0, tools_js_1.formatMessageResponse)(untagged, mailbox, this.idHashAlgorithm);
|
|
1927
|
+
let message = await (0, tools_js_1.formatMessageResponse)(untagged, mailbox, this.idHashAlgorithm, this);
|
|
1913
1928
|
if (message.flags) {
|
|
1914
1929
|
let updateEvent = {
|
|
1915
1930
|
path: mailbox.path,
|
|
@@ -1938,6 +1953,12 @@ class ImapFlow extends node_events_1.EventEmitter {
|
|
|
1938
1953
|
}
|
|
1939
1954
|
return true;
|
|
1940
1955
|
}
|
|
1956
|
+
// servername for tls.connect(), left out for an IP literal host (this.servername is false then):
|
|
1957
|
+
// Node treats a false value like a missing one, but Bun throws a TypeError for it
|
|
1958
|
+
/** @internal */
|
|
1959
|
+
tlsServername() {
|
|
1960
|
+
return this.servername ? { servername: this.servername } : {};
|
|
1961
|
+
}
|
|
1941
1962
|
// Normalizes a message range from various input formats into an IMAP-compatible
|
|
1942
1963
|
// sequence string (e.g., "1:5,7,10:*"). Handles: numbers, "*", {all:true},
|
|
1943
1964
|
// {uid:value}, search query objects (resolved via SEARCH), and arrays of numbers.
|
|
@@ -1980,6 +2001,11 @@ class ImapFlow extends node_events_1.EventEmitter {
|
|
|
1980
2001
|
if (!value) {
|
|
1981
2002
|
return false;
|
|
1982
2003
|
}
|
|
2004
|
+
// An empty mailbox has no message numbers: every sequence set, "1:*" included, would get a
|
|
2005
|
+
// BAD (RFC 9051 section 9, seq-number). UID sets may point past the end, so they are sent.
|
|
2006
|
+
if (!options.uid && this.mailbox && !this.mailbox.exists) {
|
|
2007
|
+
return false;
|
|
2008
|
+
}
|
|
1983
2009
|
return value;
|
|
1984
2010
|
}
|
|
1985
2011
|
// The single definition of "the connection is not free". A held or queued mailbox lock, a
|
|
@@ -2049,9 +2075,8 @@ class ImapFlow extends node_events_1.EventEmitter {
|
|
|
2049
2075
|
let connector = this.secureConnection ? node_tls_1.default : node_net_1.default;
|
|
2050
2076
|
let opts = Object.assign({
|
|
2051
2077
|
host: this.host,
|
|
2052
|
-
servername: this.servername,
|
|
2053
2078
|
port: this.port
|
|
2054
|
-
}, this.options.tls || {});
|
|
2079
|
+
}, this.tlsServername(), this.options.tls || {});
|
|
2055
2080
|
this.untaggedHandlers.OK = (...args) => this.initialOK(...args);
|
|
2056
2081
|
this.untaggedHandlers.BYE = (...args) => this.serverBye(...args);
|
|
2057
2082
|
this.untaggedHandlers.PREAUTH = () => this.initialPREAUTH();
|
|
@@ -3137,7 +3162,21 @@ class ImapFlow extends node_events_1.EventEmitter {
|
|
|
3137
3162
|
if (!response || !response.list || !response.list.length) {
|
|
3138
3163
|
return false;
|
|
3139
3164
|
}
|
|
3140
|
-
|
|
3165
|
+
// Every FETCH row that arrived during the command is in the list, also unsolicited ones
|
|
3166
|
+
// for other messages or with only a flag change, and a server may split the answer for
|
|
3167
|
+
// one message over several rows. Taking the first row returned a flag update instead
|
|
3168
|
+
// of the requested data, which ended a download after its first chunk (issue #426).
|
|
3169
|
+
let rows = response.list;
|
|
3170
|
+
let requested = (0, tools_js_1.parseUintValue)(String(seq), tools_js_1.MAX_UINT32_DIGITS);
|
|
3171
|
+
// a range: the first message of the answer, as before
|
|
3172
|
+
let target = requested === false ? rows[0] : rows.find(row => (options && options.uid ? row.uid : row.seq) === requested);
|
|
3173
|
+
if (!target) {
|
|
3174
|
+
return false;
|
|
3175
|
+
}
|
|
3176
|
+
// rows of the same message, without the ones a malformed answer gives no usable
|
|
3177
|
+
// sequence number or another UID
|
|
3178
|
+
let { seq: targetSeq, uid: targetUid } = target;
|
|
3179
|
+
return targetSeq ? (0, tools_js_1.mergeFetchRows)(rows.filter(row => row.seq === targetSeq && (!row.uid || !targetUid || row.uid === targetUid))) : target;
|
|
3141
3180
|
}
|
|
3142
3181
|
/**
|
|
3143
3182
|
* Download either full rfc822 formatted message or a specific bodystructure part as a Stream.
|
|
@@ -371,10 +371,13 @@ const searchCompiler = (connection, query) => {
|
|
|
371
371
|
fail('InvalidSearchQuery', `Search value for ${term.toLowerCase()} must be a string`);
|
|
372
372
|
}
|
|
373
373
|
let flag = (0, tools_js_1.formatFlag)(params[term]);
|
|
374
|
-
// formatFlag() refuses \Recent, which is not a keyword
|
|
375
|
-
// criterion would widen the search, so the query is
|
|
374
|
+
// formatFlag() refuses \Recent, which is not a keyword, and values that are
|
|
375
|
+
// not atoms. Dropping the criterion would widen the search, so the query is
|
|
376
|
+
// refused instead
|
|
376
377
|
if (flag === false) {
|
|
377
|
-
fail('InvalidSearchQuery',
|
|
378
|
+
fail('InvalidSearchQuery', /^\\recent$/i.test(params[term])
|
|
379
|
+
? `${params[term]} can not be searched as a keyword, use the "recent" search key instead`
|
|
380
|
+
: `${params[term]} is not a valid keyword`);
|
|
378
381
|
}
|
|
379
382
|
// Compiled even when the mailbox does not allow the keyword: the
|
|
380
383
|
// correct answer is then the empty set, which dropping the
|
|
@@ -287,15 +287,26 @@ export declare function getColorFlags(color: string | null | undefined): {
|
|
|
287
287
|
add: string[];
|
|
288
288
|
remove: string[];
|
|
289
289
|
} | null;
|
|
290
|
+
/**
|
|
291
|
+
* Merges the FETCH rows a server sent for one message into one message object. A server may
|
|
292
|
+
* split the data items of a message over several FETCH responses, and may put an unsolicited
|
|
293
|
+
* one (a flag change made by another session) in between (RFC 9051 sections 7.5.2 and 5.2).
|
|
294
|
+
* Later rows win for single values, bodyParts, binaryParts and partialOrigins are combined.
|
|
295
|
+
*
|
|
296
|
+
* @param rows - Formatted rows of the same message, in the order they arrived
|
|
297
|
+
* @returns One message object holding the data of every row
|
|
298
|
+
*/
|
|
299
|
+
export declare function mergeFetchRows(rows: FetchMessageObject[]): FetchMessageObject;
|
|
290
300
|
/**
|
|
291
301
|
* Formats a raw untagged FETCH response into a structured message object.
|
|
292
302
|
*
|
|
293
303
|
* @param untagged - Parsed untagged IMAP response
|
|
294
304
|
* @param mailbox - Current mailbox state object
|
|
295
305
|
* @param idHashAlgorithm - Hash for the fallback message id, `md5` unless the client was told otherwise
|
|
306
|
+
* @param connection - Connection the response arrived on, decodes Gmail labels like mailbox names
|
|
296
307
|
* @returns Formatted message object with properties like seq, uid, flags, envelope, etc.
|
|
297
308
|
*/
|
|
298
|
-
export declare function formatMessageResponse(untagged: ImapResponse, mailbox: MailboxObject, idHashAlgorithm?: string): Promise<FetchMessageObject>;
|
|
309
|
+
export declare function formatMessageResponse(untagged: ImapResponse, mailbox: MailboxObject, idHashAlgorithm?: string, connection?: ImapFlow): Promise<FetchMessageObject>;
|
|
299
310
|
/**
|
|
300
311
|
* Strips surrounding double quotes from a name string.
|
|
301
312
|
*
|
|
@@ -364,8 +375,8 @@ export declare function formatDate(value: unknown): string | undefined;
|
|
|
364
375
|
*/
|
|
365
376
|
export declare function formatDateTime(value: unknown): string | undefined;
|
|
366
377
|
/**
|
|
367
|
-
* Normalizes a flag string. Returns false for non-settable flags (e.g. \Recent)
|
|
368
|
-
* and capitalizes system flags properly.
|
|
378
|
+
* Normalizes a flag string. Returns false for non-settable flags (e.g. \Recent) and for
|
|
379
|
+
* values that are not valid flags (keywords must be atoms), and capitalizes system flags properly.
|
|
369
380
|
*
|
|
370
381
|
* @param flag - Flag string to normalize
|
|
371
382
|
* @returns Normalized flag string, or false if the flag cannot be set
|
|
@@ -32,6 +32,7 @@ exports.getSelectedMailbox = getSelectedMailbox;
|
|
|
32
32
|
exports.getFolderTree = getFolderTree;
|
|
33
33
|
exports.getFlagColor = getFlagColor;
|
|
34
34
|
exports.getColorFlags = getColorFlags;
|
|
35
|
+
exports.mergeFetchRows = mergeFetchRows;
|
|
35
36
|
exports.formatMessageResponse = formatMessageResponse;
|
|
36
37
|
exports.processName = processName;
|
|
37
38
|
exports.decodeText = decodeText;
|
|
@@ -56,6 +57,7 @@ exports.packMessageRange = packMessageRange;
|
|
|
56
57
|
const libmime_1 = __importDefault(require("libmime"));
|
|
57
58
|
const charsets_js_1 = require("./charsets.js");
|
|
58
59
|
const imap_handler_js_1 = require("./handler/imap-handler.js");
|
|
60
|
+
const imap_formal_syntax_js_1 = __importDefault(require("./handler/imap-formal-syntax.js"));
|
|
59
61
|
const node_crypto_1 = require("node:crypto");
|
|
60
62
|
const jp_decoder_js_1 = require("./jp-decoder.js");
|
|
61
63
|
const iconv_lite_1 = __importDefault(require("iconv-lite"));
|
|
@@ -336,7 +338,8 @@ function buildStatusQueryAttributes(connection, statusQuery) {
|
|
|
336
338
|
}
|
|
337
339
|
break;
|
|
338
340
|
case 'HIGHESTMODSEQ':
|
|
339
|
-
|
|
341
|
+
// QRESYNC implies CONDSTORE (RFC 7162 3.2.3)
|
|
342
|
+
if (connection.capabilities.has('CONDSTORE') || connection.capabilities.has('QRESYNC')) {
|
|
340
343
|
attributes.push({ type: 'ATOM', value: key.toUpperCase() });
|
|
341
344
|
}
|
|
342
345
|
break;
|
|
@@ -711,30 +714,74 @@ function getColorFlags(color) {
|
|
|
711
714
|
}
|
|
712
715
|
return result;
|
|
713
716
|
}
|
|
717
|
+
/**
|
|
718
|
+
* Merges the FETCH rows a server sent for one message into one message object. A server may
|
|
719
|
+
* split the data items of a message over several FETCH responses, and may put an unsolicited
|
|
720
|
+
* one (a flag change made by another session) in between (RFC 9051 sections 7.5.2 and 5.2).
|
|
721
|
+
* Later rows win for single values, bodyParts, binaryParts and partialOrigins are combined.
|
|
722
|
+
*
|
|
723
|
+
* @param rows - Formatted rows of the same message, in the order they arrived
|
|
724
|
+
* @returns One message object holding the data of every row
|
|
725
|
+
*/
|
|
726
|
+
function mergeFetchRows(rows) {
|
|
727
|
+
if (rows.length === 1) {
|
|
728
|
+
return rows[0];
|
|
729
|
+
}
|
|
730
|
+
let merged = {};
|
|
731
|
+
let partialOrigins;
|
|
732
|
+
for (let row of rows) {
|
|
733
|
+
let { bodyParts, binaryParts, ...rest } = row;
|
|
734
|
+
Object.assign(merged, rest);
|
|
735
|
+
// combined into collections of their own, so the rows stay untouched
|
|
736
|
+
bodyParts?.forEach((value, key) => (merged.bodyParts ??= new Map()).set(key, value));
|
|
737
|
+
binaryParts?.forEach(key => (merged.binaryParts ??= new Set()).add(key));
|
|
738
|
+
row.partialOrigins?.forEach((value, key) => (partialOrigins ??= new Map()).set(key, value));
|
|
739
|
+
}
|
|
740
|
+
if (partialOrigins) {
|
|
741
|
+
Object.defineProperty(merged, 'partialOrigins', { value: partialOrigins, writable: true, configurable: true });
|
|
742
|
+
}
|
|
743
|
+
return merged;
|
|
744
|
+
}
|
|
714
745
|
/**
|
|
715
746
|
* Formats a raw untagged FETCH response into a structured message object.
|
|
716
747
|
*
|
|
717
748
|
* @param untagged - Parsed untagged IMAP response
|
|
718
749
|
* @param mailbox - Current mailbox state object
|
|
719
750
|
* @param idHashAlgorithm - Hash for the fallback message id, `md5` unless the client was told otherwise
|
|
751
|
+
* @param connection - Connection the response arrived on, decodes Gmail labels like mailbox names
|
|
720
752
|
* @returns Formatted message object with properties like seq, uid, flags, envelope, etc.
|
|
721
753
|
*/
|
|
722
|
-
async function formatMessageResponse(untagged, mailbox, idHashAlgorithm) {
|
|
754
|
+
async function formatMessageResponse(untagged, mailbox, idHashAlgorithm, connection) {
|
|
723
755
|
let map = {};
|
|
724
756
|
// The sequence number indexes into mailbox state, so an unusable one is dropped rather
|
|
725
757
|
// than coerced to NaN or Infinity
|
|
726
758
|
map.seq = parseUintValue(untagged.command, exports.MAX_UINT32_DIGITS) || undefined;
|
|
727
759
|
let key;
|
|
760
|
+
// the <origin> of a partial section ("BODY[2]<1024>"), kept for the value that follows
|
|
761
|
+
let origin = false;
|
|
762
|
+
let partialOrigins;
|
|
763
|
+
let recordOrigin = (sectionKey) => {
|
|
764
|
+
if (origin !== false) {
|
|
765
|
+
if (!partialOrigins) {
|
|
766
|
+
partialOrigins = new Map();
|
|
767
|
+
}
|
|
768
|
+
partialOrigins.set(sectionKey, origin);
|
|
769
|
+
}
|
|
770
|
+
};
|
|
728
771
|
let attributes = ((untagged.attributes && untagged.attributes[1]) || []);
|
|
729
772
|
for (let i = 0, len = attributes.length; i < len; i++) {
|
|
730
773
|
let attribute = attributes[i];
|
|
731
774
|
if (i % 2 === 0) {
|
|
775
|
+
origin = false;
|
|
732
776
|
key = (await (0, imap_handler_js_1.compiler)({
|
|
733
777
|
attributes: [attribute]
|
|
734
778
|
}))
|
|
735
779
|
.toString()
|
|
736
780
|
.toLowerCase()
|
|
737
|
-
.replace(
|
|
781
|
+
.replace(/<(\d+)(\.\d+)?>$/, (match, start) => {
|
|
782
|
+
origin = parseUintValue(start, exports.MAX_UINT32_DIGITS);
|
|
783
|
+
return '';
|
|
784
|
+
});
|
|
738
785
|
continue;
|
|
739
786
|
}
|
|
740
787
|
/* c8 ignore start */ // defensive: key is always a string produced by the compiler above
|
|
@@ -779,6 +826,7 @@ async function formatMessageResponse(untagged, mailbox, idHashAlgorithm) {
|
|
|
779
826
|
case 'body[]':
|
|
780
827
|
case 'binary[]':
|
|
781
828
|
map.source = getBuffer(attribute);
|
|
829
|
+
recordOrigin('');
|
|
782
830
|
break;
|
|
783
831
|
case 'uid':
|
|
784
832
|
// A UID feeds mailbox.uidNext one line below, and from there every range
|
|
@@ -825,7 +873,8 @@ async function formatMessageResponse(untagged, mailbox, idHashAlgorithm) {
|
|
|
825
873
|
map.threadId = getString(attribute);
|
|
826
874
|
break;
|
|
827
875
|
case 'x-gm-labels':
|
|
828
|
-
|
|
876
|
+
// labels are mailbox names, modified UTF-7 unless UTF-8 is enabled
|
|
877
|
+
map.labels = new Set(getArray(attribute).map(label => (connection ? decodePath(connection, label) : label)));
|
|
829
878
|
break;
|
|
830
879
|
case 'rfc822.size':
|
|
831
880
|
map.size = getUint(attribute) || 0;
|
|
@@ -871,6 +920,7 @@ async function formatMessageResponse(untagged, mailbox, idHashAlgorithm) {
|
|
|
871
920
|
map.bodyParts = new Map();
|
|
872
921
|
}
|
|
873
922
|
map.bodyParts.set(partKey, value);
|
|
923
|
+
recordOrigin(partKey);
|
|
874
924
|
if (match[1].toLowerCase() === 'binary') {
|
|
875
925
|
// The part arrived via FETCH BINARY (RFC 3516, FETCH side folded
|
|
876
926
|
// into IMAP4rev2), so the server has already removed the
|
|
@@ -912,6 +962,10 @@ async function formatMessageResponse(untagged, mailbox, idHashAlgorithm) {
|
|
|
912
962
|
.update([path, mailbox.uidValidity?.toString() || '', map.uid.toString()].join(':'))
|
|
913
963
|
.digest('hex');
|
|
914
964
|
}
|
|
965
|
+
if (partialOrigins) {
|
|
966
|
+
// non-enumerable, so it stays out of logged and serialized fetch results
|
|
967
|
+
Object.defineProperty(map, 'partialOrigins', { value: partialOrigins, writable: true, configurable: true });
|
|
968
|
+
}
|
|
915
969
|
if (map.flags) {
|
|
916
970
|
let flagColor = getFlagColor(map.flags);
|
|
917
971
|
if (flagColor) {
|
|
@@ -1354,14 +1408,22 @@ function formatDateTime(value) {
|
|
|
1354
1408
|
let timeStr = date.toISOString().substring(11, 19);
|
|
1355
1409
|
return `${dateStr} ${timeStr} +0000`;
|
|
1356
1410
|
}
|
|
1411
|
+
// the memoized ATOM-CHAR set of RFC 9051 section 9
|
|
1412
|
+
const atomChars = imap_formal_syntax_js_1.default['ATOM-CHAR'];
|
|
1357
1413
|
/**
|
|
1358
|
-
* Normalizes a flag string. Returns false for non-settable flags (e.g. \Recent)
|
|
1359
|
-
* and capitalizes system flags properly.
|
|
1414
|
+
* Normalizes a flag string. Returns false for non-settable flags (e.g. \Recent) and for
|
|
1415
|
+
* values that are not valid flags (keywords must be atoms), and capitalizes system flags properly.
|
|
1360
1416
|
*
|
|
1361
1417
|
* @param flag - Flag string to normalize
|
|
1362
1418
|
* @returns Normalized flag string, or false if the flag cannot be set
|
|
1363
1419
|
*/
|
|
1364
1420
|
function formatFlag(flag) {
|
|
1421
|
+
// RFC 9051 section 9: flag-keyword is an atom and flag-extension is "\\" atom, the same check
|
|
1422
|
+
// the compiler uses to decide what it can send unquoted
|
|
1423
|
+
let atom = flag.charAt(0) === '\\' ? flag.slice(1) : flag;
|
|
1424
|
+
if (!atom || imap_formal_syntax_js_1.default.verify(atom, atomChars()) >= 0) {
|
|
1425
|
+
return false;
|
|
1426
|
+
}
|
|
1365
1427
|
switch (flag.toLowerCase()) {
|
|
1366
1428
|
case '\\recent':
|
|
1367
1429
|
// can not set or remove
|
|
@@ -499,6 +499,8 @@ export interface FetchQueryObject {
|
|
|
499
499
|
/** Include full message in the response, up to maxLength bytes */
|
|
500
500
|
maxLength?: number | undefined;
|
|
501
501
|
} | undefined;
|
|
502
|
+
/** Email ID (OBJECTID EMAILID or Gmail X-GM-MSGID) is always requested when the server supports either extension, so this is accepted but changes nothing */
|
|
503
|
+
emailId?: boolean | undefined;
|
|
502
504
|
/** If true then include thread ID in the response (only if server supports either OBJECTID or X-GM-EXT-1 extensions) */
|
|
503
505
|
threadId?: boolean | undefined;
|
|
504
506
|
/** If true then include GMail labels in the response (only if server supports X-GM-EXT-1 extension) */
|
|
@@ -653,9 +655,11 @@ export interface DownloadOptions {
|
|
|
653
655
|
maxBytes?: number | undefined;
|
|
654
656
|
/** How large content parts to ask from the server. Defaults to 65536 */
|
|
655
657
|
chunkSize?: number | undefined;
|
|
658
|
+
/** If true then requests the content with FETCH BINARY when the server supports it (BINARY or IMAP4rev2), so the server removes the transfer encoding */
|
|
659
|
+
binary?: boolean | undefined;
|
|
656
660
|
}
|
|
657
661
|
/** Options for downloadMany(): the download() options without `chunkSize`, as the parts come in one FETCH */
|
|
658
|
-
export type DownloadManyOptions = Pick<DownloadOptions, 'uid' | 'maxBytes'>;
|
|
662
|
+
export type DownloadManyOptions = Pick<DownloadOptions, 'uid' | 'maxBytes' | 'binary'>;
|
|
659
663
|
export interface DownloadManyPart {
|
|
660
664
|
meta: DownloadMeta;
|
|
661
665
|
content?: Buffer | null | undefined;
|
|
@@ -706,6 +710,10 @@ export interface MailboxOpenOptions {
|
|
|
706
710
|
readOnly?: boolean | undefined;
|
|
707
711
|
/** Optional description for mailbox lock tracking */
|
|
708
712
|
description?: string | undefined;
|
|
713
|
+
/** QRESYNC (RFC 7162): HIGHESTMODSEQ from an earlier session. With `uidValidity` and QRESYNC enabled, changes since then are reported as `flags` and `expunge` events. getMailboxLock() only applies it when it selects the mailbox, not when the mailbox is already open */
|
|
714
|
+
changedSince?: bigint | number | string | undefined;
|
|
715
|
+
/** QRESYNC (RFC 7162): the UIDVALIDITY known from the previous session, required with `changedSince` */
|
|
716
|
+
uidValidity?: bigint | number | string | undefined;
|
|
709
717
|
}
|
|
710
718
|
export interface MailboxLockOptions extends MailboxOpenOptions {
|
|
711
719
|
/**
|
|
@@ -63,15 +63,26 @@ async function authOauth(connection, username, accessToken) {
|
|
|
63
63
|
// Empty breaker: XOAUTH2 expects an empty response to abort the SASL exchange
|
|
64
64
|
breaker = '';
|
|
65
65
|
}
|
|
66
|
+
let encoded = Buffer.from(oauthbearer).toString('base64');
|
|
67
|
+
// Without SASL-IR the payload may not ride on the command line (RFC 4959 section 3): it is
|
|
68
|
+
// sent as the answer to the first, empty continuation request instead
|
|
69
|
+
let payloadPending = !connection.capabilities.has('SASL-IR');
|
|
66
70
|
let errorResponse = false;
|
|
67
71
|
try {
|
|
68
|
-
let
|
|
69
|
-
|
|
70
|
-
{ type: 'ATOM', value:
|
|
71
|
-
|
|
72
|
+
let attributes = [{ type: 'ATOM', value: command }];
|
|
73
|
+
if (!payloadPending) {
|
|
74
|
+
attributes.push({ type: 'ATOM', value: encoded, sensitive: true });
|
|
75
|
+
}
|
|
76
|
+
let response = await connection.exec('AUTHENTICATE', attributes, {
|
|
72
77
|
// Server sends a "+" continuation if auth fails, with a base64 JSON error payload.
|
|
73
78
|
// We decode it for diagnostics, then send the breaker to terminate the exchange.
|
|
74
79
|
onPlusTag: async (resp) => {
|
|
80
|
+
if (payloadPending) {
|
|
81
|
+
payloadPending = false;
|
|
82
|
+
connection.log.debug({ src: 'c', msg: '(* value hidden *)', comment: `Encoded response for AUTH=${command}`, cid: connection.id });
|
|
83
|
+
connection.write(encoded);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
75
86
|
if (resp.attributes && resp.attributes[0] && resp.attributes[0].type === 'TEXT') {
|
|
76
87
|
try {
|
|
77
88
|
errorResponse = JSON.parse(Buffer.from(resp.attributes[0].value, 'base64').toString());
|