@respira/wordpress-mcp-server 7.5.2 → 7.5.3

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.
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Regression test for ticket 927aa7ed: "delete_media approval flow never
3
+ * completes: token rejected in a loop".
4
+ *
5
+ * Root cause: `WordPressClient.deleteMedia()` only ever forwarded `id` to the
6
+ * WP REST endpoint (`DELETE /media/{id}`). The MCP tool schema for
7
+ * `wordpress_delete_media` advertises `approval_token` and `force` params and
8
+ * the server.ts dispatcher received them from the caller, but the client
9
+ * method silently dropped both on the floor before the request ever went
10
+ * out. The WP-side approval gate (Respira_Tool_Governance) never saw a token
11
+ * on the "confirm" call, so it always treated it as a fresh request and
12
+ * minted a brand-new token — an infinite loop, indistinguishable from the
13
+ * outside from a broken approval mechanism, even though the mechanism itself
14
+ * (proven by delete_page working) was fine.
15
+ *
16
+ * Uses the same axios mock-adapter pattern as rest-route-fallback.test.ts.
17
+ *
18
+ * @since 7.5.x (ticket 927aa7ed)
19
+ */
20
+ export {};
21
+ //# sourceMappingURL=delete-media-approval-token.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delete-media-approval-token.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/delete-media-approval-token.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG"}
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Regression test for ticket 927aa7ed: "delete_media approval flow never
3
+ * completes: token rejected in a loop".
4
+ *
5
+ * Root cause: `WordPressClient.deleteMedia()` only ever forwarded `id` to the
6
+ * WP REST endpoint (`DELETE /media/{id}`). The MCP tool schema for
7
+ * `wordpress_delete_media` advertises `approval_token` and `force` params and
8
+ * the server.ts dispatcher received them from the caller, but the client
9
+ * method silently dropped both on the floor before the request ever went
10
+ * out. The WP-side approval gate (Respira_Tool_Governance) never saw a token
11
+ * on the "confirm" call, so it always treated it as a fresh request and
12
+ * minted a brand-new token — an infinite loop, indistinguishable from the
13
+ * outside from a broken approval mechanism, even though the mechanism itself
14
+ * (proven by delete_page working) was fine.
15
+ *
16
+ * Uses the same axios mock-adapter pattern as rest-route-fallback.test.ts.
17
+ *
18
+ * @since 7.5.x (ticket 927aa7ed)
19
+ */
20
+ import { test } from 'node:test';
21
+ import assert from 'node:assert/strict';
22
+ import axios from 'axios';
23
+ import { WordPressClient } from '../wordpress-client.js';
24
+ const callLog = [];
25
+ let currentHandler = null;
26
+ const originalAdapter = axios.defaults.adapter;
27
+ function installMockAdapter() {
28
+ callLog.length = 0;
29
+ axios.defaults.adapter = ((config) => {
30
+ callLog.push({
31
+ method: (config.method || 'get').toLowerCase(),
32
+ url: config.url,
33
+ params: config.params,
34
+ });
35
+ if (!currentHandler) {
36
+ return Promise.reject(new Error('no mock handler installed'));
37
+ }
38
+ const result = currentHandler(config);
39
+ return Promise.resolve(result).then((r) => ({
40
+ status: r.status,
41
+ statusText: 'OK',
42
+ headers: {},
43
+ config,
44
+ data: r.data,
45
+ request: {},
46
+ }));
47
+ });
48
+ }
49
+ function restoreAdapter() {
50
+ axios.defaults.adapter = originalAdapter;
51
+ currentHandler = null;
52
+ }
53
+ function setHandler(h) {
54
+ currentHandler = h;
55
+ }
56
+ function buildConfig() {
57
+ return {
58
+ id: 'test-site',
59
+ name: 'Test Site',
60
+ url: 'https://example.com',
61
+ apiKey: 'respira_test_key',
62
+ };
63
+ }
64
+ // -----------------------------------------------------------------------------
65
+ // Tests
66
+ // -----------------------------------------------------------------------------
67
+ test('deleteMedia forwards approval_token on the confirm call (927aa7ed regression)', async () => {
68
+ installMockAdapter();
69
+ try {
70
+ setHandler(() => ({ status: 200, data: { success: true } }));
71
+ const client = new WordPressClient(buildConfig());
72
+ // First call: no token yet, simulates the initial delete attempt.
73
+ await client.deleteMedia(42);
74
+ assert.equal(callLog.length, 1);
75
+ assert.equal(callLog[0].method, 'delete');
76
+ assert.equal(callLog[0].url, '/media/42');
77
+ assert.ok(!callLog[0].params || callLog[0].params.approval_token === undefined, 'first call must not send an approval_token');
78
+ // Second call: the agent echoes back the exact token it was handed.
79
+ // Pre-fix this token was silently dropped and the WP side looped forever.
80
+ await client.deleteMedia(42, undefined, 'approve-tok-abc123');
81
+ assert.equal(callLog.length, 2);
82
+ assert.equal(callLog[1].method, 'delete');
83
+ assert.equal(callLog[1].url, '/media/42');
84
+ assert.equal(callLog[1].params?.approval_token, 'approve-tok-abc123', 'confirm call must forward the approval_token verbatim');
85
+ }
86
+ finally {
87
+ restoreAdapter();
88
+ }
89
+ });
90
+ test('deleteMedia forwards force alongside approval_token', async () => {
91
+ installMockAdapter();
92
+ try {
93
+ setHandler(() => ({ status: 200, data: { success: true } }));
94
+ const client = new WordPressClient(buildConfig());
95
+ await client.deleteMedia(7, true, 'tok-xyz');
96
+ assert.equal(callLog.length, 1);
97
+ assert.equal(callLog[0].params?.force, true);
98
+ assert.equal(callLog[0].params?.approval_token, 'tok-xyz');
99
+ }
100
+ finally {
101
+ restoreAdapter();
102
+ }
103
+ });
104
+ test('deletePage approval flow is unaffected (no regression)', async () => {
105
+ installMockAdapter();
106
+ try {
107
+ setHandler(() => ({ status: 200, data: { success: true } }));
108
+ const client = new WordPressClient(buildConfig());
109
+ // No force -> no params sent at all (matches pre-existing behavior).
110
+ await client.deletePage(99);
111
+ assert.equal(callLog[0].url, '/pages/99');
112
+ assert.ok(!callLog[0].params || Object.keys(callLog[0].params).length === 0);
113
+ // force + approval_token -> both forwarded, plus confirm_live_edit which
114
+ // deletePage has always sent alongside force.
115
+ await client.deletePage(99, true, 'page-tok-1');
116
+ const call = callLog[1];
117
+ assert.equal(call.url, '/pages/99');
118
+ assert.equal(call.params.force, true);
119
+ assert.equal(call.params.confirm_live_edit, true);
120
+ assert.equal(call.params.approval_token, 'page-tok-1');
121
+ }
122
+ finally {
123
+ restoreAdapter();
124
+ }
125
+ });
126
+ //# sourceMappingURL=delete-media-approval-token.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delete-media-approval-token.test.js","sourceRoot":"","sources":["../../src/__tests__/delete-media-approval-token.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAUzD,MAAM,OAAO,GAAwD,EAAE,CAAC;AACxE,IAAI,cAAc,GAAuB,IAAI,CAAC;AAE9C,MAAM,eAAe,GAAG,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC;AAE/C,SAAS,kBAAkB;IACzB,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;IACnB,KAAK,CAAC,QAAQ,CAAC,OAAO,GAAG,CAAC,CAAC,MAAW,EAAE,EAAE;QACxC,OAAO,CAAC,IAAI,CAAC;YACX,MAAM,EAAE,CAAC,MAAM,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC,WAAW,EAAE;YAC9C,GAAG,EAAE,MAAM,CAAC,GAAG;YACf,MAAM,EAAE,MAAM,CAAC,MAAM;SACtB,CAAC,CAAC;QACH,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC,CAAC;QAChE,CAAC;QACD,MAAM,MAAM,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;QACtC,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC1C,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,UAAU,EAAE,IAAI;YAChB,OAAO,EAAE,EAAE;YACX,MAAM;YACN,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,OAAO,EAAE,EAAE;SACZ,CAAC,CAAC,CAAC;IACN,CAAC,CAAQ,CAAC;AACZ,CAAC;AAED,SAAS,cAAc;IACrB,KAAK,CAAC,QAAQ,CAAC,OAAO,GAAG,eAAe,CAAC;IACzC,cAAc,GAAG,IAAI,CAAC;AACxB,CAAC;AAED,SAAS,UAAU,CAAC,CAAc;IAChC,cAAc,GAAG,CAAC,CAAC;AACrB,CAAC;AAED,SAAS,WAAW;IAClB,OAAO;QACL,EAAE,EAAE,WAAW;QACf,IAAI,EAAE,WAAW;QACjB,GAAG,EAAE,qBAAqB;QAC1B,MAAM,EAAE,kBAAkB;KAC3B,CAAC;AACJ,CAAC;AAED,gFAAgF;AAChF,QAAQ;AACR,gFAAgF;AAEhF,IAAI,CAAC,+EAA+E,EAAE,KAAK,IAAI,EAAE;IAC/F,kBAAkB,EAAE,CAAC;IACrB,IAAI,CAAC;QACH,UAAU,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;QAC7D,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,WAAW,EAAE,CAAC,CAAC;QAElD,kEAAkE;QAClE,MAAM,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QAC7B,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAChC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAC1C,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;QAC1C,MAAM,CAAC,EAAE,CACP,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,cAAc,KAAK,SAAS,EACpE,4CAA4C,CAC7C,CAAC;QAEF,oEAAoE;QACpE,0EAA0E;QAC1E,MAAM,MAAM,CAAC,WAAW,CAAC,EAAE,EAAE,SAAS,EAAE,oBAAoB,CAAC,CAAC;QAC9D,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAChC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAC1C,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;QAC1C,MAAM,CAAC,KAAK,CACV,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,cAAc,EACjC,oBAAoB,EACpB,uDAAuD,CACxD,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,cAAc,EAAE,CAAC;IACnB,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,qDAAqD,EAAE,KAAK,IAAI,EAAE;IACrE,kBAAkB,EAAE,CAAC;IACrB,IAAI,CAAC;QACH,UAAU,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;QAC7D,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,WAAW,EAAE,CAAC,CAAC;QAElD,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;QAC7C,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAChC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QAC7C,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,cAAc,EAAE,SAAS,CAAC,CAAC;IAC7D,CAAC;YAAS,CAAC;QACT,cAAc,EAAE,CAAC;IACnB,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;IACxE,kBAAkB,EAAE,CAAC;IACrB,IAAI,CAAC;QACH,UAAU,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;QAC7D,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,WAAW,EAAE,CAAC,CAAC;QAElD,qEAAqE;QACrE,MAAM,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QAC5B,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;QAC1C,MAAM,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC;QAE7E,yEAAyE;QACzE,8CAA8C;QAC9C,MAAM,MAAM,CAAC,UAAU,CAAC,EAAE,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC;QAChD,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QACxB,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;QACpC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACtC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,iBAAiB,EAAE,IAAI,CAAC,CAAC;QAClD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC;IACzD,CAAC;YAAS,CAAC;QACT,cAAc,EAAE,CAAC;IACnB,CAAC;AACH,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=upload-media-path-detection.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload-media-path-detection.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/upload-media-path-detection.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,70 @@
1
+ import { test } from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { mkdtempSync, writeFileSync, rmSync } from 'node:fs';
4
+ import { tmpdir } from 'node:os';
5
+ import { join } from 'node:path';
6
+ import { pathToFileURL } from 'node:url';
7
+ import { isLocalFilePath, resolveLocalFilePath } from '../wordpress-client.js';
8
+ // Ticket 5a19d816: on Windows, respira_upload_media(file="C:/Users/.../photo.jpg")
9
+ // fell through the local-file detection (which only matched '/', './', '../',
10
+ // '~') into the base64 branch. Buffer.from(nonBase64, 'base64') doesn't throw,
11
+ // it just silently decodes garbage bytes, so the upload "succeeded" with a
12
+ // corrupt ~80-byte file instead of reading the real one from disk.
13
+ test('isLocalFilePath: Windows drive-letter paths are detected as local files, not base64', () => {
14
+ assert.equal(isLocalFilePath('C:/Users/bob/photo.jpg'), true);
15
+ assert.equal(isLocalFilePath('C:\\Users\\bob\\photo.jpg'), true);
16
+ assert.equal(isLocalFilePath('D:\\Media\\file.png'), true);
17
+ assert.equal(isLocalFilePath('z:/lower/drive/letter.gif'), true);
18
+ });
19
+ test('isLocalFilePath: file:// URIs are detected as local files (Windows and Unix forms)', () => {
20
+ assert.equal(isLocalFilePath('file:///C:/Users/bob/photo.jpg'), true);
21
+ assert.equal(isLocalFilePath('file:///home/bob/photo.jpg'), true);
22
+ });
23
+ test('isLocalFilePath: existing POSIX-style detection is unchanged (no regression)', () => {
24
+ assert.equal(isLocalFilePath('/absolute/unix/path.jpg'), true);
25
+ assert.equal(isLocalFilePath('./relative/path.jpg'), true);
26
+ assert.equal(isLocalFilePath('../parent/path.jpg'), true);
27
+ assert.equal(isLocalFilePath('~/home/path.jpg'), true);
28
+ });
29
+ test('isLocalFilePath: base64 payloads and data:/http(s): URLs are still NOT treated as local files', () => {
30
+ // A plausible base64 blob with no path-like prefix.
31
+ assert.equal(isLocalFilePath('aGVsbG8gd29ybGQgdGhpcyBpcyBhIHRlc3Q='), false);
32
+ assert.equal(isLocalFilePath('data:image/png;base64,iVBORw0KGgo='), false);
33
+ assert.equal(isLocalFilePath('http://example.com/photo.jpg'), false);
34
+ assert.equal(isLocalFilePath('https://example.com/photo.jpg'), false);
35
+ });
36
+ test('resolveLocalFilePath: Windows drive-letter paths pass through unchanged (no cwd corruption)', () => {
37
+ // Regression guard: node:path's resolve() is POSIX on non-Windows hosts and
38
+ // does not recognize "C:\..." as absolute, so running it through resolve()
39
+ // would wrongly prefix the string with cwd. The fix must return the drive
40
+ // path verbatim so fs calls on an actual Windows host see the real path
41
+ // (and, off-Windows, this test suite sees a clean "File not found: C:\..."
42
+ // instead of a mangled "<cwd>/C:\...").
43
+ assert.equal(resolveLocalFilePath('C:\\Users\\bob\\photo.jpg'), 'C:\\Users\\bob\\photo.jpg');
44
+ assert.equal(resolveLocalFilePath('C:/Users/bob/photo.jpg'), 'C:/Users/bob/photo.jpg');
45
+ });
46
+ test('resolveLocalFilePath: file:///C:/... extracts a Windows-style path', () => {
47
+ const resolved = resolveLocalFilePath('file:///C:/Users/bob/photo.jpg');
48
+ assert.equal(resolved, 'C:\\Users\\bob\\photo.jpg');
49
+ });
50
+ test('resolveLocalFilePath: file:///... on Unix round-trips to the real file, byte for byte', () => {
51
+ const dir = mkdtempSync(join(tmpdir(), 'respira-upload-media-test-'));
52
+ const filePath = join(dir, 'photo.jpg');
53
+ writeFileSync(filePath, 'not-actually-a-jpeg-but-that-is-fine');
54
+ try {
55
+ const fileUrl = pathToFileURL(filePath).href;
56
+ assert.equal(isLocalFilePath(fileUrl), true);
57
+ const resolved = resolveLocalFilePath(fileUrl);
58
+ assert.equal(resolved, filePath);
59
+ }
60
+ finally {
61
+ rmSync(dir, { recursive: true, force: true });
62
+ }
63
+ });
64
+ test('resolveLocalFilePath: existing "~" and relative-path resolution behavior is unchanged', () => {
65
+ const home = process.env.HOME || '';
66
+ assert.equal(resolveLocalFilePath('~/photo.jpg'), `${home}/photo.jpg`);
67
+ // A relative path resolves against cwd, same as plain node:path resolve().
68
+ assert.equal(resolveLocalFilePath('./photo.jpg'), join(process.cwd(), 'photo.jpg'));
69
+ });
70
+ //# sourceMappingURL=upload-media-path-detection.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload-media-path-detection.test.js","sourceRoot":"","sources":["../../src/__tests__/upload-media-path-detection.test.ts"],"names":[],"mappings":"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"}
package/dist/server.js CHANGED
@@ -6401,7 +6401,7 @@ Allowlist: css, scss, less, json. PHP / JS theme writes are intentionally out of
6401
6401
  case 'wordpress_update_media_batch':
6402
6402
  return await client.updateMediaBatch(args.items);
6403
6403
  case 'wordpress_delete_media':
6404
- return await client.deleteMedia(args.id);
6404
+ return await client.deleteMedia(args.id, args.force, args.approval_token);
6405
6405
  // Menu Management
6406
6406
  case 'wordpress_list_menus':
6407
6407
  return await client.listMenus();