@rubytech/create-maxy-code 0.1.416 → 0.1.419
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/__tests__/brand-port-uniqueness.test.js +74 -0
- package/dist/__tests__/outlook-client-id-env.test.js +46 -0
- package/dist/index.js +31 -0
- package/dist/known-brands.js +1 -0
- package/dist/port-resolution.js +8 -1
- package/package.json +1 -1
- package/payload/platform/config/brand-registry.json +8 -0
- package/payload/platform/config/brand.json +1 -0
- package/payload/platform/lib/account-enumeration/dist/__tests__/is-provisioned.test.d.ts +2 -0
- package/payload/platform/lib/account-enumeration/dist/__tests__/is-provisioned.test.d.ts.map +1 -0
- package/payload/platform/lib/account-enumeration/dist/__tests__/is-provisioned.test.js +81 -0
- package/payload/platform/lib/account-enumeration/dist/__tests__/is-provisioned.test.js.map +1 -0
- package/payload/platform/lib/account-enumeration/dist/index.d.ts +17 -0
- package/payload/platform/lib/account-enumeration/dist/index.d.ts.map +1 -1
- package/payload/platform/lib/account-enumeration/dist/index.js +46 -9
- package/payload/platform/lib/account-enumeration/dist/index.js.map +1 -1
- package/payload/platform/lib/account-enumeration/src/__tests__/is-provisioned.test.ts +86 -0
- package/payload/platform/lib/account-enumeration/src/index.ts +45 -9
- package/payload/platform/lib/account-scope/dist/index.d.ts +14 -5
- package/payload/platform/lib/account-scope/dist/index.d.ts.map +1 -1
- package/payload/platform/lib/account-scope/dist/index.js +14 -5
- package/payload/platform/lib/account-scope/dist/index.js.map +1 -1
- package/payload/platform/lib/account-scope/src/index.ts +22 -5
- package/payload/platform/lib/active-rules/dist/index.d.ts +35 -0
- package/payload/platform/lib/active-rules/dist/index.d.ts.map +1 -0
- package/payload/platform/lib/active-rules/dist/index.js +94 -0
- package/payload/platform/lib/active-rules/dist/index.js.map +1 -0
- package/payload/platform/lib/active-rules/package.json +7 -0
- package/payload/platform/lib/active-rules/src/index.test.ts +89 -0
- package/payload/platform/lib/active-rules/src/index.ts +133 -0
- package/payload/platform/lib/active-rules/tsconfig.json +9 -0
- package/payload/platform/package.json +4 -3
- package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +55 -10
- package/payload/platform/plugins/docs/references/internals.md +10 -0
- package/payload/platform/plugins/docs/references/memory-guide.md +2 -0
- package/payload/platform/plugins/docs/references/outlook-guide.md +42 -9
- package/payload/platform/plugins/email/references/email-reference.md +1 -1
- package/payload/platform/plugins/filesystem/PLUGIN.md +1 -1
- package/payload/platform/plugins/filesystem/mcp/dist/lib/__tests__/scope.test.js +16 -2
- package/payload/platform/plugins/filesystem/mcp/dist/lib/__tests__/scope.test.js.map +1 -1
- package/payload/platform/plugins/filesystem/mcp/dist/lib/scope.d.ts +1 -1
- package/payload/platform/plugins/filesystem/mcp/dist/lib/scope.d.ts.map +1 -1
- package/payload/platform/plugins/filesystem/mcp/dist/lib/scope.js +8 -3
- package/payload/platform/plugins/filesystem/mcp/dist/lib/scope.js.map +1 -1
- package/payload/platform/plugins/filesystem/mcp/dist/tools/__tests__/handlers.test.js +2 -2
- package/payload/platform/plugins/filesystem/mcp/dist/tools/__tests__/handlers.test.js.map +1 -1
- package/payload/platform/plugins/memory/PLUGIN.md +1 -1
- package/payload/platform/plugins/memory/mcp/dist/index-testable.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/index-testable.js +14 -5
- package/payload/platform/plugins/memory/mcp/dist/index-testable.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/index.js +5 -2
- package/payload/platform/plugins/memory/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/neo4j-constraint.d.ts +29 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/neo4j-constraint.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/neo4j-constraint.js +44 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/neo4j-constraint.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/owner-person-embed-text.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/owner-person-embed-text.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/owner-person-embed-text.test.js +22 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/owner-person-embed-text.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-read-active-rules.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-read-active-rules.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-read-active-rules.test.js +49 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-read-active-rules.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-personfields-bootstrap.test.js +105 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-personfields-bootstrap.test.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-personfields-embed.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-personfields-embed.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-personfields-embed.test.js +78 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-personfields-embed.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-reconcile.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-reconcile.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-reconcile.test.js +99 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-reconcile.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/resolve-tool-account.test.js +2 -2
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/resolve-tool-account.test.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-write.d.ts +0 -5
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-write.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-write.js +2 -12
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-write.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/profile-read.d.ts +3 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/profile-read.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/profile-read.js +11 -3
- package/payload/platform/plugins/memory/mcp/dist/tools/profile-read.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.d.ts +22 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.js +212 -24
- package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.js.map +1 -1
- package/payload/platform/plugins/outlook/.claude-plugin/plugin.json +1 -1
- package/payload/platform/plugins/outlook/PLUGIN.md +40 -7
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/account-register.test.d.ts +2 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/account-register.test.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/account-register.test.js +137 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/account-register.test.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/calendar-write.test.d.ts +2 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/calendar-write.test.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/calendar-write.test.js +210 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/calendar-write.test.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/device-flow.test.d.ts +2 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/device-flow.test.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/device-flow.test.js +110 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/device-flow.test.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/graph-client-retry.test.d.ts +2 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/graph-client-retry.test.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/graph-client-retry.test.js +108 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/graph-client-retry.test.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/graph-client.test.js +13 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/graph-client.test.js.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/message.test.d.ts +2 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/message.test.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/message.test.js +32 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/message.test.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/pending-store.test.d.ts +2 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/pending-store.test.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/pending-store.test.js +67 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/pending-store.test.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/pkce-flow.test.js +7 -5
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/pkce-flow.test.js.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/write-tools.test.d.ts +2 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/write-tools.test.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/write-tools.test.js +141 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/write-tools.test.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/auth/device-flow.d.ts +69 -0
- package/payload/platform/plugins/outlook/mcp/dist/auth/device-flow.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/auth/device-flow.js +129 -0
- package/payload/platform/plugins/outlook/mcp/dist/auth/device-flow.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/auth/pending-store.d.ts +39 -0
- package/payload/platform/plugins/outlook/mcp/dist/auth/pending-store.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/auth/pending-store.js +101 -0
- package/payload/platform/plugins/outlook/mcp/dist/auth/pending-store.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/auth/pkce-flow.d.ts.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/auth/pkce-flow.js +3 -2
- package/payload/platform/plugins/outlook/mcp/dist/auth/pkce-flow.js.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/index.js +187 -5
- package/payload/platform/plugins/outlook/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/lib/graph-client.d.ts +34 -1
- 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 +96 -7
- package/payload/platform/plugins/outlook/mcp/dist/lib/graph-client.js.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/lib/message.d.ts +31 -0
- package/payload/platform/plugins/outlook/mcp/dist/lib/message.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/lib/message.js +30 -0
- package/payload/platform/plugins/outlook/mcp/dist/lib/message.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/account-register.d.ts +41 -17
- package/payload/platform/plugins/outlook/mcp/dist/tools/account-register.d.ts.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/tools/account-register.js +87 -28
- package/payload/platform/plugins/outlook/mcp/dist/tools/account-register.js.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-cancel.d.ts +17 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-cancel.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-cancel.js +38 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-cancel.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-create.d.ts +42 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-create.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-create.js +59 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-create.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-freebusy.d.ts +34 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-freebusy.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-freebusy.js +46 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-freebusy.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-respond.d.ts +15 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-respond.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-respond.js +27 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-respond.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-update.d.ts +11 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-update.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-update.js +20 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-update.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/draft-send.d.ts +17 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/draft-send.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/draft-send.js +26 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/draft-send.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/draft.d.ts +11 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/draft.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/draft.js +26 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/draft.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/mail-send.d.ts +14 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/mail-send.d.ts.map +1 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/mail-send.js +26 -0
- package/payload/platform/plugins/outlook/mcp/dist/tools/mail-send.js.map +1 -0
- package/payload/platform/plugins/outlook/mcp/scripts/verify-doc-impl.sh +2 -2
- package/payload/platform/plugins/outlook/references/auth.md +51 -54
- package/payload/platform/plugins/outlook/references/graph-surfaces.md +97 -4
- package/payload/platform/plugins/outlook/skills/outlook/SKILL.md +34 -9
- package/payload/platform/plugins/whatsapp/mcp/dist/index.js +10 -5
- package/payload/platform/plugins/whatsapp/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/whatsapp/references/channels-whatsapp.md +9 -1
- package/payload/platform/scripts/__tests__/provision-role-stamp.test.sh +3 -0
- package/payload/platform/scripts/lib/provision-account-dir.sh +9 -1
- package/payload/platform/services/claude-session-manager/dist/agent-identity-locator.d.ts +1 -1
- package/payload/platform/services/claude-session-manager/dist/agent-identity-locator.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/agent-identity-locator.js +5 -1
- package/payload/platform/services/claude-session-manager/dist/agent-identity-locator.js.map +1 -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 +9 -0
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/config.d.ts +18 -0
- package/payload/platform/services/claude-session-manager/dist/config.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/config.js +16 -0
- package/payload/platform/services/claude-session-manager/dist/config.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/http-server.d.ts +1 -0
- package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/http-server.js +36 -4
- package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/index.js +14 -0
- package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/preference-reconciliation-audit.d.ts +46 -0
- package/payload/platform/services/claude-session-manager/dist/preference-reconciliation-audit.d.ts.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/preference-reconciliation-audit.js +96 -0
- package/payload/platform/services/claude-session-manager/dist/preference-reconciliation-audit.js.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts +33 -0
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.js +61 -7
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/public-agent-reachability.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/public-agent-reachability.js +5 -1
- package/payload/platform/services/claude-session-manager/dist/public-agent-reachability.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/system-prompt.d.ts +6 -0
- package/payload/platform/services/claude-session-manager/dist/system-prompt.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/system-prompt.js +20 -0
- package/payload/platform/services/claude-session-manager/dist/system-prompt.js.map +1 -1
- package/payload/platform/services/telegram-channel/dist/instructions.d.ts +9 -0
- package/payload/platform/services/telegram-channel/dist/instructions.d.ts.map +1 -0
- package/payload/platform/services/telegram-channel/dist/instructions.js +100 -0
- package/payload/platform/services/telegram-channel/dist/instructions.js.map +1 -0
- package/payload/platform/services/telegram-channel/dist/notification.d.ts +93 -0
- package/payload/platform/services/telegram-channel/dist/notification.d.ts.map +1 -0
- package/payload/platform/services/telegram-channel/dist/notification.js +119 -0
- package/payload/platform/services/telegram-channel/dist/notification.js.map +1 -0
- package/payload/platform/services/telegram-channel/dist/server.d.ts +40 -0
- package/payload/platform/services/telegram-channel/dist/server.d.ts.map +1 -0
- package/payload/platform/services/telegram-channel/dist/server.js +291 -0
- package/payload/platform/services/telegram-channel/dist/server.js.map +1 -0
- package/payload/platform/services/telegram-channel/dist/turn-follow.d.ts +28 -0
- package/payload/platform/services/telegram-channel/dist/turn-follow.d.ts.map +1 -0
- package/payload/platform/services/telegram-channel/dist/turn-follow.js +188 -0
- package/payload/platform/services/telegram-channel/dist/turn-follow.js.map +1 -0
- package/payload/platform/services/webchat-channel/dist/notification.d.ts +5 -0
- package/payload/platform/services/webchat-channel/dist/notification.d.ts.map +1 -1
- package/payload/platform/services/webchat-channel/dist/notification.js +6 -1
- package/payload/platform/services/webchat-channel/dist/notification.js.map +1 -1
- package/payload/platform/services/whatsapp-channel/dist/notification.d.ts +6 -0
- package/payload/platform/services/whatsapp-channel/dist/notification.d.ts.map +1 -1
- package/payload/platform/services/whatsapp-channel/dist/notification.js +8 -1
- package/payload/platform/services/whatsapp-channel/dist/notification.js.map +1 -1
- package/payload/platform/templates/agents/passive/IDENTITY.md +21 -0
- package/payload/platform/templates/specialists/agents/personal-assistant.md +1 -1
- package/payload/server/public/assets/{AdminLoginScreens-CBlE6FB4.js → AdminLoginScreens-B1PkOF66.js} +1 -1
- package/payload/server/public/assets/AdminShell-D8wNArGQ.js +2 -0
- package/payload/server/public/assets/{Checkbox-B0pbYJDQ.js → Checkbox-Bm9Er726.js} +1 -1
- package/payload/server/public/assets/{Transcript-CYaAPBFX.js → Transcript-CBIyQ8T5.js} +1 -1
- package/payload/server/public/assets/{admin-CVh9HO-f.js → admin-CWM9G_yA.js} +1 -1
- package/payload/server/public/assets/{browser-C4f_D4Ih.js → browser-D8QhNffV.js} +1 -1
- package/payload/server/public/assets/{calendar-WUxQ4fVo.js → calendar-qob5K4t_.js} +1 -1
- package/payload/server/public/assets/chat-BNrxVUF6.js +1 -0
- package/payload/server/public/assets/chevron-left-BQThFVrd.js +1 -0
- package/payload/server/public/assets/data-C-EqNbRi.js +1 -0
- package/payload/server/public/assets/{graph-BNXE6mKP.js → graph-DZ2HMpIB.js} +1 -1
- package/payload/server/public/assets/{graph-labels-Csnovm_c.js → graph-labels-BFG4bjXQ.js} +1 -1
- package/payload/server/public/assets/{maximize-2-WRUJsg5n.js → maximize-2-DkZ40lSl.js} +1 -1
- package/payload/server/public/assets/{operator-CXtygMh6.js → operator-FrXrSsBj.js} +1 -1
- package/payload/server/public/assets/page-CHWMI9Tm.js +32 -0
- package/payload/server/public/assets/{page-IQDLdebG.js → page-CXKV01gT.js} +1 -1
- package/payload/server/public/assets/{public-DSeYu61E.js → public-2p1pJ4WF.js} +1 -1
- package/payload/server/public/assets/{rotate-ccw-BayMWwfc.js → rotate-ccw-D3o_bMBA.js} +1 -1
- package/payload/server/public/assets/useSubAccountSwitcher-8dLvF3Ux.js +9 -0
- package/payload/server/public/assets/useSubAccountSwitcher-BUvlETHN.css +1 -0
- package/payload/server/public/browser.html +4 -4
- package/payload/server/public/calendar.html +5 -5
- package/payload/server/public/chat.html +9 -9
- package/payload/server/public/data.html +8 -8
- package/payload/server/public/graph.html +9 -9
- package/payload/server/public/index.html +11 -11
- package/payload/server/public/operator.html +11 -11
- package/payload/server/public/public.html +9 -9
- package/payload/server/server.js +245 -40
- package/payload/server/public/assets/AdminShell-d1WQ3lLu.js +0 -2
- package/payload/server/public/assets/chat-NJ2HXhOf.js +0 -1
- package/payload/server/public/assets/chevron-left-Da-iZGi_.js +0 -1
- package/payload/server/public/assets/data-ZUdT44Ba.js +0 -1
- package/payload/server/public/assets/page-DjpQp_ir.js +0 -32
- package/payload/server/public/assets/useSubAccountSwitcher-C9aLg8yI.js +0 -9
- package/payload/server/public/assets/useSubAccountSwitcher-CRZfyJXR.css +0 -1
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth 2.0 device-code flow for Microsoft Identity Platform.
|
|
3
|
+
*
|
|
4
|
+
* Bespoke to Maxy — this is NOT the nsakki55 loopback authManager. Registration
|
|
5
|
+
* runs headless: `startDeviceCode` asks Microsoft for a user code + verification
|
|
6
|
+
* URL, the operator consents on any device at microsoft.com/devicelogin, and
|
|
7
|
+
* `pollDeviceToken` exchanges the device_code for tokens. No loopback HTTP
|
|
8
|
+
* server, no same-machine constraint.
|
|
9
|
+
*
|
|
10
|
+
* `refreshAccessToken` (used by the read path in graph-client.ts) and the SCOPES
|
|
11
|
+
* set are unchanged from the prior Auth-Code implementation.
|
|
12
|
+
*/
|
|
13
|
+
const SCOPES = [
|
|
14
|
+
"offline_access",
|
|
15
|
+
"User.Read",
|
|
16
|
+
"Mail.ReadWrite",
|
|
17
|
+
"Mail.Send",
|
|
18
|
+
"Calendars.ReadWrite",
|
|
19
|
+
"Contacts.Read",
|
|
20
|
+
];
|
|
21
|
+
function buildUrls(tenantId) {
|
|
22
|
+
const tenant = tenantId || "common";
|
|
23
|
+
return {
|
|
24
|
+
authorizeUrl: `https://login.microsoftonline.com/${tenant}/oauth2/v2.0/authorize`,
|
|
25
|
+
tokenUrl: `https://login.microsoftonline.com/${tenant}/oauth2/v2.0/token`,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Request a device code from `/oauth2/v2.0/devicecode`. Returns the user code
|
|
30
|
+
* and verification URL to relay to the operator, plus the device_code the caller
|
|
31
|
+
* persists for polling. `verificationUriComplete` uses the endpoint's field when
|
|
32
|
+
* present, else Microsoft's documented `?otc=<code>` pre-fill convenience form.
|
|
33
|
+
*/
|
|
34
|
+
export async function startDeviceCode(config) {
|
|
35
|
+
const tenant = config.tenantId || "common";
|
|
36
|
+
const url = `https://login.microsoftonline.com/${tenant}/oauth2/v2.0/devicecode`;
|
|
37
|
+
const params = new URLSearchParams({
|
|
38
|
+
client_id: config.clientId,
|
|
39
|
+
scope: SCOPES.join(" "),
|
|
40
|
+
});
|
|
41
|
+
const response = await fetch(url, {
|
|
42
|
+
method: "POST",
|
|
43
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
44
|
+
body: params.toString(),
|
|
45
|
+
});
|
|
46
|
+
if (!response.ok) {
|
|
47
|
+
const text = await response.text();
|
|
48
|
+
throw new Error(`Device-code request failed (${response.status}): ${text}`);
|
|
49
|
+
}
|
|
50
|
+
const body = (await response.json());
|
|
51
|
+
const verificationUriComplete = body.verification_uri_complete ??
|
|
52
|
+
`${body.verification_uri}?otc=${body.user_code}`;
|
|
53
|
+
return {
|
|
54
|
+
deviceCode: body.device_code,
|
|
55
|
+
userCode: body.user_code,
|
|
56
|
+
verificationUri: body.verification_uri,
|
|
57
|
+
verificationUriComplete,
|
|
58
|
+
expiresInSec: body.expires_in,
|
|
59
|
+
intervalSec: body.interval,
|
|
60
|
+
scopes: [...SCOPES],
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* One device-code token poll against `/oauth2/v2.0/token`. 200 yields tokens;
|
|
65
|
+
* the Microsoft error codes map to the polling states an RFC 8628 client must
|
|
66
|
+
* handle. Any unrecognised error throws.
|
|
67
|
+
*/
|
|
68
|
+
export async function pollDeviceToken(config, deviceCode) {
|
|
69
|
+
const { tokenUrl } = buildUrls(config.tenantId);
|
|
70
|
+
const params = new URLSearchParams({
|
|
71
|
+
client_id: config.clientId,
|
|
72
|
+
grant_type: "urn:ietf:params:oauth:grant-type:device_code",
|
|
73
|
+
device_code: deviceCode,
|
|
74
|
+
});
|
|
75
|
+
const response = await fetch(tokenUrl, {
|
|
76
|
+
method: "POST",
|
|
77
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
78
|
+
body: params.toString(),
|
|
79
|
+
});
|
|
80
|
+
if (response.ok) {
|
|
81
|
+
const tokenResponse = (await response.json());
|
|
82
|
+
const scopes = (tokenResponse.scope ?? SCOPES.join(" ")).split(/\s+/);
|
|
83
|
+
return { kind: "success", tokenResponse, scopes };
|
|
84
|
+
}
|
|
85
|
+
const text = await response.text();
|
|
86
|
+
let errorCode = "";
|
|
87
|
+
try {
|
|
88
|
+
errorCode = JSON.parse(text).error ?? "";
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
errorCode = "";
|
|
92
|
+
}
|
|
93
|
+
switch (errorCode) {
|
|
94
|
+
case "authorization_pending":
|
|
95
|
+
return { kind: "pending" };
|
|
96
|
+
case "slow_down":
|
|
97
|
+
return { kind: "slow_down" };
|
|
98
|
+
case "expired_token":
|
|
99
|
+
return { kind: "expired" };
|
|
100
|
+
case "access_denied":
|
|
101
|
+
return { kind: "denied" };
|
|
102
|
+
default:
|
|
103
|
+
throw new Error(`Device-token poll failed (${response.status}): ${text}`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// ---------------------------------------------------------------------------
|
|
107
|
+
// Token refresh (unchanged — used by the read path in graph-client.ts)
|
|
108
|
+
// ---------------------------------------------------------------------------
|
|
109
|
+
export async function refreshAccessToken(args) {
|
|
110
|
+
const { tokenUrl } = buildUrls(args.tenantId);
|
|
111
|
+
const params = new URLSearchParams({
|
|
112
|
+
client_id: args.clientId,
|
|
113
|
+
scope: SCOPES.join(" "),
|
|
114
|
+
refresh_token: args.refreshToken,
|
|
115
|
+
grant_type: "refresh_token",
|
|
116
|
+
});
|
|
117
|
+
const response = await fetch(tokenUrl, {
|
|
118
|
+
method: "POST",
|
|
119
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
120
|
+
body: params.toString(),
|
|
121
|
+
});
|
|
122
|
+
if (!response.ok) {
|
|
123
|
+
const text = await response.text();
|
|
124
|
+
throw new Error(`Token refresh failed (${response.status}): ${text}`);
|
|
125
|
+
}
|
|
126
|
+
return (await response.json());
|
|
127
|
+
}
|
|
128
|
+
export const _internals = { SCOPES };
|
|
129
|
+
//# sourceMappingURL=device-flow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device-flow.js","sourceRoot":"","sources":["../../src/auth/device-flow.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,MAAM,MAAM,GAAG;IACb,gBAAgB;IAChB,WAAW;IACX,gBAAgB;IAChB,WAAW;IACX,qBAAqB;IACrB,eAAe;CAChB,CAAC;AAOF,SAAS,SAAS,CAAC,QAAgB;IACjC,MAAM,MAAM,GAAG,QAAQ,IAAI,QAAQ,CAAC;IACpC,OAAO;QACL,YAAY,EAAE,qCAAqC,MAAM,wBAAwB;QACjF,QAAQ,EAAE,qCAAqC,MAAM,oBAAoB;KAC1E,CAAC;AACJ,CAAC;AAiCD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,MAGrC;IACC,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,IAAI,QAAQ,CAAC;IAC3C,MAAM,GAAG,GAAG,qCAAqC,MAAM,yBAAyB,CAAC;IACjF,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC;QACjC,SAAS,EAAE,MAAM,CAAC,QAAQ;QAC1B,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;KACxB,CAAC,CAAC;IACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAChC,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,mCAAmC,EAAE;QAChE,IAAI,EAAE,MAAM,CAAC,QAAQ,EAAE;KACxB,CAAC,CAAC;IACH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CAAC,+BAA+B,QAAQ,CAAC,MAAM,MAAM,IAAI,EAAE,CAAC,CAAC;IAC9E,CAAC;IACD,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAuB,CAAC;IAC3D,MAAM,uBAAuB,GAC3B,IAAI,CAAC,yBAAyB;QAC9B,GAAG,IAAI,CAAC,gBAAgB,QAAQ,IAAI,CAAC,SAAS,EAAE,CAAC;IACnD,OAAO;QACL,UAAU,EAAE,IAAI,CAAC,WAAW;QAC5B,QAAQ,EAAE,IAAI,CAAC,SAAS;QACxB,eAAe,EAAE,IAAI,CAAC,gBAAgB;QACtC,uBAAuB;QACvB,YAAY,EAAE,IAAI,CAAC,UAAU;QAC7B,WAAW,EAAE,IAAI,CAAC,QAAQ;QAC1B,MAAM,EAAE,CAAC,GAAG,MAAM,CAAC;KACpB,CAAC;AACJ,CAAC;AASD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,MAA8C,EAC9C,UAAkB;IAElB,MAAM,EAAE,QAAQ,EAAE,GAAG,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAChD,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC;QACjC,SAAS,EAAE,MAAM,CAAC,QAAQ;QAC1B,UAAU,EAAE,8CAA8C;QAC1D,WAAW,EAAE,UAAU;KACxB,CAAC,CAAC;IACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE;QACrC,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,mCAAmC,EAAE;QAChE,IAAI,EAAE,MAAM,CAAC,QAAQ,EAAE;KACxB,CAAC,CAAC;IACH,IAAI,QAAQ,CAAC,EAAE,EAAE,CAAC;QAChB,MAAM,aAAa,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAkB,CAAC;QAC/D,MAAM,MAAM,GAAG,CAAC,aAAa,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACtE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,EAAE,CAAC;IACpD,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IACnC,IAAI,SAAS,GAAG,EAAE,CAAC;IACnB,IAAI,CAAC;QACH,SAAS,GAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAwB,CAAC,KAAK,IAAI,EAAE,CAAC;IACnE,CAAC;IAAC,MAAM,CAAC;QACP,SAAS,GAAG,EAAE,CAAC;IACjB,CAAC;IACD,QAAQ,SAAS,EAAE,CAAC;QAClB,KAAK,uBAAuB;YAC1B,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QAC7B,KAAK,WAAW;YACd,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;QAC/B,KAAK,eAAe;YAClB,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QAC7B,KAAK,eAAe;YAClB,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;QAC5B;YACE,MAAM,IAAI,KAAK,CAAC,6BAA6B,QAAQ,CAAC,MAAM,MAAM,IAAI,EAAE,CAAC,CAAC;IAC9E,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,uEAAuE;AACvE,8EAA8E;AAE9E,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,IAIxC;IACC,MAAM,EAAE,QAAQ,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC;QACjC,SAAS,EAAE,IAAI,CAAC,QAAQ;QACxB,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;QACvB,aAAa,EAAE,IAAI,CAAC,YAAY;QAChC,UAAU,EAAE,eAAe;KAC5B,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE;QACrC,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,mCAAmC,EAAE;QAChE,IAAI,EAAE,MAAM,CAAC,QAAQ,EAAE;KACxB,CAAC,CAAC;IACH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CAAC,yBAAyB,QAAQ,CAAC,MAAM,MAAM,IAAI,EAAE,CAAC,CAAC;IACxE,CAAC;IACD,OAAO,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAkB,CAAC;AAClD,CAAC;AAED,MAAM,CAAC,MAAM,UAAU,GAAG,EAAE,MAAM,EAAE,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-account encrypted device-code pending store for the Outlook register flow.
|
|
3
|
+
*
|
|
4
|
+
* Holds the short-lived device_code between `outlook-account-register` (start)
|
|
5
|
+
* and `outlook-account-register-poll`. Sealed with the SAME per-account AES key
|
|
6
|
+
* as token-store.ts (secrets/outlook/.key). The key-load and seal/open are
|
|
7
|
+
* re-implemented here rather than shared, because token-store.ts must not change
|
|
8
|
+
* (Task 1477 regression boundary).
|
|
9
|
+
*
|
|
10
|
+
* pending-devicecode.enc AES-256-CBC "<iv-hex>:<cipher-hex>" of the JSON entry
|
|
11
|
+
*/
|
|
12
|
+
export interface PendingDeviceCode {
|
|
13
|
+
deviceCode: string;
|
|
14
|
+
scopes: string[];
|
|
15
|
+
intervalSec: number;
|
|
16
|
+
expiresAtMs: number;
|
|
17
|
+
issuedAtMs: number;
|
|
18
|
+
}
|
|
19
|
+
export declare class PendingStore {
|
|
20
|
+
readonly accountId: string;
|
|
21
|
+
private encryptionKey;
|
|
22
|
+
private readonly secretsDir;
|
|
23
|
+
private readonly pendingPath;
|
|
24
|
+
private readonly keyPath;
|
|
25
|
+
constructor(accountId: string, accountsDir: string);
|
|
26
|
+
/** Load (or create) the per-account AES key — the same file token-store uses. */
|
|
27
|
+
private loadKey;
|
|
28
|
+
private encrypt;
|
|
29
|
+
private decrypt;
|
|
30
|
+
/** Atomic write — temp + rename. Mode 0600. */
|
|
31
|
+
write(entry: PendingDeviceCode): void;
|
|
32
|
+
read(): PendingDeviceCode | null;
|
|
33
|
+
clear(): void;
|
|
34
|
+
/** Clear then re-stat; true only when the file is confirmed absent. */
|
|
35
|
+
clearVerified(): boolean;
|
|
36
|
+
/** 1 when a pending entry exists on disk, else 0. Rising N without clears = leak. */
|
|
37
|
+
census(): number;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=pending-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pending-store.d.ts","sourceRoot":"","sources":["../../src/auth/pending-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAeH,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,YAAY;aAOL,SAAS,EAAE,MAAM;IANnC,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAGf,SAAS,EAAE,MAAM,EACjC,WAAW,EAAE,MAAM;IAOrB,iFAAiF;IACjF,OAAO,CAAC,OAAO;IAiCf,OAAO,CAAC,OAAO;IAMf,OAAO,CAAC,OAAO;IASf,+CAA+C;IAC/C,KAAK,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI;IAQrC,IAAI,IAAI,iBAAiB,GAAG,IAAI;IAOhC,KAAK,IAAI,IAAI;IAIb,uEAAuE;IACvE,aAAa,IAAI,OAAO;IAKxB,qFAAqF;IACrF,MAAM,IAAI,MAAM;CAGjB"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-account encrypted device-code pending store for the Outlook register flow.
|
|
3
|
+
*
|
|
4
|
+
* Holds the short-lived device_code between `outlook-account-register` (start)
|
|
5
|
+
* and `outlook-account-register-poll`. Sealed with the SAME per-account AES key
|
|
6
|
+
* as token-store.ts (secrets/outlook/.key). The key-load and seal/open are
|
|
7
|
+
* re-implemented here rather than shared, because token-store.ts must not change
|
|
8
|
+
* (Task 1477 regression boundary).
|
|
9
|
+
*
|
|
10
|
+
* pending-devicecode.enc AES-256-CBC "<iv-hex>:<cipher-hex>" of the JSON entry
|
|
11
|
+
*/
|
|
12
|
+
import { createCipheriv, createDecipheriv, randomBytes } from "node:crypto";
|
|
13
|
+
import { chmodSync, existsSync, mkdirSync, readFileSync, renameSync, statSync, unlinkSync, writeFileSync, } from "node:fs";
|
|
14
|
+
import { join } from "node:path";
|
|
15
|
+
export class PendingStore {
|
|
16
|
+
accountId;
|
|
17
|
+
encryptionKey = null;
|
|
18
|
+
secretsDir;
|
|
19
|
+
pendingPath;
|
|
20
|
+
keyPath;
|
|
21
|
+
constructor(accountId, accountsDir) {
|
|
22
|
+
this.accountId = accountId;
|
|
23
|
+
this.secretsDir = join(accountsDir, accountId, "secrets", "outlook");
|
|
24
|
+
this.pendingPath = join(this.secretsDir, "pending-devicecode.enc");
|
|
25
|
+
this.keyPath = join(this.secretsDir, ".key");
|
|
26
|
+
}
|
|
27
|
+
/** Load (or create) the per-account AES key — the same file token-store uses. */
|
|
28
|
+
loadKey() {
|
|
29
|
+
if (this.encryptionKey)
|
|
30
|
+
return this.encryptionKey;
|
|
31
|
+
mkdirSync(this.secretsDir, { recursive: true, mode: 0o700 });
|
|
32
|
+
chmodSync(this.secretsDir, 0o700);
|
|
33
|
+
if (existsSync(this.keyPath)) {
|
|
34
|
+
const stat = statSync(this.keyPath);
|
|
35
|
+
if ((stat.mode & 0o777) !== 0o600)
|
|
36
|
+
chmodSync(this.keyPath, 0o600);
|
|
37
|
+
const key = Buffer.from(readFileSync(this.keyPath, "utf-8").trim(), "base64");
|
|
38
|
+
if (key.length !== 32) {
|
|
39
|
+
throw new Error(`Outlook key for account=${this.accountId} is corrupt (length=${key.length}); delete ${this.keyPath} and re-run outlook-account-register.`);
|
|
40
|
+
}
|
|
41
|
+
this.encryptionKey = key;
|
|
42
|
+
return key;
|
|
43
|
+
}
|
|
44
|
+
const newKey = randomBytes(32);
|
|
45
|
+
try {
|
|
46
|
+
writeFileSync(this.keyPath, newKey.toString("base64"), { flag: "wx", mode: 0o600 });
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
if (err.code === "EEXIST") {
|
|
50
|
+
this.encryptionKey = Buffer.from(readFileSync(this.keyPath, "utf-8").trim(), "base64");
|
|
51
|
+
return this.encryptionKey;
|
|
52
|
+
}
|
|
53
|
+
throw err;
|
|
54
|
+
}
|
|
55
|
+
this.encryptionKey = newKey;
|
|
56
|
+
return newKey;
|
|
57
|
+
}
|
|
58
|
+
encrypt(plaintext) {
|
|
59
|
+
const iv = randomBytes(16);
|
|
60
|
+
const cipher = createCipheriv("aes-256-cbc", this.loadKey(), iv);
|
|
61
|
+
return `${iv.toString("hex")}:${cipher.update(plaintext, "utf8", "hex") + cipher.final("hex")}`;
|
|
62
|
+
}
|
|
63
|
+
decrypt(payload) {
|
|
64
|
+
const [ivHex, ...rest] = payload.split(":");
|
|
65
|
+
if (!ivHex || rest.length === 0) {
|
|
66
|
+
throw new Error("pending-decrypt-failed: malformed cipher payload");
|
|
67
|
+
}
|
|
68
|
+
const decipher = createDecipheriv("aes-256-cbc", this.loadKey(), Buffer.from(ivHex, "hex"));
|
|
69
|
+
return decipher.update(rest.join(":"), "hex", "utf8") + decipher.final("utf8");
|
|
70
|
+
}
|
|
71
|
+
/** Atomic write — temp + rename. Mode 0600. */
|
|
72
|
+
write(entry) {
|
|
73
|
+
const ciphertext = this.encrypt(JSON.stringify(entry));
|
|
74
|
+
const temp = `${this.pendingPath}.tmp`;
|
|
75
|
+
writeFileSync(temp, ciphertext, { mode: 0o600 });
|
|
76
|
+
chmodSync(temp, 0o600);
|
|
77
|
+
renameSync(temp, this.pendingPath);
|
|
78
|
+
}
|
|
79
|
+
read() {
|
|
80
|
+
if (!existsSync(this.pendingPath))
|
|
81
|
+
return null;
|
|
82
|
+
const raw = readFileSync(this.pendingPath, "utf-8").trim();
|
|
83
|
+
if (!raw)
|
|
84
|
+
return null;
|
|
85
|
+
return JSON.parse(this.decrypt(raw));
|
|
86
|
+
}
|
|
87
|
+
clear() {
|
|
88
|
+
if (existsSync(this.pendingPath))
|
|
89
|
+
unlinkSync(this.pendingPath);
|
|
90
|
+
}
|
|
91
|
+
/** Clear then re-stat; true only when the file is confirmed absent. */
|
|
92
|
+
clearVerified() {
|
|
93
|
+
this.clear();
|
|
94
|
+
return !existsSync(this.pendingPath);
|
|
95
|
+
}
|
|
96
|
+
/** 1 when a pending entry exists on disk, else 0. Rising N without clears = leak. */
|
|
97
|
+
census() {
|
|
98
|
+
return existsSync(this.pendingPath) ? 1 : 0;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=pending-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pending-store.js","sourceRoot":"","sources":["../../src/auth/pending-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pkce-flow.d.ts","sourceRoot":"","sources":["../../src/auth/pkce-flow.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;
|
|
1
|
+
{"version":3,"file":"pkce-flow.d.ts","sourceRoot":"","sources":["../../src/auth/pkce-flow.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AA+BH,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,aAAa,CAAC;IAC7B,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;CACjC;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAsDlF;AAgJD,wBAAsB,kBAAkB,CAAC,IAAI,EAAE;IAC7C,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;CACtB,GAAG,OAAO,CAAC,aAAa,CAAC,CAmBzB;AAuBD;;;;GAIG;AACH,iBAAS,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAKtD;AAED,eAAO,MAAM,UAAU;;;CAA8B,CAAC"}
|
|
@@ -20,8 +20,9 @@ const FLOW_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes
|
|
|
20
20
|
const SCOPES = [
|
|
21
21
|
"offline_access",
|
|
22
22
|
"User.Read",
|
|
23
|
-
"Mail.
|
|
24
|
-
"
|
|
23
|
+
"Mail.ReadWrite",
|
|
24
|
+
"Mail.Send",
|
|
25
|
+
"Calendars.ReadWrite",
|
|
25
26
|
"Contacts.Read",
|
|
26
27
|
];
|
|
27
28
|
function buildUrls(tenantId) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pkce-flow.js","sourceRoot":"","sources":["../../src/auth/pkce-flow.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACvE,OAAO,EAAE,YAAY,EAAe,MAAM,WAAW,CAAC;AAEtD,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,GAAG,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD,MAAM,eAAe,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,YAAY;AACnD,MAAM,MAAM,GAAG;IACb,gBAAgB;IAChB,WAAW;IACX,WAAW;IACX,
|
|
1
|
+
{"version":3,"file":"pkce-flow.js","sourceRoot":"","sources":["../../src/auth/pkce-flow.ts"],"names":[],"mappings":"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"}
|
|
@@ -19,13 +19,22 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
|
|
|
19
19
|
import { resolve } from "node:path";
|
|
20
20
|
import { z } from "zod";
|
|
21
21
|
import { TokenStore } from "./auth/token-store.js";
|
|
22
|
-
import {
|
|
22
|
+
import { PendingStore } from "./auth/pending-store.js";
|
|
23
|
+
import { runAccountRegisterStart, runAccountRegisterPoll } from "./tools/account-register.js";
|
|
23
24
|
import { runMailList } from "./tools/mail-list.js";
|
|
24
25
|
import { runMailSearch } from "./tools/mail-search.js";
|
|
25
26
|
import { runCalendarList } from "./tools/calendar-list.js";
|
|
26
27
|
import { runCalendarEvent } from "./tools/calendar-event.js";
|
|
28
|
+
import { runCalendarCreate } from "./tools/calendar-create.js";
|
|
29
|
+
import { runCalendarUpdate } from "./tools/calendar-update.js";
|
|
30
|
+
import { runCalendarCancel } from "./tools/calendar-cancel.js";
|
|
31
|
+
import { runCalendarRespond } from "./tools/calendar-respond.js";
|
|
32
|
+
import { runCalendarFreebusy } from "./tools/calendar-freebusy.js";
|
|
27
33
|
import { runContactsList } from "./tools/contacts-list.js";
|
|
28
34
|
import { runMailboxInfo } from "./tools/mailbox-info.js";
|
|
35
|
+
import { runMailSend } from "./tools/mail-send.js";
|
|
36
|
+
import { runDraft } from "./tools/draft.js";
|
|
37
|
+
import { runDraftSend } from "./tools/draft-send.js";
|
|
29
38
|
import { lifelineTool } from "../../../../lib/mcp-lifeline/dist/index.js";
|
|
30
39
|
// Plugin-system boot tolerance — see Task 202.
|
|
31
40
|
// Module-init must never exit; the plugin-system spawn enumerates tools/list
|
|
@@ -35,7 +44,11 @@ const PLATFORM_ROOT = process.env.PLATFORM_ROOT ?? process.cwd();
|
|
|
35
44
|
const ACCOUNTS_DIR = resolve(PLATFORM_ROOT, "..", "data/accounts");
|
|
36
45
|
const OUTLOOK_CLIENT_ID = process.env.OUTLOOK_CLIENT_ID ?? "";
|
|
37
46
|
const OUTLOOK_TENANT_ID = process.env.OUTLOOK_TENANT_ID ?? "common";
|
|
38
|
-
|
|
47
|
+
// Task 1473 — standing per-boot reconciliation of expected (brand.json
|
|
48
|
+
// outlookClientId, stamped onto the session-manager env and passed through the
|
|
49
|
+
// PLUGIN.md mcp.env block) vs actual (this process's env). clientIdConfigured=false
|
|
50
|
+
// on an install whose brand ships a non-empty value is the mis-stamp signature.
|
|
51
|
+
process.stderr.write(`[outlook-mcp] boot accountId=${ACCOUNT_ID ?? "null"} clientIdConfigured=${OUTLOOK_CLIENT_ID ? "true" : "false"}\n`);
|
|
39
52
|
function refuseNoAccount(toolName) {
|
|
40
53
|
process.stderr.write(`[outlook-mcp] tool=${toolName} refuse reason=no-account-context\n`);
|
|
41
54
|
return {
|
|
@@ -54,6 +67,12 @@ function getStore() {
|
|
|
54
67
|
}
|
|
55
68
|
return new TokenStore(ACCOUNT_ID, ACCOUNTS_DIR);
|
|
56
69
|
}
|
|
70
|
+
function getPendingStore() {
|
|
71
|
+
if (!ACCOUNT_ID) {
|
|
72
|
+
throw new Error("getPendingStore() called without ACCOUNT_ID — handler guard missing");
|
|
73
|
+
}
|
|
74
|
+
return new PendingStore(ACCOUNT_ID, ACCOUNTS_DIR);
|
|
75
|
+
}
|
|
57
76
|
function getConfig() {
|
|
58
77
|
if (!ACCOUNT_ID) {
|
|
59
78
|
throw new Error("getConfig() called without ACCOUNT_ID — handler guard missing");
|
|
@@ -82,16 +101,16 @@ const server = new McpServer({
|
|
|
82
101
|
name: "outlook",
|
|
83
102
|
version: "0.1.0",
|
|
84
103
|
});
|
|
85
|
-
lifelineTool(server, "outlook-account-register", "
|
|
104
|
+
lifelineTool(server, "outlook-account-register", "Start the OAuth device-code flow for this account. Returns immediately with a userCode and verificationUri (microsoft.com/devicelogin). Relay both to the operator: they open the URL on any device, enter the code, sign in and consent. Then call outlook-account-register-poll to finish. Does NOT block.", {}, async () => {
|
|
86
105
|
if (!ACCOUNT_ID)
|
|
87
106
|
return refuseNoAccount("outlook-account-register");
|
|
88
107
|
try {
|
|
89
108
|
const config = getConfig();
|
|
90
|
-
const result = await
|
|
109
|
+
const result = await runAccountRegisterStart({
|
|
91
110
|
accountId: ACCOUNT_ID,
|
|
92
111
|
clientId: config.clientId,
|
|
93
112
|
tenantId: config.tenantId,
|
|
94
|
-
|
|
113
|
+
pendingStore: getPendingStore(),
|
|
95
114
|
});
|
|
96
115
|
return ok(result);
|
|
97
116
|
}
|
|
@@ -99,6 +118,24 @@ lifelineTool(server, "outlook-account-register", "Initiate the OAuth Auth Code +
|
|
|
99
118
|
return fail(`outlook-account-register failed: ${err.message}`);
|
|
100
119
|
}
|
|
101
120
|
});
|
|
121
|
+
lifelineTool(server, "outlook-account-register-poll", "Poll for completion of the device-code flow started by outlook-account-register. One check per call. Returns status: pending (wait intervalSec, then call again), registered (done — tokens persisted), expired (code timed out — restart with outlook-account-register), or denied (operator declined).", {}, async () => {
|
|
122
|
+
if (!ACCOUNT_ID)
|
|
123
|
+
return refuseNoAccount("outlook-account-register-poll");
|
|
124
|
+
try {
|
|
125
|
+
const config = getConfig();
|
|
126
|
+
const result = await runAccountRegisterPoll({
|
|
127
|
+
accountId: ACCOUNT_ID,
|
|
128
|
+
clientId: config.clientId,
|
|
129
|
+
tenantId: config.tenantId,
|
|
130
|
+
tokenStore: config.tokenStore,
|
|
131
|
+
pendingStore: getPendingStore(),
|
|
132
|
+
});
|
|
133
|
+
return ok(result);
|
|
134
|
+
}
|
|
135
|
+
catch (err) {
|
|
136
|
+
return fail(`outlook-account-register-poll failed: ${err.message}`);
|
|
137
|
+
}
|
|
138
|
+
});
|
|
102
139
|
lifelineTool(server, "outlook-mail-list", "List recent messages in the mailbox. Defaults to top=25 ordered by receivedDateTime DESC. Folder defaults to Inbox; pass a folder displayName or id for other folders. Returns id, subject, from, receivedDateTime, bodyPreview, isRead.", {
|
|
103
140
|
top: z.number().int().min(1).max(250).optional(),
|
|
104
141
|
folder: z.string().optional(),
|
|
@@ -154,6 +191,102 @@ lifelineTool(server, "outlook-calendar-event", "Fetch a single calendar event by
|
|
|
154
191
|
return fail(`outlook-calendar-event failed: ${err.message}`);
|
|
155
192
|
}
|
|
156
193
|
});
|
|
194
|
+
const eventTimeSchema = z.object({
|
|
195
|
+
dateTime: z.string().min(1),
|
|
196
|
+
timeZone: z.string().min(1),
|
|
197
|
+
});
|
|
198
|
+
const attendeeSchema = z.object({
|
|
199
|
+
email: z.string().min(1),
|
|
200
|
+
name: z.string().optional(),
|
|
201
|
+
type: z.enum(["required", "optional", "resource"]).optional(),
|
|
202
|
+
});
|
|
203
|
+
lifelineTool(server, "outlook-calendar-create", "Create a calendar event on the operator's Outlook calendar (POST /me/events). Requires subject, start, and end (each start/end is { dateTime, timeZone }). Optional: body (HTML), attendees, location, isOnlineMeeting, and a Graph recurrence object. Returns the new eventId and webLink.", {
|
|
204
|
+
subject: z.string().min(1),
|
|
205
|
+
start: eventTimeSchema,
|
|
206
|
+
end: eventTimeSchema,
|
|
207
|
+
body: z.string().optional(),
|
|
208
|
+
attendees: z.array(attendeeSchema).optional(),
|
|
209
|
+
location: z.string().optional(),
|
|
210
|
+
isOnlineMeeting: z.boolean().optional(),
|
|
211
|
+
recurrence: z.record(z.string(), z.unknown()).optional(),
|
|
212
|
+
}, async (args) => {
|
|
213
|
+
if (!ACCOUNT_ID)
|
|
214
|
+
return refuseNoAccount("outlook-calendar-create");
|
|
215
|
+
try {
|
|
216
|
+
const result = await runCalendarCreate(getConfig(), args);
|
|
217
|
+
return ok(result);
|
|
218
|
+
}
|
|
219
|
+
catch (err) {
|
|
220
|
+
return fail(`outlook-calendar-create failed: ${err.message}`);
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
lifelineTool(server, "outlook-calendar-update", "Update or reschedule an existing calendar event (PATCH /me/events/{id}). Pass eventId plus only the fields to change: subject, start, end, body, attendees, location, isOnlineMeeting, recurrence.", {
|
|
224
|
+
eventId: z.string().min(1),
|
|
225
|
+
subject: z.string().optional(),
|
|
226
|
+
start: eventTimeSchema.optional(),
|
|
227
|
+
end: eventTimeSchema.optional(),
|
|
228
|
+
body: z.string().optional(),
|
|
229
|
+
attendees: z.array(attendeeSchema).optional(),
|
|
230
|
+
location: z.string().optional(),
|
|
231
|
+
isOnlineMeeting: z.boolean().optional(),
|
|
232
|
+
recurrence: z.record(z.string(), z.unknown()).optional(),
|
|
233
|
+
}, async (args) => {
|
|
234
|
+
if (!ACCOUNT_ID)
|
|
235
|
+
return refuseNoAccount("outlook-calendar-update");
|
|
236
|
+
try {
|
|
237
|
+
const result = await runCalendarUpdate(getConfig(), args);
|
|
238
|
+
return ok(result);
|
|
239
|
+
}
|
|
240
|
+
catch (err) {
|
|
241
|
+
return fail(`outlook-calendar-update failed: ${err.message}`);
|
|
242
|
+
}
|
|
243
|
+
});
|
|
244
|
+
lifelineTool(server, "outlook-calendar-cancel", "Cancel a calendar event (DELETE /me/events/{id}, or POST /me/events/{id}/cancel when the account organises a meeting so attendees are notified). The mode is chosen automatically. Optional comment is the cancellation message to attendees.", {
|
|
245
|
+
eventId: z.string().min(1),
|
|
246
|
+
comment: z.string().optional(),
|
|
247
|
+
}, async ({ eventId, comment }) => {
|
|
248
|
+
if (!ACCOUNT_ID)
|
|
249
|
+
return refuseNoAccount("outlook-calendar-cancel");
|
|
250
|
+
try {
|
|
251
|
+
const result = await runCalendarCancel(getConfig(), { eventId, comment });
|
|
252
|
+
return ok(result);
|
|
253
|
+
}
|
|
254
|
+
catch (err) {
|
|
255
|
+
return fail(`outlook-calendar-cancel failed: ${err.message}`);
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
lifelineTool(server, "outlook-calendar-respond", "Respond to a meeting invite (POST /me/events/{id}/{accept|decline|tentativelyAccept}). action is accept, decline, or tentative. Optional comment is sent with the response; sendResponse defaults to true.", {
|
|
259
|
+
eventId: z.string().min(1),
|
|
260
|
+
action: z.enum(["accept", "decline", "tentative"]),
|
|
261
|
+
comment: z.string().optional(),
|
|
262
|
+
sendResponse: z.boolean().optional(),
|
|
263
|
+
}, async ({ eventId, action, comment, sendResponse }) => {
|
|
264
|
+
if (!ACCOUNT_ID)
|
|
265
|
+
return refuseNoAccount("outlook-calendar-respond");
|
|
266
|
+
try {
|
|
267
|
+
const result = await runCalendarRespond(getConfig(), { eventId, action, comment, sendResponse });
|
|
268
|
+
return ok(result);
|
|
269
|
+
}
|
|
270
|
+
catch (err) {
|
|
271
|
+
return fail(`outlook-calendar-respond failed: ${err.message}`);
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
lifelineTool(server, "outlook-calendar-freebusy", "Query free/busy availability for one or more addresses over a window (POST /me/calendar/getSchedule). Pass schedules (email addresses), start and end ({ dateTime, timeZone }), and optional intervalMinutes (default 60). Returns per-address availability; an address Graph cannot resolve carries an error and is not counted in resolved, so resolved below requested flags a bad address.", {
|
|
275
|
+
schedules: z.array(z.string().min(1)).min(1),
|
|
276
|
+
start: eventTimeSchema,
|
|
277
|
+
end: eventTimeSchema,
|
|
278
|
+
intervalMinutes: z.number().int().min(5).max(1440).optional(),
|
|
279
|
+
}, async ({ schedules, start, end, intervalMinutes }) => {
|
|
280
|
+
if (!ACCOUNT_ID)
|
|
281
|
+
return refuseNoAccount("outlook-calendar-freebusy");
|
|
282
|
+
try {
|
|
283
|
+
const result = await runCalendarFreebusy(getConfig(), { schedules, start, end, intervalMinutes });
|
|
284
|
+
return ok(result);
|
|
285
|
+
}
|
|
286
|
+
catch (err) {
|
|
287
|
+
return fail(`outlook-calendar-freebusy failed: ${err.message}`);
|
|
288
|
+
}
|
|
289
|
+
});
|
|
157
290
|
lifelineTool(server, "outlook-contacts-list", "List contacts. Defaults to top=50, max 250. Returns id, displayName, emailAddresses, phones, jobTitle, companyName.", {
|
|
158
291
|
top: z.number().int().min(1).max(250).optional(),
|
|
159
292
|
}, async ({ top }) => {
|
|
@@ -178,6 +311,55 @@ lifelineTool(server, "outlook-mailbox-info", "Health probe — reports auth stat
|
|
|
178
311
|
return fail(`outlook-mailbox-info failed: ${err.message}`);
|
|
179
312
|
}
|
|
180
313
|
});
|
|
314
|
+
lifelineTool(server, "outlook-mail-send", "Send a message via Microsoft Graph POST /me/sendMail. Recipients are string arrays (to required, cc/bcc optional). The body is HTML when isHtml=true, otherwise plain text. Saves a copy to Sent Items. Success is asserted on Graph's 202; the message is not returned with an id. Requires the Mail.Send scope — a mailbox registered under the old read-only consent returns an actionable 're-register to grant send' error.", {
|
|
315
|
+
to: z.array(z.string().min(3)).min(1),
|
|
316
|
+
cc: z.array(z.string()).optional(),
|
|
317
|
+
bcc: z.array(z.string()).optional(),
|
|
318
|
+
subject: z.string(),
|
|
319
|
+
body: z.string(),
|
|
320
|
+
isHtml: z.boolean().optional(),
|
|
321
|
+
}, async ({ to, cc, bcc, subject, body, isHtml }) => {
|
|
322
|
+
if (!ACCOUNT_ID)
|
|
323
|
+
return refuseNoAccount("outlook-mail-send");
|
|
324
|
+
try {
|
|
325
|
+
const result = await runMailSend(getConfig(), { to, cc, bcc, subject, body, isHtml });
|
|
326
|
+
return ok(result);
|
|
327
|
+
}
|
|
328
|
+
catch (err) {
|
|
329
|
+
return fail(`outlook-mail-send failed: ${err.message}`);
|
|
330
|
+
}
|
|
331
|
+
});
|
|
332
|
+
lifelineTool(server, "outlook-draft", "Create a draft message in the Drafts folder via Microsoft Graph POST /me/messages. Same body model as outlook-mail-send (to/cc/bcc arrays, subject, body, isHtml). Returns the created draft's id for a later outlook-draft-send. Does not send. Requires the Mail.ReadWrite scope.", {
|
|
333
|
+
to: z.array(z.string().min(3)).min(1),
|
|
334
|
+
cc: z.array(z.string()).optional(),
|
|
335
|
+
bcc: z.array(z.string()).optional(),
|
|
336
|
+
subject: z.string(),
|
|
337
|
+
body: z.string(),
|
|
338
|
+
isHtml: z.boolean().optional(),
|
|
339
|
+
}, async ({ to, cc, bcc, subject, body, isHtml }) => {
|
|
340
|
+
if (!ACCOUNT_ID)
|
|
341
|
+
return refuseNoAccount("outlook-draft");
|
|
342
|
+
try {
|
|
343
|
+
const result = await runDraft(getConfig(), { to, cc, bcc, subject, body, isHtml });
|
|
344
|
+
return ok(result);
|
|
345
|
+
}
|
|
346
|
+
catch (err) {
|
|
347
|
+
return fail(`outlook-draft failed: ${err.message}`);
|
|
348
|
+
}
|
|
349
|
+
});
|
|
350
|
+
lifelineTool(server, "outlook-draft-send", "Send an existing draft by id via Microsoft Graph POST /me/messages/{id}/send. Graph consumes the draft on send and returns 202. Pass the draftId returned by outlook-draft. Requires the Mail.Send scope.", {
|
|
351
|
+
draftId: z.string().min(1),
|
|
352
|
+
}, async ({ draftId }) => {
|
|
353
|
+
if (!ACCOUNT_ID)
|
|
354
|
+
return refuseNoAccount("outlook-draft-send");
|
|
355
|
+
try {
|
|
356
|
+
const result = await runDraftSend(getConfig(), { draftId });
|
|
357
|
+
return ok(result);
|
|
358
|
+
}
|
|
359
|
+
catch (err) {
|
|
360
|
+
return fail(`outlook-draft-send failed: ${err.message}`);
|
|
361
|
+
}
|
|
362
|
+
});
|
|
181
363
|
const transport = new StdioServerTransport();
|
|
182
364
|
await server.connect(transport);
|
|
183
365
|
process.stderr.write(`[outlook-mcp] ready account=${ACCOUNT_ID ?? "null"}\n`);
|