@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
|
@@ -9,10 +9,10 @@ function makeAccountsDir() {
|
|
|
9
9
|
const dir = mkdtempSync(join(tmpdir(), "outlook-list-"));
|
|
10
10
|
return { dir, cleanup: () => rmSync(dir, { recursive: true, force: true }) };
|
|
11
11
|
}
|
|
12
|
-
test("runMailboxList reports zero mailboxes for a fresh account", () => {
|
|
12
|
+
test("runMailboxList reports zero mailboxes for a fresh account", async () => {
|
|
13
13
|
const { dir, cleanup } = makeAccountsDir();
|
|
14
14
|
try {
|
|
15
|
-
const result = runMailboxList("acct", dir);
|
|
15
|
+
const result = await runMailboxList("acct", dir);
|
|
16
16
|
assert.equal(result.count, 0);
|
|
17
17
|
assert.deepEqual(result.mailboxes, []);
|
|
18
18
|
}
|
|
@@ -20,7 +20,7 @@ test("runMailboxList reports zero mailboxes for a fresh account", () => {
|
|
|
20
20
|
cleanup();
|
|
21
21
|
}
|
|
22
22
|
});
|
|
23
|
-
test("runMailboxList lists connected mailboxes with identity and token health", () => {
|
|
23
|
+
test("runMailboxList lists connected mailboxes with identity and token health", async () => {
|
|
24
24
|
const { dir, cleanup } = makeAccountsDir();
|
|
25
25
|
try {
|
|
26
26
|
new TokenStore("acct", dir, "rob-guid").store("a", "r", 3600, {
|
|
@@ -29,7 +29,7 @@ test("runMailboxList lists connected mailboxes with identity and token health",
|
|
|
29
29
|
new TokenStore("acct", dir, "info-guid").store("a", "r", 3600, {
|
|
30
30
|
graphUserId: "info-guid", mail: "info@ecolecltd.co.uk", scopes: ["Mail.Read"],
|
|
31
31
|
});
|
|
32
|
-
const result = runMailboxList("acct", dir);
|
|
32
|
+
const result = await runMailboxList("acct", dir);
|
|
33
33
|
assert.equal(result.count, 2);
|
|
34
34
|
const rob = result.mailboxes.find((m) => m.mailbox === "rob@ecolecltd.co.uk");
|
|
35
35
|
assert.ok(rob);
|
|
@@ -41,7 +41,7 @@ test("runMailboxList lists connected mailboxes with identity and token health",
|
|
|
41
41
|
cleanup();
|
|
42
42
|
}
|
|
43
43
|
});
|
|
44
|
-
test("runMailboxList reports addressable count and per-mailbox status; a blank-email record is not a healthy count", () => {
|
|
44
|
+
test("runMailboxList reports addressable count and per-mailbox status; a blank-email record is not a healthy count", async () => {
|
|
45
45
|
const { dir, cleanup } = makeAccountsDir();
|
|
46
46
|
try {
|
|
47
47
|
new TokenStore("acct", dir, "ok-guid").store("a", "r", 3600, {
|
|
@@ -52,7 +52,7 @@ test("runMailboxList reports addressable count and per-mailbox status; a blank-e
|
|
|
52
52
|
new TokenStore("acct", dir, "blank-guid").store("a", "r", 3600, {
|
|
53
53
|
graphUserId: "blank-guid", mail: "", scopes: [],
|
|
54
54
|
});
|
|
55
|
-
const result = runMailboxList("acct", dir);
|
|
55
|
+
const result = await runMailboxList("acct", dir);
|
|
56
56
|
assert.equal(result.count, 2, "both records are present");
|
|
57
57
|
assert.equal(result.addressable, 1, "only the ok record is addressable");
|
|
58
58
|
const ok = result.mailboxes.find((m) => m.mailboxKey === "ok-guid");
|
|
@@ -64,7 +64,7 @@ test("runMailboxList reports addressable count and per-mailbox status; a blank-e
|
|
|
64
64
|
cleanup();
|
|
65
65
|
}
|
|
66
66
|
});
|
|
67
|
-
test("runMailboxList reconciles an unreadable blob rather than hiding it", () => {
|
|
67
|
+
test("runMailboxList reconciles an unreadable blob rather than hiding it", async () => {
|
|
68
68
|
const { dir, cleanup } = makeAccountsDir();
|
|
69
69
|
try {
|
|
70
70
|
new TokenStore("acct", dir, "good-guid").store("a", "r", 3600, {
|
|
@@ -73,7 +73,7 @@ test("runMailboxList reconciles an unreadable blob rather than hiding it", () =>
|
|
|
73
73
|
const badDir = join(dir, "acct", "secrets", "outlook", "mailboxes", "bad-guid");
|
|
74
74
|
mkdirSync(badDir, { recursive: true });
|
|
75
75
|
writeFileSync(join(badDir, "tokens.enc"), "garbage");
|
|
76
|
-
const result = runMailboxList("acct", dir);
|
|
76
|
+
const result = await runMailboxList("acct", dir);
|
|
77
77
|
assert.equal(result.count, 2);
|
|
78
78
|
const bad = result.mailboxes.find((m) => m.mailboxKey === "bad-guid");
|
|
79
79
|
assert.ok(bad);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mailbox-list.test.js","sourceRoot":"","sources":["../../src/__tests__/mailbox-list.test.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxE,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,SAAS,eAAe;IACtB,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,eAAe,CAAC,CAAC,CAAC;IACzD,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;AAC/E,CAAC;AAED,IAAI,CAAC,2DAA2D,EAAE,
|
|
1
|
+
{"version":3,"file":"mailbox-list.test.js","sourceRoot":"","sources":["../../src/__tests__/mailbox-list.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mailbox-path-prefix.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/mailbox-path-prefix.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import test from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { applyMailboxPrefix, sharedMailboxPrefix } from "../lib/graph-client.js";
|
|
4
|
+
test("sharedMailboxPrefix encodes the address", () => {
|
|
5
|
+
assert.equal(sharedMailboxPrefix("team@muvin.co.uk"), "/users/team%40muvin.co.uk");
|
|
6
|
+
});
|
|
7
|
+
test("the default prefix leaves every path untouched", () => {
|
|
8
|
+
assert.equal(applyMailboxPrefix("/me/messages/AAA", "/me"), "/me/messages/AAA");
|
|
9
|
+
assert.equal(applyMailboxPrefix("/me", "/me"), "/me");
|
|
10
|
+
});
|
|
11
|
+
test("a delegated prefix replaces a leading /me", () => {
|
|
12
|
+
const p = sharedMailboxPrefix("team@muvin.co.uk");
|
|
13
|
+
assert.equal(applyMailboxPrefix("/me/messages/AAA", p), "/users/team%40muvin.co.uk/messages/AAA");
|
|
14
|
+
assert.equal(applyMailboxPrefix("/me/mailFolders/Inbox/messages", p), "/users/team%40muvin.co.uk/mailFolders/Inbox/messages");
|
|
15
|
+
assert.equal(applyMailboxPrefix("/me", p), "/users/team%40muvin.co.uk");
|
|
16
|
+
});
|
|
17
|
+
test("a delegated prefix leaves a nextLink cursor URL untouched", () => {
|
|
18
|
+
const p = sharedMailboxPrefix("team@muvin.co.uk");
|
|
19
|
+
const cursor = "https://graph.microsoft.com/v1.0/me/messages?$skiptoken=ABC";
|
|
20
|
+
assert.equal(applyMailboxPrefix(cursor, p), cursor);
|
|
21
|
+
});
|
|
22
|
+
test("a delegated prefix does not touch a path that only starts with the letters me", () => {
|
|
23
|
+
const p = sharedMailboxPrefix("team@muvin.co.uk");
|
|
24
|
+
assert.equal(applyMailboxPrefix("/members/1", p), "/members/1");
|
|
25
|
+
assert.equal(applyMailboxPrefix("/messages", p), "/messages");
|
|
26
|
+
});
|
|
27
|
+
//# sourceMappingURL=mailbox-path-prefix.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mailbox-path-prefix.test.js","sourceRoot":"","sources":["../../src/__tests__/mailbox-path-prefix.test.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAEjF,IAAI,CAAC,yCAAyC,EAAE,GAAG,EAAE;IACnD,MAAM,CAAC,KAAK,CAAC,mBAAmB,CAAC,kBAAkB,CAAC,EAAE,2BAA2B,CAAC,CAAC;AACrF,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,gDAAgD,EAAE,GAAG,EAAE;IAC1D,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,kBAAkB,EAAE,KAAK,CAAC,EAAE,kBAAkB,CAAC,CAAC;IAChF,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC;AACxD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,2CAA2C,EAAE,GAAG,EAAE;IACrD,MAAM,CAAC,GAAG,mBAAmB,CAAC,kBAAkB,CAAC,CAAC;IAClD,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,kBAAkB,EAAE,CAAC,CAAC,EAAE,wCAAwC,CAAC,CAAC;IAClG,MAAM,CAAC,KAAK,CACV,kBAAkB,CAAC,gCAAgC,EAAE,CAAC,CAAC,EACvD,sDAAsD,CACvD,CAAC;IACF,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,2BAA2B,CAAC,CAAC;AAC1E,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,2DAA2D,EAAE,GAAG,EAAE;IACrE,MAAM,CAAC,GAAG,mBAAmB,CAAC,kBAAkB,CAAC,CAAC;IAClD,MAAM,MAAM,GAAG,6DAA6D,CAAC;IAC7E,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;AACtD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,+EAA+E,EAAE,GAAG,EAAE;IACzF,MAAM,CAAC,GAAG,mBAAmB,CAAC,kBAAkB,CAAC,CAAC;IAClD,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,YAAY,EAAE,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC;IAChE,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,WAAW,EAAE,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;AAChE,CAAC,CAAC,CAAC"}
|
package/payload/platform/plugins/outlook/mcp/dist/__tests__/shared-mail-only-guard.test.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared-mail-only-guard.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/shared-mail-only-guard.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import test from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { mkdtempSync, rmSync } from "node:fs";
|
|
4
|
+
import { tmpdir } from "node:os";
|
|
5
|
+
import { join } from "node:path";
|
|
6
|
+
import { callGraph, sharedMailboxPrefix } from "../lib/graph-client.js";
|
|
7
|
+
import { TokenStore } from "../auth/token-store.js";
|
|
8
|
+
function configFor(prefix) {
|
|
9
|
+
const dir = mkdtempSync(join(tmpdir(), "outlook-guard-"));
|
|
10
|
+
const store = new TokenStore("acct-A", dir, "user-1");
|
|
11
|
+
store.store("access", "refresh", 3600, {
|
|
12
|
+
graphUserId: "user-1",
|
|
13
|
+
mail: "admin@muvin.co.uk",
|
|
14
|
+
scopes: [],
|
|
15
|
+
});
|
|
16
|
+
return {
|
|
17
|
+
config: {
|
|
18
|
+
clientId: "c",
|
|
19
|
+
tenantId: "common",
|
|
20
|
+
accountId: "acct-A",
|
|
21
|
+
tokenStore: store,
|
|
22
|
+
mailboxPathPrefix: prefix,
|
|
23
|
+
},
|
|
24
|
+
cleanup: () => rmSync(dir, { recursive: true, force: true }),
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
test("a calendar tool is refused under a delegated prefix and never invokes Graph", async () => {
|
|
28
|
+
const { config, cleanup } = configFor(sharedMailboxPrefix("team@muvin.co.uk"));
|
|
29
|
+
try {
|
|
30
|
+
let invoked = false;
|
|
31
|
+
await assert.rejects(() => callGraph(config, async () => {
|
|
32
|
+
invoked = true;
|
|
33
|
+
return null;
|
|
34
|
+
}, { tool: "calendar-list" }), /covers mail only/);
|
|
35
|
+
assert.equal(invoked, false, "the guard must fire before any request is built");
|
|
36
|
+
}
|
|
37
|
+
finally {
|
|
38
|
+
cleanup();
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
test("a contacts tool is refused under a delegated prefix", async () => {
|
|
42
|
+
const { config, cleanup } = configFor(sharedMailboxPrefix("team@muvin.co.uk"));
|
|
43
|
+
try {
|
|
44
|
+
await assert.rejects(() => callGraph(config, async () => null, { tool: "contacts-list" }), /covers mail only/);
|
|
45
|
+
}
|
|
46
|
+
finally {
|
|
47
|
+
cleanup();
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
test("a mail tool proceeds under a delegated prefix", async () => {
|
|
51
|
+
const { config, cleanup } = configFor(sharedMailboxPrefix("team@muvin.co.uk"));
|
|
52
|
+
try {
|
|
53
|
+
const result = await callGraph(config, async () => "reached", { tool: "mail-list" });
|
|
54
|
+
assert.equal(result, "reached");
|
|
55
|
+
}
|
|
56
|
+
finally {
|
|
57
|
+
cleanup();
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
test("a calendar tool proceeds on the signed-in mailbox", async () => {
|
|
61
|
+
const { config, cleanup } = configFor(undefined);
|
|
62
|
+
try {
|
|
63
|
+
const result = await callGraph(config, async () => "reached", { tool: "calendar-list" });
|
|
64
|
+
assert.equal(result, "reached");
|
|
65
|
+
}
|
|
66
|
+
finally {
|
|
67
|
+
cleanup();
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
//# sourceMappingURL=shared-mail-only-guard.test.js.map
|
package/payload/platform/plugins/outlook/mcp/dist/__tests__/shared-mail-only-guard.test.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared-mail-only-guard.test.js","sourceRoot":"","sources":["../../src/__tests__/shared-mail-only-guard.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared-mailbox-add.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/shared-mailbox-add.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import test from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { mkdtempSync, rmSync } from "node:fs";
|
|
4
|
+
import { tmpdir } from "node:os";
|
|
5
|
+
import { join } from "node:path";
|
|
6
|
+
import { runSharedMailboxAdd, SHARED_MAIL_SCOPE, } from "../tools/shared-mailbox-add.js";
|
|
7
|
+
import { runSharedMailboxRemove } from "../tools/shared-mailbox-remove.js";
|
|
8
|
+
import { DelegatedStore } from "../auth/delegated-store.js";
|
|
9
|
+
import { TokenStore } from "../auth/token-store.js";
|
|
10
|
+
/** A probe that resolves, or throws an error shaped like the Graph SDK's. */
|
|
11
|
+
function probeThat(behaviour) {
|
|
12
|
+
const seen = [];
|
|
13
|
+
return {
|
|
14
|
+
seen,
|
|
15
|
+
probe: async (probeConfig, address) => {
|
|
16
|
+
seen.push({ prefix: probeConfig.mailboxPathPrefix, address });
|
|
17
|
+
if (behaviour === "ok")
|
|
18
|
+
return;
|
|
19
|
+
const err = new Error(`Graph ${behaviour}`);
|
|
20
|
+
err.statusCode = behaviour;
|
|
21
|
+
throw err;
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
function makeDeps(scopes, probe) {
|
|
26
|
+
const dir = mkdtempSync(join(tmpdir(), "outlook-shared-add-"));
|
|
27
|
+
const store = new TokenStore("acct-A", dir, "user-1");
|
|
28
|
+
store.store("access", "refresh", 3600, {
|
|
29
|
+
graphUserId: "user-1",
|
|
30
|
+
mail: "admin@muvin.co.uk",
|
|
31
|
+
scopes,
|
|
32
|
+
});
|
|
33
|
+
return {
|
|
34
|
+
dir,
|
|
35
|
+
deps: {
|
|
36
|
+
config: { clientId: "c", tenantId: "common", accountId: "acct-A", tokenStore: store },
|
|
37
|
+
accountsDir: dir,
|
|
38
|
+
viaMailboxKey: "user-1",
|
|
39
|
+
viaIdentity: "admin@muvin.co.uk",
|
|
40
|
+
viaScopes: scopes,
|
|
41
|
+
nowMs: 1753724400000,
|
|
42
|
+
probe,
|
|
43
|
+
},
|
|
44
|
+
cleanup: () => rmSync(dir, { recursive: true, force: true }),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
test("a delegator without the shared scope is refused, and nothing is probed or written", async () => {
|
|
48
|
+
const { probe, seen } = probeThat("ok");
|
|
49
|
+
const { deps, dir, cleanup } = makeDeps(["Mail.ReadWrite"], probe);
|
|
50
|
+
try {
|
|
51
|
+
await assert.rejects(() => runSharedMailboxAdd(deps, { address: "team@muvin.co.uk" }), new RegExp(SHARED_MAIL_SCOPE.replace(/\./g, "\\.")));
|
|
52
|
+
assert.deepEqual(seen, [], "the scope check must precede the network call");
|
|
53
|
+
assert.deepEqual(new DelegatedStore("acct-A", dir).read(), {});
|
|
54
|
+
}
|
|
55
|
+
finally {
|
|
56
|
+
cleanup();
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
test("the probe runs against the shared prefix the real tools will use", async () => {
|
|
60
|
+
const { probe, seen } = probeThat("ok");
|
|
61
|
+
const { deps, cleanup } = makeDeps(["Mail.ReadWrite", SHARED_MAIL_SCOPE], probe);
|
|
62
|
+
try {
|
|
63
|
+
await runSharedMailboxAdd(deps, { address: "team@muvin.co.uk" });
|
|
64
|
+
assert.deepEqual(seen, [
|
|
65
|
+
{ prefix: "/users/team%40muvin.co.uk", address: "team@muvin.co.uk" },
|
|
66
|
+
]);
|
|
67
|
+
}
|
|
68
|
+
finally {
|
|
69
|
+
cleanup();
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
test("a 403 from Graph names Full Access and writes nothing", async () => {
|
|
73
|
+
const { probe } = probeThat(403);
|
|
74
|
+
const { deps, dir, cleanup } = makeDeps(["Mail.ReadWrite", SHARED_MAIL_SCOPE], probe);
|
|
75
|
+
try {
|
|
76
|
+
await assert.rejects(() => runSharedMailboxAdd(deps, { address: "team@muvin.co.uk" }), /Full Access/);
|
|
77
|
+
assert.deepEqual(new DelegatedStore("acct-A", dir).read(), {});
|
|
78
|
+
}
|
|
79
|
+
finally {
|
|
80
|
+
cleanup();
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
test("a 404 from Graph names the tenant and writes nothing", async () => {
|
|
84
|
+
const { probe } = probeThat(404);
|
|
85
|
+
const { deps, dir, cleanup } = makeDeps(["Mail.ReadWrite", SHARED_MAIL_SCOPE], probe);
|
|
86
|
+
try {
|
|
87
|
+
await assert.rejects(() => runSharedMailboxAdd(deps, { address: "nobody@muvin.co.uk" }), /no mailbox with this address/);
|
|
88
|
+
assert.deepEqual(new DelegatedStore("acct-A", dir).read(), {});
|
|
89
|
+
}
|
|
90
|
+
finally {
|
|
91
|
+
cleanup();
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
test("a successful probe writes exactly one entry, keyed lowercase", async () => {
|
|
95
|
+
const { probe } = probeThat("ok");
|
|
96
|
+
const { deps, dir, cleanup } = makeDeps(["Mail.ReadWrite", SHARED_MAIL_SCOPE], probe);
|
|
97
|
+
try {
|
|
98
|
+
const result = await runSharedMailboxAdd(deps, { address: "Team@Muvin.co.uk" });
|
|
99
|
+
assert.equal(result.address, "team@muvin.co.uk");
|
|
100
|
+
assert.equal(result.via, "admin@muvin.co.uk");
|
|
101
|
+
assert.equal(result.alreadyAttached, false);
|
|
102
|
+
assert.deepEqual(new DelegatedStore("acct-A", dir).read(), {
|
|
103
|
+
"team@muvin.co.uk": { viaMailboxKey: "user-1", addedAt: 1753724400000 },
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
finally {
|
|
107
|
+
cleanup();
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
test("re-adding the same address reports alreadyAttached and keeps one entry", async () => {
|
|
111
|
+
const { probe } = probeThat("ok");
|
|
112
|
+
const { deps, dir, cleanup } = makeDeps(["Mail.ReadWrite", SHARED_MAIL_SCOPE], probe);
|
|
113
|
+
try {
|
|
114
|
+
await runSharedMailboxAdd(deps, { address: "team@muvin.co.uk" });
|
|
115
|
+
const again = await runSharedMailboxAdd(deps, { address: "team@muvin.co.uk" });
|
|
116
|
+
assert.equal(again.alreadyAttached, true);
|
|
117
|
+
assert.equal(Object.keys(new DelegatedStore("acct-A", dir).read()).length, 1);
|
|
118
|
+
}
|
|
119
|
+
finally {
|
|
120
|
+
cleanup();
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
test("a 500 propagates rather than being reported as a permission problem", async () => {
|
|
124
|
+
const { probe } = probeThat(500);
|
|
125
|
+
const { deps, dir, cleanup } = makeDeps(["Mail.ReadWrite", SHARED_MAIL_SCOPE], probe);
|
|
126
|
+
try {
|
|
127
|
+
await assert.rejects(() => runSharedMailboxAdd(deps, { address: "team@muvin.co.uk" }), /Graph 500/);
|
|
128
|
+
assert.deepEqual(new DelegatedStore("acct-A", dir).read(), {});
|
|
129
|
+
}
|
|
130
|
+
finally {
|
|
131
|
+
cleanup();
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
test("remove drops the entry once", async () => {
|
|
135
|
+
const { probe } = probeThat("ok");
|
|
136
|
+
const { deps, dir, cleanup } = makeDeps(["Mail.ReadWrite", SHARED_MAIL_SCOPE], probe);
|
|
137
|
+
try {
|
|
138
|
+
await runSharedMailboxAdd(deps, { address: "team@muvin.co.uk" });
|
|
139
|
+
assert.deepEqual(runSharedMailboxRemove("acct-A", dir, "TEAM@muvin.co.uk"), {
|
|
140
|
+
address: "team@muvin.co.uk",
|
|
141
|
+
removed: true,
|
|
142
|
+
});
|
|
143
|
+
assert.deepEqual(runSharedMailboxRemove("acct-A", dir, "team@muvin.co.uk"), {
|
|
144
|
+
address: "team@muvin.co.uk",
|
|
145
|
+
removed: false,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
finally {
|
|
149
|
+
cleanup();
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
//# sourceMappingURL=shared-mailbox-add.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared-mailbox-add.test.js","sourceRoot":"","sources":["../../src/__tests__/shared-mailbox-add.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-account registry of DELEGATED mailboxes — shared mailboxes the signed-in
|
|
3
|
+
* user can reach through Exchange Full Access.
|
|
4
|
+
*
|
|
5
|
+
* A delegated mailbox never signs in, so it has no tokens of its own and cannot
|
|
6
|
+
* live in `mailboxes/<graphUserId>/tokens.enc` like a registered mailbox does.
|
|
7
|
+
* What is stored is a pointer: the shared address, and the mailbox key of the
|
|
8
|
+
* signed-in mailbox whose tokens address it. Holding no secret, this file is
|
|
9
|
+
* plain JSON rather than an encrypted blob, but it sits under the same 0700
|
|
10
|
+
* secrets directory and is written 0600 so its permissions never widen the
|
|
11
|
+
* directory's.
|
|
12
|
+
*/
|
|
13
|
+
export interface DelegatedEntry {
|
|
14
|
+
/** The `mailboxKey` of the signed-in mailbox whose tokens reach this address. */
|
|
15
|
+
viaMailboxKey: string;
|
|
16
|
+
/** Unix ms, supplied by the caller so the write is deterministic under test. */
|
|
17
|
+
addedAt: number;
|
|
18
|
+
}
|
|
19
|
+
export type DelegatedMap = Record<string, DelegatedEntry>;
|
|
20
|
+
/** The one address form used as a key, everywhere. */
|
|
21
|
+
export declare function normalizeAddress(address: string): string;
|
|
22
|
+
export declare class DelegatedStore {
|
|
23
|
+
readonly accountId: string;
|
|
24
|
+
private readonly secretsDir;
|
|
25
|
+
private readonly filePath;
|
|
26
|
+
constructor(accountId: string, accountsDir: string);
|
|
27
|
+
/**
|
|
28
|
+
* Every delegated mailbox on this account. An absent or unparseable file
|
|
29
|
+
* reads as empty: a delegated record carries no credential, so a corrupt one
|
|
30
|
+
* costs the operator a re-add, and refusing to list the readable mailboxes
|
|
31
|
+
* beside it would be the larger failure. An entry missing either field is
|
|
32
|
+
* dropped rather than surfaced half-formed, since a record without a
|
|
33
|
+
* delegator cannot address anything.
|
|
34
|
+
*/
|
|
35
|
+
read(): DelegatedMap;
|
|
36
|
+
add(address: string, viaMailboxKey: string, nowMs: number): void;
|
|
37
|
+
/** True when an entry was removed, false when there was nothing to remove. */
|
|
38
|
+
remove(address: string): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Read, change, write under an exclusive lock.
|
|
41
|
+
*
|
|
42
|
+
* Each write is atomic on its own, but add and remove are read-modify-write,
|
|
43
|
+
* so two processes attaching different mailboxes at the same moment would
|
|
44
|
+
* each write a map built from the state before the other's write and one
|
|
45
|
+
* record would be lost while both reported success. The MCP server runs one
|
|
46
|
+
* process per spawn and an account can hold several at once, so this is
|
|
47
|
+
* reachable. The lock is a directory, whose creation is atomic on every
|
|
48
|
+
* filesystem this runs on, and a holder older than the timeout is stolen so a
|
|
49
|
+
* process killed mid-write cannot wedge the account permanently.
|
|
50
|
+
*/
|
|
51
|
+
private mutate;
|
|
52
|
+
/** Atomic: temp plus rename, so a reader sees either the old map or the new
|
|
53
|
+
* one and never a partial write. The temp name carries this writer's pid, so
|
|
54
|
+
* two processes on one account never share a temp path. */
|
|
55
|
+
private write;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=delegated-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delegated-store.d.ts","sourceRoot":"","sources":["../../src/auth/delegated-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AA6BH,MAAM,WAAW,cAAc;IAC7B,iFAAiF;IACjF,aAAa,EAAE,MAAM,CAAC;IACtB,gFAAgF;IAChF,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;AAE1D,sDAAsD;AACtD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,qBAAa,cAAc;aAKP,SAAS,EAAE,MAAM;IAJnC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;gBAGhB,SAAS,EAAE,MAAM,EACjC,WAAW,EAAE,MAAM;IAMrB;;;;;;;OAOG;IACH,IAAI,IAAI,YAAY;IAiBpB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAOhE,8EAA8E;IAC9E,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAShC;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,MAAM;IA0Cd;;+DAE2D;IAC3D,OAAO,CAAC,KAAK;CAed"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-account registry of DELEGATED mailboxes — shared mailboxes the signed-in
|
|
3
|
+
* user can reach through Exchange Full Access.
|
|
4
|
+
*
|
|
5
|
+
* A delegated mailbox never signs in, so it has no tokens of its own and cannot
|
|
6
|
+
* live in `mailboxes/<graphUserId>/tokens.enc` like a registered mailbox does.
|
|
7
|
+
* What is stored is a pointer: the shared address, and the mailbox key of the
|
|
8
|
+
* signed-in mailbox whose tokens address it. Holding no secret, this file is
|
|
9
|
+
* plain JSON rather than an encrypted blob, but it sits under the same 0700
|
|
10
|
+
* secrets directory and is written 0600 so its permissions never widen the
|
|
11
|
+
* directory's.
|
|
12
|
+
*/
|
|
13
|
+
import { existsSync, mkdirSync, readFileSync, renameSync, rmSync, statSync, unlinkSync, writeFileSync, } from "node:fs";
|
|
14
|
+
import { randomBytes } from "node:crypto";
|
|
15
|
+
import { join } from "node:path";
|
|
16
|
+
/** How long a writer waits for a peer's lock before refusing. Bounded because
|
|
17
|
+
* the caller is a live tool call, not a background job. */
|
|
18
|
+
const DELEGATED_LOCK_WAIT_MS = 5_000;
|
|
19
|
+
const DELEGATED_LOCK_POLL_MS = 25;
|
|
20
|
+
/** A lock older than this belonged to a process that died mid-write. Well
|
|
21
|
+
* inside the wait budget, so stealing one still leaves time to finish. */
|
|
22
|
+
const DELEGATED_LOCK_STALE_MS = 10_000;
|
|
23
|
+
/** Block this process briefly. The mutation is a few file operations long, so
|
|
24
|
+
* an async lock would buy nothing and would make every caller async. */
|
|
25
|
+
function sleepSync(ms) {
|
|
26
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
27
|
+
}
|
|
28
|
+
/** The one address form used as a key, everywhere. */
|
|
29
|
+
export function normalizeAddress(address) {
|
|
30
|
+
return address.trim().toLowerCase();
|
|
31
|
+
}
|
|
32
|
+
export class DelegatedStore {
|
|
33
|
+
accountId;
|
|
34
|
+
secretsDir;
|
|
35
|
+
filePath;
|
|
36
|
+
constructor(accountId, accountsDir) {
|
|
37
|
+
this.accountId = accountId;
|
|
38
|
+
this.secretsDir = join(accountsDir, accountId, "secrets", "outlook");
|
|
39
|
+
this.filePath = join(this.secretsDir, "delegated.json");
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Every delegated mailbox on this account. An absent or unparseable file
|
|
43
|
+
* reads as empty: a delegated record carries no credential, so a corrupt one
|
|
44
|
+
* costs the operator a re-add, and refusing to list the readable mailboxes
|
|
45
|
+
* beside it would be the larger failure. An entry missing either field is
|
|
46
|
+
* dropped rather than surfaced half-formed, since a record without a
|
|
47
|
+
* delegator cannot address anything.
|
|
48
|
+
*/
|
|
49
|
+
read() {
|
|
50
|
+
if (!existsSync(this.filePath))
|
|
51
|
+
return {};
|
|
52
|
+
try {
|
|
53
|
+
const parsed = JSON.parse(readFileSync(this.filePath, "utf8"));
|
|
54
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
55
|
+
return {};
|
|
56
|
+
const out = {};
|
|
57
|
+
for (const [address, entry] of Object.entries(parsed)) {
|
|
58
|
+
const e = entry;
|
|
59
|
+
if (typeof e?.viaMailboxKey !== "string" || typeof e?.addedAt !== "number")
|
|
60
|
+
continue;
|
|
61
|
+
out[normalizeAddress(address)] = { viaMailboxKey: e.viaMailboxKey, addedAt: e.addedAt };
|
|
62
|
+
}
|
|
63
|
+
return out;
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return {};
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
add(address, viaMailboxKey, nowMs) {
|
|
70
|
+
this.mutate((map) => {
|
|
71
|
+
map[normalizeAddress(address)] = { viaMailboxKey, addedAt: nowMs };
|
|
72
|
+
return true;
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
/** True when an entry was removed, false when there was nothing to remove. */
|
|
76
|
+
remove(address) {
|
|
77
|
+
const key = normalizeAddress(address);
|
|
78
|
+
return this.mutate((map) => {
|
|
79
|
+
if (!Object.hasOwn(map, key))
|
|
80
|
+
return false;
|
|
81
|
+
delete map[key];
|
|
82
|
+
return true;
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Read, change, write under an exclusive lock.
|
|
87
|
+
*
|
|
88
|
+
* Each write is atomic on its own, but add and remove are read-modify-write,
|
|
89
|
+
* so two processes attaching different mailboxes at the same moment would
|
|
90
|
+
* each write a map built from the state before the other's write and one
|
|
91
|
+
* record would be lost while both reported success. The MCP server runs one
|
|
92
|
+
* process per spawn and an account can hold several at once, so this is
|
|
93
|
+
* reachable. The lock is a directory, whose creation is atomic on every
|
|
94
|
+
* filesystem this runs on, and a holder older than the timeout is stolen so a
|
|
95
|
+
* process killed mid-write cannot wedge the account permanently.
|
|
96
|
+
*/
|
|
97
|
+
mutate(change) {
|
|
98
|
+
const lockPath = `${this.filePath}.lock`;
|
|
99
|
+
mkdirSync(this.secretsDir, { recursive: true, mode: 0o700 });
|
|
100
|
+
const deadline = Date.now() + DELEGATED_LOCK_WAIT_MS;
|
|
101
|
+
for (;;) {
|
|
102
|
+
try {
|
|
103
|
+
mkdirSync(lockPath);
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
catch (err) {
|
|
107
|
+
if (err.code !== "EEXIST")
|
|
108
|
+
throw err;
|
|
109
|
+
let ageMs = 0;
|
|
110
|
+
try {
|
|
111
|
+
ageMs = Date.now() - statSync(lockPath).mtimeMs;
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
continue; // the holder released it between our attempt and the stat
|
|
115
|
+
}
|
|
116
|
+
if (ageMs > DELEGATED_LOCK_STALE_MS) {
|
|
117
|
+
try {
|
|
118
|
+
rmSync(lockPath, { recursive: true, force: true });
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
// another process stole it first; retry the acquire
|
|
122
|
+
}
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
if (Date.now() > deadline) {
|
|
126
|
+
throw new Error(`Another process is updating this account's shared-mailbox records and did not release within ${DELEGATED_LOCK_WAIT_MS} ms. Retry.`);
|
|
127
|
+
}
|
|
128
|
+
sleepSync(DELEGATED_LOCK_POLL_MS);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
try {
|
|
132
|
+
const map = this.read();
|
|
133
|
+
const changed = change(map);
|
|
134
|
+
if (changed)
|
|
135
|
+
this.write(map);
|
|
136
|
+
return changed;
|
|
137
|
+
}
|
|
138
|
+
finally {
|
|
139
|
+
rmSync(lockPath, { recursive: true, force: true });
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/** Atomic: temp plus rename, so a reader sees either the old map or the new
|
|
143
|
+
* one and never a partial write. The temp name carries this writer's pid, so
|
|
144
|
+
* two processes on one account never share a temp path. */
|
|
145
|
+
write(map) {
|
|
146
|
+
mkdirSync(this.secretsDir, { recursive: true, mode: 0o700 });
|
|
147
|
+
const temp = `${this.filePath}.${process.pid}.${randomBytes(6).toString("hex")}.tmp`;
|
|
148
|
+
writeFileSync(temp, `${JSON.stringify(map, null, 2)}\n`, { mode: 0o600 });
|
|
149
|
+
try {
|
|
150
|
+
renameSync(temp, this.filePath);
|
|
151
|
+
}
|
|
152
|
+
catch (err) {
|
|
153
|
+
try {
|
|
154
|
+
unlinkSync(temp);
|
|
155
|
+
}
|
|
156
|
+
catch {
|
|
157
|
+
// the temp is already gone; nothing to clean up
|
|
158
|
+
}
|
|
159
|
+
throw err;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=delegated-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delegated-store.js","sourceRoot":"","sources":["../../src/auth/delegated-store.ts"],"names":[],"mappings":"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"}
|