payload-mcp-toolkit 0.7.0 → 0.7.4

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 (48) hide show
  1. package/README.md +29 -8
  2. package/dist/api-keys.js +57 -21
  3. package/dist/api-keys.js.map +1 -1
  4. package/dist/auth-strategy.d.ts +18 -7
  5. package/dist/auth-strategy.js +54 -12
  6. package/dist/auth-strategy.js.map +1 -1
  7. package/dist/tools/_helpers.d.ts +34 -0
  8. package/dist/tools/_helpers.js +98 -0
  9. package/dist/tools/_helpers.js.map +1 -1
  10. package/dist/tools/publish-draft.js +33 -1
  11. package/dist/tools/publish-draft.js.map +1 -1
  12. package/dist/tools/publish-global-draft.js +30 -1
  13. package/dist/tools/publish-global-draft.js.map +1 -1
  14. package/package.json +29 -15
  15. package/dist/__tests__/api-keys.test.js +0 -292
  16. package/dist/__tests__/api-keys.test.js.map +0 -1
  17. package/dist/__tests__/auth-strategy.test.js +0 -681
  18. package/dist/__tests__/auth-strategy.test.js.map +0 -1
  19. package/dist/__tests__/conflict-detection.test.js +0 -69
  20. package/dist/__tests__/conflict-detection.test.js.map +0 -1
  21. package/dist/__tests__/delete-document.test.js +0 -70
  22. package/dist/__tests__/delete-document.test.js.map +0 -1
  23. package/dist/__tests__/endpoint.test.js +0 -143
  24. package/dist/__tests__/endpoint.test.js.map +0 -1
  25. package/dist/__tests__/find-document.test.js +0 -178
  26. package/dist/__tests__/find-document.test.js.map +0 -1
  27. package/dist/__tests__/find-global.test.js +0 -173
  28. package/dist/__tests__/find-global.test.js.map +0 -1
  29. package/dist/__tests__/global-versions.test.js +0 -183
  30. package/dist/__tests__/global-versions.test.js.map +0 -1
  31. package/dist/__tests__/hash.test.js +0 -58
  32. package/dist/__tests__/hash.test.js.map +0 -1
  33. package/dist/__tests__/index-integration.test.js +0 -191
  34. package/dist/__tests__/index-integration.test.js.map +0 -1
  35. package/dist/__tests__/introspection.test.js +0 -659
  36. package/dist/__tests__/introspection.test.js.map +0 -1
  37. package/dist/__tests__/patch-global-layout.test.js +0 -474
  38. package/dist/__tests__/patch-global-layout.test.js.map +0 -1
  39. package/dist/__tests__/patch-layout.test.js +0 -171
  40. package/dist/__tests__/patch-layout.test.js.map +0 -1
  41. package/dist/__tests__/registry.test.js +0 -795
  42. package/dist/__tests__/registry.test.js.map +0 -1
  43. package/dist/__tests__/resources.test.js +0 -139
  44. package/dist/__tests__/resources.test.js.map +0 -1
  45. package/dist/__tests__/update-global.test.js +0 -157
  46. package/dist/__tests__/update-global.test.js.map +0 -1
  47. package/dist/__tests__/url-validator.test.js +0 -326
  48. package/dist/__tests__/url-validator.test.js.map +0 -1
@@ -1,326 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
- import dns from 'node:dns';
3
- import { isPrivateIp, validateAndFetchUrl } from '../url-validator';
4
- // ─── isPrivateIp — pure unit tests ────────────────────────────────
5
- describe('isPrivateIp', ()=>{
6
- describe('IPv4 — blocked ranges', ()=>{
7
- it.each([
8
- [
9
- '10.0.0.1',
10
- '10.0.0.0/8'
11
- ],
12
- [
13
- '10.255.255.255',
14
- '10.0.0.0/8 upper'
15
- ],
16
- [
17
- '172.16.0.1',
18
- '172.16.0.0/12 lower'
19
- ],
20
- [
21
- '172.20.5.5',
22
- '172.16.0.0/12 mid'
23
- ],
24
- [
25
- '172.31.255.255',
26
- '172.16.0.0/12 upper'
27
- ],
28
- [
29
- '192.168.1.1',
30
- '192.168.0.0/16'
31
- ],
32
- [
33
- '127.0.0.1',
34
- '127.0.0.0/8 loopback'
35
- ],
36
- [
37
- '127.255.255.255',
38
- '127.0.0.0/8 upper'
39
- ],
40
- [
41
- '169.254.169.254',
42
- '169.254.0.0/16 — AWS metadata'
43
- ],
44
- [
45
- '0.0.0.0',
46
- 'unspecified — 0.0.0.0/8'
47
- ],
48
- [
49
- '0.0.0.1',
50
- '0.0.0.0/8 not just :0'
51
- ],
52
- [
53
- '0.255.255.255',
54
- '0.0.0.0/8 upper'
55
- ],
56
- [
57
- '100.64.0.0',
58
- '100.64.0.0/10 — CGNAT lower'
59
- ],
60
- [
61
- '100.100.50.50',
62
- '100.64.0.0/10 — CGNAT mid'
63
- ],
64
- [
65
- '100.127.255.255',
66
- '100.64.0.0/10 — CGNAT upper'
67
- ]
68
- ])('blocks %s (%s)', (ip)=>{
69
- expect(isPrivateIp(ip)).toBe(true);
70
- });
71
- });
72
- describe('IPv4 — public (allowed)', ()=>{
73
- it.each([
74
- [
75
- '8.8.8.8'
76
- ],
77
- [
78
- '1.1.1.1'
79
- ],
80
- [
81
- '172.15.0.1'
82
- ],
83
- [
84
- '172.32.0.1'
85
- ],
86
- [
87
- '11.0.0.1'
88
- ],
89
- [
90
- '192.169.1.1'
91
- ],
92
- [
93
- '126.255.255.255'
94
- ],
95
- [
96
- '128.0.0.1'
97
- ],
98
- [
99
- '100.63.255.255'
100
- ],
101
- [
102
- '100.128.0.0'
103
- ],
104
- [
105
- '1.0.0.1'
106
- ]
107
- ])('allows %s', (ip)=>{
108
- expect(isPrivateIp(ip)).toBe(false);
109
- });
110
- });
111
- describe('IPv6 — blocked ranges', ()=>{
112
- it.each([
113
- [
114
- '::1',
115
- 'loopback shorthand'
116
- ],
117
- [
118
- '0:0:0:0:0:0:0:1',
119
- 'loopback expanded'
120
- ],
121
- [
122
- '0000:0000:0000:0000:0000:0000:0000:0001',
123
- 'loopback fully expanded'
124
- ],
125
- [
126
- 'fc00::1',
127
- 'unique local fc'
128
- ],
129
- [
130
- 'fd12:3456:789a::1',
131
- 'unique local fd'
132
- ],
133
- [
134
- 'fe80::1',
135
- 'link-local'
136
- ],
137
- [
138
- 'FE80::1',
139
- 'link-local case-insensitive'
140
- ],
141
- [
142
- 'febf::1',
143
- 'link-local upper boundary fe80::/10'
144
- ],
145
- [
146
- '::ffff:127.0.0.1',
147
- 'IPv4-mapped loopback'
148
- ],
149
- [
150
- '::ffff:10.0.0.1',
151
- 'IPv4-mapped private 10/8'
152
- ],
153
- [
154
- '::ffff:169.254.169.254',
155
- 'IPv4-mapped AWS metadata'
156
- ],
157
- [
158
- '::ffff:100.64.0.1',
159
- 'IPv4-mapped CGNAT'
160
- ],
161
- [
162
- '::127.0.0.1',
163
- 'IPv4-compat loopback'
164
- ]
165
- ])('blocks %s (%s)', (ip)=>{
166
- expect(isPrivateIp(ip)).toBe(true);
167
- });
168
- });
169
- describe('IPv6 — public (allowed)', ()=>{
170
- it.each([
171
- [
172
- '2001:4860:4860::8888'
173
- ],
174
- [
175
- '2606:4700:4700::1111'
176
- ],
177
- [
178
- 'ff00::1'
179
- ],
180
- [
181
- '::ffff:8.8.8.8'
182
- ],
183
- [
184
- 'fec0::1'
185
- ]
186
- ])('allows %s', (ip)=>{
187
- expect(isPrivateIp(ip)).toBe(false);
188
- });
189
- });
190
- });
191
- // ─── validateAndFetchUrl — integration with mocked DNS + fetch ────
192
- describe('validateAndFetchUrl', ()=>{
193
- const originalFetch = globalThis.fetch;
194
- let dnsLookupSpy;
195
- beforeEach(()=>{
196
- dnsLookupSpy = vi.spyOn(dns.promises, 'lookup');
197
- });
198
- afterEach(()=>{
199
- vi.restoreAllMocks();
200
- globalThis.fetch = originalFetch;
201
- });
202
- function mockDns(address, family = 4) {
203
- dnsLookupSpy.mockResolvedValue({
204
- address,
205
- family
206
- });
207
- }
208
- function mockFetch(impl) {
209
- globalThis.fetch = vi.fn((url)=>Promise.resolve(impl(String(url))));
210
- }
211
- it('rejects non-HTTPS schemes', async ()=>{
212
- await expect(validateAndFetchUrl('http://example.com/x.png')).rejects.toThrow(/HTTPS/);
213
- });
214
- it('rejects when DNS resolves to a private IPv4 (SSRF)', async ()=>{
215
- mockDns('10.0.0.5');
216
- await expect(validateAndFetchUrl('https://attacker.example/x.png')).rejects.toThrow(/SSRF blocked/);
217
- });
218
- it('rejects when DNS resolves to AWS metadata IP (SSRF)', async ()=>{
219
- mockDns('169.254.169.254');
220
- await expect(validateAndFetchUrl('https://metadata.example/x.png')).rejects.toThrow(/SSRF blocked/);
221
- });
222
- it('rejects when DNS resolves to ::1 (SSRF)', async ()=>{
223
- mockDns('::1', 6);
224
- await expect(validateAndFetchUrl('https://localhost.example/x.png')).rejects.toThrow(/SSRF blocked/);
225
- });
226
- it('fetches successfully when DNS resolves to a public IP', async ()=>{
227
- mockDns('8.8.8.8');
228
- mockFetch(()=>new Response(new Uint8Array([
229
- 1,
230
- 2,
231
- 3
232
- ]), {
233
- status: 200,
234
- headers: {
235
- 'content-type': 'image/png'
236
- }
237
- }));
238
- const result = await validateAndFetchUrl('https://example.com/cat.png');
239
- expect(result.contentType).toBe('image/png');
240
- expect(result.filename).toBe('cat.png');
241
- expect(result.buffer.length).toBe(3);
242
- });
243
- it('follows redirects and re-validates the redirect target', async ()=>{
244
- let call = 0;
245
- // First lookup: public. Second lookup (after redirect): private → must block.
246
- dnsLookupSpy.mockImplementation(async ()=>{
247
- call++;
248
- return {
249
- address: call === 1 ? '8.8.8.8' : '127.0.0.1',
250
- family: 4
251
- };
252
- });
253
- mockFetch((url)=>{
254
- if (url === 'https://example.com/start') {
255
- return new Response(null, {
256
- status: 302,
257
- headers: {
258
- location: 'https://internal.example/secret'
259
- }
260
- });
261
- }
262
- throw new Error(`should not reach ${url} — redirect target must be blocked`);
263
- });
264
- await expect(validateAndFetchUrl('https://example.com/start')).rejects.toThrow(/SSRF blocked/);
265
- expect(call).toBe(2);
266
- });
267
- it('caps redirect chains at maxRedirects', async ()=>{
268
- mockDns('8.8.8.8');
269
- mockFetch((url)=>new Response(null, {
270
- status: 302,
271
- headers: {
272
- location: url + '/again'
273
- }
274
- }));
275
- await expect(validateAndFetchUrl('https://example.com/loop', {
276
- maxRedirects: 2
277
- })).rejects.toThrow(/Too many redirects/);
278
- });
279
- it('errors when a redirect response has no Location header', async ()=>{
280
- mockDns('8.8.8.8');
281
- mockFetch(()=>new Response(null, {
282
- status: 302
283
- }));
284
- await expect(validateAndFetchUrl('https://example.com/x.png')).rejects.toThrow(/Location header/);
285
- });
286
- it('surfaces non-OK HTTP responses', async ()=>{
287
- mockDns('8.8.8.8');
288
- mockFetch(()=>new Response(null, {
289
- status: 404,
290
- statusText: 'Not Found'
291
- }));
292
- await expect(validateAndFetchUrl('https://example.com/x.png')).rejects.toThrow(/404/);
293
- });
294
- it('derives a UUID filename when the URL path has no extension', async ()=>{
295
- mockDns('8.8.8.8');
296
- mockFetch(()=>new Response(new Uint8Array([
297
- 0
298
- ]), {
299
- status: 200,
300
- headers: {
301
- 'content-type': 'image/jpeg'
302
- }
303
- }));
304
- const result = await validateAndFetchUrl('https://example.com/no-extension');
305
- expect(result.filename).toMatch(/\.jpg$/);
306
- expect(result.filename).not.toBe('no-extension');
307
- });
308
- it('strips path traversal segments from derived filenames', async ()=>{
309
- mockDns('8.8.8.8');
310
- mockFetch(()=>new Response(new Uint8Array([
311
- 0
312
- ]), {
313
- status: 200,
314
- headers: {
315
- 'content-type': 'image/png'
316
- }
317
- }));
318
- const result = await validateAndFetchUrl('https://example.com/foo/..%2Fevil.png');
319
- // URL parser decodes %2F into /, so lastSegment ends up "..evil.png" after .. strip
320
- expect(result.filename).not.toContain('..');
321
- expect(result.filename).not.toContain('/');
322
- expect(result.filename).not.toContain('\\');
323
- });
324
- });
325
-
326
- //# sourceMappingURL=url-validator.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/__tests__/url-validator.test.ts"],"sourcesContent":["import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'\nimport dns from 'node:dns'\nimport { isPrivateIp, validateAndFetchUrl } from '../url-validator'\n\n// ─── isPrivateIp — pure unit tests ────────────────────────────────\n\ndescribe('isPrivateIp', () => {\n describe('IPv4 — blocked ranges', () => {\n it.each([\n ['10.0.0.1', '10.0.0.0/8'],\n ['10.255.255.255', '10.0.0.0/8 upper'],\n ['172.16.0.1', '172.16.0.0/12 lower'],\n ['172.20.5.5', '172.16.0.0/12 mid'],\n ['172.31.255.255', '172.16.0.0/12 upper'],\n ['192.168.1.1', '192.168.0.0/16'],\n ['127.0.0.1', '127.0.0.0/8 loopback'],\n ['127.255.255.255', '127.0.0.0/8 upper'],\n ['169.254.169.254', '169.254.0.0/16 — AWS metadata'],\n ['0.0.0.0', 'unspecified — 0.0.0.0/8'],\n ['0.0.0.1', '0.0.0.0/8 not just :0'],\n ['0.255.255.255', '0.0.0.0/8 upper'],\n ['100.64.0.0', '100.64.0.0/10 — CGNAT lower'],\n ['100.100.50.50', '100.64.0.0/10 — CGNAT mid'],\n ['100.127.255.255', '100.64.0.0/10 — CGNAT upper'],\n ])('blocks %s (%s)', (ip) => {\n expect(isPrivateIp(ip)).toBe(true)\n })\n })\n\n describe('IPv4 — public (allowed)', () => {\n it.each([\n ['8.8.8.8'],\n ['1.1.1.1'],\n ['172.15.0.1'], // just outside 172.16/12\n ['172.32.0.1'], // just outside 172.16/12\n ['11.0.0.1'],\n ['192.169.1.1'], // not 192.168\n ['126.255.255.255'],\n ['128.0.0.1'],\n ['100.63.255.255'], // just below CGNAT\n ['100.128.0.0'], // just above CGNAT\n ['1.0.0.1'], // outside 0.0.0.0/8\n ])('allows %s', (ip) => {\n expect(isPrivateIp(ip)).toBe(false)\n })\n })\n\n describe('IPv6 — blocked ranges', () => {\n it.each([\n ['::1', 'loopback shorthand'],\n ['0:0:0:0:0:0:0:1', 'loopback expanded'],\n ['0000:0000:0000:0000:0000:0000:0000:0001', 'loopback fully expanded'],\n ['fc00::1', 'unique local fc'],\n ['fd12:3456:789a::1', 'unique local fd'],\n ['fe80::1', 'link-local'],\n ['FE80::1', 'link-local case-insensitive'],\n ['febf::1', 'link-local upper boundary fe80::/10'],\n ['::ffff:127.0.0.1', 'IPv4-mapped loopback'],\n ['::ffff:10.0.0.1', 'IPv4-mapped private 10/8'],\n ['::ffff:169.254.169.254', 'IPv4-mapped AWS metadata'],\n ['::ffff:100.64.0.1', 'IPv4-mapped CGNAT'],\n ['::127.0.0.1', 'IPv4-compat loopback'],\n ])('blocks %s (%s)', (ip) => {\n expect(isPrivateIp(ip)).toBe(true)\n })\n })\n\n describe('IPv6 — public (allowed)', () => {\n it.each([\n ['2001:4860:4860::8888'], // Google DNS\n ['2606:4700:4700::1111'], // Cloudflare DNS\n ['ff00::1'], // multicast — not in our private blocklist\n ['::ffff:8.8.8.8'], // IPv4-mapped public\n ['fec0::1'], // outside fe80::/10 (deprecated site-local, but not our match)\n ])('allows %s', (ip) => {\n expect(isPrivateIp(ip)).toBe(false)\n })\n })\n})\n\n// ─── validateAndFetchUrl — integration with mocked DNS + fetch ────\n\ndescribe('validateAndFetchUrl', () => {\n const originalFetch = globalThis.fetch\n let dnsLookupSpy: ReturnType<typeof vi.spyOn>\n\n beforeEach(() => {\n dnsLookupSpy = vi.spyOn(dns.promises, 'lookup')\n })\n\n afterEach(() => {\n vi.restoreAllMocks()\n globalThis.fetch = originalFetch\n })\n\n function mockDns(address: string, family: 4 | 6 = 4) {\n dnsLookupSpy.mockResolvedValue({ address, family } as any)\n }\n\n function mockFetch(impl: (url: string) => Promise<Response> | Response) {\n globalThis.fetch = vi.fn(((url: any) => Promise.resolve(impl(String(url)))) as any) as any\n }\n\n it('rejects non-HTTPS schemes', async () => {\n await expect(validateAndFetchUrl('http://example.com/x.png')).rejects.toThrow(/HTTPS/)\n })\n\n it('rejects when DNS resolves to a private IPv4 (SSRF)', async () => {\n mockDns('10.0.0.5')\n await expect(validateAndFetchUrl('https://attacker.example/x.png')).rejects.toThrow(\n /SSRF blocked/,\n )\n })\n\n it('rejects when DNS resolves to AWS metadata IP (SSRF)', async () => {\n mockDns('169.254.169.254')\n await expect(validateAndFetchUrl('https://metadata.example/x.png')).rejects.toThrow(\n /SSRF blocked/,\n )\n })\n\n it('rejects when DNS resolves to ::1 (SSRF)', async () => {\n mockDns('::1', 6)\n await expect(validateAndFetchUrl('https://localhost.example/x.png')).rejects.toThrow(\n /SSRF blocked/,\n )\n })\n\n it('fetches successfully when DNS resolves to a public IP', async () => {\n mockDns('8.8.8.8')\n mockFetch(\n () =>\n new Response(new Uint8Array([1, 2, 3]), {\n status: 200,\n headers: { 'content-type': 'image/png' },\n }),\n )\n\n const result = await validateAndFetchUrl('https://example.com/cat.png')\n expect(result.contentType).toBe('image/png')\n expect(result.filename).toBe('cat.png')\n expect(result.buffer.length).toBe(3)\n })\n\n it('follows redirects and re-validates the redirect target', async () => {\n let call = 0\n // First lookup: public. Second lookup (after redirect): private → must block.\n dnsLookupSpy.mockImplementation(async () => {\n call++\n return { address: call === 1 ? '8.8.8.8' : '127.0.0.1', family: 4 } as any\n })\n\n mockFetch((url) => {\n if (url === 'https://example.com/start') {\n return new Response(null, {\n status: 302,\n headers: { location: 'https://internal.example/secret' },\n })\n }\n throw new Error(`should not reach ${url} — redirect target must be blocked`)\n })\n\n await expect(validateAndFetchUrl('https://example.com/start')).rejects.toThrow(\n /SSRF blocked/,\n )\n expect(call).toBe(2)\n })\n\n it('caps redirect chains at maxRedirects', async () => {\n mockDns('8.8.8.8')\n mockFetch(\n (url) =>\n new Response(null, {\n status: 302,\n headers: { location: url + '/again' },\n }),\n )\n\n await expect(\n validateAndFetchUrl('https://example.com/loop', { maxRedirects: 2 }),\n ).rejects.toThrow(/Too many redirects/)\n })\n\n it('errors when a redirect response has no Location header', async () => {\n mockDns('8.8.8.8')\n mockFetch(() => new Response(null, { status: 302 }))\n\n await expect(validateAndFetchUrl('https://example.com/x.png')).rejects.toThrow(\n /Location header/,\n )\n })\n\n it('surfaces non-OK HTTP responses', async () => {\n mockDns('8.8.8.8')\n mockFetch(() => new Response(null, { status: 404, statusText: 'Not Found' }))\n\n await expect(validateAndFetchUrl('https://example.com/x.png')).rejects.toThrow(/404/)\n })\n\n it('derives a UUID filename when the URL path has no extension', async () => {\n mockDns('8.8.8.8')\n mockFetch(\n () =>\n new Response(new Uint8Array([0]), {\n status: 200,\n headers: { 'content-type': 'image/jpeg' },\n }),\n )\n\n const result = await validateAndFetchUrl('https://example.com/no-extension')\n expect(result.filename).toMatch(/\\.jpg$/)\n expect(result.filename).not.toBe('no-extension')\n })\n\n it('strips path traversal segments from derived filenames', async () => {\n mockDns('8.8.8.8')\n mockFetch(\n () =>\n new Response(new Uint8Array([0]), {\n status: 200,\n headers: { 'content-type': 'image/png' },\n }),\n )\n\n const result = await validateAndFetchUrl('https://example.com/foo/..%2Fevil.png')\n // URL parser decodes %2F into /, so lastSegment ends up \"..evil.png\" after .. strip\n expect(result.filename).not.toContain('..')\n expect(result.filename).not.toContain('/')\n expect(result.filename).not.toContain('\\\\')\n })\n})\n"],"names":["describe","it","expect","vi","beforeEach","afterEach","dns","isPrivateIp","validateAndFetchUrl","each","ip","toBe","originalFetch","globalThis","fetch","dnsLookupSpy","spyOn","promises","restoreAllMocks","mockDns","address","family","mockResolvedValue","mockFetch","impl","fn","url","Promise","resolve","String","rejects","toThrow","Response","Uint8Array","status","headers","result","contentType","filename","buffer","length","call","mockImplementation","location","Error","maxRedirects","statusText","toMatch","not","toContain"],"mappings":"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"}