@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
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import test from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { mkdtempSync, rmSync, statSync, writeFileSync, mkdirSync, utimesSync } from "node:fs";
|
|
4
|
+
import { tmpdir } from "node:os";
|
|
5
|
+
import { dirname, join } from "node:path";
|
|
6
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
7
|
+
import { spawn } from "node:child_process";
|
|
8
|
+
import { DelegatedStore, normalizeAddress } from "../auth/delegated-store.js";
|
|
9
|
+
function makeAccountsDir() {
|
|
10
|
+
const dir = mkdtempSync(join(tmpdir(), "outlook-delegated-"));
|
|
11
|
+
return { dir, cleanup: () => rmSync(dir, { recursive: true, force: true }) };
|
|
12
|
+
}
|
|
13
|
+
test("an absent file reads as an empty map", () => {
|
|
14
|
+
const { dir, cleanup } = makeAccountsDir();
|
|
15
|
+
try {
|
|
16
|
+
assert.deepEqual(new DelegatedStore("acct-A", dir).read(), {});
|
|
17
|
+
}
|
|
18
|
+
finally {
|
|
19
|
+
cleanup();
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
test("add then read round-trips, keyed by the lowercased address", () => {
|
|
23
|
+
const { dir, cleanup } = makeAccountsDir();
|
|
24
|
+
try {
|
|
25
|
+
const store = new DelegatedStore("acct-A", dir);
|
|
26
|
+
store.add("Team@Muvin.co.uk", "user-1", 1753724400000);
|
|
27
|
+
assert.deepEqual(store.read(), {
|
|
28
|
+
"team@muvin.co.uk": { viaMailboxKey: "user-1", addedAt: 1753724400000 },
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
finally {
|
|
32
|
+
cleanup();
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
test("the file is 0600 and its directory 0700", () => {
|
|
36
|
+
const { dir, cleanup } = makeAccountsDir();
|
|
37
|
+
try {
|
|
38
|
+
const store = new DelegatedStore("acct-A", dir);
|
|
39
|
+
store.add("team@muvin.co.uk", "user-1", 1);
|
|
40
|
+
const filePath = join(dir, "acct-A", "secrets", "outlook", "delegated.json");
|
|
41
|
+
assert.equal(statSync(filePath).mode & 0o777, 0o600);
|
|
42
|
+
assert.equal(statSync(join(dir, "acct-A", "secrets", "outlook")).mode & 0o777, 0o700);
|
|
43
|
+
}
|
|
44
|
+
finally {
|
|
45
|
+
cleanup();
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
test("remove returns true once and false thereafter", () => {
|
|
49
|
+
const { dir, cleanup } = makeAccountsDir();
|
|
50
|
+
try {
|
|
51
|
+
const store = new DelegatedStore("acct-A", dir);
|
|
52
|
+
store.add("team@muvin.co.uk", "user-1", 1);
|
|
53
|
+
assert.equal(store.remove("TEAM@muvin.co.uk"), true);
|
|
54
|
+
assert.equal(store.remove("team@muvin.co.uk"), false);
|
|
55
|
+
assert.deepEqual(store.read(), {});
|
|
56
|
+
}
|
|
57
|
+
finally {
|
|
58
|
+
cleanup();
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
test("a second address coexists with the first", () => {
|
|
62
|
+
const { dir, cleanup } = makeAccountsDir();
|
|
63
|
+
try {
|
|
64
|
+
const store = new DelegatedStore("acct-A", dir);
|
|
65
|
+
store.add("team@muvin.co.uk", "user-1", 1);
|
|
66
|
+
store.add("info@muvin.co.uk", "user-1", 2);
|
|
67
|
+
assert.deepEqual(Object.keys(store.read()).sort(), ["info@muvin.co.uk", "team@muvin.co.uk"]);
|
|
68
|
+
}
|
|
69
|
+
finally {
|
|
70
|
+
cleanup();
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
test("a corrupt file reads as empty rather than throwing", () => {
|
|
74
|
+
const { dir, cleanup } = makeAccountsDir();
|
|
75
|
+
try {
|
|
76
|
+
const secrets = join(dir, "acct-A", "secrets", "outlook");
|
|
77
|
+
mkdirSync(secrets, { recursive: true, mode: 0o700 });
|
|
78
|
+
writeFileSync(join(secrets, "delegated.json"), "{not json", { mode: 0o600 });
|
|
79
|
+
assert.deepEqual(new DelegatedStore("acct-A", dir).read(), {});
|
|
80
|
+
}
|
|
81
|
+
finally {
|
|
82
|
+
cleanup();
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
test("an entry missing its fields is dropped rather than surfaced half-formed", () => {
|
|
86
|
+
const { dir, cleanup } = makeAccountsDir();
|
|
87
|
+
try {
|
|
88
|
+
const secrets = join(dir, "acct-A", "secrets", "outlook");
|
|
89
|
+
mkdirSync(secrets, { recursive: true, mode: 0o700 });
|
|
90
|
+
writeFileSync(join(secrets, "delegated.json"), JSON.stringify({
|
|
91
|
+
"good@muvin.co.uk": { viaMailboxKey: "user-1", addedAt: 1 },
|
|
92
|
+
"bad@muvin.co.uk": { viaMailboxKey: "user-1" },
|
|
93
|
+
}), { mode: 0o600 });
|
|
94
|
+
assert.deepEqual(Object.keys(new DelegatedStore("acct-A", dir).read()), ["good@muvin.co.uk"]);
|
|
95
|
+
}
|
|
96
|
+
finally {
|
|
97
|
+
cleanup();
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
test("concurrent writers from separate processes both survive", async () => {
|
|
101
|
+
// add/remove are read-modify-write. Without a lock, two processes attaching
|
|
102
|
+
// different mailboxes at the same moment each write a map built from the
|
|
103
|
+
// state before the other's write, and one record is lost while both report
|
|
104
|
+
// success. Separate processes are the real case: one MCP spawn per session,
|
|
105
|
+
// several per account.
|
|
106
|
+
const { dir, cleanup } = makeAccountsDir();
|
|
107
|
+
try {
|
|
108
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
109
|
+
const storeUrl = pathToFileURL(join(here, "../auth/delegated-store.js")).href;
|
|
110
|
+
const child = (address) => new Promise((resolve, reject) => {
|
|
111
|
+
const p = spawn(process.execPath, [
|
|
112
|
+
"--input-type=module",
|
|
113
|
+
"-e",
|
|
114
|
+
`import { DelegatedStore } from ${JSON.stringify(storeUrl)};
|
|
115
|
+
new DelegatedStore("acct-A", ${JSON.stringify(dir)}).add(${JSON.stringify(address)}, "user-1", 1);`,
|
|
116
|
+
], { stdio: "ignore" });
|
|
117
|
+
p.on("exit", (code) => (code === 0 ? resolve() : reject(new Error(`exit ${code}`))));
|
|
118
|
+
p.on("error", reject);
|
|
119
|
+
});
|
|
120
|
+
await Promise.all([child("a@muvin.co.uk"), child("b@muvin.co.uk"), child("c@muvin.co.uk")]);
|
|
121
|
+
assert.deepEqual(Object.keys(new DelegatedStore("acct-A", dir).read()).sort(), [
|
|
122
|
+
"a@muvin.co.uk",
|
|
123
|
+
"b@muvin.co.uk",
|
|
124
|
+
"c@muvin.co.uk",
|
|
125
|
+
]);
|
|
126
|
+
}
|
|
127
|
+
finally {
|
|
128
|
+
cleanup();
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
test("a stale lock left by a dead process is stolen rather than wedging the account", () => {
|
|
132
|
+
const { dir, cleanup } = makeAccountsDir();
|
|
133
|
+
try {
|
|
134
|
+
const store = new DelegatedStore("acct-A", dir);
|
|
135
|
+
store.add("first@muvin.co.uk", "user-1", 1);
|
|
136
|
+
const lockPath = join(dir, "acct-A", "secrets", "outlook", "delegated.json.lock");
|
|
137
|
+
mkdirSync(lockPath);
|
|
138
|
+
// Backdate it well past the stale threshold, as a killed holder would look.
|
|
139
|
+
const old = new Date(Date.now() - 60_000);
|
|
140
|
+
utimesSync(lockPath, old, old);
|
|
141
|
+
store.add("second@muvin.co.uk", "user-1", 2);
|
|
142
|
+
assert.deepEqual(Object.keys(store.read()).sort(), ["first@muvin.co.uk", "second@muvin.co.uk"]);
|
|
143
|
+
}
|
|
144
|
+
finally {
|
|
145
|
+
cleanup();
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
test("normalizeAddress lowercases and trims", () => {
|
|
149
|
+
assert.equal(normalizeAddress(" Team@Muvin.co.uk "), "team@muvin.co.uk");
|
|
150
|
+
});
|
|
151
|
+
//# sourceMappingURL=delegated-store.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delegated-store.test.js","sourceRoot":"","sources":["../../src/__tests__/delegated-store.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -52,8 +52,9 @@ test("startDeviceCode uses verification_uri_complete when the endpoint provides
|
|
|
52
52
|
m.restore();
|
|
53
53
|
}
|
|
54
54
|
});
|
|
55
|
-
test("startDeviceCode requests the full read+send scope set", () => {
|
|
56
|
-
assert.deepEqual([..._internals.SCOPES].sort(), ["Calendars.ReadWrite", "Contacts.Read", "Mail.ReadWrite", "Mail.
|
|
55
|
+
test("startDeviceCode requests the full read+send+shared scope set", () => {
|
|
56
|
+
assert.deepEqual([..._internals.SCOPES].sort(), ["Calendars.ReadWrite", "Contacts.Read", "Mail.ReadWrite", "Mail.ReadWrite.Shared",
|
|
57
|
+
"Mail.Send", "Mail.Send.Shared", "User.Read", "offline_access"].sort());
|
|
57
58
|
});
|
|
58
59
|
test("pollDeviceToken maps authorization_pending -> pending", async () => {
|
|
59
60
|
const m = mockFetch(() => json({ error: "authorization_pending" }, 400));
|
|
@@ -140,6 +141,39 @@ test("regression: device-flow.ts binds no HTTP server", () => {
|
|
|
140
141
|
assert.ok(!/createServer/.test(src), "must not import/use createServer");
|
|
141
142
|
assert.ok(!/\.listen\(/.test(src), "must not bind a listener");
|
|
142
143
|
});
|
|
144
|
+
test("refreshAccessToken sends the mailbox's GRANTED scopes, never the current constant", async () => {
|
|
145
|
+
// Task 2122 widened SCOPES with the two `.Shared` entries. A mailbox that
|
|
146
|
+
// consented before that must not be made to re-consent on a routine refresh:
|
|
147
|
+
// Azure answering `invalid_grant` is treated as a revoked grant, which clears
|
|
148
|
+
// the mailbox's credentials. So the refresh asks for what was granted.
|
|
149
|
+
const m = mockFetch(() => json({ access_token: "AT", refresh_token: "RT", expires_in: 3600 }));
|
|
150
|
+
try {
|
|
151
|
+
await refreshAccessToken({
|
|
152
|
+
clientId: "c",
|
|
153
|
+
tenantId: "t",
|
|
154
|
+
refreshToken: "r",
|
|
155
|
+
grantedScopes: ["offline_access", "Mail.ReadWrite"],
|
|
156
|
+
});
|
|
157
|
+
const body = new URLSearchParams(m.calls[0].body);
|
|
158
|
+
assert.equal(body.get("scope"), "offline_access Mail.ReadWrite");
|
|
159
|
+
assert.ok(!body.get("scope").includes("Shared"), "must not request unconsented scopes");
|
|
160
|
+
}
|
|
161
|
+
finally {
|
|
162
|
+
m.restore();
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
test("refreshAccessToken omits scope entirely when the blob records none", async () => {
|
|
166
|
+
// An empty list means "return the original grant unchanged"; sending an empty
|
|
167
|
+
// scope string instead would be a request for no scopes at all.
|
|
168
|
+
const m = mockFetch(() => json({ access_token: "AT", refresh_token: "RT", expires_in: 3600 }));
|
|
169
|
+
try {
|
|
170
|
+
await refreshAccessToken({ clientId: "c", tenantId: "t", refreshToken: "r", grantedScopes: [] });
|
|
171
|
+
assert.equal(new URLSearchParams(m.calls[0].body).has("scope"), false);
|
|
172
|
+
}
|
|
173
|
+
finally {
|
|
174
|
+
m.restore();
|
|
175
|
+
}
|
|
176
|
+
});
|
|
143
177
|
test("refreshAccessToken carries the parsed Azure error as structured state", async () => {
|
|
144
178
|
const { restore } = mockFetch(() => new Response(JSON.stringify({
|
|
145
179
|
error: "invalid_grant",
|
|
@@ -149,7 +183,7 @@ test("refreshAccessToken carries the parsed Azure error as structured state", as
|
|
|
149
183
|
correlation_id: "corr-1",
|
|
150
184
|
}), { status: 400 }));
|
|
151
185
|
try {
|
|
152
|
-
await assert.rejects(() => refreshAccessToken({ clientId: "c", tenantId: "t", refreshToken: "r" }), (err) => {
|
|
186
|
+
await assert.rejects(() => refreshAccessToken({ clientId: "c", tenantId: "t", refreshToken: "r", grantedScopes: [] }), (err) => {
|
|
153
187
|
const e = err;
|
|
154
188
|
assert.equal(e.name, "TokenRefreshError");
|
|
155
189
|
assert.equal(e.oauthError, "invalid_grant");
|
|
@@ -168,7 +202,7 @@ test("refreshAccessToken carries the parsed Azure error as structured state", as
|
|
|
168
202
|
test("refreshAccessToken leaves oauthError null on a non-JSON body", async () => {
|
|
169
203
|
const { restore } = mockFetch(() => new Response("<html>upstream exploded</html>", { status: 503 }));
|
|
170
204
|
try {
|
|
171
|
-
await assert.rejects(() => refreshAccessToken({ clientId: "c", tenantId: "t", refreshToken: "r" }), (err) => {
|
|
205
|
+
await assert.rejects(() => refreshAccessToken({ clientId: "c", tenantId: "t", refreshToken: "r", grantedScopes: [] }), (err) => {
|
|
172
206
|
const e = err;
|
|
173
207
|
assert.equal(e.oauthError, null, "a gateway 5xx carries no OAuth error code");
|
|
174
208
|
assert.equal(e.statusCode, 503);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"device-flow.test.js","sourceRoot":"","sources":["../../src/__tests__/device-flow.test.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"device-flow.test.js","sourceRoot":"","sources":["../../src/__tests__/device-flow.test.ts"],"names":[],"mappings":"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"}
|
package/payload/platform/plugins/outlook/mcp/dist/__tests__/graph-client-prefix-wiring.test.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph-client-prefix-wiring.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/graph-client-prefix-wiring.test.ts"],"names":[],"mappings":""}
|
package/payload/platform/plugins/outlook/mcp/dist/__tests__/graph-client-prefix-wiring.test.js
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
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 { createGraphClient, sharedMailboxPrefix } from "../lib/graph-client.js";
|
|
7
|
+
import { TokenStore } from "../auth/token-store.js";
|
|
8
|
+
/**
|
|
9
|
+
* The prefix helper being correct is not the same claim as the factory using
|
|
10
|
+
* it. These assert the URL the SDK actually REQUESTS, by capturing the fetch,
|
|
11
|
+
* which is the only place the wiring is observable end to end without a
|
|
12
|
+
* network — and the only claim that matters, since every tool's path runs
|
|
13
|
+
* through this one factory.
|
|
14
|
+
*/
|
|
15
|
+
function clientFor(prefix) {
|
|
16
|
+
const dir = mkdtempSync(join(tmpdir(), "outlook-prefix-wiring-"));
|
|
17
|
+
const store = new TokenStore("acct-A", dir, "user-1");
|
|
18
|
+
store.store("access", "refresh", 3600, {
|
|
19
|
+
graphUserId: "user-1",
|
|
20
|
+
mail: "admin@muvin.co.uk",
|
|
21
|
+
scopes: [],
|
|
22
|
+
});
|
|
23
|
+
return {
|
|
24
|
+
client: createGraphClient({
|
|
25
|
+
clientId: "c",
|
|
26
|
+
tenantId: "common",
|
|
27
|
+
accountId: "acct-A",
|
|
28
|
+
tokenStore: store,
|
|
29
|
+
mailboxPathPrefix: prefix,
|
|
30
|
+
}),
|
|
31
|
+
cleanup: () => rmSync(dir, { recursive: true, force: true }),
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/** Capture the URL the SDK requests, answering with an empty collection. */
|
|
35
|
+
function captureFetch() {
|
|
36
|
+
const urls = [];
|
|
37
|
+
const original = globalThis.fetch;
|
|
38
|
+
globalThis.fetch = (async (input) => {
|
|
39
|
+
urls.push(typeof input === "string" ? input : String(input?.url ?? input));
|
|
40
|
+
return new Response(JSON.stringify({ value: [] }), {
|
|
41
|
+
status: 200,
|
|
42
|
+
headers: { "content-type": "application/json" },
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
return { urls, restore: () => { globalThis.fetch = original; } };
|
|
46
|
+
}
|
|
47
|
+
test("a request on the signed-in mailbox is sent to /me", async () => {
|
|
48
|
+
const { client, cleanup } = clientFor(undefined);
|
|
49
|
+
const { urls, restore } = captureFetch();
|
|
50
|
+
try {
|
|
51
|
+
await client.api("/me/mailFolders/Inbox/messages").top(3).get();
|
|
52
|
+
assert.equal(urls.length, 1);
|
|
53
|
+
assert.equal(urls[0], "https://graph.microsoft.com/v1.0/me/mailFolders/Inbox/messages?$top=3");
|
|
54
|
+
}
|
|
55
|
+
finally {
|
|
56
|
+
restore();
|
|
57
|
+
cleanup();
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
test("a request on a delegated mailbox is sent to /users/<address>", async () => {
|
|
61
|
+
const { client, cleanup } = clientFor(sharedMailboxPrefix("team@muvin.co.uk"));
|
|
62
|
+
const { urls, restore } = captureFetch();
|
|
63
|
+
try {
|
|
64
|
+
await client.api("/me/mailFolders/Inbox/messages").top(3).get();
|
|
65
|
+
assert.equal(urls.length, 1);
|
|
66
|
+
assert.equal(urls[0], "https://graph.microsoft.com/v1.0/users/team%40muvin.co.uk/mailFolders/Inbox/messages?$top=3");
|
|
67
|
+
}
|
|
68
|
+
finally {
|
|
69
|
+
restore();
|
|
70
|
+
cleanup();
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
test("a delegated cursor replayed on the signed-in mailbox is refused", async () => {
|
|
74
|
+
// Reproduced before the guard existed: page 1 of team@ returns a nextLink
|
|
75
|
+
// rooted at /users/team%40…; replaying it with `mailbox` omitted resolved the
|
|
76
|
+
// operator's own mailbox, and the shared mailbox's page 2 was returned while
|
|
77
|
+
// cred-resolve logged kind=signed-in. Correct data, lying log, and the same
|
|
78
|
+
// mechanism serves the wrong mailbox in the other direction.
|
|
79
|
+
const { client, cleanup } = clientFor(undefined);
|
|
80
|
+
const { urls, restore } = captureFetch();
|
|
81
|
+
try {
|
|
82
|
+
assert.throws(() => client.api("https://graph.microsoft.com/v1.0/users/team%40muvin.co.uk/mailFolders/Inbox/messages?$skiptoken=ABC"), /belongs to a different mailbox/);
|
|
83
|
+
assert.equal(urls.length, 0, "nothing may be requested once the cursor is refused");
|
|
84
|
+
}
|
|
85
|
+
finally {
|
|
86
|
+
restore();
|
|
87
|
+
cleanup();
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
test("an own-mailbox cursor replayed on a delegated mailbox is refused", async () => {
|
|
91
|
+
// The wrong-data direction: the caller asks for team@ and would receive the
|
|
92
|
+
// operator's OWN inbox as team@'s page 2, silently.
|
|
93
|
+
const { client, cleanup } = clientFor(sharedMailboxPrefix("team@muvin.co.uk"));
|
|
94
|
+
const { urls, restore } = captureFetch();
|
|
95
|
+
try {
|
|
96
|
+
assert.throws(() => client.api("https://graph.microsoft.com/v1.0/me/mailFolders/Inbox/messages?$skiptoken=XYZ"), /belongs to a different mailbox/);
|
|
97
|
+
assert.equal(urls.length, 0);
|
|
98
|
+
}
|
|
99
|
+
finally {
|
|
100
|
+
restore();
|
|
101
|
+
cleanup();
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
test("a cursor from a different shared mailbox is refused", async () => {
|
|
105
|
+
const { client, cleanup } = clientFor(sharedMailboxPrefix("team@muvin.co.uk"));
|
|
106
|
+
const { urls, restore } = captureFetch();
|
|
107
|
+
try {
|
|
108
|
+
assert.throws(() => client.api("https://graph.microsoft.com/v1.0/users/info%40muvin.co.uk/mailFolders/Inbox/messages?$skiptoken=Q"), /belongs to a different mailbox/);
|
|
109
|
+
assert.equal(urls.length, 0);
|
|
110
|
+
}
|
|
111
|
+
finally {
|
|
112
|
+
restore();
|
|
113
|
+
cleanup();
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
test("an own-mailbox cursor on the signed-in mailbox still pages", async () => {
|
|
117
|
+
const { client, cleanup } = clientFor(undefined);
|
|
118
|
+
const { urls, restore } = captureFetch();
|
|
119
|
+
try {
|
|
120
|
+
const cursor = "https://graph.microsoft.com/v1.0/me/mailFolders/Inbox/messages?$skiptoken=XYZ";
|
|
121
|
+
await client.api(cursor).get();
|
|
122
|
+
assert.deepEqual(urls, [cursor]);
|
|
123
|
+
}
|
|
124
|
+
finally {
|
|
125
|
+
restore();
|
|
126
|
+
cleanup();
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
test("an absolute nextLink cursor is sent unchanged under a delegated prefix", async () => {
|
|
130
|
+
const { client, cleanup } = clientFor(sharedMailboxPrefix("team@muvin.co.uk"));
|
|
131
|
+
const { urls, restore } = captureFetch();
|
|
132
|
+
try {
|
|
133
|
+
// callGraphPaged feeds the server's @odata.nextLink straight back into
|
|
134
|
+
// client.api(). It already carries its own root, so rewriting it would
|
|
135
|
+
// corrupt the cursor and silently restart or misdirect the paging.
|
|
136
|
+
const cursor = "https://graph.microsoft.com/v1.0/users/team%40muvin.co.uk/mailFolders/Inbox/messages?$skiptoken=ABC";
|
|
137
|
+
await client.api(cursor).get();
|
|
138
|
+
assert.equal(urls.length, 1);
|
|
139
|
+
assert.equal(urls[0], cursor);
|
|
140
|
+
}
|
|
141
|
+
finally {
|
|
142
|
+
restore();
|
|
143
|
+
cleanup();
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
//# sourceMappingURL=graph-client-prefix-wiring.test.js.map
|
package/payload/platform/plugins/outlook/mcp/dist/__tests__/graph-client-prefix-wiring.test.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph-client-prefix-wiring.test.js","sourceRoot":"","sources":["../../src/__tests__/graph-client-prefix-wiring.test.ts"],"names":[],"mappings":"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"}
|
package/payload/platform/plugins/outlook/mcp/dist/__tests__/mailbox-list-delegated.test.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mailbox-list-delegated.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/mailbox-list-delegated.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,120 @@
|
|
|
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 { runMailboxList } from "../tools/mailbox-list.js";
|
|
7
|
+
import { DelegatedStore } from "../auth/delegated-store.js";
|
|
8
|
+
import { TokenStore } from "../auth/token-store.js";
|
|
9
|
+
function makeAccountsDir() {
|
|
10
|
+
const dir = mkdtempSync(join(tmpdir(), "outlook-list-delegated-"));
|
|
11
|
+
return { dir, cleanup: () => rmSync(dir, { recursive: true, force: true }) };
|
|
12
|
+
}
|
|
13
|
+
function connect(dir) {
|
|
14
|
+
new TokenStore("acct-A", dir, "user-1").store("access", "refresh", 3600, {
|
|
15
|
+
graphUserId: "user-1",
|
|
16
|
+
mail: "admin@muvin.co.uk",
|
|
17
|
+
scopes: ["Mail.ReadWrite.Shared"],
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
test("a delegated entry is listed with its kind and delegator", async () => {
|
|
21
|
+
const { dir, cleanup } = makeAccountsDir();
|
|
22
|
+
try {
|
|
23
|
+
connect(dir);
|
|
24
|
+
new DelegatedStore("acct-A", dir).add("team@muvin.co.uk", "user-1", 1);
|
|
25
|
+
const result = await runMailboxList("acct-A", dir);
|
|
26
|
+
assert.equal(result.count, 2);
|
|
27
|
+
assert.equal(result.delegated, 1);
|
|
28
|
+
assert.equal(result.addressable, 1, "a delegated entry is not a signed-in mailbox");
|
|
29
|
+
const shared = result.mailboxes.find((m) => m.mailbox === "team@muvin.co.uk");
|
|
30
|
+
assert.ok(shared);
|
|
31
|
+
assert.equal(shared.kind, "delegated");
|
|
32
|
+
assert.equal(shared.via, "admin@muvin.co.uk");
|
|
33
|
+
assert.equal(shared.status, "delegated");
|
|
34
|
+
assert.equal(shared.reachable, null);
|
|
35
|
+
const own = result.mailboxes.find((m) => m.mailbox === "admin@muvin.co.uk");
|
|
36
|
+
assert.equal(own.kind, "signed-in");
|
|
37
|
+
assert.equal(own.via, null);
|
|
38
|
+
}
|
|
39
|
+
finally {
|
|
40
|
+
cleanup();
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
test("verify probes each delegated entry and reports reachability", async () => {
|
|
44
|
+
const { dir, cleanup } = makeAccountsDir();
|
|
45
|
+
try {
|
|
46
|
+
connect(dir);
|
|
47
|
+
new DelegatedStore("acct-A", dir).add("team@muvin.co.uk", "user-1", 1);
|
|
48
|
+
const seen = [];
|
|
49
|
+
const result = await runMailboxList("acct-A", dir, {
|
|
50
|
+
verify: true,
|
|
51
|
+
probe: async (address) => {
|
|
52
|
+
seen.push(address);
|
|
53
|
+
return false;
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
assert.deepEqual(seen, ["team@muvin.co.uk"]);
|
|
57
|
+
assert.equal(result.mailboxes.find((m) => m.mailbox === "team@muvin.co.uk").reachable, false);
|
|
58
|
+
assert.equal(result.mailboxes.find((m) => m.mailbox === "admin@muvin.co.uk").reachable, null, "a signed-in mailbox is never probed by this flag");
|
|
59
|
+
}
|
|
60
|
+
finally {
|
|
61
|
+
cleanup();
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
test("without verify, nothing is probed", async () => {
|
|
65
|
+
const { dir, cleanup } = makeAccountsDir();
|
|
66
|
+
try {
|
|
67
|
+
connect(dir);
|
|
68
|
+
new DelegatedStore("acct-A", dir).add("team@muvin.co.uk", "user-1", 1);
|
|
69
|
+
let probed = 0;
|
|
70
|
+
await runMailboxList("acct-A", dir, {
|
|
71
|
+
probe: async () => {
|
|
72
|
+
probed += 1;
|
|
73
|
+
return true;
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
assert.equal(probed, 0);
|
|
77
|
+
}
|
|
78
|
+
finally {
|
|
79
|
+
cleanup();
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
test("a delegated entry whose delegator is gone is listed as delegator-missing", async () => {
|
|
83
|
+
const { dir, cleanup } = makeAccountsDir();
|
|
84
|
+
try {
|
|
85
|
+
connect(dir);
|
|
86
|
+
new DelegatedStore("acct-A", dir).add("team@muvin.co.uk", "user-gone", 1);
|
|
87
|
+
let probed = 0;
|
|
88
|
+
const result = await runMailboxList("acct-A", dir, {
|
|
89
|
+
verify: true,
|
|
90
|
+
probe: async () => {
|
|
91
|
+
probed += 1;
|
|
92
|
+
return true;
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
const shared = result.mailboxes.find((m) => m.mailbox === "team@muvin.co.uk");
|
|
96
|
+
assert.equal(shared.status, "delegator-missing");
|
|
97
|
+
assert.equal(shared.via, "user-gone");
|
|
98
|
+
assert.equal(shared.readable, false);
|
|
99
|
+
assert.equal(probed, 0, "there is no token to probe with");
|
|
100
|
+
}
|
|
101
|
+
finally {
|
|
102
|
+
cleanup();
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
test("an account with no delegated entries reports the same shape as before", async () => {
|
|
106
|
+
const { dir, cleanup } = makeAccountsDir();
|
|
107
|
+
try {
|
|
108
|
+
connect(dir);
|
|
109
|
+
const result = await runMailboxList("acct-A", dir);
|
|
110
|
+
assert.equal(result.count, 1);
|
|
111
|
+
assert.equal(result.delegated, 0);
|
|
112
|
+
assert.equal(result.addressable, 1);
|
|
113
|
+
assert.equal(result.unreadable, 0);
|
|
114
|
+
assert.equal(result.mailboxes[0].kind, "signed-in");
|
|
115
|
+
}
|
|
116
|
+
finally {
|
|
117
|
+
cleanup();
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
//# sourceMappingURL=mailbox-list-delegated.test.js.map
|
package/payload/platform/plugins/outlook/mcp/dist/__tests__/mailbox-list-delegated.test.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mailbox-list-delegated.test.js","sourceRoot":"","sources":["../../src/__tests__/mailbox-list-delegated.test.ts"],"names":[],"mappings":"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"}
|