@rubytech/create-sitedesk-code 0.1.521 → 0.1.522
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/dist/index.js +17 -3
- package/package.json +1 -1
- package/payload/platform/lib/account-schema-regions/package-lock.json +12 -0
- package/payload/platform/lib/active-rules/package-lock.json +12 -0
- package/payload/platform/lib/mcp-lifeline/package-lock.json +12 -0
- package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +43 -6
- package/payload/platform/plugins/admin/skills/whats-new/SKILL.md +6 -0
- package/payload/platform/plugins/docs/references/admin-ui.md +10 -0
- package/payload/platform/plugins/docs/references/internals.md +4 -0
- package/payload/platform/plugins/docs/references/outlook-guide.md +27 -4
- package/payload/platform/plugins/outlook/.claude-plugin/plugin.json +1 -1
- package/payload/platform/plugins/outlook/PLUGIN.md +9 -1
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/delegated-resolve.test.d.ts +2 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/delegated-resolve.test.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/delegated-resolve.test.js +151 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/delegated-resolve.test.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/delegated-store.test.d.ts +2 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/delegated-store.test.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/delegated-store.test.js +151 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/delegated-store.test.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/device-flow.test.js +38 -4
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/device-flow.test.js.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/graph-client-prefix-wiring.test.d.ts +2 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/graph-client-prefix-wiring.test.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/graph-client-prefix-wiring.test.js +146 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/graph-client-prefix-wiring.test.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/mailbox-list-delegated.test.d.ts +2 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/mailbox-list-delegated.test.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/mailbox-list-delegated.test.js +120 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/mailbox-list-delegated.test.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/mailbox-list.test.js +8 -8
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/mailbox-list.test.js.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/mailbox-path-prefix.test.d.ts +2 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/mailbox-path-prefix.test.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/mailbox-path-prefix.test.js +27 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/mailbox-path-prefix.test.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/shared-mail-only-guard.test.d.ts +2 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/shared-mail-only-guard.test.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/shared-mail-only-guard.test.js +70 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/shared-mail-only-guard.test.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/shared-mailbox-add.test.d.ts +2 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/shared-mailbox-add.test.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/shared-mailbox-add.test.js +152 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/shared-mailbox-add.test.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/auth/delegated-store.d.ts +57 -0
- package/payload/platform/plugins/outlook/mcp/dist/auth/delegated-store.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/auth/delegated-store.js +163 -0
- package/payload/platform/plugins/outlook/mcp/dist/auth/delegated-store.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/auth/device-flow.d.ts +12 -0
- package/payload/platform/plugins/outlook/mcp/dist/auth/device-flow.d.ts.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/auth/device-flow.js +21 -1
- package/payload/platform/plugins/outlook/mcp/dist/auth/device-flow.js.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/auth/mailbox-registry.d.ts +35 -4
- package/payload/platform/plugins/outlook/mcp/dist/auth/mailbox-registry.d.ts.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/auth/mailbox-registry.js +92 -10
- package/payload/platform/plugins/outlook/mcp/dist/auth/mailbox-registry.js.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/index.js +106 -3
- package/payload/platform/plugins/outlook/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/lib/graph-client.d.ts +49 -0
- package/payload/platform/plugins/outlook/mcp/dist/lib/graph-client.d.ts.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/lib/graph-client.js +126 -8
- package/payload/platform/plugins/outlook/mcp/dist/lib/graph-client.js.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/tools/mailbox-info.d.ts +13 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/mailbox-info.d.ts.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/tools/mailbox-info.js +9 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/mailbox-info.js.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/tools/mailbox-list.d.ts +42 -8
- package/payload/platform/plugins/outlook/mcp/dist/tools/mailbox-list.d.ts.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/tools/mailbox-list.js +59 -19
- package/payload/platform/plugins/outlook/mcp/dist/tools/mailbox-list.js.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/tools/shared-mailbox-add.d.ts +47 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/shared-mailbox-add.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/shared-mailbox-add.js +67 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/shared-mailbox-add.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/shared-mailbox-remove.d.ts +12 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/shared-mailbox-remove.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/shared-mailbox-remove.js +18 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/shared-mailbox-remove.js.map +1 -0
- package/payload/platform/plugins/outlook/references/auth.md +15 -2
- package/payload/platform/plugins/outlook/references/graph-surfaces.md +8 -0
- package/payload/platform/plugins/outlook/skills/outlook/SKILL.md +21 -1
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +2 -0
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
- package/payload/platform/templates/specialists/agents/personal-assistant.md +1 -1
- package/payload/server/{chunk-AZLT4LVO.js → chunk-K7CJGZPU.js} +419 -189
- package/payload/server/{manager-CQBSUJXR.js → manager-RKL7JZ4Y.js} +3 -1
- package/payload/server/public/activity.html +5 -5
- package/payload/server/public/agents.html +4 -4
- package/payload/server/public/assets/{AdminLoginScreens-Dar_MMJm.js → AdminLoginScreens-zc2_qqh-.js} +1 -1
- package/payload/server/public/assets/AdminLoginScreens-zc2_qqh-.js.br +0 -0
- package/payload/server/public/assets/AdminLoginScreens-zc2_qqh-.js.gz +0 -0
- package/payload/server/public/assets/{AdminShell-CpaI2F_p.js → AdminShell-IGUdTx5q.js} +1 -1
- package/payload/server/public/assets/AdminShell-IGUdTx5q.js.br +0 -0
- package/payload/server/public/assets/{AdminShell-CpaI2F_p.js.gz → AdminShell-IGUdTx5q.js.gz} +0 -0
- package/payload/server/public/assets/{activity-B1rt4GIy.js → activity-DVgO8YuM.js} +1 -1
- package/payload/server/public/assets/activity-DVgO8YuM.js.br +0 -0
- package/payload/server/public/assets/activity-DVgO8YuM.js.gz +0 -0
- package/payload/server/public/assets/admin-xtpM7fgl.js +1 -0
- package/payload/server/public/assets/admin-xtpM7fgl.js.br +0 -0
- package/payload/server/public/assets/admin-xtpM7fgl.js.gz +0 -0
- package/payload/server/public/assets/{agents-BXq8woVf.js → agents-P0nTIxo-.js} +1 -1
- package/payload/server/public/assets/agents-P0nTIxo-.js.br +0 -0
- package/payload/server/public/assets/agents-P0nTIxo-.js.gz +0 -0
- package/payload/server/public/assets/{browser-1QSCPl3X.js → browser-Mw7DY3ft.js} +1 -1
- package/payload/server/public/assets/browser-Mw7DY3ft.js.br +0 -0
- package/payload/server/public/assets/browser-Mw7DY3ft.js.gz +0 -0
- package/payload/server/public/assets/{calendar-D009qWVV.js → calendar-B9gvL_1_.js} +1 -1
- package/payload/server/public/assets/calendar-B9gvL_1_.js.br +0 -0
- package/payload/server/public/assets/calendar-B9gvL_1_.js.gz +0 -0
- package/payload/server/public/assets/chat-DBGqh4wg.js +1 -0
- package/payload/server/public/assets/chat-DBGqh4wg.js.br +2 -0
- package/payload/server/public/assets/chat-DBGqh4wg.js.gz +0 -0
- package/payload/server/public/assets/chevron-left-Bl4vpOM0.js +1 -0
- package/payload/server/public/assets/chevron-left-Bl4vpOM0.js.br +0 -0
- package/payload/server/public/assets/chevron-right-BExigCnp.js +1 -0
- package/payload/server/public/assets/chevron-right-BExigCnp.js.br +0 -0
- package/payload/server/public/assets/clock-D8TJvgJC.js +1 -0
- package/payload/server/public/assets/clock-D8TJvgJC.js.br +0 -0
- package/payload/server/public/assets/data-HfFSxaC2.js +1 -0
- package/payload/server/public/assets/data-HfFSxaC2.js.br +0 -0
- package/payload/server/public/assets/data-HfFSxaC2.js.gz +0 -0
- package/payload/server/public/assets/{file-text-DwGAfCsd.js → file-text-dYBnXNEX.js} +1 -1
- package/payload/server/public/assets/file-text-dYBnXNEX.js.br +0 -0
- package/payload/server/public/assets/file-text-dYBnXNEX.js.gz +0 -0
- package/payload/server/public/assets/{graph-D-DGlfhW.js → graph-CDyzd1Et.js} +1 -1
- package/payload/server/public/assets/graph-CDyzd1Et.js.br +0 -0
- package/payload/server/public/assets/graph-CDyzd1Et.js.gz +0 -0
- package/payload/server/public/assets/{graph-labels-BbX3fXzl.js → graph-labels-D1LkKiJr.js} +1 -1
- package/payload/server/public/assets/graph-labels-D1LkKiJr.js.br +0 -0
- package/payload/server/public/assets/graph-labels-D1LkKiJr.js.gz +0 -0
- package/payload/server/public/assets/{maximize-2-C_-KapxH.js → maximize-2-M-iSaznd.js} +1 -1
- package/payload/server/public/assets/maximize-2-M-iSaznd.js.br +0 -0
- package/payload/server/public/assets/maximize-2-M-iSaznd.js.gz +0 -0
- package/payload/server/public/assets/{operator-CFrZVcv6.js → operator-9jfCv1Fg.js} +1 -1
- package/payload/server/public/assets/operator-9jfCv1Fg.js.br +0 -0
- package/payload/server/public/assets/operator-9jfCv1Fg.js.gz +0 -0
- package/payload/server/public/assets/{page-E74MYB18.js → page-CZ-73FAk.js} +1 -1
- package/payload/server/public/assets/page-CZ-73FAk.js.br +0 -0
- package/payload/server/public/assets/page-CZ-73FAk.js.gz +0 -0
- package/payload/server/public/assets/{page-CHt62f1_.js → page-CjwSt7kx.js} +1 -1
- package/payload/server/public/assets/page-CjwSt7kx.js.br +0 -0
- package/payload/server/public/assets/page-CjwSt7kx.js.gz +0 -0
- package/payload/server/public/assets/{public-CI6K1sNW.js → public-CN-ltC8x.js} +1 -1
- package/payload/server/public/assets/public-CN-ltC8x.js.br +0 -0
- package/payload/server/public/assets/public-CN-ltC8x.js.gz +0 -0
- package/payload/server/public/assets/{rotate-ccw-PWu_QGrD.js → rotate-ccw-Buopsc22.js} +1 -1
- package/payload/server/public/assets/rotate-ccw-Buopsc22.js.br +0 -0
- package/payload/server/public/assets/rotate-ccw-Buopsc22.js.gz +0 -0
- package/payload/server/public/assets/{routines-Cp3_XS7S.js → routines-C-yr8ddT.js} +1 -1
- package/payload/server/public/assets/routines-C-yr8ddT.js.br +0 -0
- package/payload/server/public/assets/routines-C-yr8ddT.js.gz +0 -0
- package/payload/server/public/assets/{skills-g8HvunPA.js → skills-DiiuVzDK.js} +1 -1
- package/payload/server/public/assets/skills-DiiuVzDK.js.br +0 -0
- package/payload/server/public/assets/skills-DiiuVzDK.js.gz +0 -0
- package/payload/server/public/assets/tasks-CnHIfn2_.js +1 -0
- package/payload/server/public/assets/tasks-CnHIfn2_.js.br +0 -0
- package/payload/server/public/assets/tasks-CnHIfn2_.js.gz +0 -0
- package/payload/server/public/assets/{time-entry-format-BXWuQ6Sw.js → time-entry-format-BBokCF-D.js} +1 -1
- package/payload/server/public/assets/time-entry-format-BBokCF-D.js.br +0 -0
- package/payload/server/public/assets/time-entry-format-BBokCF-D.js.gz +0 -0
- package/payload/server/public/assets/{triangle-alert-BNshRC13.js → triangle-alert-C_AcpTW5.js} +1 -1
- package/payload/server/public/assets/triangle-alert-C_AcpTW5.js.br +0 -0
- package/payload/server/public/assets/triangle-alert-C_AcpTW5.js.gz +0 -0
- package/payload/server/public/assets/{useCopyFeedback-CwTZ9DqH.js → useCopyFeedback-TdimmPVR.js} +1 -1
- package/payload/server/public/assets/useCopyFeedback-TdimmPVR.js.br +0 -0
- package/payload/server/public/assets/useCopyFeedback-TdimmPVR.js.gz +0 -0
- package/payload/server/public/assets/{useSubAccountSwitcher-BuUYMDWl.js → useSubAccountSwitcher-BwHqV55p.js} +1 -1
- package/payload/server/public/assets/useSubAccountSwitcher-BwHqV55p.js.br +0 -0
- package/payload/server/public/assets/{useSubAccountSwitcher-BuUYMDWl.js.gz → useSubAccountSwitcher-BwHqV55p.js.gz} +0 -0
- package/payload/server/public/assets/{useSubAccountSwitcher-dzDnmWq9.css → useSubAccountSwitcher-CsrPYqtm.css} +1 -1
- package/payload/server/public/assets/useSubAccountSwitcher-CsrPYqtm.css.br +0 -0
- package/payload/server/public/assets/{useSubAccountSwitcher-dzDnmWq9.css.gz → useSubAccountSwitcher-CsrPYqtm.css.gz} +0 -0
- package/payload/server/public/assets/{useVoiceRecorder-BGqV5R6u.js → useVoiceRecorder-BT2738ZS.js} +1 -1
- package/payload/server/public/assets/useVoiceRecorder-BT2738ZS.js.br +0 -0
- package/payload/server/public/assets/useVoiceRecorder-BT2738ZS.js.gz +0 -0
- package/payload/server/public/assets/{wrench-DQ045Pyk.js → wrench-B51s5kGA.js} +1 -1
- package/payload/server/public/assets/wrench-B51s5kGA.js.br +0 -0
- package/payload/server/public/assets/wrench-B51s5kGA.js.gz +0 -0
- package/payload/server/public/browser.html +4 -4
- package/payload/server/public/calendar.html +7 -7
- package/payload/server/public/chat.html +13 -13
- package/payload/server/public/data.html +11 -11
- package/payload/server/public/graph.html +9 -9
- package/payload/server/public/index.html +14 -14
- package/payload/server/public/operator.html +14 -14
- package/payload/server/public/public.html +13 -13
- package/payload/server/public/routines.html +6 -6
- package/payload/server/public/skills.html +5 -5
- package/payload/server/public/tasks.html +6 -6
- package/payload/server/server.js +1006 -606
- package/payload/server/public/assets/AdminLoginScreens-Dar_MMJm.js.br +0 -0
- package/payload/server/public/assets/AdminLoginScreens-Dar_MMJm.js.gz +0 -0
- package/payload/server/public/assets/AdminShell-CpaI2F_p.js.br +0 -0
- package/payload/server/public/assets/activity-B1rt4GIy.js.br +0 -0
- package/payload/server/public/assets/activity-B1rt4GIy.js.gz +0 -0
- package/payload/server/public/assets/admin-DE3lLNje.js +0 -1
- package/payload/server/public/assets/admin-DE3lLNje.js.br +0 -0
- package/payload/server/public/assets/admin-DE3lLNje.js.gz +0 -0
- package/payload/server/public/assets/agents-BXq8woVf.js.br +0 -0
- package/payload/server/public/assets/agents-BXq8woVf.js.gz +0 -0
- package/payload/server/public/assets/browser-1QSCPl3X.js.br +0 -0
- package/payload/server/public/assets/browser-1QSCPl3X.js.gz +0 -0
- package/payload/server/public/assets/calendar-D009qWVV.js.br +0 -0
- package/payload/server/public/assets/calendar-D009qWVV.js.gz +0 -0
- package/payload/server/public/assets/chat-CUg1fTqJ.js +0 -1
- package/payload/server/public/assets/chat-CUg1fTqJ.js.br +0 -1
- package/payload/server/public/assets/chat-CUg1fTqJ.js.gz +0 -0
- package/payload/server/public/assets/chevron-left-C2JEy7uU.js +0 -1
- package/payload/server/public/assets/chevron-left-C2JEy7uU.js.br +0 -0
- package/payload/server/public/assets/chevron-right-DWa047Ys.js +0 -1
- package/payload/server/public/assets/chevron-right-DWa047Ys.js.br +0 -0
- package/payload/server/public/assets/clock-C3OqfCnn.js +0 -1
- package/payload/server/public/assets/clock-C3OqfCnn.js.br +0 -0
- package/payload/server/public/assets/clock-C3OqfCnn.js.gz +0 -0
- package/payload/server/public/assets/data-Bu_yCScC.js +0 -1
- package/payload/server/public/assets/data-Bu_yCScC.js.br +0 -0
- package/payload/server/public/assets/data-Bu_yCScC.js.gz +0 -0
- package/payload/server/public/assets/file-text-DwGAfCsd.js.br +0 -0
- package/payload/server/public/assets/file-text-DwGAfCsd.js.gz +0 -0
- package/payload/server/public/assets/graph-D-DGlfhW.js.br +0 -0
- package/payload/server/public/assets/graph-D-DGlfhW.js.gz +0 -0
- package/payload/server/public/assets/graph-labels-BbX3fXzl.js.br +0 -0
- package/payload/server/public/assets/graph-labels-BbX3fXzl.js.gz +0 -0
- package/payload/server/public/assets/maximize-2-C_-KapxH.js.br +0 -0
- package/payload/server/public/assets/maximize-2-C_-KapxH.js.gz +0 -0
- package/payload/server/public/assets/operator-CFrZVcv6.js.br +0 -0
- package/payload/server/public/assets/operator-CFrZVcv6.js.gz +0 -0
- package/payload/server/public/assets/page-CHt62f1_.js.br +0 -0
- package/payload/server/public/assets/page-CHt62f1_.js.gz +0 -0
- package/payload/server/public/assets/page-E74MYB18.js.br +0 -0
- package/payload/server/public/assets/page-E74MYB18.js.gz +0 -0
- package/payload/server/public/assets/public-CI6K1sNW.js.br +0 -0
- package/payload/server/public/assets/public-CI6K1sNW.js.gz +0 -0
- package/payload/server/public/assets/rotate-ccw-PWu_QGrD.js.br +0 -0
- package/payload/server/public/assets/rotate-ccw-PWu_QGrD.js.gz +0 -0
- package/payload/server/public/assets/routines-Cp3_XS7S.js.br +0 -0
- package/payload/server/public/assets/routines-Cp3_XS7S.js.gz +0 -0
- package/payload/server/public/assets/skills-g8HvunPA.js.br +0 -0
- package/payload/server/public/assets/skills-g8HvunPA.js.gz +0 -0
- package/payload/server/public/assets/tasks-CMC_jDVm.js +0 -1
- package/payload/server/public/assets/tasks-CMC_jDVm.js.br +0 -0
- package/payload/server/public/assets/tasks-CMC_jDVm.js.gz +0 -0
- package/payload/server/public/assets/time-entry-format-BXWuQ6Sw.js.br +0 -2
- package/payload/server/public/assets/time-entry-format-BXWuQ6Sw.js.gz +0 -0
- package/payload/server/public/assets/triangle-alert-BNshRC13.js.br +0 -0
- package/payload/server/public/assets/triangle-alert-BNshRC13.js.gz +0 -0
- package/payload/server/public/assets/useCopyFeedback-CwTZ9DqH.js.br +0 -0
- package/payload/server/public/assets/useCopyFeedback-CwTZ9DqH.js.gz +0 -0
- package/payload/server/public/assets/useSubAccountSwitcher-BuUYMDWl.js.br +0 -0
- package/payload/server/public/assets/useSubAccountSwitcher-dzDnmWq9.css.br +0 -0
- package/payload/server/public/assets/useVoiceRecorder-BGqV5R6u.js.br +0 -0
- package/payload/server/public/assets/useVoiceRecorder-BGqV5R6u.js.gz +0 -0
- package/payload/server/public/assets/wrench-DQ045Pyk.js.br +0 -0
- package/payload/server/public/assets/wrench-DQ045Pyk.js.gz +0 -0
|
@@ -99,10 +99,22 @@ export declare class TokenRefreshError extends Error {
|
|
|
99
99
|
get oauthError(): string | null;
|
|
100
100
|
get statusCode(): number;
|
|
101
101
|
}
|
|
102
|
+
/**
|
|
103
|
+
* Mint a new access token from a stored refresh token.
|
|
104
|
+
*
|
|
105
|
+
* `grantedScopes` is what THIS mailbox actually consented to, read from its
|
|
106
|
+
* stored blob — never the `SCOPES` constant. A refresh must ask for what was
|
|
107
|
+
* granted: widening `SCOPES` (Task 2122 added the two `.Shared` scopes) would
|
|
108
|
+
* otherwise make every already-connected mailbox request consent it never gave,
|
|
109
|
+
* and an `invalid_grant` answer to that is treated as a revoked grant, which
|
|
110
|
+
* clears the mailbox's credentials. An empty list omits `scope` entirely, which
|
|
111
|
+
* is how the token endpoint is told to return the original grant unchanged.
|
|
112
|
+
*/
|
|
102
113
|
export declare function refreshAccessToken(args: {
|
|
103
114
|
clientId: string;
|
|
104
115
|
tenantId: string;
|
|
105
116
|
refreshToken: string;
|
|
117
|
+
grantedScopes: string[];
|
|
106
118
|
}): Promise<TokenResponse>;
|
|
107
119
|
export declare const _internals: {
|
|
108
120
|
SCOPES: string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"device-flow.d.ts","sourceRoot":"","sources":["../../src/auth/device-flow.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;
|
|
1
|
+
{"version":3,"file":"device-flow.d.ts","sourceRoot":"","sources":["../../src/auth/device-flow.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AA+BH,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAMD,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,uBAAuB,EAAE,MAAM,CAAC;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAWD;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,MAAM,EAAE;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,OAAO,CAAC,eAAe,CAAC,CA6B3B;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,OAAO,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,MAAM,CAAC;IACzB,oFAAoF;IACpF,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB;iFAC6E;IAC7E,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,qFAAqF;IACrF,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GACrB;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,GAClB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,aAAa,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,GACnE,eAAe,CAAC;AAEpB;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,eAAe,CA6CtF;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,MAAM,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,EAC9C,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,WAAW,CAAC,CA+BtB;AAMD;;;;;;;;GAQG;AACH,qBAAa,iBAAkB,SAAQ,KAAK;IAGxC,QAAQ,CAAC,KAAK,EAAE,eAAe;gBAD/B,OAAO,EAAE,MAAM,EACN,KAAK,EAAE,eAAe;IAMjC;6CACyC;IACzC,IAAI,UAAU,IAAI,MAAM,GAAG,IAAI,CAE9B;IAED,IAAI,UAAU,IAAI,MAAM,CAEvB;CACF;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE;IAC7C,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB,GAAG,OAAO,CAAC,aAAa,CAAC,CAwBzB;AAED,eAAO,MAAM,UAAU;;CAAa,CAAC"}
|
|
@@ -10,11 +10,18 @@
|
|
|
10
10
|
* `refreshAccessToken` (used by the read path in graph-client.ts) and the SCOPES
|
|
11
11
|
* set are unchanged from the prior Auth-Code implementation.
|
|
12
12
|
*/
|
|
13
|
+
// The two `.Shared` scopes are what make a shared or delegated mailbox
|
|
14
|
+
// reachable at /users/<address>; without them Graph returns 403 even when the
|
|
15
|
+
// signed-in user holds Full Access. They widen only what THIS registration
|
|
16
|
+
// consents to — a mailbox already connected keeps the grant it was given and
|
|
17
|
+
// must be re-registered before it can reach a shared mailbox (Task 2122).
|
|
13
18
|
const SCOPES = [
|
|
14
19
|
"offline_access",
|
|
15
20
|
"User.Read",
|
|
16
21
|
"Mail.ReadWrite",
|
|
17
22
|
"Mail.Send",
|
|
23
|
+
"Mail.ReadWrite.Shared",
|
|
24
|
+
"Mail.Send.Shared",
|
|
18
25
|
"Calendars.ReadWrite",
|
|
19
26
|
"Contacts.Read",
|
|
20
27
|
];
|
|
@@ -172,14 +179,27 @@ export class TokenRefreshError extends Error {
|
|
|
172
179
|
return this.azure.httpStatus;
|
|
173
180
|
}
|
|
174
181
|
}
|
|
182
|
+
/**
|
|
183
|
+
* Mint a new access token from a stored refresh token.
|
|
184
|
+
*
|
|
185
|
+
* `grantedScopes` is what THIS mailbox actually consented to, read from its
|
|
186
|
+
* stored blob — never the `SCOPES` constant. A refresh must ask for what was
|
|
187
|
+
* granted: widening `SCOPES` (Task 2122 added the two `.Shared` scopes) would
|
|
188
|
+
* otherwise make every already-connected mailbox request consent it never gave,
|
|
189
|
+
* and an `invalid_grant` answer to that is treated as a revoked grant, which
|
|
190
|
+
* clears the mailbox's credentials. An empty list omits `scope` entirely, which
|
|
191
|
+
* is how the token endpoint is told to return the original grant unchanged.
|
|
192
|
+
*/
|
|
175
193
|
export async function refreshAccessToken(args) {
|
|
176
194
|
const { tokenUrl } = buildUrls(args.tenantId);
|
|
177
195
|
const params = new URLSearchParams({
|
|
178
196
|
client_id: args.clientId,
|
|
179
|
-
scope: SCOPES.join(" "),
|
|
180
197
|
refresh_token: args.refreshToken,
|
|
181
198
|
grant_type: "refresh_token",
|
|
182
199
|
});
|
|
200
|
+
if (args.grantedScopes.length > 0) {
|
|
201
|
+
params.set("scope", args.grantedScopes.join(" "));
|
|
202
|
+
}
|
|
183
203
|
const response = await fetch(tokenUrl, {
|
|
184
204
|
method: "POST",
|
|
185
205
|
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"device-flow.js","sourceRoot":"","sources":["../../src/auth/device-flow.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,MAAM,MAAM,GAAG;IACb,gBAAgB;IAChB,WAAW;IACX,gBAAgB;IAChB,WAAW;IACX,qBAAqB;IACrB,eAAe;CAChB,CAAC;AAOF,SAAS,SAAS,CAAC,QAAgB;IACjC,MAAM,MAAM,GAAG,QAAQ,IAAI,QAAQ,CAAC;IACpC,OAAO;QACL,YAAY,EAAE,qCAAqC,MAAM,wBAAwB;QACjF,QAAQ,EAAE,qCAAqC,MAAM,oBAAoB;KAC1E,CAAC;AACJ,CAAC;AAiCD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,MAGrC;IACC,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,IAAI,QAAQ,CAAC;IAC3C,MAAM,GAAG,GAAG,qCAAqC,MAAM,yBAAyB,CAAC;IACjF,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC;QACjC,SAAS,EAAE,MAAM,CAAC,QAAQ;QAC1B,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;KACxB,CAAC,CAAC;IACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAChC,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,mCAAmC,EAAE;QAChE,IAAI,EAAE,MAAM,CAAC,QAAQ,EAAE;KACxB,CAAC,CAAC;IACH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CAAC,+BAA+B,QAAQ,CAAC,MAAM,MAAM,IAAI,EAAE,CAAC,CAAC;IAC9E,CAAC;IACD,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAuB,CAAC;IAC3D,MAAM,uBAAuB,GAC3B,IAAI,CAAC,yBAAyB;QAC9B,GAAG,IAAI,CAAC,gBAAgB,QAAQ,IAAI,CAAC,SAAS,EAAE,CAAC;IACnD,OAAO;QACL,UAAU,EAAE,IAAI,CAAC,WAAW;QAC5B,QAAQ,EAAE,IAAI,CAAC,SAAS;QACxB,eAAe,EAAE,IAAI,CAAC,gBAAgB;QACtC,uBAAuB;QACvB,YAAY,EAAE,IAAI,CAAC,UAAU;QAC7B,WAAW,EAAE,IAAI,CAAC,QAAQ;QAC1B,MAAM,EAAE,CAAC,GAAG,MAAM,CAAC;KACpB,CAAC;AACJ,CAAC;AA2BD;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,UAAkB,EAAE,IAAY;IACnE,IAAI,KAAK,GAAG,EAAE,CAAC;IACf,IAAI,gBAAgB,GAAG,EAAE,CAAC;IAC1B,IAAI,QAAQ,GAAkB,IAAI,CAAC;IACnC,IAAI,aAAa,GAAkB,IAAI,CAAC;IACxC,IAAI,OAAO,GAAkB,IAAI,CAAC;IAClC,IAAI,SAAS,GAAkB,IAAI,CAAC;IACpC,IAAI,MAAM,GAAkB,IAAI,CAAC;IACjC,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAQxB,CAAC;QACF,KAAK,GAAG,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QACtB,gBAAgB,GAAG,CAAC,CAAC,iBAAiB,IAAI,EAAE,CAAC;QAC7C,QAAQ,GAAG,CAAC,CAAC,QAAQ,IAAI,IAAI,CAAC;QAC9B,aAAa,GAAG,CAAC,CAAC,cAAc,IAAI,IAAI,CAAC;QACzC,OAAO,GAAG,CAAC,CAAC,QAAQ,IAAI,IAAI,CAAC;QAC7B,SAAS,GAAG,CAAC,CAAC,SAAS,IAAI,IAAI,CAAC;QAChC,IAAI,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC;YAAE,MAAM,GAAG,SAAS,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;IACtF,CAAC;IAAC,MAAM,CAAC;QACP,+EAA+E;QAC/E,+DAA+D;IACjE,CAAC;IACD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,CAAC,GAAG,WAAW,CAAC,IAAI,CAAC,gBAAgB,IAAI,IAAI,CAAC,CAAC;QACrD,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC3B,CAAC;IACD,OAAO;QACL,IAAI,EAAE,OAAO;QACb,UAAU;QACV,KAAK;QACL,gBAAgB;QAChB,MAAM;QACN,QAAQ;QACR,aAAa;QACb,OAAO;QACP,SAAS;QACT,GAAG,EAAE,IAAI;KACV,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,MAA8C,EAC9C,UAAkB;IAElB,MAAM,EAAE,QAAQ,EAAE,GAAG,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAChD,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC;QACjC,SAAS,EAAE,MAAM,CAAC,QAAQ;QAC1B,UAAU,EAAE,8CAA8C;QAC1D,WAAW,EAAE,UAAU;KACxB,CAAC,CAAC;IACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE;QACrC,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,mCAAmC,EAAE;QAChE,IAAI,EAAE,MAAM,CAAC,QAAQ,EAAE;KACxB,CAAC,CAAC;IACH,IAAI,QAAQ,CAAC,EAAE,EAAE,CAAC;QAChB,MAAM,aAAa,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAkB,CAAC;QAC/D,MAAM,MAAM,GAAG,CAAC,aAAa,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACtE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,EAAE,CAAC;IACpD,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IACnC,MAAM,MAAM,GAAG,oBAAoB,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC3D,QAAQ,MAAM,CAAC,KAAK,EAAE,CAAC;QACrB,KAAK,uBAAuB;YAC1B,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QAC7B,KAAK,WAAW;YACd,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;QAC/B,KAAK,eAAe;YAClB,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QAC7B,KAAK,eAAe;YAClB,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;QAC5B;YACE,OAAO,MAAM,CAAC;IAClB,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,uEAAuE;AACvE,8EAA8E;AAE9E;;;;;;;;GAQG;AACH,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IAG/B;IAFX,YACE,OAAe,EACN,KAAsB;QAE/B,KAAK,CAAC,OAAO,CAAC,CAAC;QAFN,UAAK,GAAL,KAAK,CAAiB;QAG/B,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;IAClC,CAAC;IAED;6CACyC;IACzC,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,IAAI,CAAC;IAClC,CAAC;IAED,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC;IAC/B,CAAC;CACF;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,
|
|
1
|
+
{"version":3,"file":"device-flow.js","sourceRoot":"","sources":["../../src/auth/device-flow.ts"],"names":[],"mappings":"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"}
|
|
@@ -53,6 +53,12 @@ export type ResolveResult = {
|
|
|
53
53
|
kind: "ok";
|
|
54
54
|
store: TokenStore;
|
|
55
55
|
descriptor: MailboxDescriptor;
|
|
56
|
+
/** "/me" for a signed-in mailbox, "/users/<encoded address>" for a delegated one. */
|
|
57
|
+
pathPrefix: string;
|
|
58
|
+
/** The delegator's identity when this is a delegated mailbox, else null. */
|
|
59
|
+
via: string | null;
|
|
60
|
+
/** The delegated address when this is a delegated mailbox, else null. */
|
|
61
|
+
delegatedAddress: string | null;
|
|
56
62
|
} | {
|
|
57
63
|
kind: "none";
|
|
58
64
|
} | {
|
|
@@ -62,12 +68,27 @@ export type ResolveResult = {
|
|
|
62
68
|
kind: "notfound";
|
|
63
69
|
selector: string;
|
|
64
70
|
identities: string[];
|
|
71
|
+
}
|
|
72
|
+
/** A shared mailbox is attached, but the mailbox that delegates for it is no
|
|
73
|
+
* longer connected. Distinct from `notfound` because the record exists and
|
|
74
|
+
* the remedy is different: re-register the delegator, or drop the record. */
|
|
75
|
+
| {
|
|
76
|
+
kind: "delegator-missing";
|
|
77
|
+
selector: string;
|
|
78
|
+
via: string;
|
|
65
79
|
};
|
|
66
80
|
export interface CredResolveEvent {
|
|
67
81
|
event: "cred-resolve";
|
|
68
82
|
account: string;
|
|
69
83
|
mailbox: string;
|
|
70
84
|
source: "arg" | "sole" | "none" | "refused";
|
|
85
|
+
/** Whether the call runs against the operator's own mailbox or through a
|
|
86
|
+
* delegation. Without it, a delegated call is indistinguishable in the log
|
|
87
|
+
* from a signed-in one, which is exactly the difference that matters when a
|
|
88
|
+
* shared mailbox stops answering. */
|
|
89
|
+
kind: "signed-in" | "delegated";
|
|
90
|
+
/** The delegator's identity on a delegated resolution, else "". */
|
|
91
|
+
via: string;
|
|
71
92
|
}
|
|
72
93
|
/**
|
|
73
94
|
* The observability line for a resolution: names the *resolved* mailbox and how
|
|
@@ -82,6 +103,7 @@ export declare class MailboxRegistry {
|
|
|
82
103
|
private readonly secretsDir;
|
|
83
104
|
private readonly mailboxesDir;
|
|
84
105
|
private readonly legacyTokensPath;
|
|
106
|
+
private readonly delegatedStore;
|
|
85
107
|
constructor(accountId: string, accountsDir: string);
|
|
86
108
|
/**
|
|
87
109
|
* Move a pre-migration `secrets/outlook/tokens.enc` into
|
|
@@ -94,12 +116,21 @@ export declare class MailboxRegistry {
|
|
|
94
116
|
list(): MailboxDescriptor[];
|
|
95
117
|
private describe;
|
|
96
118
|
/**
|
|
97
|
-
* Resolve a mailbox selector to a TokenStore
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
119
|
+
* Resolve a mailbox selector to a TokenStore and the Graph path prefix that
|
|
120
|
+
* addresses it. Order: an explicit selector against the signed-in mailboxes
|
|
121
|
+
* (graphUserId or mail, case-insensitive) → the same selector against the
|
|
122
|
+
* delegated records → the sole readable signed-in mailbox → ambiguous (≥2
|
|
123
|
+
* attached, none named) → none. Unreadable mailboxes are never addressable.
|
|
124
|
+
*
|
|
125
|
+
* Delegated records deliberately take part in NEITHER the sole-mailbox
|
|
126
|
+
* default nor the ambiguity count. Attaching a shared mailbox must not change
|
|
127
|
+
* what a bare call means, or every existing tool call on a single-mailbox
|
|
128
|
+
* account would start refusing the moment a shared mailbox was added.
|
|
101
129
|
*/
|
|
102
130
|
resolve(selector?: string): ResolveResult;
|
|
131
|
+
/** Every selectable identity on this account, signed-in and delegated, so a
|
|
132
|
+
* refusal is honest about what IS attached rather than listing half of it. */
|
|
133
|
+
private identities;
|
|
103
134
|
/** A TokenStore for a specific mailbox key (a graphUserId at register time, or
|
|
104
135
|
* a descriptor's mailboxKey). Overwrites that mailbox in place on store(). */
|
|
105
136
|
storeFor(mailboxKey: string): TokenStore;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mailbox-registry.d.ts","sourceRoot":"","sources":["../../src/auth/mailbox-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,OAAO,EAAE,UAAU,EAAsB,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"mailbox-registry.d.ts","sourceRoot":"","sources":["../../src/auth/mailbox-registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
import { existsSync, mkdirSync, readdirSync, renameSync, unlinkSync } from "node:fs";
|
|
15
15
|
import { join } from "node:path";
|
|
16
16
|
import { TokenStore, sanitizeMailboxKey } from "./token-store.js";
|
|
17
|
+
import { DelegatedStore, normalizeAddress } from "./delegated-store.js";
|
|
18
|
+
import { OWN_MAILBOX_PREFIX, sharedMailboxPrefix } from "../lib/graph-client.js";
|
|
17
19
|
/**
|
|
18
20
|
* Classify a mailbox's usability from its readable/mail/refresh facts. Pure and
|
|
19
21
|
* total, evaluated in precedence order so the most blocking condition wins:
|
|
@@ -48,14 +50,43 @@ export function credResolveEvent(resolved, account, selector) {
|
|
|
48
50
|
return {
|
|
49
51
|
event: "cred-resolve",
|
|
50
52
|
account,
|
|
51
|
-
mailbox: identityOf(resolved.descriptor),
|
|
53
|
+
mailbox: resolved.delegatedAddress ?? identityOf(resolved.descriptor),
|
|
52
54
|
source: selector ? "arg" : "sole",
|
|
55
|
+
kind: resolved.delegatedAddress ? "delegated" : "signed-in",
|
|
56
|
+
via: resolved.via ?? "",
|
|
53
57
|
};
|
|
54
58
|
}
|
|
55
59
|
if (resolved.kind === "none") {
|
|
56
|
-
return {
|
|
60
|
+
return {
|
|
61
|
+
event: "cred-resolve",
|
|
62
|
+
account,
|
|
63
|
+
mailbox: "",
|
|
64
|
+
source: "none",
|
|
65
|
+
kind: "signed-in",
|
|
66
|
+
via: "",
|
|
67
|
+
};
|
|
57
68
|
}
|
|
58
|
-
|
|
69
|
+
if (resolved.kind === "delegator-missing") {
|
|
70
|
+
// The one refusal these two fields exist to diagnose. Labelling it
|
|
71
|
+
// signed-in with no delegator would hide exactly the fact the operator
|
|
72
|
+
// needs: which mailbox was supposed to reach this shared one.
|
|
73
|
+
return {
|
|
74
|
+
event: "cred-resolve",
|
|
75
|
+
account,
|
|
76
|
+
mailbox: resolved.selector,
|
|
77
|
+
source: "refused",
|
|
78
|
+
kind: "delegated",
|
|
79
|
+
via: resolved.via,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
return {
|
|
83
|
+
event: "cred-resolve",
|
|
84
|
+
account,
|
|
85
|
+
mailbox: selector ?? "",
|
|
86
|
+
source: "refused",
|
|
87
|
+
kind: "signed-in",
|
|
88
|
+
via: "",
|
|
89
|
+
};
|
|
59
90
|
}
|
|
60
91
|
export class MailboxRegistry {
|
|
61
92
|
accountId;
|
|
@@ -63,12 +94,14 @@ export class MailboxRegistry {
|
|
|
63
94
|
secretsDir;
|
|
64
95
|
mailboxesDir;
|
|
65
96
|
legacyTokensPath;
|
|
97
|
+
delegatedStore;
|
|
66
98
|
constructor(accountId, accountsDir) {
|
|
67
99
|
this.accountId = accountId;
|
|
68
100
|
this.accountsDir = accountsDir;
|
|
69
101
|
this.secretsDir = join(accountsDir, accountId, "secrets", "outlook");
|
|
70
102
|
this.mailboxesDir = join(this.secretsDir, "mailboxes");
|
|
71
103
|
this.legacyTokensPath = join(this.secretsDir, "tokens.enc");
|
|
104
|
+
this.delegatedStore = new DelegatedStore(accountId, accountsDir);
|
|
72
105
|
}
|
|
73
106
|
/**
|
|
74
107
|
* Move a pre-migration `secrets/outlook/tokens.enc` into
|
|
@@ -149,22 +182,56 @@ export class MailboxRegistry {
|
|
|
149
182
|
}
|
|
150
183
|
}
|
|
151
184
|
/**
|
|
152
|
-
* Resolve a mailbox selector to a TokenStore
|
|
153
|
-
*
|
|
154
|
-
*
|
|
155
|
-
*
|
|
185
|
+
* Resolve a mailbox selector to a TokenStore and the Graph path prefix that
|
|
186
|
+
* addresses it. Order: an explicit selector against the signed-in mailboxes
|
|
187
|
+
* (graphUserId or mail, case-insensitive) → the same selector against the
|
|
188
|
+
* delegated records → the sole readable signed-in mailbox → ambiguous (≥2
|
|
189
|
+
* attached, none named) → none. Unreadable mailboxes are never addressable.
|
|
190
|
+
*
|
|
191
|
+
* Delegated records deliberately take part in NEITHER the sole-mailbox
|
|
192
|
+
* default nor the ambiguity count. Attaching a shared mailbox must not change
|
|
193
|
+
* what a bare call means, or every existing tool call on a single-mailbox
|
|
194
|
+
* account would start refusing the moment a shared mailbox was added.
|
|
156
195
|
*/
|
|
157
196
|
resolve(selector) {
|
|
158
197
|
const all = this.list();
|
|
159
198
|
const addressable = all.filter((d) => d.readable);
|
|
199
|
+
const delegated = this.delegatedStore.read();
|
|
160
200
|
if (selector) {
|
|
161
201
|
const needle = selector.toLowerCase();
|
|
162
202
|
const match = addressable.find((d) => d.graphUserId?.toLowerCase() === needle ||
|
|
163
203
|
d.mail?.toLowerCase() === needle);
|
|
164
204
|
if (match) {
|
|
165
|
-
return {
|
|
205
|
+
return {
|
|
206
|
+
kind: "ok",
|
|
207
|
+
store: this.storeFor(match.mailboxKey),
|
|
208
|
+
descriptor: match,
|
|
209
|
+
pathPrefix: OWN_MAILBOX_PREFIX,
|
|
210
|
+
via: null,
|
|
211
|
+
delegatedAddress: null,
|
|
212
|
+
};
|
|
166
213
|
}
|
|
167
|
-
|
|
214
|
+
const address = normalizeAddress(selector);
|
|
215
|
+
// Own-property check, not a bare index: a plain object answers
|
|
216
|
+
// "constructor" or "toString" with an inherited function, which would
|
|
217
|
+
// read as an attached delegated record and refuse with a confabulated
|
|
218
|
+
// "attached through a mailbox that is no longer connected".
|
|
219
|
+
const entry = Object.hasOwn(delegated, address) ? delegated[address] : undefined;
|
|
220
|
+
if (entry) {
|
|
221
|
+
const delegator = addressable.find((d) => d.mailboxKey === entry.viaMailboxKey);
|
|
222
|
+
if (!delegator) {
|
|
223
|
+
return { kind: "delegator-missing", selector: address, via: entry.viaMailboxKey };
|
|
224
|
+
}
|
|
225
|
+
return {
|
|
226
|
+
kind: "ok",
|
|
227
|
+
store: this.storeFor(delegator.mailboxKey),
|
|
228
|
+
descriptor: delegator,
|
|
229
|
+
pathPrefix: sharedMailboxPrefix(address),
|
|
230
|
+
via: identityOf(delegator),
|
|
231
|
+
delegatedAddress: address,
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
return { kind: "notfound", selector, identities: this.identities(all, delegated) };
|
|
168
235
|
}
|
|
169
236
|
// Ambiguity is decided by the number of mailboxes *attached* (readable or
|
|
170
237
|
// not), never the readable subset. If a second mailbox is transiently
|
|
@@ -174,11 +241,26 @@ export class MailboxRegistry {
|
|
|
174
241
|
return { kind: "none" };
|
|
175
242
|
if (all.length === 1) {
|
|
176
243
|
return addressable.length === 1
|
|
177
|
-
? {
|
|
244
|
+
? {
|
|
245
|
+
kind: "ok",
|
|
246
|
+
store: this.storeFor(addressable[0].mailboxKey),
|
|
247
|
+
descriptor: addressable[0],
|
|
248
|
+
pathPrefix: OWN_MAILBOX_PREFIX,
|
|
249
|
+
via: null,
|
|
250
|
+
delegatedAddress: null,
|
|
251
|
+
}
|
|
178
252
|
: { kind: "none" };
|
|
179
253
|
}
|
|
180
254
|
return { kind: "ambiguous", identities: all.map(identityOf) };
|
|
181
255
|
}
|
|
256
|
+
/** Every selectable identity on this account, signed-in and delegated, so a
|
|
257
|
+
* refusal is honest about what IS attached rather than listing half of it. */
|
|
258
|
+
identities(all, delegated) {
|
|
259
|
+
return [
|
|
260
|
+
...all.map(identityOf),
|
|
261
|
+
...Object.keys(delegated).map((address) => `${address} (delegated)`),
|
|
262
|
+
];
|
|
263
|
+
}
|
|
182
264
|
/** A TokenStore for a specific mailbox key (a graphUserId at register time, or
|
|
183
265
|
* a descriptor's mailboxKey). Overwrites that mailbox in place on store(). */
|
|
184
266
|
storeFor(mailboxKey) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mailbox-registry.js","sourceRoot":"","sources":["../../src/auth/mailbox-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrF,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"mailbox-registry.js","sourceRoot":"","sources":["../../src/auth/mailbox-registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -21,6 +21,9 @@ import { z } from "zod";
|
|
|
21
21
|
import { TokenStore } from "./auth/token-store.js";
|
|
22
22
|
import { PendingStore } from "./auth/pending-store.js";
|
|
23
23
|
import { MailboxRegistry, credResolveEvent } from "./auth/mailbox-registry.js";
|
|
24
|
+
import { callGraph, OWN_MAILBOX_PREFIX } from "./lib/graph-client.js";
|
|
25
|
+
import { graphInboxProbe, runSharedMailboxAdd } from "./tools/shared-mailbox-add.js";
|
|
26
|
+
import { runSharedMailboxRemove } from "./tools/shared-mailbox-remove.js";
|
|
24
27
|
import { runAccountRegisterStart, runAccountRegisterPoll } from "./tools/account-register.js";
|
|
25
28
|
import { runMailList } from "./tools/mail-list.js";
|
|
26
29
|
import { runMailSearch } from "./tools/mail-search.js";
|
|
@@ -99,6 +102,46 @@ function getClientCreds() {
|
|
|
99
102
|
}
|
|
100
103
|
return { clientId: OUTLOOK_CLIENT_ID, tenantId: OUTLOOK_TENANT_ID };
|
|
101
104
|
}
|
|
105
|
+
/**
|
|
106
|
+
* Resolve the SIGNED-IN mailbox that will delegate for a shared one.
|
|
107
|
+
*
|
|
108
|
+
* Distinct from getConfig because a delegation cannot itself be delegated: the
|
|
109
|
+
* caller must name a mailbox that actually signed in, and resolving to a
|
|
110
|
+
* delegated record here would silently build a pointer to a pointer.
|
|
111
|
+
*/
|
|
112
|
+
function getDelegator(via) {
|
|
113
|
+
if (!ACCOUNT_ID) {
|
|
114
|
+
throw new Error("getDelegator() called without ACCOUNT_ID — handler guard missing");
|
|
115
|
+
}
|
|
116
|
+
const { clientId, tenantId } = getClientCreds();
|
|
117
|
+
const resolved = getRegistry().resolve(via);
|
|
118
|
+
log({ ...credResolveEvent(resolved, ACCOUNT_ID, via) });
|
|
119
|
+
if (resolved.kind === "ambiguous") {
|
|
120
|
+
throw new Error(`This account has ${resolved.identities.length} Outlook mailboxes (${resolved.identities.join(", ")}). Pass via=<email or id> to say which one has Full Access to the shared mailbox.`);
|
|
121
|
+
}
|
|
122
|
+
// Each refusal names what is actually true. Collapsing these into "nothing is
|
|
123
|
+
// connected" asserts the opposite of the resolver's own result whenever the
|
|
124
|
+
// caller merely mistyped `via`, and sends the operator to re-register a
|
|
125
|
+
// mailbox that is working.
|
|
126
|
+
if (resolved.kind === "notfound") {
|
|
127
|
+
throw new Error(`No connected Outlook mailbox matches via="${resolved.selector}". Connected: ${resolved.identities.join(", ") || "none"}. Pass via=<one of those> — it must be a mailbox that signed in, not the shared mailbox you are attaching.`);
|
|
128
|
+
}
|
|
129
|
+
if (resolved.kind === "delegator-missing") {
|
|
130
|
+
throw new Error(`via="${resolved.selector}" is itself a shared mailbox, and the mailbox that reaches it (${resolved.via}) is no longer connected. Pass via=<a signed-in mailbox>.`);
|
|
131
|
+
}
|
|
132
|
+
if (resolved.kind !== "ok") {
|
|
133
|
+
throw new Error("No Outlook mailbox is connected for this account, so there is nothing to delegate through. Run outlook-account-register first.");
|
|
134
|
+
}
|
|
135
|
+
if (resolved.delegatedAddress) {
|
|
136
|
+
throw new Error(`${resolved.delegatedAddress} is itself a shared mailbox reached through ${resolved.via}. Pass via=<the signed-in mailbox> instead.`);
|
|
137
|
+
}
|
|
138
|
+
return {
|
|
139
|
+
config: { clientId, tenantId, accountId: ACCOUNT_ID, tokenStore: resolved.store },
|
|
140
|
+
mailboxKey: resolved.descriptor.mailboxKey,
|
|
141
|
+
identity: resolved.descriptor.mail ?? resolved.descriptor.graphUserId ?? resolved.descriptor.mailboxKey,
|
|
142
|
+
scopes: resolved.descriptor.scopes,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
102
145
|
/**
|
|
103
146
|
* Build a GraphClientConfig for the mailbox the caller named, or the sole
|
|
104
147
|
* configured mailbox when none is named. Resolution order: explicit `mailbox`
|
|
@@ -116,8 +159,10 @@ function getConfig(mailbox) {
|
|
|
116
159
|
const resolved = getRegistry().resolve(mailbox);
|
|
117
160
|
log({ ...credResolveEvent(resolved, ACCOUNT_ID, mailbox) });
|
|
118
161
|
let tokenStore;
|
|
162
|
+
let mailboxPathPrefix = OWN_MAILBOX_PREFIX;
|
|
119
163
|
if (resolved.kind === "ok") {
|
|
120
164
|
tokenStore = resolved.store;
|
|
165
|
+
mailboxPathPrefix = resolved.pathPrefix;
|
|
121
166
|
}
|
|
122
167
|
else if (resolved.kind === "none") {
|
|
123
168
|
tokenStore = new TokenStore(ACCOUNT_ID, ACCOUNTS_DIR, UNCONFIGURED_MAILBOX);
|
|
@@ -125,10 +170,13 @@ function getConfig(mailbox) {
|
|
|
125
170
|
else if (resolved.kind === "ambiguous") {
|
|
126
171
|
throw new Error(`This account has ${resolved.identities.length} Outlook mailboxes (${resolved.identities.join(", ")}). Pass mailbox=<email or id> to choose one.`);
|
|
127
172
|
}
|
|
173
|
+
else if (resolved.kind === "delegator-missing") {
|
|
174
|
+
throw new Error(`The shared mailbox "${resolved.selector}" is attached through a mailbox that is no longer connected (${resolved.via}). Re-run outlook-account-register for that mailbox, or drop the shared mailbox with outlook-shared-mailbox-remove.`);
|
|
175
|
+
}
|
|
128
176
|
else {
|
|
129
177
|
throw new Error(`No Outlook mailbox "${resolved.selector}" is connected for this account. Connected: ${resolved.identities.join(", ") || "none"}.`);
|
|
130
178
|
}
|
|
131
|
-
return { clientId, tenantId, accountId: ACCOUNT_ID, tokenStore };
|
|
179
|
+
return { clientId, tenantId, accountId: ACCOUNT_ID, tokenStore, mailboxPathPrefix };
|
|
132
180
|
}
|
|
133
181
|
function ok(payload) {
|
|
134
182
|
return {
|
|
@@ -478,17 +526,72 @@ lifelineTool(server, "outlook-mailbox-info", "Health probe — reports auth stat
|
|
|
478
526
|
return fail(`outlook-mailbox-info failed: ${err.message}`);
|
|
479
527
|
}
|
|
480
528
|
});
|
|
481
|
-
lifelineTool(server, "outlook-mailbox-list", "List every Outlook mailbox attached to this account, with each mailbox's email, graphUserId, granted scopes, token expiry, and a `status`. `count` is how many records are attached; `addressable` is how many are usable by their email right now (`status:ok`). Do NOT read a bare `count` of 1 as 'connected' — a record can be attached but not addressable: `status:blank-email` (readable but no stored email, so it cannot be resolved by address), `status:refresh-expired` (needs re-auth),
|
|
529
|
+
lifelineTool(server, "outlook-mailbox-list", "List every Outlook mailbox attached to this account, with each mailbox's email, graphUserId, granted scopes, token expiry, and a `status`. `count` is how many records are attached; `addressable` is how many SIGNED-IN mailboxes are usable by their email right now (`status:ok`); `delegated` is how many are shared mailboxes reached through another. Each entry carries `kind` (`signed-in` or `delegated`) and, when delegated, `via` (the mailbox whose Full Access reaches it). Do NOT read a bare `count` of 1 as 'connected' — a record can be attached but not addressable: `status:blank-email` (readable but no stored email, so it cannot be resolved by address), `status:refresh-expired` (needs re-auth), `status:unreadable` (stored credentials will not decrypt), or `status:delegator-missing` (a shared mailbox whose delegating mailbox is no longer connected). Local only by default — reads the stored credentials, never the network. Pass verify:true to probe each attached shared mailbox and report `reachable`. `reachable:false` means the probe did not succeed just now — a revoked Full Access grant is the usual cause, but so is a network or Graph outage, so read the `graph-error` log line for the reason rather than treating false as proof the delegation is gone. Call this before addressing a specific mailbox; pass the email of an `ok` or `delegated` mailbox as the `mailbox` argument on the other tools.", {
|
|
530
|
+
verify: z
|
|
531
|
+
.boolean()
|
|
532
|
+
.optional()
|
|
533
|
+
.describe("Probe each attached shared mailbox against Graph and report `reachable`. Off by default; the listing is otherwise local-only and works when Graph is unreachable. A false answer means the probe failed now, not specifically that Full Access was revoked."),
|
|
534
|
+
}, async ({ verify }) => {
|
|
482
535
|
if (!ACCOUNT_ID)
|
|
483
536
|
return refuseNoAccount("outlook-mailbox-list");
|
|
484
537
|
try {
|
|
485
|
-
const result = runMailboxList(ACCOUNT_ID, ACCOUNTS_DIR
|
|
538
|
+
const result = await runMailboxList(ACCOUNT_ID, ACCOUNTS_DIR, {
|
|
539
|
+
verify,
|
|
540
|
+
probe: async (address) => {
|
|
541
|
+
try {
|
|
542
|
+
await callGraph(getConfig(address), async (client) => client.api("/me/mailFolders/Inbox").select("id").get(), { tool: "mailbox-list", target: address });
|
|
543
|
+
return true;
|
|
544
|
+
}
|
|
545
|
+
catch {
|
|
546
|
+
// Any failure means "cannot reach it right now". The reason is
|
|
547
|
+
// already on the graph-error line; this flag answers only whether
|
|
548
|
+
// the mailbox still answers.
|
|
549
|
+
return false;
|
|
550
|
+
}
|
|
551
|
+
},
|
|
552
|
+
});
|
|
486
553
|
return ok(result);
|
|
487
554
|
}
|
|
488
555
|
catch (err) {
|
|
489
556
|
return fail(`outlook-mailbox-list failed: ${err.message}`);
|
|
490
557
|
}
|
|
491
558
|
});
|
|
559
|
+
lifelineTool(server, "outlook-shared-mailbox-add", "Attach a Microsoft 365 SHARED mailbox (one with no sign-in of its own, e.g. team@company.com) so the mail tools can read, draft, reply and send from it. This is the correct answer whenever an operator asks for a shared, team or delegated mailbox — it does NOT need a licence and must never be given a sign-in. It works through the signed-in mailbox's Full Access delegation: pass address=<the shared mailbox>, plus via=<the signed-in mailbox> when this account has more than one connected. Access is proved before anything is stored, so a refusal here is the real answer: 'does not have Full Access' means the delegation is missing and is granted in the Microsoft 365 admin centre, and 'no mailbox with this address' means the address is wrong or is a distribution list. Once attached, pass the shared address as the `mailbox` argument to any mail tool, and see it in outlook-mailbox-list. Calendar and contacts tools are refused on a shared mailbox. Requires the delegating mailbox to hold the Mail.ReadWrite.Shared scope; a mailbox connected before that scope existed must be re-registered with outlook-account-register first.", {
|
|
560
|
+
address: z.string().min(3),
|
|
561
|
+
via: z
|
|
562
|
+
.string()
|
|
563
|
+
.optional()
|
|
564
|
+
.describe("The signed-in mailbox that has Full Access to the shared one. Required only when two or more mailboxes are connected."),
|
|
565
|
+
}, async ({ address, via }) => {
|
|
566
|
+
if (!ACCOUNT_ID)
|
|
567
|
+
return refuseNoAccount("outlook-shared-mailbox-add");
|
|
568
|
+
try {
|
|
569
|
+
const delegator = getDelegator(via);
|
|
570
|
+
const result = await runSharedMailboxAdd({
|
|
571
|
+
config: delegator.config,
|
|
572
|
+
accountsDir: ACCOUNTS_DIR,
|
|
573
|
+
viaMailboxKey: delegator.mailboxKey,
|
|
574
|
+
viaIdentity: delegator.identity,
|
|
575
|
+
viaScopes: delegator.scopes,
|
|
576
|
+
nowMs: Date.now(),
|
|
577
|
+
probe: graphInboxProbe,
|
|
578
|
+
}, { address });
|
|
579
|
+
return ok(result);
|
|
580
|
+
}
|
|
581
|
+
catch (err) {
|
|
582
|
+
return fail(`outlook-shared-mailbox-add failed: ${err.message}`);
|
|
583
|
+
}
|
|
584
|
+
});
|
|
585
|
+
lifelineTool(server, "outlook-shared-mailbox-remove", "Detach a shared mailbox attached by outlook-shared-mailbox-add. Drops the pointer only — no credential is touched, and the mailbox that delegates for it keeps working. `removed:false` means the address was not attached in the first place.", { address: z.string().min(3) }, async ({ address }) => {
|
|
586
|
+
if (!ACCOUNT_ID)
|
|
587
|
+
return refuseNoAccount("outlook-shared-mailbox-remove");
|
|
588
|
+
try {
|
|
589
|
+
return ok(runSharedMailboxRemove(ACCOUNT_ID, ACCOUNTS_DIR, address));
|
|
590
|
+
}
|
|
591
|
+
catch (err) {
|
|
592
|
+
return fail(`outlook-shared-mailbox-remove failed: ${err.message}`);
|
|
593
|
+
}
|
|
594
|
+
});
|
|
492
595
|
lifelineTool(server, "outlook-mail-send", "Send a message via Microsoft Graph. Recipients are string arrays (to required, cc/bcc optional). The body is HTML when isHtml=true, otherwise plain text. attachments is an array of file paths inside the account directory (up to 25 MB per file) — with no attachments the message goes via POST /me/sendMail; with attachments it is composed as a draft, the files are attached, and the draft is sent, because /me/sendMail cannot carry a large file. Saves a copy to Sent Items. Success is asserted on Graph's 202; the message is not returned with an id on either route. Requires the Mail.Send scope (plus Mail.ReadWrite when attaching) — a mailbox registered under the old read-only consent returns an actionable 're-register to grant send' error.", {
|
|
493
596
|
to: z.array(z.string().min(3)).min(1),
|
|
494
597
|
cc: z.array(z.string()).optional(),
|