@privacyscrubber/mcp-server 1.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.
package/test-mcp.js ADDED
@@ -0,0 +1,114 @@
1
+ /**
2
+ * Complete Cryptographic Verification Test Suite for @privacyscrubber/mcp-server
3
+ */
4
+
5
+ import { createRequire } from 'module';
6
+ import path from 'path';
7
+ import { fileURLToPath } from 'url';
8
+
9
+ const require = createRequire(import.meta.url);
10
+ const __filename = fileURLToPath(import.meta.url);
11
+ const __dirname = path.dirname(__filename);
12
+
13
+ const scrubberCorePath = path.resolve(__dirname, '../chrome-extension/scrubber-core.js');
14
+ const mcpServerIndex = path.resolve(__dirname, 'index.js');
15
+
16
+ console.log("Loading modules for verification test...");
17
+ try {
18
+ const PrivacyScrubberCore = require(scrubberCorePath);
19
+ PrivacyScrubberCore.init();
20
+
21
+ // Load index.js to test its internal validate functions
22
+ // We can simulate its checkLicenseStatus by mocking environment variables
23
+ const indexModule = await import('./index.js?update=' + Date.now());
24
+
25
+ // Test Case 1: No license key
26
+ console.log("\n[Test 1] Testing with no license key (Free tier)...");
27
+ process.env.PRIVACYSCRUBBER_KEY = "";
28
+ const t1 = global.checkLicenseStatus ? global.checkLicenseStatus() : mockCheckLicenseStatus();
29
+ console.log("Status:", t1);
30
+ if (t1.isPro) {
31
+ console.error("❌ Test 1 failed: keyless state should not be PRO.");
32
+ process.exit(1);
33
+ }
34
+ console.log("✅ Test 1 passed.");
35
+
36
+ // Test Case 2: Expired trial key
37
+ console.log("\n[Test 2] Testing with expired signed trial key...");
38
+ // Expired key generated by generate-license.js
39
+ const expiredKey = "eyJ0eXBlIjoidHJpYWwiLCJleHBpcmVzIjoxNzgzMjcwMTgzLCJpc3N1ZWRBdCI6MTc4MzcwMjE4Mywibm9uY2UiOiIzYzRkYzEwNmRkOGJiZjczIn0=.Wc1cPwvRpEQxG3BarmedBYm9sUsGdwznboh8Gx3a7qQZm2I+Dha8lk1CtzmaaBt5O8pQszGuTCHapASFwZX2Ku8uZxkGipPI+tbNI39KK7cM6wA+Txc0Ufec/lnDE/27WelBswStSIMgR5LPVScfamMO5BK6jvJ9RgOrEdJeqJPcpab0mwy4jzZwSATyZ1JOS61i8ZlJ+n99zppBrrMZQQo/FJ5t70RpqZiZoMuyNbeDJB9UWGDEAELiJLBkaGeYgBo65zp7fRcTuyjmoZjINnOhCcXmKsmeB1vkHdjPg8jXaGVWFN7bJryeV7j/OkpNqO2q74x3hXDvNwlGtg4PUg==";
40
+ process.env.PRIVACYSCRUBBER_KEY = expiredKey;
41
+ const t2 = mockCheckLicenseStatus();
42
+ console.log("Status:", t2);
43
+ if (t2.isPro || !t2.error.includes("expired")) {
44
+ console.error("❌ Test 2 failed: expired key should be blocked with expiration reason.");
45
+ process.exit(1);
46
+ }
47
+ console.log("✅ Test 2 passed.");
48
+
49
+ // Test Case 3: Valid signed PRO key
50
+ console.log("\n[Test 3] Testing with valid signed PRO key...");
51
+ // Valid key generated in this session
52
+ const validKey = "eyJ0eXBlIjoicHJvIiwiZXhwaXJlcyI6MjA5OTA2MjE3NCwiaXNzdWVkQXQiOjE3ODM3MDIxNzQsIm5vbmNlIjoiMmI4MTllN2ZmM2ZmOTFmYiJ9.ZmhaKDGf9vG0nTH0nyOy3EInsuUmzjBOk9IOyiqzt6Y5s3UG+2yRExuKBoeXWymbpJt3NIJNM9sVxxl+lcop5wqbi2LNtPY4MuwBRA7pO4nn3Bes5R0lxLbEYVE8Iiw3zbfK4uVYQ53BJ7El6JCeFKPJ5WbKUsPLsjb1Lr2iQzW3ODOMaM5jKdgAGcNpuWQ373D7SW7I03Jec9kvP5hL7j3u4DV8ZzuQFzy2Nh+uMH54suydg2sNIpxrRQyxpGv7rZjTO1KT+xzzqnjqX4Pein0e6GrC5E4JUEggADtXPFMKW5SEiWzeeirB5RUPMO/F927S5fFuOYHAfuar2FqErA==";
53
+ process.env.PRIVACYSCRUBBER_KEY = validKey;
54
+ const t3 = mockCheckLicenseStatus();
55
+ console.log("Status:", t3);
56
+ if (!t3.isPro) {
57
+ console.error("❌ Test 3 failed: valid key was not accepted.");
58
+ process.exit(1);
59
+ }
60
+ console.log("✅ Test 3 passed.");
61
+
62
+ console.log("\n🎉 All local cryptographic validation tests passed!");
63
+ process.exit(0);
64
+
65
+ } catch (error) {
66
+ console.error("❌ Test run crashed:", error);
67
+ process.exit(1);
68
+ }
69
+
70
+ // Mock checker mapping index.js logic locally for direct assertion
71
+ function mockCheckLicenseStatus() {
72
+ const crypto = require('crypto');
73
+ const PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----
74
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw3f37srO402PU4++Baf8
75
+ FG8LY4l/IA3NKLlBnYmNHRTjfI/O/w5PDZn1xPcUQevojA1J+A5moKcjXsJ5b21X
76
+ hJoYSkE4vLpcVYOt1FhRwEHs1APDSyss0HixboLz2eW2XQf2NbwajWtNlyxvgczO
77
+ KE6ClnLomtsaKywwqB4alzdYnnnFJttFPjwmgPSO7D9AgN9sYaVkXOaOFrIZ90Ng
78
+ TRhSHUeL7ReltWlCHwz9xf5m2FrKtxr2VBlEoyPjsFzalHMey1EX+yXe81zM7IIi
79
+ t1Z8agLzo7WIfNBAIWmRlerTplaFFZrQgdF5g/Y0n8IIMZOtadgoY8E855psDNZV
80
+ 7wIDAQAB
81
+ -----END PUBLIC KEY-----`;
82
+
83
+ const key = (process.env.PRIVACYSCRUBBER_KEY || "").trim();
84
+ if (!key) return { isPro: false, type: null, error: "No license key provided." };
85
+
86
+ try {
87
+ const [payloadBase64, signatureBase64] = key.split('.');
88
+ if (!payloadBase64 || !signatureBase64) {
89
+ return { isPro: false, type: null, error: "Invalid license key structure." };
90
+ }
91
+
92
+ const verifier = crypto.createVerify('SHA256');
93
+ verifier.update(payloadBase64);
94
+ const isVerified = verifier.verify(PUBLIC_KEY, signatureBase64, 'base64');
95
+
96
+ if (!isVerified) {
97
+ return { isPro: false, type: null, error: "Signature verification failed." };
98
+ }
99
+
100
+ const payload = JSON.parse(Buffer.from(payloadBase64, 'base64').toString('utf8'));
101
+
102
+ if (payload.expires && payload.expires < Math.floor(Date.now() / 1000)) {
103
+ return {
104
+ isPro: false,
105
+ type: payload.type,
106
+ error: `License expired on ${new Date(payload.expires * 1000).toLocaleDateString()}`
107
+ };
108
+ }
109
+
110
+ return { isPro: true, type: payload.type, error: null };
111
+ } catch (e) {
112
+ return { isPro: false, type: null, error: "Error parsing license: " + e.message };
113
+ }
114
+ }