@rubytech/create-maxy-code 0.1.440 → 0.1.442

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.
Files changed (107) hide show
  1. package/dist/index.js +99 -1
  2. package/package.json +1 -1
  3. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +64 -8
  4. package/payload/platform/plugins/cloudflare/skills/calendar-site/SKILL.md +15 -5
  5. package/payload/platform/plugins/cloudflare/skills/calendar-site/template/functions/api/calendar/free-busy.ts +152 -0
  6. package/payload/platform/plugins/cloudflare/skills/calendar-site/template/public/index.html +6 -3
  7. package/payload/platform/plugins/cloudflare/skills/calendar-site/template/schema.sql +11 -0
  8. package/payload/platform/plugins/docs/references/admin-ui.md +1 -1
  9. package/payload/platform/plugins/docs/references/calendar-booking.md +1 -1
  10. package/payload/platform/plugins/docs/references/graph.md +19 -3
  11. package/payload/platform/plugins/docs/references/outlook-guide.md +7 -2
  12. package/payload/platform/plugins/docs/references/troubleshooting.md +35 -0
  13. package/payload/platform/plugins/outlook/.claude-plugin/plugin.json +1 -1
  14. package/payload/platform/plugins/outlook/PLUGIN.md +7 -3
  15. package/payload/platform/plugins/outlook/mcp/dist/__tests__/account-register.test.js +100 -10
  16. package/payload/platform/plugins/outlook/mcp/dist/__tests__/account-register.test.js.map +1 -1
  17. package/payload/platform/plugins/outlook/mcp/dist/__tests__/device-flow.test.js +37 -4
  18. package/payload/platform/plugins/outlook/mcp/dist/__tests__/device-flow.test.js.map +1 -1
  19. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mailbox-list.test.d.ts +2 -0
  20. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mailbox-list.test.d.ts.map +1 -0
  21. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mailbox-list.test.js +64 -0
  22. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mailbox-list.test.js.map +1 -0
  23. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mailbox-registry.test.d.ts +2 -0
  24. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mailbox-registry.test.d.ts.map +1 -0
  25. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mailbox-registry.test.js +193 -0
  26. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mailbox-registry.test.js.map +1 -0
  27. package/payload/platform/plugins/outlook/mcp/dist/__tests__/token-store.test.js +58 -1
  28. package/payload/platform/plugins/outlook/mcp/dist/__tests__/token-store.test.js.map +1 -1
  29. package/payload/platform/plugins/outlook/mcp/dist/auth/device-flow.d.ts +27 -3
  30. package/payload/platform/plugins/outlook/mcp/dist/auth/device-flow.d.ts.map +1 -1
  31. package/payload/platform/plugins/outlook/mcp/dist/auth/device-flow.js +52 -11
  32. package/payload/platform/plugins/outlook/mcp/dist/auth/device-flow.js.map +1 -1
  33. package/payload/platform/plugins/outlook/mcp/dist/auth/mailbox-registry.d.ts +81 -0
  34. package/payload/platform/plugins/outlook/mcp/dist/auth/mailbox-registry.d.ts.map +1 -0
  35. package/payload/platform/plugins/outlook/mcp/dist/auth/mailbox-registry.js +171 -0
  36. package/payload/platform/plugins/outlook/mcp/dist/auth/mailbox-registry.js.map +1 -0
  37. package/payload/platform/plugins/outlook/mcp/dist/auth/token-store.d.ts +16 -1
  38. package/payload/platform/plugins/outlook/mcp/dist/auth/token-store.d.ts.map +1 -1
  39. package/payload/platform/plugins/outlook/mcp/dist/auth/token-store.js +25 -3
  40. package/payload/platform/plugins/outlook/mcp/dist/auth/token-store.js.map +1 -1
  41. package/payload/platform/plugins/outlook/mcp/dist/index.js +119 -50
  42. package/payload/platform/plugins/outlook/mcp/dist/index.js.map +1 -1
  43. package/payload/platform/plugins/outlook/mcp/dist/lib/graph-client.js +1 -1
  44. package/payload/platform/plugins/outlook/mcp/dist/lib/graph-client.js.map +1 -1
  45. package/payload/platform/plugins/outlook/mcp/dist/tools/account-register.d.ts +13 -4
  46. package/payload/platform/plugins/outlook/mcp/dist/tools/account-register.d.ts.map +1 -1
  47. package/payload/platform/plugins/outlook/mcp/dist/tools/account-register.js +54 -3
  48. package/payload/platform/plugins/outlook/mcp/dist/tools/account-register.js.map +1 -1
  49. package/payload/platform/plugins/outlook/mcp/dist/tools/mailbox-list.d.ts +26 -0
  50. package/payload/platform/plugins/outlook/mcp/dist/tools/mailbox-list.d.ts.map +1 -0
  51. package/payload/platform/plugins/outlook/mcp/dist/tools/mailbox-list.js +28 -0
  52. package/payload/platform/plugins/outlook/mcp/dist/tools/mailbox-list.js.map +1 -0
  53. package/payload/platform/plugins/outlook/references/auth.md +36 -8
  54. package/payload/platform/plugins/scheduling/mcp/dist/scripts/publish-availability.d.ts +27 -0
  55. package/payload/platform/plugins/scheduling/mcp/dist/scripts/publish-availability.d.ts.map +1 -0
  56. package/payload/platform/plugins/scheduling/mcp/dist/scripts/publish-availability.js +241 -0
  57. package/payload/platform/plugins/scheduling/mcp/dist/scripts/publish-availability.js.map +1 -0
  58. package/payload/platform/plugins/whatsapp/mcp/dist/index.js +20 -22
  59. package/payload/platform/plugins/whatsapp/mcp/dist/index.js.map +1 -1
  60. package/payload/platform/plugins/whatsapp/references/channels-whatsapp.md +3 -1
  61. package/payload/platform/scripts/logs-read.sh +24 -6
  62. package/payload/platform/scripts/logs-read.test.sh +42 -0
  63. package/payload/platform/scripts/rss-sampler.sh +107 -0
  64. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
  65. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +1 -0
  66. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
  67. package/payload/platform/templates/specialists/agents/personal-assistant.md +1 -1
  68. package/payload/server/public/assets/{AdminLoginScreens-CukwQufW.js → AdminLoginScreens-BJVwtpLH.js} +1 -1
  69. package/payload/server/public/assets/{AdminShell-BwEBH6tT.js → AdminShell-CMu8_Xwn.js} +1 -1
  70. package/payload/server/public/assets/{Checkbox-B629mOPp.js → Checkbox-CzD0ORqA.js} +1 -1
  71. package/payload/server/public/assets/{admin-CdFRCUUZ.js → admin-D0yk2LMq.js} +1 -1
  72. package/payload/server/public/assets/{browser-BWR59IkB.js → browser-CvfbgznO.js} +1 -1
  73. package/payload/server/public/assets/{calendar-kuTcxX1t.js → calendar-fw4WethJ.js} +1 -1
  74. package/payload/server/public/assets/chat-DhD-NES_.js +1 -0
  75. package/payload/server/public/assets/chevron-left-B3xSeEDR.js +1 -0
  76. package/payload/server/public/assets/data-CUnDzDox.js +1 -0
  77. package/payload/server/public/assets/{file-download-4mKJxUi-.js → file-download-Px4s0Bhp.js} +1 -1
  78. package/payload/server/public/assets/{graph-NgQDY0Pb.js → graph-DbT8nA6R.js} +2 -2
  79. package/payload/server/public/assets/{graph-labels-B8YAdo3Z.js → graph-labels-C1YIyLiA.js} +1 -1
  80. package/payload/server/public/assets/{maximize-2-CxstTgoK.js → maximize-2-BwphzI9S.js} +1 -1
  81. package/payload/server/public/assets/{operator-oSaB1mya.js → operator-zcIfeB14.js} +1 -1
  82. package/payload/server/public/assets/{page-DMeJHVfA.js → page-6fCnIb45.js} +2 -2
  83. package/payload/server/public/assets/page-CfQFAJia.js +1 -0
  84. package/payload/server/public/assets/{public-C54tl6V4.js → public-C0ehZCdE.js} +1 -1
  85. package/payload/server/public/assets/{rotate-ccw-COGQTi7n.js → rotate-ccw-C7BqkMec.js} +1 -1
  86. package/payload/server/public/assets/{tasks-B97VpwEJ.js → tasks-DlgiCafL.js} +1 -1
  87. package/payload/server/public/assets/{time-entry-format-C09rDHo9.js → time-entry-format-CyNYVDkq.js} +1 -1
  88. package/payload/server/public/assets/{useCopyFeedback-DHoYHiK9.js → useCopyFeedback-ByGUMN94.js} +1 -1
  89. package/payload/server/public/assets/useSubAccountSwitcher-1izQvPiD.css +1 -0
  90. package/payload/server/public/assets/useVoiceRecorder-XgpWvXpk.js +2 -0
  91. package/payload/server/public/browser.html +5 -5
  92. package/payload/server/public/calendar.html +6 -6
  93. package/payload/server/public/chat.html +12 -12
  94. package/payload/server/public/data.html +10 -10
  95. package/payload/server/public/graph.html +11 -11
  96. package/payload/server/public/index.html +13 -13
  97. package/payload/server/public/operator.html +14 -14
  98. package/payload/server/public/public.html +12 -12
  99. package/payload/server/public/tasks.html +5 -5
  100. package/payload/server/server.js +498 -180
  101. package/payload/server/public/assets/chat-ejnq2rck.js +0 -1
  102. package/payload/server/public/assets/chevron-left-u4tjq7fI.js +0 -1
  103. package/payload/server/public/assets/data-dZbOyLdT.js +0 -1
  104. package/payload/server/public/assets/page-DEkI-Gl1.js +0 -1
  105. package/payload/server/public/assets/useSubAccountSwitcher-Dzmd7Aip.css +0 -1
  106. package/payload/server/public/assets/useVoiceRecorder-b7HzTFs0.js +0 -2
  107. /package/payload/server/public/assets/{useSubAccountSwitcher-DLJFISqf.js → useSubAccountSwitcher-s6WlRn52.js} +0 -0
@@ -8,6 +8,7 @@ The `outlook` plugin gives the admin agent access to Microsoft 365 / Outlook.com
8
8
  2. **Per account: register the Outlook account** — in admin chat, ask the agent to "register my Outlook account". The agent runs `outlook-account-register`, which returns a short user code and the URL `microsoft.com/devicelogin` and relays both to you.
9
9
  3. **Consent on any device** — open `microsoft.com/devicelogin` on your phone or laptop, enter the code, sign in to your Microsoft account, and consent to the requested scopes (`offline_access`, `User.Read`, `Mail.ReadWrite`, `Mail.Send`, `Calendars.ReadWrite`, `Contacts.Read`). `Mail.Send` enables sending and `Calendars.ReadWrite` enables calendar control; a mailbox last consented on an older read-only scope set must re-register before send or any calendar write succeeds. The agent finishes by calling `outlook-account-register-poll`.
10
10
  4. **Done.** Subsequent tool calls (mail, calendar, contacts) use the persisted refresh token transparently.
11
+ 5. **Several mailboxes on one account.** Register again to add a second mailbox; it is stored alongside the first, not in place of it. Every operational tool then takes an optional `mailbox` argument — an email address or graphUserId. With one mailbox, omit it. With two or more, name it; omitting it returns a refusal listing the connected mailboxes. `outlook-mailbox-list` shows every connected mailbox. Only one registration runs at a time per account; starting another while one is live returns an in-progress signal.
11
12
 
12
13
  ## Tools
13
14
 
@@ -25,7 +26,8 @@ The `outlook` plugin gives the admin agent access to Microsoft 365 / Outlook.com
25
26
  | `outlook-calendar-respond` | Accept, decline, or tentatively accept an invite. |
26
27
  | `outlook-calendar-freebusy` | Availability for one or more addresses over a window. |
27
28
  | `outlook-contacts-list` | Top contacts. Default top=50. |
28
- | `outlook-mailbox-info` | Health probe — auth state, refresh-window, folder count. |
29
+ | `outlook-mailbox-info` | Health probe for one mailbox — auth state, refresh-window, folder count. Name the mailbox with `mailbox` when several are attached. |
30
+ | `outlook-mailbox-list` | Every connected mailbox with its email, scopes, and token health. Local only — no network — so it also flags a mailbox whose stored credentials cannot be read. |
29
31
  | `outlook-mail-send` | Send a message (`POST /me/sendMail`). to/cc/bcc arrays, subject, body, isHtml. Success asserted on Graph 202. Needs `Mail.Send`. |
30
32
  | `outlook-draft` | Create a draft in Drafts (`POST /me/messages`). Same body model. Returns the draft id. Needs `Mail.ReadWrite`. |
31
33
  | `outlook-draft-send` | Send an existing draft by id (`POST /me/messages/{id}/send`). Graph consumes the draft, returns 202. Needs `Mail.Send`. |
@@ -43,7 +45,9 @@ All log lines start with `[outlook-mcp]` and write to `server.log`. They are key
43
45
  | Pending-store census | `pending-store-census account=<id> live=<N>` |
44
46
  | Pending cleared | `pending-cleared account=<id> verified=<bool>` |
45
47
  | /me failed post-token | `me-failed account=<id> status=<N>` |
46
- | Auth ok | `auth-ok account=<id> graphUserId=<id> scopes=<csv> tokenExpSec=<N>` |
48
+ | Auth ok | `auth-ok account=<id> graphUserId=<id> mail=<addr> scopes=<csv> tokenExpSec=<N>` |
49
+ | Registration already in flight | `register-in-progress account=<id>` (start refused; one device-code flow at a time) |
50
+ | Credential resolve | `cred-resolve account=<id> mailbox=<id-or-empty> source=arg|sole|none|refused` — names the resolved mailbox and how it was chosen; `source=refused` is the ambiguity/not-found refusal |
47
51
  | Token refreshed | `token-refreshed account=<id> oldExpSec=<N> newExpSec=<N>` |
48
52
  | Refresh failed | `token-refresh-failed account=<id> reason=<err>` (terminal) |
49
53
  | Mail list | `mail-list op=resolve account=<id> folderIn=<name> folderResolved=<token> asRawId=<bool> count=<N> elapsedMs=<N>` (on error, `error=<msg>` replaces `count`) |
@@ -58,6 +62,7 @@ All log lines start with `[outlook-mcp]` and write to `server.log`. They are key
58
62
  | Scope insufficient | `scope-insufficient tool=<t> account=<id> missing=Calendars.ReadWrite` (stale read-only consent) |
59
63
  | Contacts list | `contacts-list account=<id> count=<N> elapsedMs=<N>` |
60
64
  | Mailbox info | `mailbox-info account=<id> tokenWithinRefreshWindow=<bool> folderCount=<N>` |
65
+ | Mailbox list | `mailbox-list account=<id> count=<N> unreadable=<N>` (unreadable>0 flags an orphaned or corrupt mailbox store) |
61
66
  | Graph error | `graph-error account=<id> status=<N> code=<graphErrorCode> retryAfterMs=<N-or-null>` — writes flow through the same `callGraph` loop, so a failed write logs `graph-error` too |
62
67
  | On-prem rejected | `on-prem-rejected account=<id> mailServer=<host>` (terminal) |
63
68
  | Scope insufficient | `scope-insufficient account=<id> tool=<t> missing=Mail.Send` (terminal — re-register to grant send) |
@@ -224,6 +224,41 @@ For specific plugin logs: "Show Telegram logs" or "Show contacts plugin logs."
224
224
 
225
225
  ---
226
226
 
227
+ ## Box went unreachable, suspected memory exhaustion
228
+
229
+ **Symptom:** The Pi stopped responding to everything (no web, no SSH, no ping) and needed a power-cycle. This is the signature of memory exhaustion: the box fills RAM and swap, then wedges while the kernel tries to free memory.
230
+
231
+ **What protects against it:** Every install runs a standing memory audit every 30 seconds, zram compressed swap so pressure hits RAM instead of the SD card, and earlyoom, which kills the single largest process before the kernel freezes the box. A kill shows up as one service restarting, not a whole-box outage, and SSH is protected so the box stays reachable.
232
+
233
+ **Check the approach to OOM after a reboot.** The audit log survives reboot. Read it:
234
+
235
+ ```
236
+ ~/<install>/platform/scripts/logs-read.sh --tail mem 100
237
+ ```
238
+
239
+ Replace `<install>` with the install directory (for example `realagent-code`). Then:
240
+
241
+ - Look for `op=mem-pressure` lines. They fire when available memory crosses the low-water mark, before any kill, and name the heaviest service (`topSlice`).
242
+ - A single service's reading (`ptys`, `neo4j`, `brand`, `edge`, `vnc`) rising over time while the others stay flat is a memory leak in that service.
243
+ - `op=mem-sample` lines that read `na` for the per-service fields are normal until the kernel memory controller is enabled on that box; available memory, swap, and the pressure warning still work.
244
+
245
+ **Confirm a kill happened and the service came back:**
246
+
247
+ ```
248
+ journalctl -t earlyoom --since -1h
249
+ journalctl --user -u <hostname>.service --since -1h | grep -iE "Started|Scheduled restart"
250
+ ```
251
+
252
+ **Check whether the kernel OOM-killer fired anyway** (it should not, if earlyoom pre-empted it):
253
+
254
+ ```
255
+ journalctl -b -1 -k | grep -i oom
256
+ ```
257
+
258
+ A kernel `invoked oom-killer` line means the mitigation did not pre-empt the kernel on that occasion. A gap in the `op=mem-sample` timestamps means the sampler itself stopped. Both are worth escalating.
259
+
260
+ ---
261
+
227
262
  ## Cloudflare Tunnel Down (Remote Access Broken)
228
263
 
229
264
  **Symptom:** You can reach {{productName}} on your local network but not via your public domain.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "outlook",
3
- "description": "Microsoft 365 / Outlook.com via Microsoft Graph. Mail is read + draft + send; contacts are read-only; calendar is read + control. Per-account OAuth device-code flow; no client secret. Tools — outlook-account-register / outlook-account-register-poll: device-code register (start + poll); outlook-mail-list / outlook-mail-search: inbox; outlook-mail-send / outlook-draft / outlook-draft-send: compose and send; outlook-calendar-list / outlook-calendar-event: read calendar; outlook-calendar-create / outlook-calendar-update / outlook-calendar-cancel / outlook-calendar-respond / outlook-calendar-freebusy: control calendar; outlook-contacts-list: contacts; outlook-mailbox-info: auth state + folder count.",
3
+ "description": "Microsoft 365 / Outlook.com via Microsoft Graph. Mail is read + draft + send; contacts are read-only; calendar is read + control. Per-account OAuth device-code flow; no client secret. One account can hold several mailboxes at once; every operational tool takes an optional mailbox selector (email or graphUserId) and refuses ambiguously when two or more are attached and none is named. Tools — outlook-account-register / outlook-account-register-poll: device-code register (start + poll); outlook-mail-list / outlook-mail-search: inbox; outlook-mail-send / outlook-draft / outlook-draft-send: compose and send; outlook-calendar-list / outlook-calendar-event: read calendar; outlook-calendar-create / outlook-calendar-update / outlook-calendar-cancel / outlook-calendar-respond / outlook-calendar-freebusy: control calendar; outlook-contacts-list: contacts; outlook-mailbox-info: auth state + folder count for one mailbox; outlook-mailbox-list: every connected mailbox.",
4
4
  "version": "0.1.0",
5
5
  "author": {
6
6
  "name": "Rubytech LLC"
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: outlook
3
- description: Microsoft 365 / Outlook.com via Microsoft Graph. Mail is read + draft + send; contacts are read-only; calendar is read + control. Per-account OAuth device-code flow; no client secret. Tools — outlook-account-register / outlook-account-register-poll: device-code register (start + poll); outlook-mail-list / outlook-mail-search: inbox; outlook-mail-send / outlook-draft / outlook-draft-send: compose and send; outlook-calendar-list / outlook-calendar-event: read calendar; outlook-calendar-create / outlook-calendar-update / outlook-calendar-cancel / outlook-calendar-respond / outlook-calendar-freebusy: control calendar; outlook-contacts-list: contacts; outlook-mailbox-info: auth state + folder count.
3
+ description: Microsoft 365 / Outlook.com via Microsoft Graph. Mail is read + draft + send; contacts are read-only; calendar is read + control. Per-account OAuth device-code flow; no client secret. One account can hold several mailboxes at once; every operational tool takes an optional mailbox selector (email or graphUserId) and refuses ambiguously when two or more are attached and none is named. Tools — outlook-account-register / outlook-account-register-poll: device-code register (start + poll); outlook-mail-list / outlook-mail-search: inbox; outlook-mail-send / outlook-draft / outlook-draft-send: compose and send; outlook-calendar-list / outlook-calendar-event: read calendar; outlook-calendar-create / outlook-calendar-update / outlook-calendar-cancel / outlook-calendar-respond / outlook-calendar-freebusy: control calendar; outlook-contacts-list: contacts; outlook-mailbox-info: auth state + folder count for one mailbox; outlook-mailbox-list: every connected mailbox.
4
4
  tools:
5
5
  - name: outlook-account-register
6
6
  publicAllowlist: false
@@ -50,6 +50,9 @@ tools:
50
50
  - name: outlook-mailbox-info
51
51
  publicAllowlist: false
52
52
  adminAllowlist: false
53
+ - name: outlook-mailbox-list
54
+ publicAllowlist: false
55
+ adminAllowlist: false
53
56
  always: false
54
57
  embed: ["admin"]
55
58
  metadata: {"platform":{"optional":true}}
@@ -75,12 +78,13 @@ Microsoft Graph access for Outlook.com / Microsoft 365 mailboxes. Mail is read,
75
78
 
76
79
  ## Capabilities
77
80
 
78
- - **Register:** `outlook-account-register` — starts the OAuth device-code flow against the brand's Entra app and returns a user code + verification URL immediately. The operator opens `microsoft.com/devicelogin` on any device, enters the code, and consents. `outlook-account-register-poll` completes registration — one check per call. Tokens persist per-account, encrypted on disk (AES-256-CBC).
81
+ - **Register:** `outlook-account-register` — starts the OAuth device-code flow against the brand's Entra app and returns a user code + verification URL immediately. The operator opens `microsoft.com/devicelogin` on any device, enters the code, and consents. `outlook-account-register-poll` completes registration — one check per call. Registering a second mailbox on the same account adds it alongside the first rather than replacing it; each mailbox holds its own encrypted tokens (AES-256-CBC) under a shared account key. One device-code flow runs at a time per account; starting another while one is live returns an `in-progress` signal.
82
+ - **Multiple mailboxes:** one account can hold several mailboxes. Every operational tool takes an optional `mailbox` argument (email or graphUserId). With one mailbox, omit it. With two or more, name it — omitting it returns a refusal listing the connected mailboxes. `outlook-mailbox-list` shows them all.
79
83
  - **Mail (read):** `outlook-mail-list` returns recent messages; `outlook-mail-search` runs a Graph `$search` query.
80
84
  - **Mail (send / draft):** `outlook-mail-send` sends via `POST /me/sendMail` (success asserted on Graph 202); `outlook-draft` creates a draft and returns its id; `outlook-draft-send` sends an existing draft by id. Recipients are to/cc/bcc arrays; body is HTML or plain text via `isHtml`. Requires `Mail.Send` + `Mail.ReadWrite`; a mailbox on the old read-only consent returns an actionable "re-register to grant send" signal.
81
85
  - **Calendar (read + control):** `outlook-calendar-list` and `outlook-calendar-event` read events; `outlook-calendar-create` books an event; `outlook-calendar-update` reschedules or edits one; `outlook-calendar-cancel` cancels a meeting (notifying attendees when the account organises it) or deletes a personal appointment; `outlook-calendar-respond` accepts, declines, or tentatively accepts an invite; `outlook-calendar-freebusy` reports availability for one or more addresses over a window. Writes require the `Calendars.ReadWrite` consent; a mailbox on stale read-only consent returns a distinct signal naming the scope and `outlook-account-register`.
82
86
  - **Contacts (read-only):** `outlook-contacts-list` returns contacts.
83
- - **Health:** `outlook-mailbox-info` reports auth state, refresh-window status, and top-level folder count. Use this to answer "did account X auth?" without grepping logs.
87
+ - **Health:** `outlook-mailbox-info` reports auth state, refresh-window status, and top-level folder count for one mailbox (name it with `mailbox` when several are attached). `outlook-mailbox-list` lists every connected mailbox with its email, scopes, and token health, reading local stores only — no network — so it also flags a mailbox whose stored credentials cannot be read. Use these to answer "did mailbox X auth?" without grepping logs.
84
88
 
85
89
  ## Out of scope
86
90
 
@@ -4,7 +4,7 @@ import { mkdtempSync, rmSync } from "node:fs";
4
4
  import { tmpdir } from "node:os";
5
5
  import { join } from "node:path";
6
6
  import { PendingStore } from "../auth/pending-store.js";
7
- import { TokenStore } from "../auth/token-store.js";
7
+ import { MailboxRegistry } from "../auth/mailbox-registry.js";
8
8
  import { runAccountRegisterStart, runAccountRegisterPoll } from "../tools/account-register.js";
9
9
  const mk = () => {
10
10
  const dir = mkdtempSync(join(tmpdir(), "outlook-reg-"));
@@ -64,7 +64,7 @@ test("poll authorization_pending -> pending", async () => {
64
64
  ps.write(pendingEntry());
65
65
  const restore = withFetch([() => json({ error: "authorization_pending" }, 400)]);
66
66
  try {
67
- const out = await runAccountRegisterPoll({ accountId: "acct-2", ...cfg, tokenStore: new TokenStore("acct-2", dir), pendingStore: ps });
67
+ const out = await runAccountRegisterPoll({ accountId: "acct-2", ...cfg, registry: new MailboxRegistry("acct-2", dir), pendingStore: ps });
68
68
  assert.equal(out.status, "pending");
69
69
  }
70
70
  finally {
@@ -72,21 +72,26 @@ test("poll authorization_pending -> pending", async () => {
72
72
  cleanup();
73
73
  }
74
74
  });
75
- test("poll success -> registered, tokens persisted, pending cleared", async () => {
75
+ test("poll success -> registered under the /me mailbox, mail stored, pending cleared", async () => {
76
76
  const { dir, cleanup } = mk();
77
77
  const ps = new PendingStore("acct-3", dir);
78
78
  ps.write(pendingEntry());
79
- const ts = new TokenStore("acct-3", dir);
79
+ const reg = new MailboxRegistry("acct-3", dir);
80
80
  const restore = withFetch([
81
81
  () => json({ access_token: "AT", refresh_token: "RT", expires_in: 3600, token_type: "Bearer", scope: "offline_access User.Read Mail.ReadWrite Mail.Send Calendars.ReadWrite Contacts.Read" }),
82
82
  () => json({ id: "graph-123", mail: "a@b.com" }),
83
83
  ]);
84
84
  try {
85
- const out = await runAccountRegisterPoll({ accountId: "acct-3", ...cfg, tokenStore: ts, pendingStore: ps });
85
+ const out = await runAccountRegisterPoll({ accountId: "acct-3", ...cfg, registry: reg, pendingStore: ps });
86
86
  assert.equal(out.status, "registered");
87
- if (out.status === "registered")
87
+ if (out.status === "registered") {
88
88
  assert.equal(out.graphUserId, "graph-123");
89
- assert.equal(ts.read()?.accessToken, "AT");
89
+ assert.equal(out.mail, "a@b.com");
90
+ }
91
+ // Tokens persisted under the resolved mailbox, addressable and carrying mail.
92
+ const store = reg.storeFor("graph-123");
93
+ assert.equal(store.read()?.accessToken, "AT");
94
+ assert.equal(store.read()?.mail, "a@b.com");
90
95
  assert.equal(ps.census(), 0);
91
96
  }
92
97
  finally {
@@ -100,7 +105,7 @@ test("poll expired_token -> expired and pending cleared", async () => {
100
105
  ps.write(pendingEntry());
101
106
  const restore = withFetch([() => json({ error: "expired_token" }, 400)]);
102
107
  try {
103
- const out = await runAccountRegisterPoll({ accountId: "acct-4", ...cfg, tokenStore: new TokenStore("acct-4", dir), pendingStore: ps });
108
+ const out = await runAccountRegisterPoll({ accountId: "acct-4", ...cfg, registry: new MailboxRegistry("acct-4", dir), pendingStore: ps });
104
109
  assert.equal(out.status, "expired");
105
110
  assert.equal(ps.census(), 0);
106
111
  }
@@ -115,7 +120,7 @@ test("poll access_denied -> denied and pending cleared", async () => {
115
120
  ps.write(pendingEntry());
116
121
  const restore = withFetch([() => json({ error: "access_denied" }, 400)]);
117
122
  try {
118
- const out = await runAccountRegisterPoll({ accountId: "acct-5", ...cfg, tokenStore: new TokenStore("acct-5", dir), pendingStore: ps });
123
+ const out = await runAccountRegisterPoll({ accountId: "acct-5", ...cfg, registry: new MailboxRegistry("acct-5", dir), pendingStore: ps });
119
124
  assert.equal(out.status, "denied");
120
125
  assert.equal(ps.census(), 0);
121
126
  }
@@ -127,11 +132,96 @@ test("poll access_denied -> denied and pending cleared", async () => {
127
132
  test("poll with no pending entry -> expired", async () => {
128
133
  const { dir, cleanup } = mk();
129
134
  try {
130
- const out = await runAccountRegisterPoll({ accountId: "acct-6", ...cfg, tokenStore: new TokenStore("acct-6", dir), pendingStore: new PendingStore("acct-6", dir) });
135
+ const out = await runAccountRegisterPoll({ accountId: "acct-6", ...cfg, registry: new MailboxRegistry("acct-6", dir), pendingStore: new PendingStore("acct-6", dir) });
131
136
  assert.equal(out.status, "expired");
132
137
  }
133
138
  finally {
134
139
  cleanup();
135
140
  }
136
141
  });
142
+ test("start refuses with in-progress when a live registration is already pending", async () => {
143
+ const { dir, cleanup } = mk();
144
+ const ps = new PendingStore("acct-ip", dir);
145
+ ps.write(pendingEntry()); // live: expiresAtMs is now + 900_000
146
+ const before = ps.read()?.deviceCode;
147
+ try {
148
+ const res = await runAccountRegisterStart({ accountId: "acct-ip", ...cfg, pendingStore: ps });
149
+ assert.equal(res.status, "in-progress");
150
+ // Existing pending entry is untouched — not overwritten by a new device code.
151
+ assert.equal(ps.read()?.deviceCode, before);
152
+ }
153
+ finally {
154
+ cleanup();
155
+ }
156
+ });
157
+ test("start proceeds when the existing pending entry has expired", async () => {
158
+ const { dir, cleanup } = mk();
159
+ const ps = new PendingStore("acct-exp", dir);
160
+ ps.write({ ...pendingEntry(), deviceCode: "OLD", expiresAtMs: Date.now() - 1000 });
161
+ const restore = withFetch([() => json({
162
+ device_code: "NEW", user_code: "AAAA-1111",
163
+ verification_uri: "https://microsoft.com/devicelogin", expires_in: 900, interval: 5,
164
+ })]);
165
+ try {
166
+ const res = await runAccountRegisterStart({ accountId: "acct-exp", ...cfg, pendingStore: ps });
167
+ assert.equal(res.status, "pending");
168
+ assert.equal(ps.read()?.deviceCode, "NEW", "expired pending must be replaced");
169
+ }
170
+ finally {
171
+ restore();
172
+ cleanup();
173
+ }
174
+ });
175
+ test("a second distinct mailbox is added, not evicted (Rob then info@)", async () => {
176
+ const { dir, cleanup } = mk();
177
+ const reg = new MailboxRegistry("acct-two", dir);
178
+ // Rob completes.
179
+ let ps = new PendingStore("acct-two", dir);
180
+ ps.write(pendingEntry());
181
+ let restore = withFetch([
182
+ () => json({ access_token: "AT-rob", refresh_token: "RT", expires_in: 3600, token_type: "Bearer", scope: "Mail.Read" }),
183
+ () => json({ id: "rob-guid", mail: "rob@ecolecltd.co.uk" }),
184
+ ]);
185
+ await runAccountRegisterPoll({ accountId: "acct-two", ...cfg, registry: reg, pendingStore: ps });
186
+ restore();
187
+ // info@ completes.
188
+ ps = new PendingStore("acct-two", dir);
189
+ ps.write(pendingEntry());
190
+ restore = withFetch([
191
+ () => json({ access_token: "AT-info", refresh_token: "RT", expires_in: 3600, token_type: "Bearer", scope: "Mail.Read" }),
192
+ () => json({ id: "info-guid", mail: "info@ecolecltd.co.uk" }),
193
+ ]);
194
+ try {
195
+ await runAccountRegisterPoll({ accountId: "acct-two", ...cfg, registry: reg, pendingStore: ps });
196
+ const boxes = new MailboxRegistry("acct-two", dir).list();
197
+ assert.equal(boxes.length, 2, "both mailboxes must remain attached");
198
+ assert.equal(reg.storeFor("rob-guid").read()?.accessToken, "AT-rob", "Rob not evicted");
199
+ assert.equal(reg.storeFor("info-guid").read()?.accessToken, "AT-info");
200
+ }
201
+ finally {
202
+ restore();
203
+ cleanup();
204
+ }
205
+ });
206
+ test("re-registering the same mailbox updates in place (no duplicate)", async () => {
207
+ const { dir, cleanup } = mk();
208
+ const reg = new MailboxRegistry("acct-re", dir);
209
+ for (const at of ["AT-1", "AT-2"]) {
210
+ const ps = new PendingStore("acct-re", dir);
211
+ ps.write(pendingEntry());
212
+ const restore = withFetch([
213
+ () => json({ access_token: at, refresh_token: "RT", expires_in: 3600, token_type: "Bearer", scope: "Mail.Read" }),
214
+ () => json({ id: "same-guid", mail: "same@x.com" }),
215
+ ]);
216
+ await runAccountRegisterPoll({ accountId: "acct-re", ...cfg, registry: reg, pendingStore: ps });
217
+ restore();
218
+ }
219
+ try {
220
+ assert.equal(new MailboxRegistry("acct-re", dir).list().length, 1);
221
+ assert.equal(reg.storeFor("same-guid").read()?.accessToken, "AT-2");
222
+ }
223
+ finally {
224
+ cleanup();
225
+ }
226
+ });
137
227
  //# sourceMappingURL=account-register.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"account-register.test.js","sourceRoot":"","sources":["../../src/__tests__/account-register.test.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAE/F,MAAM,EAAE,GAAG,GAAG,EAAE;IACd,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,cAAc,CAAC,CAAC,CAAC;IACxD,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;AAC/E,CAAC,CAAC;AACF,SAAS,SAAS,CAAC,GAA0B;IAC3C,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC;IAClC,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,UAAU,CAAC,KAAK,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAiB,CAAC;IACxF,OAAO,GAAG,EAAE,GAAG,UAAU,CAAC,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;AAChD,CAAC;AACD,SAAS,aAAa;IACpB,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACtD,OAAO,CAAC,MAAM,CAAC,KAA2C,GAAG,CAAC,CAAC,CAAS,EAAE,EAAE;QAC3E,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;IACH,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,GAAI,OAAO,CAAC,MAAM,CAAC,KAAiB,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;AACvG,CAAC;AACD,MAAM,IAAI,GAAG,CAAC,CAAU,EAAE,MAAM,GAAG,GAAG,EAAE,EAAE,CACxC,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,EAAE,CAAC,CAAC;AAC/F,MAAM,GAAG,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;AACpD,MAAM,YAAY,GAAG,GAAG,EAAE,CAAC,CAAC;IAC1B,UAAU,EAAE,KAAK;IACjB,MAAM,EAAE,CAAC,WAAW,CAAC;IACrB,WAAW,EAAE,CAAC;IACd,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO;IACjC,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE;CACvB,CAAC,CAAC;AAEH,IAAI,CAAC,wEAAwE,EAAE,KAAK,IAAI,EAAE;IACxF,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC;IAC9B,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC;YACpC,WAAW,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW;YAC1C,gBAAgB,EAAE,mCAAmC,EAAE,UAAU,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC;SACpF,CAAC,CAAC,CAAC,CAAC;IACL,MAAM,GAAG,GAAG,aAAa,EAAE,CAAC;IAC5B,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,IAAI,YAAY,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QAC3C,MAAM,GAAG,GAAG,MAAM,uBAAuB,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,GAAG,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC,CAAC;QAC7F,GAAG,CAAC,OAAO,EAAE,CAAC;QACd,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QACpC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;QACxC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC;QAC3C,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,mBAAmB,CAAC,CAAC;QAC9C,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,oBAAoB,CAAC,CAAC;QAC/C,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,4CAA4C,CAAC,CAAC;IACzE,CAAC;YAAS,CAAC;QAAC,GAAG,CAAC,OAAO,EAAE,CAAC;QAAC,OAAO,EAAE,CAAC;QAAC,OAAO,EAAE,CAAC;IAAC,CAAC;AACpD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;IACvD,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC;IAC9B,MAAM,EAAE,GAAG,IAAI,YAAY,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;IAC3C,EAAE,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC,CAAC;IACzB,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,uBAAuB,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IACjF,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,sBAAsB,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,GAAG,EAAE,UAAU,EAAE,IAAI,UAAU,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC,CAAC;QACvI,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACtC,CAAC;YAAS,CAAC;QAAC,OAAO,EAAE,CAAC;QAAC,OAAO,EAAE,CAAC;IAAC,CAAC;AACrC,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,+DAA+D,EAAE,KAAK,IAAI,EAAE;IAC/E,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC;IAC9B,MAAM,EAAE,GAAG,IAAI,YAAY,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;IAC3C,EAAE,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC,CAAC;IACzB,MAAM,EAAE,GAAG,IAAI,UAAU,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;IACzC,MAAM,OAAO,GAAG,SAAS,CAAC;QACxB,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE,qFAAqF,EAAE,CAAC;QAC7L,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;KACjD,CAAC,CAAC;IACH,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,sBAAsB,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,GAAG,EAAE,UAAU,EAAE,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC,CAAC;QAC5G,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;QACvC,IAAI,GAAG,CAAC,MAAM,KAAK,YAAY;YAAE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;QAC5E,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC;QAC3C,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC;IAC/B,CAAC;YAAS,CAAC;QAAC,OAAO,EAAE,CAAC;QAAC,OAAO,EAAE,CAAC;IAAC,CAAC;AACrC,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;IACnE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC;IAC9B,MAAM,EAAE,GAAG,IAAI,YAAY,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;IAC3C,EAAE,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC,CAAC;IACzB,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,eAAe,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IACzE,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,sBAAsB,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,GAAG,EAAE,UAAU,EAAE,IAAI,UAAU,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC,CAAC;QACvI,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QACpC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC;IAC/B,CAAC;YAAS,CAAC;QAAC,OAAO,EAAE,CAAC;QAAC,OAAO,EAAE,CAAC;IAAC,CAAC;AACrC,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;IAClE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC;IAC9B,MAAM,EAAE,GAAG,IAAI,YAAY,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;IAC3C,EAAE,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC,CAAC;IACzB,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,eAAe,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IACzE,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,sBAAsB,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,GAAG,EAAE,UAAU,EAAE,IAAI,UAAU,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC,CAAC;QACvI,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QACnC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC;IAC/B,CAAC;YAAS,CAAC;QAAC,OAAO,EAAE,CAAC;QAAC,OAAO,EAAE,CAAC;IAAC,CAAC;AACrC,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;IACvD,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC;IAC9B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,sBAAsB,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,GAAG,EAAE,UAAU,EAAE,IAAI,UAAU,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE,YAAY,EAAE,IAAI,YAAY,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;QACpK,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACtC,CAAC;YAAS,CAAC;QAAC,OAAO,EAAE,CAAC;IAAC,CAAC;AAC1B,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"account-register.test.js","sourceRoot":"","sources":["../../src/__tests__/account-register.test.ts"],"names":[],"mappings":"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"}
@@ -3,7 +3,7 @@ import assert from "node:assert/strict";
3
3
  import { readFileSync } from "node:fs";
4
4
  import { fileURLToPath } from "node:url";
5
5
  import { dirname, resolve } from "node:path";
6
- import { _internals, startDeviceCode, pollDeviceToken } from "../auth/device-flow.js";
6
+ import { _internals, startDeviceCode, pollDeviceToken, parseAzureTokenError } from "../auth/device-flow.js";
7
7
  function mockFetch(handler) {
8
8
  const calls = [];
9
9
  const original = globalThis.fetch;
@@ -75,15 +75,48 @@ test("pollDeviceToken maps slow_down / expired_token / access_denied", async ()
75
75
  }
76
76
  }
77
77
  });
78
- test("pollDeviceToken throws on an unrecognised error", async () => {
79
- const m = mockFetch(() => json({ error: "invalid_client" }, 400));
78
+ test("pollDeviceToken returns a structured error (not a throw) on an unrecognised error", async () => {
79
+ const m = mockFetch(() => json({
80
+ error: "invalid_grant",
81
+ error_description: "AADSTS70008: The provided authorization code or refresh token has expired due to inactivity.",
82
+ error_codes: [70008],
83
+ suberror: "token_expired",
84
+ correlation_id: "corr-1",
85
+ trace_id: "trace-1",
86
+ timestamp: "2026-07-13 16:10:17Z",
87
+ }, 400));
80
88
  try {
81
- await assert.rejects(pollDeviceToken({ clientId: "c", tenantId: "common" }, "D"), /invalid_client/);
89
+ const out = await pollDeviceToken({ clientId: "c", tenantId: "common" }, "D");
90
+ assert.equal(out.kind, "error");
91
+ if (out.kind === "error") {
92
+ assert.equal(out.httpStatus, 400);
93
+ assert.equal(out.error, "invalid_grant");
94
+ assert.equal(out.aadsts, "AADSTS70008");
95
+ assert.equal(out.suberror, "token_expired");
96
+ assert.equal(out.correlationId, "corr-1");
97
+ assert.equal(out.traceId, "trace-1");
98
+ assert.match(out.errorDescription, /expired due to inactivity/);
99
+ }
82
100
  }
83
101
  finally {
84
102
  m.restore();
85
103
  }
86
104
  });
105
+ test("parseAzureTokenError recovers the AADSTS code from the description when error_codes is absent", () => {
106
+ const e = parseAzureTokenError(400, JSON.stringify({
107
+ error: "invalid_grant",
108
+ error_description: "AADSTS50011: The redirect URI does not match.",
109
+ }));
110
+ assert.equal(e.aadsts, "AADSTS50011");
111
+ assert.equal(e.error, "invalid_grant");
112
+ });
113
+ test("parseAzureTokenError keeps a non-JSON body in raw without throwing", () => {
114
+ const e = parseAzureTokenError(502, "<html>Bad Gateway</html>");
115
+ assert.equal(e.kind, "error");
116
+ assert.equal(e.httpStatus, 502);
117
+ assert.equal(e.aadsts, null);
118
+ assert.equal(e.raw, "<html>Bad Gateway</html>");
119
+ });
87
120
  test("pollDeviceToken 200 -> success with tokenResponse + scopes", async () => {
88
121
  const m = mockFetch(() => json({
89
122
  access_token: "AT", refresh_token: "RT", expires_in: 3600, token_type: "Bearer",
@@ -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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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=mailbox-list.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mailbox-list.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/mailbox-list.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,64 @@
1
+ import test from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import { mkdtempSync, rmSync, mkdirSync, writeFileSync } from "node:fs";
4
+ import { tmpdir } from "node:os";
5
+ import { join } from "node:path";
6
+ import { TokenStore } from "../auth/token-store.js";
7
+ import { runMailboxList } from "../tools/mailbox-list.js";
8
+ function makeAccountsDir() {
9
+ const dir = mkdtempSync(join(tmpdir(), "outlook-list-"));
10
+ return { dir, cleanup: () => rmSync(dir, { recursive: true, force: true }) };
11
+ }
12
+ test("runMailboxList reports zero mailboxes for a fresh account", () => {
13
+ const { dir, cleanup } = makeAccountsDir();
14
+ try {
15
+ const result = runMailboxList("acct", dir);
16
+ assert.equal(result.count, 0);
17
+ assert.deepEqual(result.mailboxes, []);
18
+ }
19
+ finally {
20
+ cleanup();
21
+ }
22
+ });
23
+ test("runMailboxList lists connected mailboxes with identity and token health", () => {
24
+ const { dir, cleanup } = makeAccountsDir();
25
+ try {
26
+ new TokenStore("acct", dir, "rob-guid").store("a", "r", 3600, {
27
+ graphUserId: "rob-guid", mail: "rob@ecolecltd.co.uk", scopes: ["Mail.Read"],
28
+ });
29
+ new TokenStore("acct", dir, "info-guid").store("a", "r", 3600, {
30
+ graphUserId: "info-guid", mail: "info@ecolecltd.co.uk", scopes: ["Mail.Read"],
31
+ });
32
+ const result = runMailboxList("acct", dir);
33
+ assert.equal(result.count, 2);
34
+ const rob = result.mailboxes.find((m) => m.mailbox === "rob@ecolecltd.co.uk");
35
+ assert.ok(rob);
36
+ assert.equal(rob.graphUserId, "rob-guid");
37
+ assert.equal(rob.readable, true);
38
+ assert.deepEqual(rob.scopes, ["Mail.Read"]);
39
+ }
40
+ finally {
41
+ cleanup();
42
+ }
43
+ });
44
+ test("runMailboxList reconciles an unreadable blob rather than hiding it", () => {
45
+ const { dir, cleanup } = makeAccountsDir();
46
+ try {
47
+ new TokenStore("acct", dir, "good-guid").store("a", "r", 3600, {
48
+ graphUserId: "good-guid", mail: "good@x.com", scopes: [],
49
+ });
50
+ const badDir = join(dir, "acct", "secrets", "outlook", "mailboxes", "bad-guid");
51
+ mkdirSync(badDir, { recursive: true });
52
+ writeFileSync(join(badDir, "tokens.enc"), "garbage");
53
+ const result = runMailboxList("acct", dir);
54
+ assert.equal(result.count, 2);
55
+ const bad = result.mailboxes.find((m) => m.mailboxKey === "bad-guid");
56
+ assert.ok(bad);
57
+ assert.equal(bad.readable, false);
58
+ assert.equal(result.unreadable, 1);
59
+ }
60
+ finally {
61
+ cleanup();
62
+ }
63
+ });
64
+ //# sourceMappingURL=mailbox-list.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mailbox-list.test.js","sourceRoot":"","sources":["../../src/__tests__/mailbox-list.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=mailbox-registry.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mailbox-registry.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/mailbox-registry.test.ts"],"names":[],"mappings":""}