@rubytech/create-maxy-code 0.1.459 → 0.1.461

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 (189) hide show
  1. package/dist/__tests__/cron-heartbeat-registration.test.js +57 -28
  2. package/dist/__tests__/launchd-plist.test.js +26 -0
  3. package/dist/cron-registration.js +30 -8
  4. package/dist/index.js +50 -9
  5. package/dist/launchd-plist.js +1 -1
  6. package/dist/uninstall.js +9 -3
  7. package/package.json +1 -1
  8. package/payload/platform/lib/storage-broker/dist/__tests__/cf-exec.test.js +116 -6
  9. package/payload/platform/lib/storage-broker/dist/__tests__/cf-exec.test.js.map +1 -1
  10. package/payload/platform/lib/storage-broker/dist/__tests__/object-limits.test.js +20 -0
  11. package/payload/platform/lib/storage-broker/dist/__tests__/object-limits.test.js.map +1 -1
  12. package/payload/platform/lib/storage-broker/dist/__tests__/resource-limits.test.d.ts +2 -0
  13. package/payload/platform/lib/storage-broker/dist/__tests__/resource-limits.test.d.ts.map +1 -0
  14. package/payload/platform/lib/storage-broker/dist/__tests__/resource-limits.test.js +41 -0
  15. package/payload/platform/lib/storage-broker/dist/__tests__/resource-limits.test.js.map +1 -0
  16. package/payload/platform/lib/storage-broker/dist/cf-exec.d.ts +1 -0
  17. package/payload/platform/lib/storage-broker/dist/cf-exec.d.ts.map +1 -1
  18. package/payload/platform/lib/storage-broker/dist/cf-exec.js +116 -48
  19. package/payload/platform/lib/storage-broker/dist/cf-exec.js.map +1 -1
  20. package/payload/platform/lib/storage-broker/dist/index.d.ts +1 -0
  21. package/payload/platform/lib/storage-broker/dist/index.d.ts.map +1 -1
  22. package/payload/platform/lib/storage-broker/dist/index.js +1 -0
  23. package/payload/platform/lib/storage-broker/dist/index.js.map +1 -1
  24. package/payload/platform/lib/storage-broker/dist/object-limits.d.ts +27 -0
  25. package/payload/platform/lib/storage-broker/dist/object-limits.d.ts.map +1 -1
  26. package/payload/platform/lib/storage-broker/dist/object-limits.js +27 -7
  27. package/payload/platform/lib/storage-broker/dist/object-limits.js.map +1 -1
  28. package/payload/platform/lib/storage-broker/dist/resource-limits.d.ts +102 -0
  29. package/payload/platform/lib/storage-broker/dist/resource-limits.d.ts.map +1 -0
  30. package/payload/platform/lib/storage-broker/dist/resource-limits.js +105 -0
  31. package/payload/platform/lib/storage-broker/dist/resource-limits.js.map +1 -0
  32. package/payload/platform/lib/storage-broker/src/__tests__/cf-exec.test.ts +130 -7
  33. package/payload/platform/lib/storage-broker/src/__tests__/object-limits.test.ts +30 -0
  34. package/payload/platform/lib/storage-broker/src/__tests__/resource-limits.test.ts +49 -0
  35. package/payload/platform/lib/storage-broker/src/cf-exec.ts +129 -56
  36. package/payload/platform/lib/storage-broker/src/index.ts +1 -0
  37. package/payload/platform/lib/storage-broker/src/object-limits.ts +26 -6
  38. package/payload/platform/lib/storage-broker/src/resource-limits.ts +105 -0
  39. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +5 -4
  40. package/payload/platform/plugins/cloudflare/PLUGIN.md +3 -1
  41. package/payload/platform/plugins/cloudflare/bin/portal-enrol.mjs +96 -0
  42. package/payload/platform/plugins/cloudflare/mcp/__tests__/auth-route.test.ts +220 -0
  43. package/payload/platform/plugins/cloudflare/mcp/__tests__/authorize.test.ts +201 -0
  44. package/payload/platform/plugins/cloudflare/mcp/__tests__/file-routes.test.ts +178 -0
  45. package/payload/platform/plugins/cloudflare/mcp/__tests__/harness.test.ts +32 -0
  46. package/payload/platform/plugins/cloudflare/mcp/__tests__/passcode.test.ts +204 -0
  47. package/payload/platform/plugins/cloudflare/mcp/__tests__/portal-enrol.test.ts +207 -0
  48. package/payload/platform/plugins/cloudflare/mcp/__tests__/ratelimit.test.ts +77 -0
  49. package/payload/platform/plugins/cloudflare/mcp/__tests__/skill-contract.test.ts +46 -0
  50. package/payload/platform/plugins/cloudflare/mcp/__tests__/template-config.test.ts +55 -0
  51. package/payload/platform/plugins/cloudflare/mcp/__tests__/upload-route.test.ts +255 -0
  52. package/payload/platform/plugins/cloudflare/mcp/package.json +5 -2
  53. package/payload/platform/plugins/cloudflare/references/r2-object-storage.md +46 -0
  54. package/payload/platform/plugins/cloudflare/skills/data-portal/SKILL.md +125 -0
  55. package/payload/platform/plugins/cloudflare/skills/data-portal/template/functions/api/_lib/authorize.ts +32 -0
  56. package/payload/platform/plugins/cloudflare/skills/data-portal/template/functions/api/_lib/log.ts +12 -0
  57. package/payload/platform/plugins/cloudflare/skills/data-portal/template/functions/api/_lib/passcode.mjs +193 -0
  58. package/payload/platform/plugins/cloudflare/skills/data-portal/template/functions/api/_lib/ratelimit.ts +55 -0
  59. package/payload/platform/plugins/cloudflare/skills/data-portal/template/functions/api/_lib/session.ts +85 -0
  60. package/payload/platform/plugins/cloudflare/skills/data-portal/template/functions/api/_lib/types.ts +44 -0
  61. package/payload/platform/plugins/cloudflare/skills/data-portal/template/functions/api/auth.ts +119 -0
  62. package/payload/platform/plugins/cloudflare/skills/data-portal/template/functions/api/delete.ts +89 -0
  63. package/payload/platform/plugins/cloudflare/skills/data-portal/template/functions/api/download.ts +70 -0
  64. package/payload/platform/plugins/cloudflare/skills/data-portal/template/functions/api/files.ts +41 -0
  65. package/payload/platform/plugins/cloudflare/skills/data-portal/template/functions/api/upload.ts +151 -0
  66. package/payload/platform/plugins/cloudflare/skills/data-portal/template/public/index.html +42 -0
  67. package/payload/platform/plugins/cloudflare/skills/data-portal/template/public/portal.css +113 -0
  68. package/payload/platform/plugins/cloudflare/skills/data-portal/template/public/portal.js +155 -0
  69. package/payload/platform/plugins/cloudflare/skills/data-portal/template/schema.sql +73 -0
  70. package/payload/platform/plugins/cloudflare/skills/data-portal/template/wrangler.toml +21 -0
  71. package/payload/platform/plugins/cloudflare/skills/site-deploy/SKILL.md +8 -0
  72. package/payload/platform/plugins/docs/references/outlook-guide.md +3 -3
  73. package/payload/platform/plugins/docs/references/voice-mirror-guide.md +1 -0
  74. package/payload/platform/plugins/filesystem/PLUGIN.md +0 -1
  75. package/payload/platform/plugins/filesystem/mcp/dist/lib/scope.d.ts +14 -10
  76. package/payload/platform/plugins/filesystem/mcp/dist/lib/scope.d.ts.map +1 -1
  77. package/payload/platform/plugins/filesystem/mcp/dist/lib/scope.js +14 -10
  78. package/payload/platform/plugins/filesystem/mcp/dist/lib/scope.js.map +1 -1
  79. package/payload/platform/plugins/outlook/.claude-plugin/plugin.json +1 -1
  80. package/payload/platform/plugins/outlook/PLUGIN.md +3 -5
  81. package/payload/platform/plugins/outlook/mcp/dist/__tests__/detach.test.d.ts +2 -0
  82. package/payload/platform/plugins/outlook/mcp/dist/__tests__/detach.test.d.ts.map +1 -0
  83. package/payload/platform/plugins/outlook/mcp/dist/__tests__/detach.test.js +75 -0
  84. package/payload/platform/plugins/outlook/mcp/dist/__tests__/detach.test.js.map +1 -0
  85. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-edit-removal.test.d.ts +2 -0
  86. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-edit-removal.test.d.ts.map +1 -0
  87. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-edit-removal.test.js +187 -0
  88. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-edit-removal.test.js.map +1 -0
  89. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-edit.test.js +1 -1
  90. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-edit.test.js.map +1 -1
  91. package/payload/platform/plugins/outlook/mcp/dist/index.js +3 -2
  92. package/payload/platform/plugins/outlook/mcp/dist/index.js.map +1 -1
  93. package/payload/platform/plugins/outlook/mcp/dist/lib/attachment-list.d.ts +43 -0
  94. package/payload/platform/plugins/outlook/mcp/dist/lib/attachment-list.d.ts.map +1 -0
  95. package/payload/platform/plugins/outlook/mcp/dist/lib/attachment-list.js +65 -0
  96. package/payload/platform/plugins/outlook/mcp/dist/lib/attachment-list.js.map +1 -0
  97. package/payload/platform/plugins/outlook/mcp/dist/lib/detach.d.ts +65 -0
  98. package/payload/platform/plugins/outlook/mcp/dist/lib/detach.d.ts.map +1 -0
  99. package/payload/platform/plugins/outlook/mcp/dist/lib/detach.js +99 -0
  100. package/payload/platform/plugins/outlook/mcp/dist/lib/detach.js.map +1 -0
  101. package/payload/platform/plugins/outlook/mcp/dist/lib/outbound-attachments.d.ts +6 -1
  102. package/payload/platform/plugins/outlook/mcp/dist/lib/outbound-attachments.d.ts.map +1 -1
  103. package/payload/platform/plugins/outlook/mcp/dist/lib/outbound-attachments.js.map +1 -1
  104. package/payload/platform/plugins/outlook/mcp/dist/tools/draft-edit.d.ts +42 -22
  105. package/payload/platform/plugins/outlook/mcp/dist/tools/draft-edit.d.ts.map +1 -1
  106. package/payload/platform/plugins/outlook/mcp/dist/tools/draft-edit.js +59 -23
  107. package/payload/platform/plugins/outlook/mcp/dist/tools/draft-edit.js.map +1 -1
  108. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-attachment.d.ts +15 -16
  109. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-attachment.d.ts.map +1 -1
  110. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-attachment.js +8 -41
  111. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-attachment.js.map +1 -1
  112. package/payload/platform/plugins/outlook/references/auth.md +1 -1
  113. package/payload/platform/plugins/outlook/references/graph-surfaces.md +7 -3
  114. package/payload/platform/plugins/outlook/skills/outlook/SKILL.md +1 -1
  115. package/payload/platform/plugins/storage-broker/PLUGIN.md +1 -1
  116. package/payload/platform/plugins/voice-mirror/PLUGIN.md +19 -7
  117. package/payload/platform/plugins/voice-mirror/mcp/dist/index.d.ts.map +1 -1
  118. package/payload/platform/plugins/voice-mirror/mcp/dist/index.js +35 -16
  119. package/payload/platform/plugins/voice-mirror/mcp/dist/index.js.map +1 -1
  120. package/payload/platform/plugins/voice-mirror/mcp/dist/lib/admin-user.d.ts +31 -0
  121. package/payload/platform/plugins/voice-mirror/mcp/dist/lib/admin-user.d.ts.map +1 -0
  122. package/payload/platform/plugins/voice-mirror/mcp/dist/lib/admin-user.js +87 -0
  123. package/payload/platform/plugins/voice-mirror/mcp/dist/lib/admin-user.js.map +1 -0
  124. package/payload/platform/plugins/voice-mirror/mcp/dist/tools/voice-distil-profile.d.ts.map +1 -1
  125. package/payload/platform/plugins/voice-mirror/mcp/dist/tools/voice-distil-profile.js +111 -12
  126. package/payload/platform/plugins/voice-mirror/mcp/dist/tools/voice-distil-profile.js.map +1 -1
  127. package/payload/platform/plugins/voice-mirror/mcp/dist/tools/voice-ingest-session-text.d.ts.map +1 -1
  128. package/payload/platform/plugins/voice-mirror/mcp/dist/tools/voice-ingest-session-text.js +2 -1
  129. package/payload/platform/plugins/voice-mirror/mcp/dist/tools/voice-ingest-session-text.js.map +1 -1
  130. package/payload/platform/plugins/voice-mirror/mcp/dist/tools/voice-record-feedback.d.ts.map +1 -1
  131. package/payload/platform/plugins/voice-mirror/mcp/dist/tools/voice-record-feedback.js +2 -1
  132. package/payload/platform/plugins/voice-mirror/mcp/dist/tools/voice-record-feedback.js.map +1 -1
  133. package/payload/platform/plugins/voice-mirror/mcp/dist/tools/voice-retrieve-conditioning.d.ts.map +1 -1
  134. package/payload/platform/plugins/voice-mirror/mcp/dist/tools/voice-retrieve-conditioning.js +54 -21
  135. package/payload/platform/plugins/voice-mirror/mcp/dist/tools/voice-retrieve-conditioning.js.map +1 -1
  136. package/payload/platform/plugins/voice-mirror/mcp/dist/tools/voice-tag-content.d.ts +2 -2
  137. package/payload/platform/plugins/voice-mirror/mcp/dist/tools/voice-tag-content.d.ts.map +1 -1
  138. package/payload/platform/plugins/voice-mirror/mcp/dist/tools/voice-tag-content.js +12 -3
  139. package/payload/platform/plugins/voice-mirror/mcp/dist/tools/voice-tag-content.js.map +1 -1
  140. package/payload/platform/plugins/voice-mirror/mcp/scripts/smoke.mjs +444 -0
  141. package/payload/platform/plugins/voice-mirror/skills/voice-mirror/SKILL.md +18 -2
  142. package/payload/platform/scripts/__tests__/logs-rotate.test.sh +256 -0
  143. package/payload/platform/scripts/__tests__/resume-tunnel.test.sh +79 -0
  144. package/payload/platform/scripts/logs-rotate.sh +204 -0
  145. package/payload/platform/scripts/resume-tunnel.sh +27 -0
  146. package/payload/platform/scripts/voice-author-key-audit.sh +155 -0
  147. package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
  148. package/payload/platform/services/claude-session-manager/dist/http-server.js +41 -5
  149. package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
  150. package/payload/platform/services/claude-session-manager/dist/index.d.ts +1 -0
  151. package/payload/platform/services/claude-session-manager/dist/index.d.ts.map +1 -1
  152. package/payload/platform/services/claude-session-manager/dist/index.js +22 -0
  153. package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
  154. package/payload/platform/services/claude-session-manager/dist/install-start-counter.d.ts +2 -0
  155. package/payload/platform/services/claude-session-manager/dist/install-start-counter.d.ts.map +1 -0
  156. package/payload/platform/services/claude-session-manager/dist/install-start-counter.js +12 -0
  157. package/payload/platform/services/claude-session-manager/dist/install-start-counter.js.map +1 -0
  158. package/payload/platform/services/claude-session-manager/dist/mcp-descriptor-resolve.d.ts +17 -0
  159. package/payload/platform/services/claude-session-manager/dist/mcp-descriptor-resolve.d.ts.map +1 -0
  160. package/payload/platform/services/claude-session-manager/dist/mcp-descriptor-resolve.js +88 -0
  161. package/payload/platform/services/claude-session-manager/dist/mcp-descriptor-resolve.js.map +1 -0
  162. package/payload/platform/services/claude-session-manager/dist/pty-census.d.ts +122 -9
  163. package/payload/platform/services/claude-session-manager/dist/pty-census.d.ts.map +1 -1
  164. package/payload/platform/services/claude-session-manager/dist/pty-census.js +214 -29
  165. package/payload/platform/services/claude-session-manager/dist/pty-census.js.map +1 -1
  166. package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts +0 -1
  167. package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts.map +1 -1
  168. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js +36 -24
  169. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
  170. package/payload/platform/services/claude-session-manager/dist/rc-daemon.d.ts.map +1 -1
  171. package/payload/platform/services/claude-session-manager/dist/rc-daemon.js +13 -1
  172. package/payload/platform/services/claude-session-manager/dist/rc-daemon.js.map +1 -1
  173. package/payload/platform/services/claude-session-manager/dist/session-memory-cap.d.ts.map +1 -1
  174. package/payload/platform/services/claude-session-manager/dist/session-memory-cap.js +4 -2
  175. package/payload/platform/services/claude-session-manager/dist/session-memory-cap.js.map +1 -1
  176. package/payload/platform/services/claude-session-manager/dist/slice-memory-policy.d.ts +150 -0
  177. package/payload/platform/services/claude-session-manager/dist/slice-memory-policy.d.ts.map +1 -0
  178. package/payload/platform/services/claude-session-manager/dist/slice-memory-policy.js +333 -0
  179. package/payload/platform/services/claude-session-manager/dist/slice-memory-policy.js.map +1 -0
  180. package/payload/platform/services/claude-session-manager/dist/start-counter.d.ts +10 -0
  181. package/payload/platform/services/claude-session-manager/dist/start-counter.d.ts.map +1 -0
  182. package/payload/platform/services/claude-session-manager/dist/start-counter.js +55 -0
  183. package/payload/platform/services/claude-session-manager/dist/start-counter.js.map +1 -0
  184. package/payload/server/{chunk-Q6W4U6HL.js → chunk-JXWFVE5X.js} +83 -39
  185. package/payload/server/server.js +268 -73
  186. package/payload/server/{src-3I2RYZFB.js → src-4F37OHLK.js} +11 -1
  187. package/payload/platform/plugins/outlook/mcp/dist/__tests__/pkce-flow.test.d.ts +0 -2
  188. package/payload/platform/plugins/outlook/mcp/dist/__tests__/pkce-flow.test.js +0 -215
  189. package/payload/platform/plugins/outlook/mcp/dist/__tests__/pkce-flow.test.js.map +0 -1
@@ -1,215 +0,0 @@
1
- import test from "node:test";
2
- import assert from "node:assert/strict";
3
- import { _internals, startPkceFlow } from "../auth/pkce-flow.js";
4
- const { sameLengthEqual } = _internals;
5
- // ---------------------------------------------------------------------------
6
- // sameLengthEqual: timing-safe state comparison
7
- // ---------------------------------------------------------------------------
8
- test("sameLengthEqual matches identical strings", () => {
9
- assert.equal(sameLengthEqual("abcdef0123456789", "abcdef0123456789"), true);
10
- });
11
- test("sameLengthEqual rejects different equal-length strings", () => {
12
- assert.equal(sameLengthEqual("abcdef0123456789", "abcdef0123456780"), false);
13
- });
14
- test("sameLengthEqual rejects length mismatch without throwing", () => {
15
- assert.equal(sameLengthEqual("short", "longerstring"), false);
16
- });
17
- function mockFetch(handler) {
18
- const calls = [];
19
- const original = globalThis.fetch;
20
- globalThis.fetch = (async (url, init) => {
21
- const urlStr = typeof url === "string" ? url : url instanceof URL ? url.toString() : url.url;
22
- // Pass loopback callbacks through to the real fetch — only the upstream
23
- // token endpoint is intercepted. Otherwise the test's own callback
24
- // request would loop back into the mock and never reach the bound server.
25
- if (urlStr.startsWith("http://127.0.0.1:") || urlStr.startsWith("http://localhost:")) {
26
- return original(url, init);
27
- }
28
- calls.push({ url: urlStr, init });
29
- return handler(urlStr, init);
30
- });
31
- return {
32
- calls,
33
- restore: () => {
34
- globalThis.fetch = original;
35
- },
36
- };
37
- }
38
- function tokenSuccess() {
39
- return new Response(JSON.stringify({
40
- access_token: "test-access",
41
- refresh_token: "test-refresh",
42
- expires_in: 3600,
43
- token_type: "Bearer",
44
- scope: "offline_access User.Read Mail.ReadWrite Mail.Send Calendars.ReadWrite Contacts.Read",
45
- }), { status: 200, headers: { "Content-Type": "application/json" } });
46
- }
47
- function extractStateFromAuthUrl(authUrl) {
48
- const url = new URL(authUrl);
49
- const state = url.searchParams.get("state");
50
- assert.ok(state, "auth URL must include state param");
51
- return state;
52
- }
53
- function extractRedirectUriPort(redirectUri) {
54
- const url = new URL(redirectUri);
55
- return Number(url.port);
56
- }
57
- test("PKCE happy path: state matches → tokens exchanged", async () => {
58
- const fetchMock = mockFetch(() => tokenSuccess());
59
- try {
60
- const flow = await startPkceFlow({
61
- clientId: "test-client",
62
- tenantId: "common",
63
- accountId: "acct-pkce-1",
64
- });
65
- const state = extractStateFromAuthUrl(flow.authUrl);
66
- const port = extractRedirectUriPort(flow.redirectUri);
67
- // Drive the callback synthetically, as Microsoft would after consent.
68
- const callbackResp = await fetch(`http://127.0.0.1:${port}/callback?code=fake-code&state=${state}`);
69
- assert.equal(callbackResp.status, 200);
70
- const result = await flow.result;
71
- assert.equal(result.tokenResponse.access_token, "test-access");
72
- assert.equal(result.tokenResponse.refresh_token, "test-refresh");
73
- assert.deepEqual(result.scopes.sort(), [
74
- "Calendars.ReadWrite",
75
- "Contacts.Read",
76
- "Mail.ReadWrite",
77
- "Mail.Send",
78
- "User.Read",
79
- "offline_access",
80
- ].sort());
81
- // Token endpoint was called with code + verifier + redirect_uri.
82
- assert.equal(fetchMock.calls.length, 1);
83
- const body = String(fetchMock.calls[0].init?.body ?? "");
84
- assert.match(body, /code=fake-code/);
85
- assert.match(body, /code_verifier=/);
86
- assert.match(body, /grant_type=authorization_code/);
87
- }
88
- finally {
89
- fetchMock.restore();
90
- }
91
- });
92
- test("PKCE state mismatch → flow rejects, token endpoint NOT called", async () => {
93
- const fetchMock = mockFetch(() => {
94
- throw new Error("token endpoint should not be called on state mismatch");
95
- });
96
- try {
97
- const flow = await startPkceFlow({
98
- clientId: "test-client",
99
- tenantId: "common",
100
- accountId: "acct-pkce-2",
101
- });
102
- // Subscribe BEFORE driving the callback — otherwise the rejection lands
103
- // before any handler is attached and Node flags it as unhandled.
104
- const rejection = assert.rejects(flow.result, /State mismatch/i);
105
- const port = extractRedirectUriPort(flow.redirectUri);
106
- const cbResp = await fetch(`http://127.0.0.1:${port}/callback?code=fake-code&state=wrong-state-value`);
107
- assert.equal(cbResp.status, 400);
108
- await rejection;
109
- assert.equal(fetchMock.calls.length, 0, "token endpoint must not be called");
110
- }
111
- finally {
112
- fetchMock.restore();
113
- }
114
- });
115
- test("PKCE OAuth error in callback → flow rejects, no token call", async () => {
116
- const fetchMock = mockFetch(() => {
117
- throw new Error("token endpoint should not be called on OAuth error");
118
- });
119
- try {
120
- const flow = await startPkceFlow({
121
- clientId: "test-client",
122
- tenantId: "common",
123
- accountId: "acct-pkce-3",
124
- });
125
- const rejection = assert.rejects(flow.result, /OAuth error: access_denied/);
126
- const state = extractStateFromAuthUrl(flow.authUrl);
127
- const port = extractRedirectUriPort(flow.redirectUri);
128
- const cbResp = await fetch(`http://127.0.0.1:${port}/callback?error=access_denied&error_description=user%20cancelled&state=${state}`);
129
- assert.equal(cbResp.status, 400);
130
- await rejection;
131
- assert.equal(fetchMock.calls.length, 0);
132
- }
133
- finally {
134
- fetchMock.restore();
135
- }
136
- });
137
- test("PKCE callback missing code → flow rejects", async () => {
138
- const fetchMock = mockFetch(() => {
139
- throw new Error("token endpoint should not be called");
140
- });
141
- try {
142
- const flow = await startPkceFlow({
143
- clientId: "test-client",
144
- tenantId: "common",
145
- accountId: "acct-pkce-4",
146
- });
147
- const rejection = assert.rejects(flow.result, /No authorization code received/);
148
- const state = extractStateFromAuthUrl(flow.authUrl);
149
- const port = extractRedirectUriPort(flow.redirectUri);
150
- const cbResp = await fetch(`http://127.0.0.1:${port}/callback?state=${state}`);
151
- assert.equal(cbResp.status, 400);
152
- await rejection;
153
- assert.equal(fetchMock.calls.length, 0);
154
- }
155
- finally {
156
- fetchMock.restore();
157
- }
158
- });
159
- test("PKCE auth URL has S256 challenge + correct scopes + prompt=select_account", async () => {
160
- // No mock needed — we assert URL structure and abort the flow without
161
- // exchanging tokens. Sending an OAuth error in the callback closes the
162
- // server and rejects flow.result loudly; we catch it explicitly.
163
- const flow = await startPkceFlow({
164
- clientId: "client-X",
165
- tenantId: "common",
166
- accountId: "acct-pkce-5",
167
- });
168
- const expectedRejection = assert.rejects(flow.result, /OAuth error/);
169
- try {
170
- const url = new URL(flow.authUrl);
171
- assert.equal(url.searchParams.get("client_id"), "client-X");
172
- assert.equal(url.searchParams.get("response_type"), "code");
173
- assert.equal(url.searchParams.get("code_challenge_method"), "S256");
174
- assert.equal(url.searchParams.get("prompt"), "select_account");
175
- const challenge = url.searchParams.get("code_challenge");
176
- assert.ok(challenge && challenge.length > 30, "challenge should be base64url-encoded SHA-256");
177
- const scope = url.searchParams.get("scope") ?? "";
178
- assert.match(scope, /offline_access/);
179
- assert.match(scope, /User\.Read/);
180
- assert.match(scope, /Mail\.ReadWrite/);
181
- assert.match(scope, /Mail\.Send/);
182
- assert.match(scope, /Calendars\.ReadWrite/);
183
- assert.match(scope, /Contacts\.Read/);
184
- // Abort the flow by sending an OAuth error. Server closes; result rejects.
185
- const port = extractRedirectUriPort(flow.redirectUri);
186
- const state = url.searchParams.get("state");
187
- await fetch(`http://127.0.0.1:${port}/callback?error=access_denied&state=${state}`);
188
- }
189
- finally {
190
- await expectedRejection;
191
- }
192
- });
193
- test("PKCE redirect URI uses ephemeral loopback port (not fixed 49152)", async () => {
194
- // No token-exchange mock — abort each flow with an OAuth error so the
195
- // server closes without invoking exchangeCode.
196
- const flow1 = await startPkceFlow({ clientId: "c", tenantId: "common", accountId: "a1" });
197
- const flow2 = await startPkceFlow({ clientId: "c", tenantId: "common", accountId: "a2" });
198
- const r1 = assert.rejects(flow1.result, /OAuth error/);
199
- const r2 = assert.rejects(flow2.result, /OAuth error/);
200
- try {
201
- const port1 = extractRedirectUriPort(flow1.redirectUri);
202
- const port2 = extractRedirectUriPort(flow2.redirectUri);
203
- assert.ok(port1 > 0 && port1 < 65536);
204
- assert.ok(port2 > 0 && port2 < 65536);
205
- assert.notEqual(port1, port2, "two parallel flows must allocate different ephemeral ports");
206
- const s1 = extractStateFromAuthUrl(flow1.authUrl);
207
- const s2 = extractStateFromAuthUrl(flow2.authUrl);
208
- await fetch(`http://127.0.0.1:${port1}/callback?error=access_denied&state=${s1}`);
209
- await fetch(`http://127.0.0.1:${port2}/callback?error=access_denied&state=${s2}`);
210
- }
211
- finally {
212
- await Promise.all([r1, r2]);
213
- }
214
- });
215
- //# sourceMappingURL=pkce-flow.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pkce-flow.test.js","sourceRoot":"","sources":["../../src/__tests__/pkce-flow.test.ts"],"names":[],"mappings":"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"}