mcp-twake-mail 0.1.0 → 2.0.0

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 (86) hide show
  1. package/README.md +168 -74
  2. package/build/cli/commands/setup.js +54 -12
  3. package/build/cli/commands/setup.js.map +1 -1
  4. package/build/cli/prompts/setup-wizard.d.ts +33 -1
  5. package/build/cli/prompts/setup-wizard.js +134 -2
  6. package/build/cli/prompts/setup-wizard.js.map +1 -1
  7. package/build/cli/prompts/setup-wizard.test.d.ts +1 -0
  8. package/build/cli/prompts/setup-wizard.test.js +161 -0
  9. package/build/cli/prompts/setup-wizard.test.js.map +1 -0
  10. package/build/config/schema.d.ts +2 -0
  11. package/build/config/schema.js +3 -0
  12. package/build/config/schema.js.map +1 -1
  13. package/build/discovery/dns-srv.d.ts +18 -0
  14. package/build/discovery/dns-srv.js +60 -0
  15. package/build/discovery/dns-srv.js.map +1 -0
  16. package/build/discovery/dns-srv.test.d.ts +4 -0
  17. package/build/discovery/dns-srv.test.js +79 -0
  18. package/build/discovery/dns-srv.test.js.map +1 -0
  19. package/build/discovery/index.d.ts +9 -0
  20. package/build/discovery/index.js +13 -0
  21. package/build/discovery/index.js.map +1 -0
  22. package/build/discovery/oauth-discovery.d.ts +34 -0
  23. package/build/discovery/oauth-discovery.js +160 -0
  24. package/build/discovery/oauth-discovery.js.map +1 -0
  25. package/build/discovery/oauth-discovery.test.d.ts +1 -0
  26. package/build/discovery/oauth-discovery.test.js +198 -0
  27. package/build/discovery/oauth-discovery.test.js.map +1 -0
  28. package/build/discovery/orchestrator.d.ts +31 -0
  29. package/build/discovery/orchestrator.js +87 -0
  30. package/build/discovery/orchestrator.js.map +1 -0
  31. package/build/discovery/orchestrator.test.d.ts +4 -0
  32. package/build/discovery/orchestrator.test.js +242 -0
  33. package/build/discovery/orchestrator.test.js.map +1 -0
  34. package/build/discovery/types.d.ts +18 -0
  35. package/build/discovery/types.js +15 -0
  36. package/build/discovery/types.js.map +1 -0
  37. package/build/discovery/well-known.d.ts +21 -0
  38. package/build/discovery/well-known.js +52 -0
  39. package/build/discovery/well-known.js.map +1 -0
  40. package/build/discovery/well-known.test.d.ts +4 -0
  41. package/build/discovery/well-known.test.js +120 -0
  42. package/build/discovery/well-known.test.js.map +1 -0
  43. package/build/jmap/client.js +1 -1
  44. package/build/jmap/client.js.map +1 -1
  45. package/build/mcp/server.d.ts +5 -3
  46. package/build/mcp/server.js +11 -5
  47. package/build/mcp/server.js.map +1 -1
  48. package/build/mcp/tools/batch-operations.d.ts +10 -0
  49. package/build/mcp/tools/batch-operations.js +609 -0
  50. package/build/mcp/tools/batch-operations.js.map +1 -0
  51. package/build/mcp/tools/batch-operations.test.d.ts +1 -0
  52. package/build/mcp/tools/batch-operations.test.js +875 -0
  53. package/build/mcp/tools/batch-operations.test.js.map +1 -0
  54. package/build/mcp/tools/email-operations.js +355 -1
  55. package/build/mcp/tools/email-operations.js.map +1 -1
  56. package/build/mcp/tools/email-operations.test.js +5 -3
  57. package/build/mcp/tools/email-operations.test.js.map +1 -1
  58. package/build/mcp/tools/email-sending.d.ts +10 -1
  59. package/build/mcp/tools/email-sending.js +481 -14
  60. package/build/mcp/tools/email-sending.js.map +1 -1
  61. package/build/mcp/tools/index.d.ts +10 -1
  62. package/build/mcp/tools/index.js +7 -3
  63. package/build/mcp/tools/index.js.map +1 -1
  64. package/build/mcp/tools/mailbox.js +433 -1
  65. package/build/mcp/tools/mailbox.js.map +1 -1
  66. package/build/mcp/tools/mailbox.test.js +5 -2
  67. package/build/mcp/tools/mailbox.test.js.map +1 -1
  68. package/build/signature/converter.d.ts +2 -0
  69. package/build/signature/converter.js +23 -0
  70. package/build/signature/converter.js.map +1 -0
  71. package/build/signature/converter.test.d.ts +1 -0
  72. package/build/signature/converter.test.js +84 -0
  73. package/build/signature/converter.test.js.map +1 -0
  74. package/build/signature/index.d.ts +2 -0
  75. package/build/signature/index.js +3 -0
  76. package/build/signature/index.js.map +1 -0
  77. package/build/signature/loader.d.ts +6 -0
  78. package/build/signature/loader.js +31 -0
  79. package/build/signature/loader.js.map +1 -0
  80. package/build/signature/loader.test.d.ts +1 -0
  81. package/build/signature/loader.test.js +85 -0
  82. package/build/signature/loader.test.js.map +1 -0
  83. package/build/types/jmap.d.ts +23 -0
  84. package/docs/auto-discovery.md +210 -0
  85. package/docs/oidc-configuration.md +261 -0
  86. package/package.json +3 -1
@@ -0,0 +1,242 @@
1
+ /**
2
+ * Tests for discovery orchestrator
3
+ */
4
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
5
+ import { discoverFromEmail, extractDomain } from './orchestrator.js';
6
+ import { DiscoveryError } from './types.js';
7
+ // Mock the discovery modules
8
+ vi.mock('./dns-srv.js');
9
+ vi.mock('./well-known.js');
10
+ vi.mock('./oauth-discovery.js');
11
+ import { resolveSrvRecord } from './dns-srv.js';
12
+ import { fetchWellKnownJmap, verifyJmapUrl } from './well-known.js';
13
+ import { discoverOAuthFromResource } from './oauth-discovery.js';
14
+ describe('extractDomain', () => {
15
+ it('extracts domain from valid email', () => {
16
+ expect(extractDomain('user@example.com')).toBe('example.com');
17
+ });
18
+ it('extracts domain from email with subdomain', () => {
19
+ expect(extractDomain('user@mail.example.com')).toBe('mail.example.com');
20
+ });
21
+ it('throws on email without @', () => {
22
+ expect(() => extractDomain('userexample.com')).toThrow('Invalid email format');
23
+ });
24
+ it('throws on domain without dot', () => {
25
+ expect(() => extractDomain('user@localhost')).toThrow('Invalid email format');
26
+ });
27
+ it('throws on multiple @ symbols', () => {
28
+ expect(() => extractDomain('user@test@example.com')).toThrow('Invalid email format');
29
+ });
30
+ it('throws on empty domain', () => {
31
+ expect(() => extractDomain('user@')).toThrow('Invalid email format');
32
+ });
33
+ });
34
+ describe('discoverFromEmail', () => {
35
+ beforeEach(() => {
36
+ vi.clearAllMocks();
37
+ });
38
+ describe('DNS SRV success path', () => {
39
+ it('discovers via DNS SRV with standard port', async () => {
40
+ // Mock DNS SRV success
41
+ vi.mocked(resolveSrvRecord).mockResolvedValue({
42
+ hostname: 'jmap.example.com',
43
+ port: 443,
44
+ });
45
+ // Mock URL verification
46
+ vi.mocked(verifyJmapUrl).mockResolvedValue('https://jmap.example.com/.well-known/jmap');
47
+ // Mock OAuth discovery
48
+ vi.mocked(discoverOAuthFromResource).mockResolvedValue({
49
+ issuer: 'https://auth.example.com',
50
+ method: 'protected-resource',
51
+ });
52
+ const result = await discoverFromEmail('user@example.com');
53
+ expect(result).toEqual({
54
+ jmap: {
55
+ sessionUrl: 'https://jmap.example.com/.well-known/jmap',
56
+ method: 'dns-srv',
57
+ },
58
+ oidc: {
59
+ issuer: 'https://auth.example.com',
60
+ method: 'protected-resource',
61
+ },
62
+ email: 'user@example.com',
63
+ domain: 'example.com',
64
+ });
65
+ // Verify correct URL was constructed
66
+ expect(verifyJmapUrl).toHaveBeenCalledWith('https://jmap.example.com/.well-known/jmap');
67
+ });
68
+ it('discovers via DNS SRV with non-standard port', async () => {
69
+ // Mock DNS SRV success with non-standard port
70
+ vi.mocked(resolveSrvRecord).mockResolvedValue({
71
+ hostname: 'jmap.example.com',
72
+ port: 8443,
73
+ });
74
+ // Mock URL verification
75
+ vi.mocked(verifyJmapUrl).mockResolvedValue('https://jmap.example.com:8443/.well-known/jmap');
76
+ // Mock OAuth discovery (no OAuth info)
77
+ vi.mocked(discoverOAuthFromResource).mockResolvedValue(null);
78
+ const result = await discoverFromEmail('user@example.com');
79
+ expect(result).toEqual({
80
+ jmap: {
81
+ sessionUrl: 'https://jmap.example.com:8443/.well-known/jmap',
82
+ method: 'dns-srv',
83
+ },
84
+ oidc: undefined,
85
+ email: 'user@example.com',
86
+ domain: 'example.com',
87
+ });
88
+ // Verify URL includes non-standard port
89
+ expect(verifyJmapUrl).toHaveBeenCalledWith('https://jmap.example.com:8443/.well-known/jmap');
90
+ });
91
+ it('discovers without OAuth info', async () => {
92
+ // Mock DNS SRV success
93
+ vi.mocked(resolveSrvRecord).mockResolvedValue({
94
+ hostname: 'jmap.example.com',
95
+ port: 443,
96
+ });
97
+ // Mock URL verification
98
+ vi.mocked(verifyJmapUrl).mockResolvedValue('https://jmap.example.com/.well-known/jmap');
99
+ // Mock OAuth discovery returning null
100
+ vi.mocked(discoverOAuthFromResource).mockResolvedValue(null);
101
+ const result = await discoverFromEmail('user@example.com');
102
+ expect(result.oidc).toBeUndefined();
103
+ expect(result.jmap.sessionUrl).toBe('https://jmap.example.com/.well-known/jmap');
104
+ });
105
+ });
106
+ describe('Well-known fallback path', () => {
107
+ it('falls back to well-known when DNS SRV returns null', async () => {
108
+ // Mock DNS SRV failure
109
+ vi.mocked(resolveSrvRecord).mockResolvedValue(null);
110
+ // Mock well-known success
111
+ vi.mocked(fetchWellKnownJmap).mockResolvedValue('https://example.com/jmap/session');
112
+ // Mock OAuth discovery
113
+ vi.mocked(discoverOAuthFromResource).mockResolvedValue({
114
+ issuer: 'https://auth.example.com',
115
+ method: 'www-authenticate',
116
+ });
117
+ const result = await discoverFromEmail('user@example.com');
118
+ expect(result).toEqual({
119
+ jmap: {
120
+ sessionUrl: 'https://example.com/jmap/session',
121
+ method: 'well-known-direct',
122
+ },
123
+ oidc: {
124
+ issuer: 'https://auth.example.com',
125
+ method: 'www-authenticate',
126
+ },
127
+ email: 'user@example.com',
128
+ domain: 'example.com',
129
+ });
130
+ // Verify DNS SRV was tried first
131
+ expect(resolveSrvRecord).toHaveBeenCalledWith('example.com');
132
+ // Verify well-known was called
133
+ expect(fetchWellKnownJmap).toHaveBeenCalledWith('example.com');
134
+ });
135
+ it('falls back to well-known when DNS SRV verification fails', async () => {
136
+ // Mock DNS SRV success but verification failure
137
+ vi.mocked(resolveSrvRecord).mockResolvedValue({
138
+ hostname: 'jmap.example.com',
139
+ port: 443,
140
+ });
141
+ vi.mocked(verifyJmapUrl).mockResolvedValue(null);
142
+ // Mock well-known success
143
+ vi.mocked(fetchWellKnownJmap).mockResolvedValue('https://example.com/.well-known/jmap');
144
+ // Mock no OAuth
145
+ vi.mocked(discoverOAuthFromResource).mockResolvedValue(null);
146
+ const result = await discoverFromEmail('user@example.com');
147
+ expect(result.jmap.method).toBe('well-known-direct');
148
+ expect(result.jmap.sessionUrl).toBe('https://example.com/.well-known/jmap');
149
+ // Verify both were tried
150
+ expect(resolveSrvRecord).toHaveBeenCalled();
151
+ expect(fetchWellKnownJmap).toHaveBeenCalled();
152
+ });
153
+ });
154
+ describe('Complete failure path', () => {
155
+ it('throws DiscoveryError when all methods fail', async () => {
156
+ // Mock DNS SRV failure
157
+ vi.mocked(resolveSrvRecord).mockResolvedValue(null);
158
+ // Mock well-known failure
159
+ vi.mocked(fetchWellKnownJmap).mockResolvedValue(null);
160
+ await expect(discoverFromEmail('user@example.com')).rejects.toThrow(DiscoveryError);
161
+ await expect(discoverFromEmail('user@example.com')).rejects.toThrow('Could not discover JMAP server for domain "example.com"');
162
+ });
163
+ it('throws DiscoveryError with correct domain and stage', async () => {
164
+ // Mock all failures
165
+ vi.mocked(resolveSrvRecord).mockResolvedValue(null);
166
+ vi.mocked(fetchWellKnownJmap).mockResolvedValue(null);
167
+ try {
168
+ await discoverFromEmail('user@example.com');
169
+ expect.fail('Should have thrown DiscoveryError');
170
+ }
171
+ catch (error) {
172
+ expect(error).toBeInstanceOf(DiscoveryError);
173
+ if (error instanceof DiscoveryError) {
174
+ expect(error.domain).toBe('example.com');
175
+ expect(error.stage).toBe('well-known');
176
+ }
177
+ }
178
+ });
179
+ it('throws on invalid email format', async () => {
180
+ await expect(discoverFromEmail('not-an-email')).rejects.toThrow('Invalid email format');
181
+ // Verify no discovery methods were called
182
+ expect(resolveSrvRecord).not.toHaveBeenCalled();
183
+ expect(fetchWellKnownJmap).not.toHaveBeenCalled();
184
+ });
185
+ });
186
+ describe('OAuth discovery integration', () => {
187
+ it('includes OAuth info when discovered via protected-resource', async () => {
188
+ vi.mocked(resolveSrvRecord).mockResolvedValue({
189
+ hostname: 'jmap.example.com',
190
+ port: 443,
191
+ });
192
+ vi.mocked(verifyJmapUrl).mockResolvedValue('https://jmap.example.com/.well-known/jmap');
193
+ vi.mocked(discoverOAuthFromResource).mockResolvedValue({
194
+ issuer: 'https://auth.example.com',
195
+ clientId: 'optional-client-id',
196
+ method: 'protected-resource',
197
+ });
198
+ const result = await discoverFromEmail('user@example.com');
199
+ expect(result.oidc).toEqual({
200
+ issuer: 'https://auth.example.com',
201
+ clientId: 'optional-client-id',
202
+ method: 'protected-resource',
203
+ });
204
+ });
205
+ it('includes OAuth info when discovered via www-authenticate', async () => {
206
+ vi.mocked(resolveSrvRecord).mockResolvedValue(null);
207
+ vi.mocked(fetchWellKnownJmap).mockResolvedValue('https://example.com/.well-known/jmap');
208
+ vi.mocked(discoverOAuthFromResource).mockResolvedValue({
209
+ issuer: 'https://auth.example.com',
210
+ method: 'www-authenticate',
211
+ });
212
+ const result = await discoverFromEmail('user@example.com');
213
+ expect(result.oidc).toEqual({
214
+ issuer: 'https://auth.example.com',
215
+ method: 'www-authenticate',
216
+ });
217
+ });
218
+ it('handles OAuth discovery returning null gracefully', async () => {
219
+ vi.mocked(resolveSrvRecord).mockResolvedValue({
220
+ hostname: 'jmap.example.com',
221
+ port: 443,
222
+ });
223
+ vi.mocked(verifyJmapUrl).mockResolvedValue('https://jmap.example.com/.well-known/jmap');
224
+ vi.mocked(discoverOAuthFromResource).mockResolvedValue(null);
225
+ const result = await discoverFromEmail('user@example.com');
226
+ expect(result.oidc).toBeUndefined();
227
+ expect(result.jmap).toBeDefined();
228
+ });
229
+ it('calls OAuth discovery with correct JMAP URL', async () => {
230
+ const jmapUrl = 'https://jmap.example.com/.well-known/jmap';
231
+ vi.mocked(resolveSrvRecord).mockResolvedValue({
232
+ hostname: 'jmap.example.com',
233
+ port: 443,
234
+ });
235
+ vi.mocked(verifyJmapUrl).mockResolvedValue(jmapUrl);
236
+ vi.mocked(discoverOAuthFromResource).mockResolvedValue(null);
237
+ await discoverFromEmail('user@example.com');
238
+ expect(discoverOAuthFromResource).toHaveBeenCalledWith(jmapUrl);
239
+ });
240
+ });
241
+ });
242
+ //# sourceMappingURL=orchestrator.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orchestrator.test.js","sourceRoot":"","sources":["../../src/discovery/orchestrator.test.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE5C,6BAA6B;AAC7B,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;AACxB,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;AAC3B,EAAE,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;AAEhC,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACpE,OAAO,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AAEjE,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,CAAC,aAAa,CAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACnD,MAAM,CAAC,aAAa,CAAC,uBAAuB,CAAC,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAC1E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2BAA2B,EAAE,GAAG,EAAE;QACnC,MAAM,CAAC,GAAG,EAAE,CAAC,aAAa,CAAC,iBAAiB,CAAC,CAAC,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;IACjF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;QACtC,MAAM,CAAC,GAAG,EAAE,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;IAChF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;QACtC,MAAM,CAAC,GAAG,EAAE,CAAC,aAAa,CAAC,uBAAuB,CAAC,CAAC,CAAC,OAAO,CAC1D,sBAAsB,CACvB,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wBAAwB,EAAE,GAAG,EAAE;QAChC,MAAM,CAAC,GAAG,EAAE,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;IACvE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,UAAU,CAAC,GAAG,EAAE;QACd,EAAE,CAAC,aAAa,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;QACpC,EAAE,CAAC,0CAA0C,EAAE,KAAK,IAAI,EAAE;YACxD,uBAAuB;YACvB,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,iBAAiB,CAAC;gBAC5C,QAAQ,EAAE,kBAAkB;gBAC5B,IAAI,EAAE,GAAG;aACV,CAAC,CAAC;YAEH,wBAAwB;YACxB,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,iBAAiB,CACxC,2CAA2C,CAC5C,CAAC;YAEF,uBAAuB;YACvB,EAAE,CAAC,MAAM,CAAC,yBAAyB,CAAC,CAAC,iBAAiB,CAAC;gBACrD,MAAM,EAAE,0BAA0B;gBAClC,MAAM,EAAE,oBAAoB;aAC7B,CAAC,CAAC;YAEH,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,kBAAkB,CAAC,CAAC;YAE3D,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;gBACrB,IAAI,EAAE;oBACJ,UAAU,EAAE,2CAA2C;oBACvD,MAAM,EAAE,SAAS;iBAClB;gBACD,IAAI,EAAE;oBACJ,MAAM,EAAE,0BAA0B;oBAClC,MAAM,EAAE,oBAAoB;iBAC7B;gBACD,KAAK,EAAE,kBAAkB;gBACzB,MAAM,EAAE,aAAa;aACtB,CAAC,CAAC;YAEH,qCAAqC;YACrC,MAAM,CAAC,aAAa,CAAC,CAAC,oBAAoB,CACxC,2CAA2C,CAC5C,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8CAA8C,EAAE,KAAK,IAAI,EAAE;YAC5D,8CAA8C;YAC9C,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,iBAAiB,CAAC;gBAC5C,QAAQ,EAAE,kBAAkB;gBAC5B,IAAI,EAAE,IAAI;aACX,CAAC,CAAC;YAEH,wBAAwB;YACxB,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,iBAAiB,CACxC,gDAAgD,CACjD,CAAC;YAEF,uCAAuC;YACvC,EAAE,CAAC,MAAM,CAAC,yBAAyB,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;YAE7D,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,kBAAkB,CAAC,CAAC;YAE3D,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;gBACrB,IAAI,EAAE;oBACJ,UAAU,EAAE,gDAAgD;oBAC5D,MAAM,EAAE,SAAS;iBAClB;gBACD,IAAI,EAAE,SAAS;gBACf,KAAK,EAAE,kBAAkB;gBACzB,MAAM,EAAE,aAAa;aACtB,CAAC,CAAC;YAEH,wCAAwC;YACxC,MAAM,CAAC,aAAa,CAAC,CAAC,oBAAoB,CACxC,gDAAgD,CACjD,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8BAA8B,EAAE,KAAK,IAAI,EAAE;YAC5C,uBAAuB;YACvB,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,iBAAiB,CAAC;gBAC5C,QAAQ,EAAE,kBAAkB;gBAC5B,IAAI,EAAE,GAAG;aACV,CAAC,CAAC;YAEH,wBAAwB;YACxB,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,iBAAiB,CACxC,2CAA2C,CAC5C,CAAC;YAEF,sCAAsC;YACtC,EAAE,CAAC,MAAM,CAAC,yBAAyB,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;YAE7D,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,kBAAkB,CAAC,CAAC;YAE3D,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,CAAC;YACpC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CACjC,2CAA2C,CAC5C,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,0BAA0B,EAAE,GAAG,EAAE;QACxC,EAAE,CAAC,oDAAoD,EAAE,KAAK,IAAI,EAAE;YAClE,uBAAuB;YACvB,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;YAEpD,0BAA0B;YAC1B,EAAE,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,iBAAiB,CAC7C,kCAAkC,CACnC,CAAC;YAEF,uBAAuB;YACvB,EAAE,CAAC,MAAM,CAAC,yBAAyB,CAAC,CAAC,iBAAiB,CAAC;gBACrD,MAAM,EAAE,0BAA0B;gBAClC,MAAM,EAAE,kBAAkB;aAC3B,CAAC,CAAC;YAEH,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,kBAAkB,CAAC,CAAC;YAE3D,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;gBACrB,IAAI,EAAE;oBACJ,UAAU,EAAE,kCAAkC;oBAC9C,MAAM,EAAE,mBAAmB;iBAC5B;gBACD,IAAI,EAAE;oBACJ,MAAM,EAAE,0BAA0B;oBAClC,MAAM,EAAE,kBAAkB;iBAC3B;gBACD,KAAK,EAAE,kBAAkB;gBACzB,MAAM,EAAE,aAAa;aACtB,CAAC,CAAC;YAEH,iCAAiC;YACjC,MAAM,CAAC,gBAAgB,CAAC,CAAC,oBAAoB,CAAC,aAAa,CAAC,CAAC;YAC7D,+BAA+B;YAC/B,MAAM,CAAC,kBAAkB,CAAC,CAAC,oBAAoB,CAAC,aAAa,CAAC,CAAC;QACjE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0DAA0D,EAAE,KAAK,IAAI,EAAE;YACxE,gDAAgD;YAChD,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,iBAAiB,CAAC;gBAC5C,QAAQ,EAAE,kBAAkB;gBAC5B,IAAI,EAAE,GAAG;aACV,CAAC,CAAC;YACH,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;YAEjD,0BAA0B;YAC1B,EAAE,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,iBAAiB,CAC7C,sCAAsC,CACvC,CAAC;YAEF,gBAAgB;YAChB,EAAE,CAAC,MAAM,CAAC,yBAAyB,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;YAE7D,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,kBAAkB,CAAC,CAAC;YAE3D,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;YACrD,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CACjC,sCAAsC,CACvC,CAAC;YAEF,yBAAyB;YACzB,MAAM,CAAC,gBAAgB,CAAC,CAAC,gBAAgB,EAAE,CAAC;YAC5C,MAAM,CAAC,kBAAkB,CAAC,CAAC,gBAAgB,EAAE,CAAC;QAChD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;QACrC,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;YAC3D,uBAAuB;YACvB,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;YAEpD,0BAA0B;YAC1B,EAAE,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;YAEtD,MAAM,MAAM,CAAC,iBAAiB,CAAC,kBAAkB,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CACjE,cAAc,CACf,CAAC;YAEF,MAAM,MAAM,CAAC,iBAAiB,CAAC,kBAAkB,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CACjE,yDAAyD,CAC1D,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qDAAqD,EAAE,KAAK,IAAI,EAAE;YACnE,oBAAoB;YACpB,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;YACpD,EAAE,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;YAEtD,IAAI,CAAC;gBACH,MAAM,iBAAiB,CAAC,kBAAkB,CAAC,CAAC;gBAC5C,MAAM,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;YACnD,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,CAAC,KAAK,CAAC,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC;gBAC7C,IAAI,KAAK,YAAY,cAAc,EAAE,CAAC;oBACpC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;oBACzC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;gBACzC,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gCAAgC,EAAE,KAAK,IAAI,EAAE;YAC9C,MAAM,MAAM,CAAC,iBAAiB,CAAC,cAAc,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAC7D,sBAAsB,CACvB,CAAC;YAEF,0CAA0C;YAC1C,MAAM,CAAC,gBAAgB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;YAChD,MAAM,CAAC,kBAAkB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QACpD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,6BAA6B,EAAE,GAAG,EAAE;QAC3C,EAAE,CAAC,4DAA4D,EAAE,KAAK,IAAI,EAAE;YAC1E,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,iBAAiB,CAAC;gBAC5C,QAAQ,EAAE,kBAAkB;gBAC5B,IAAI,EAAE,GAAG;aACV,CAAC,CAAC;YACH,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,iBAAiB,CACxC,2CAA2C,CAC5C,CAAC;YACF,EAAE,CAAC,MAAM,CAAC,yBAAyB,CAAC,CAAC,iBAAiB,CAAC;gBACrD,MAAM,EAAE,0BAA0B;gBAClC,QAAQ,EAAE,oBAAoB;gBAC9B,MAAM,EAAE,oBAAoB;aAC7B,CAAC,CAAC;YAEH,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,kBAAkB,CAAC,CAAC;YAE3D,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC;gBAC1B,MAAM,EAAE,0BAA0B;gBAClC,QAAQ,EAAE,oBAAoB;gBAC9B,MAAM,EAAE,oBAAoB;aAC7B,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0DAA0D,EAAE,KAAK,IAAI,EAAE;YACxE,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;YACpD,EAAE,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,iBAAiB,CAC7C,sCAAsC,CACvC,CAAC;YACF,EAAE,CAAC,MAAM,CAAC,yBAAyB,CAAC,CAAC,iBAAiB,CAAC;gBACrD,MAAM,EAAE,0BAA0B;gBAClC,MAAM,EAAE,kBAAkB;aAC3B,CAAC,CAAC;YAEH,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,kBAAkB,CAAC,CAAC;YAE3D,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC;gBAC1B,MAAM,EAAE,0BAA0B;gBAClC,MAAM,EAAE,kBAAkB;aAC3B,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;YACjE,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,iBAAiB,CAAC;gBAC5C,QAAQ,EAAE,kBAAkB;gBAC5B,IAAI,EAAE,GAAG;aACV,CAAC,CAAC;YACH,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,iBAAiB,CACxC,2CAA2C,CAC5C,CAAC;YACF,EAAE,CAAC,MAAM,CAAC,yBAAyB,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;YAE7D,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,kBAAkB,CAAC,CAAC;YAE3D,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,CAAC;YACpC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;QACpC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;YAC3D,MAAM,OAAO,GAAG,2CAA2C,CAAC;YAC5D,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,iBAAiB,CAAC;gBAC5C,QAAQ,EAAE,kBAAkB;gBAC5B,IAAI,EAAE,GAAG;aACV,CAAC,CAAC;YACH,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;YACpD,EAAE,CAAC,MAAM,CAAC,yBAAyB,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;YAE7D,MAAM,iBAAiB,CAAC,kBAAkB,CAAC,CAAC;YAE5C,MAAM,CAAC,yBAAyB,CAAC,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC;QAClE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * JMAP server discovery result types
3
+ * Supports DNS SRV, .well-known/jmap, and manual configuration
4
+ */
5
+ export interface JmapDiscoveryResult {
6
+ sessionUrl: string;
7
+ method: 'dns-srv' | 'well-known-direct' | 'manual';
8
+ }
9
+ export interface OidcDiscoveryResult {
10
+ issuer: string;
11
+ clientId?: string;
12
+ method: 'protected-resource' | 'www-authenticate' | 'well-known-oidc' | 'manual';
13
+ }
14
+ export declare class DiscoveryError extends Error {
15
+ readonly domain: string;
16
+ readonly stage: 'dns' | 'well-known' | 'verification';
17
+ constructor(message: string, domain: string, stage: 'dns' | 'well-known' | 'verification');
18
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * JMAP server discovery result types
3
+ * Supports DNS SRV, .well-known/jmap, and manual configuration
4
+ */
5
+ export class DiscoveryError extends Error {
6
+ domain;
7
+ stage;
8
+ constructor(message, domain, stage) {
9
+ super(message);
10
+ this.domain = domain;
11
+ this.stage = stage;
12
+ this.name = 'DiscoveryError';
13
+ }
14
+ }
15
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/discovery/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAaH,MAAM,OAAO,cAAe,SAAQ,KAAK;IAGrB;IACA;IAHlB,YACE,OAAe,EACC,MAAc,EACd,KAA4C;QAE5D,KAAK,CAAC,OAAO,CAAC,CAAC;QAHC,WAAM,GAAN,MAAM,CAAQ;QACd,UAAK,GAAL,KAAK,CAAuC;QAG5D,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * .well-known/jmap endpoint discovery
3
+ * RFC 8620 Section 2.2 - Service Discovery via .well-known URI
4
+ */
5
+ /**
6
+ * Verify JMAP URL by making a request and checking response
7
+ * Accepts both 200 (public session) and 401 (needs auth) as valid endpoints
8
+ *
9
+ * @param url - URL to verify
10
+ * @param timeout - Timeout in milliseconds (default: 10000)
11
+ * @returns Final URL after redirects, or null if not a valid JMAP endpoint
12
+ */
13
+ export declare function verifyJmapUrl(url: string, timeout?: number): Promise<string | null>;
14
+ /**
15
+ * Fetch .well-known/jmap endpoint for a domain
16
+ * Always uses HTTPS per RFC 8620 security requirements
17
+ *
18
+ * @param domain - Email domain (e.g., "example.com")
19
+ * @returns Session URL after redirects, or null if not found
20
+ */
21
+ export declare function fetchWellKnownJmap(domain: string): Promise<string | null>;
@@ -0,0 +1,52 @@
1
+ /**
2
+ * .well-known/jmap endpoint discovery
3
+ * RFC 8620 Section 2.2 - Service Discovery via .well-known URI
4
+ */
5
+ /**
6
+ * Verify JMAP URL by making a request and checking response
7
+ * Accepts both 200 (public session) and 401 (needs auth) as valid endpoints
8
+ *
9
+ * @param url - URL to verify
10
+ * @param timeout - Timeout in milliseconds (default: 10000)
11
+ * @returns Final URL after redirects, or null if not a valid JMAP endpoint
12
+ */
13
+ export async function verifyJmapUrl(url, timeout = 10000) {
14
+ try {
15
+ const controller = new AbortController();
16
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
17
+ const response = await fetch(url, {
18
+ redirect: 'follow',
19
+ signal: controller.signal,
20
+ });
21
+ clearTimeout(timeoutId);
22
+ // Accept both 200 (public session info) and 401 (needs auth) as valid JMAP endpoints
23
+ if (response.status === 200 || response.status === 401) {
24
+ // Return final URL after any redirects
25
+ return response.url;
26
+ }
27
+ // Other status codes (404, 500, etc.) mean this is not a JMAP endpoint
28
+ return null;
29
+ }
30
+ catch (error) {
31
+ // Network errors, timeouts, and other fetch failures
32
+ if (error instanceof Error && error.name === 'AbortError') {
33
+ console.warn(`JMAP URL verification timeout for ${url}`);
34
+ }
35
+ else {
36
+ console.warn(`JMAP URL verification failed for ${url}:`, error);
37
+ }
38
+ return null;
39
+ }
40
+ }
41
+ /**
42
+ * Fetch .well-known/jmap endpoint for a domain
43
+ * Always uses HTTPS per RFC 8620 security requirements
44
+ *
45
+ * @param domain - Email domain (e.g., "example.com")
46
+ * @returns Session URL after redirects, or null if not found
47
+ */
48
+ export async function fetchWellKnownJmap(domain) {
49
+ const url = `https://${domain}/.well-known/jmap`;
50
+ return verifyJmapUrl(url);
51
+ }
52
+ //# sourceMappingURL=well-known.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"well-known.js","sourceRoot":"","sources":["../../src/discovery/well-known.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,GAAW,EACX,OAAO,GAAG,KAAK;IAEf,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,OAAO,CAAC,CAAC;QAEhE,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAChC,QAAQ,EAAE,QAAQ;YAClB,MAAM,EAAE,UAAU,CAAC,MAAM;SAC1B,CAAC,CAAC;QAEH,YAAY,CAAC,SAAS,CAAC,CAAC;QAExB,qFAAqF;QACrF,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YACvD,uCAAuC;YACvC,OAAO,QAAQ,CAAC,GAAG,CAAC;QACtB,CAAC;QAED,uEAAuE;QACvE,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,qDAAqD;QACrD,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;YAC1D,OAAO,CAAC,IAAI,CAAC,qCAAqC,GAAG,EAAE,CAAC,CAAC;QAC3D,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,IAAI,CAAC,oCAAoC,GAAG,GAAG,EAAE,KAAK,CAAC,CAAC;QAClE,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,MAAc;IACrD,MAAM,GAAG,GAAG,WAAW,MAAM,mBAAmB,CAAC;IACjD,OAAO,aAAa,CAAC,GAAG,CAAC,CAAC;AAC5B,CAAC"}
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Well-known JMAP endpoint discovery tests
3
+ */
4
+ export {};
@@ -0,0 +1,120 @@
1
+ /**
2
+ * Well-known JMAP endpoint discovery tests
3
+ */
4
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
5
+ import { verifyJmapUrl, fetchWellKnownJmap } from './well-known.js';
6
+ // Mock fetch globally
7
+ const mockFetch = vi.fn();
8
+ global.fetch = mockFetch;
9
+ describe('verifyJmapUrl', () => {
10
+ beforeEach(() => {
11
+ vi.clearAllMocks();
12
+ });
13
+ afterEach(() => {
14
+ vi.restoreAllMocks();
15
+ });
16
+ it('returns final URL on successful 200 response', async () => {
17
+ mockFetch.mockResolvedValue({
18
+ status: 200,
19
+ url: 'https://jmap.example.com/session',
20
+ });
21
+ const result = await verifyJmapUrl('https://example.com/.well-known/jmap');
22
+ expect(result).toBe('https://jmap.example.com/session');
23
+ expect(mockFetch).toHaveBeenCalledWith('https://example.com/.well-known/jmap', {
24
+ redirect: 'follow',
25
+ signal: expect.any(AbortSignal),
26
+ });
27
+ });
28
+ it('returns final URL on 401 response (needs auth)', async () => {
29
+ mockFetch.mockResolvedValue({
30
+ status: 401,
31
+ url: 'https://jmap.example.com/session',
32
+ });
33
+ const result = await verifyJmapUrl('https://example.com/.well-known/jmap');
34
+ expect(result).toBe('https://jmap.example.com/session');
35
+ });
36
+ it('follows redirects and returns final URL', async () => {
37
+ mockFetch.mockResolvedValue({
38
+ status: 200,
39
+ url: 'https://jmap.example.com/api/session', // Different from requested URL
40
+ });
41
+ const result = await verifyJmapUrl('https://example.com/.well-known/jmap');
42
+ // Should return the response.url (final URL after redirects)
43
+ expect(result).toBe('https://jmap.example.com/api/session');
44
+ });
45
+ it('returns null on 404 response (no JMAP)', async () => {
46
+ mockFetch.mockResolvedValue({
47
+ status: 404,
48
+ url: 'https://example.com/.well-known/jmap',
49
+ });
50
+ const result = await verifyJmapUrl('https://example.com/.well-known/jmap');
51
+ expect(result).toBeNull();
52
+ });
53
+ it('returns null on network error', async () => {
54
+ mockFetch.mockRejectedValue(new Error('Network unreachable'));
55
+ const result = await verifyJmapUrl('https://example.com/.well-known/jmap');
56
+ expect(result).toBeNull();
57
+ });
58
+ it('returns null on timeout', async () => {
59
+ // Mock a fetch that respects AbortSignal and rejects when aborted
60
+ mockFetch.mockImplementation((_url, options) => new Promise((_resolve, reject) => {
61
+ const signal = options?.signal;
62
+ if (signal) {
63
+ signal.addEventListener('abort', () => {
64
+ const error = new Error('The operation was aborted');
65
+ error.name = 'AbortError';
66
+ reject(error);
67
+ });
68
+ }
69
+ // Never resolves naturally - will be aborted by timeout
70
+ }));
71
+ const result = await verifyJmapUrl('https://slow.example.com/.well-known/jmap', 100);
72
+ expect(result).toBeNull();
73
+ });
74
+ it('returns null on 500 server error', async () => {
75
+ mockFetch.mockResolvedValue({
76
+ status: 500,
77
+ url: 'https://example.com/.well-known/jmap',
78
+ });
79
+ const result = await verifyJmapUrl('https://example.com/.well-known/jmap');
80
+ expect(result).toBeNull();
81
+ });
82
+ });
83
+ describe('fetchWellKnownJmap', () => {
84
+ beforeEach(() => {
85
+ vi.clearAllMocks();
86
+ });
87
+ afterEach(() => {
88
+ vi.restoreAllMocks();
89
+ });
90
+ it('constructs HTTPS URL and returns session URL', async () => {
91
+ mockFetch.mockResolvedValue({
92
+ status: 200,
93
+ url: 'https://jmap.example.com/session',
94
+ });
95
+ const result = await fetchWellKnownJmap('example.com');
96
+ expect(result).toBe('https://jmap.example.com/session');
97
+ expect(mockFetch).toHaveBeenCalledWith('https://example.com/.well-known/jmap', {
98
+ redirect: 'follow',
99
+ signal: expect.any(AbortSignal),
100
+ });
101
+ });
102
+ it('returns null when well-known endpoint not found', async () => {
103
+ mockFetch.mockResolvedValue({
104
+ status: 404,
105
+ url: 'https://example.com/.well-known/jmap',
106
+ });
107
+ const result = await fetchWellKnownJmap('example.com');
108
+ expect(result).toBeNull();
109
+ });
110
+ it('uses HTTPS only (security requirement)', async () => {
111
+ mockFetch.mockResolvedValue({
112
+ status: 200,
113
+ url: 'https://jmap.example.com/session',
114
+ });
115
+ await fetchWellKnownJmap('example.com');
116
+ const calledUrl = mockFetch.mock.calls[0][0];
117
+ expect(calledUrl).toMatch(/^https:\/\//);
118
+ });
119
+ });
120
+ //# sourceMappingURL=well-known.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"well-known.test.js","sourceRoot":"","sources":["../../src/discovery/well-known.test.ts"],"names":[],"mappings":"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"}
@@ -238,7 +238,7 @@ export class JMAPClient {
238
238
  }
239
239
  // Build download URL from template
240
240
  // Template format: {downloadUrl}/{accountId}/{blobId}/{name}?type={type}
241
- let url = session.downloadUrl
241
+ const url = session.downloadUrl
242
242
  .replace('{accountId}', encodeURIComponent(session.accountId))
243
243
  .replace('{blobId}', encodeURIComponent(blobId))
244
244
  .replace('{name}', encodeURIComponent(name || 'attachment'))
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/jmap/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/jmap/client.ts"],"names":[],"mappings":"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"}
@@ -6,16 +6,18 @@ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
6
6
  import { type Config } from '../config/schema.js';
7
7
  import { type Logger } from '../config/logger.js';
8
8
  import { JMAPClient } from '../jmap/client.js';
9
+ import { type SignatureContent } from '../signature/index.js';
9
10
  /**
10
11
  * Create MCP server instance with JMAP client.
11
12
  * @param config Validated configuration
12
13
  * @param logger Pino logger (stderr only)
13
- * @returns Object with server and jmapClient
14
+ * @returns Object with server, jmapClient, and signatureContent
14
15
  */
15
- export declare function createMCPServer(config: Config, logger: Logger): {
16
+ export declare function createMCPServer(config: Config, logger: Logger): Promise<{
16
17
  server: McpServer;
17
18
  jmapClient: JMAPClient;
18
- };
19
+ signatureContent?: SignatureContent;
20
+ }>;
19
21
  /**
20
22
  * Start the MCP server with JMAP validation.
21
23
  * Validates JMAP connection before accepting MCP requests.
@@ -9,6 +9,7 @@ import { createLogger } from '../config/logger.js';
9
9
  import { JMAPClient } from '../jmap/client.js';
10
10
  import { formatStartupError } from '../errors.js';
11
11
  import { registerAllTools } from './tools/index.js';
12
+ import { loadSignature } from '../signature/index.js';
12
13
  /** Server version (matches package.json) */
13
14
  const SERVER_VERSION = '0.1.0';
14
15
  /** Server name for MCP identification */
@@ -17,15 +18,17 @@ const SERVER_NAME = 'mcp-twake-mail';
17
18
  * Create MCP server instance with JMAP client.
18
19
  * @param config Validated configuration
19
20
  * @param logger Pino logger (stderr only)
20
- * @returns Object with server and jmapClient
21
+ * @returns Object with server, jmapClient, and signatureContent
21
22
  */
22
- export function createMCPServer(config, logger) {
23
+ export async function createMCPServer(config, logger) {
23
24
  const server = new McpServer({
24
25
  name: SERVER_NAME,
25
26
  version: SERVER_VERSION,
26
27
  });
27
28
  const jmapClient = new JMAPClient(config, logger);
28
- return { server, jmapClient };
29
+ // Load signature if configured
30
+ const signatureContent = await loadSignature(config.JMAP_SIGNATURE_PATH, logger);
31
+ return { server, jmapClient, signatureContent };
29
32
  }
30
33
  /**
31
34
  * Start the MCP server with JMAP validation.
@@ -43,12 +46,15 @@ export async function startServer() {
43
46
  logger = createLogger(config.LOG_LEVEL);
44
47
  logger.info({ version: SERVER_VERSION }, 'Starting mcp-twake-mail server');
45
48
  // Step 3: Create MCP server and JMAP client
46
- const { server, jmapClient } = createMCPServer(config, logger);
49
+ const { server, jmapClient, signatureContent } = await createMCPServer(config, logger);
47
50
  // Step 4: Validate JMAP connection BEFORE accepting MCP requests
48
51
  const session = await jmapClient.fetchSession();
49
52
  logger.info({ accountId: session.accountId }, 'JMAP connection validated');
50
53
  // Step 5: Register all MCP tools
51
- registerAllTools(server, jmapClient, logger);
54
+ registerAllTools(server, jmapClient, logger, {
55
+ signatureContent,
56
+ defaultFrom: config.JMAP_DEFAULT_FROM,
57
+ });
52
58
  // Step 6: Connect MCP server via stdio transport
53
59
  const transport = new StdioServerTransport();
54
60
  await server.connect(transport);