72b453994169

fix: SEC-002/THREAT-003 delete TEST handlers (v2.45.2)

time
2026-05-15 20:55 UTC · 5 months ago
machine
koh2
parent
5c4a71d3e83b
6 files manifest.firefox.json+1 −1manifest.json+1 −1package.json+1 −1src/background/messages.ts+0 −120src/content/passkeys-firefox-relay.test.ts+2 −2src/shared/types.ts+0 −5
manifest.firefox.json+1 −1
@@ -1,7 +1,7 @@11 {22   "manifest_version": 3,33   "name": "Peach",4-  "version": "2.45.1",4+  "version": "2.45.2",55   "description": "Zero-knowledge password manager",66   "browser_specific_settings": {77     "gecko": {

view file

manifest.json+1 −1
@@ -1,7 +1,7 @@11 {22   "manifest_version": 3,33   "name": "Peach",4-  "version": "2.45.1",4+  "version": "2.45.2",55   "description": "Zero-knowledge password manager",66   "action": {77     "default_popup": "src/popup/index.html",

view file

package.json+1 −1
@@ -1,6 +1,6 @@11 {22   "name": "peach",3-  "version": "2.45.1",3+  "version": "2.45.2",44   "description": "Zero-knowledge password manager",55   "type": "module",66   "scripts": {

view file

src/background/messages.ts+0 −120
@@ -1337,126 +1337,6 @@13371337         await publishInMemoryVault(entries);13381338         return { ok: true };13391339       }1340-      // --- PNA compatibility test handlers — REMOVE BEFORE RELEASE ---1341-      case "TEST_LOCAL_WEBSOCKET": {1342-        const { ip } = (msg.payload ?? {}) as { ip?: string };1343-        if (!ip) return { ok: false, error: "ip required" };1344-        return new Promise((resolve) => {1345-          try {1346-            const ws = new WebSocket(`ws://${ip}:44100`);1347-            ws.onopen = () => { ws.close(); resolve({ ok: true, data: { connected: true } }); };1348-            ws.onerror = () => resolve({ ok: false, error: "connection_failed" });1349-            setTimeout(() => { ws.close(); resolve({ ok: false, error: "timeout" }); }, 3000);1350-          } catch (err) {1351-            resolve({ ok: false, error: String(err) });1352-          }1353-        });1354-      }1355-      case "TEST_SUBNET_DETECTION": {1356-        const subnet = await getLocalSubnet();1357-        return { ok: true, data: { subnet } };1358-      }1359-      case "TEST_SUBNET_SCAN": {1360-        const subnet = await getLocalSubnet();1361-        if (!subnet) return { ok: false, error: "no_subnet" };1362-        const start = Date.now();1363-        const result = await discoverDevice(subnet, "000000000000000000000000000000000000000000000000000000000000000000");1364-        return { ok: true, data: { elapsed: Date.now() - start, found: !!result } };1365-      }1366-      case 'TEST_WS_LOCAL': {1367-        const { ip } = msg.payload as { ip: string };1368-1369-        return new Promise((resolve) => {1370-          const log: string[] = [];1371-          log.push(`Attempting ws://${ip}:44100 from service worker...`);1372-1373-          let ws: WebSocket;1374-          let settled = false;1375-          const settle = (result: MessageResponse) => {1376-            if (!settled) { settled = true; resolve(result); }1377-          };1378-1379-          try {1380-            ws = new WebSocket(`ws://${ip}:44100`);1381-1382-            ws.onopen = () => {1383-              log.push('SUCCESS: WebSocket connected');1384-              ws.close();1385-              settle({ ok: true, data: { log } });1386-            };1387-1388-            ws.onerror = (e) => {1389-              log.push(`FAILED: onerror fired — ${String(e)}`);1390-              settle({ ok: false, error: 'ws_error', data: { log } });1391-            };1392-1393-            ws.onclose = (e) => {1394-              if (e.code !== 1000) {1395-                log.push(`CLOSED unexpectedly: code=${e.code} reason=${e.reason}`);1396-                settle({ ok: false, error: 'ws_closed', data: { code: e.code, log } });1397-              }1398-            };1399-1400-            setTimeout(() => {1401-              try { ws.close(); } catch {}1402-              log.push('FAILED: 5 second timeout — connection never opened');1403-              settle({ ok: false, error: 'timeout', data: { log } });1404-            }, 5000);1405-1406-          } catch (err) {1407-            log.push(`FAILED: WebSocket constructor threw — ${String(err)}`);1408-            settle({ ok: false, error: 'constructor_threw', data: { log } });1409-          }1410-        });1411-      }1412-1413-      case 'TEST_SUBNET_DETECT': {1414-        return new Promise((resolve) => {1415-          try {1416-            // RTCPeerConnection availability varies by context — this is what we're testing1417-            // eslint-disable-next-line @typescript-eslint/no-explicit-any1418-            const RTC = (globalThis as any).RTCPeerConnection as (new (cfg: object) => RTCPeerConnection) | undefined;1419-            if (!RTC) {1420-              resolve({ ok: false, error: 'RTCPeerConnection is not defined' });1421-              return;1422-            }1423-            const pc = new RTC({ iceServers: [] });1424-            pc.createDataChannel('');1425-            pc.createOffer().then((o) => pc.setLocalDescription(o));1426-1427-            const candidates: string[] = [];1428-            const timer = setTimeout(() => {1429-              pc.close();1430-              if (candidates.length === 0) {1431-                resolve({ ok: false, error: 'no_candidates', data: { candidates } });1432-              } else {1433-                const subnet = candidates[0].match(/(\d+\.\d+\.\d+)\.\d+/)?.[1];1434-                resolve({ ok: true, data: { subnet, candidates } });1435-              }1436-            }, 2000);1437-1438-            pc.onicecandidate = (e) => {1439-              if (!e.candidate) return;1440-              const m = e.candidate.candidate.match(/(\d+\.\d+\.\d+\.\d+)/);1441-              if (m && !m[1].startsWith('127')) candidates.push(m[1]);1442-            };1443-1444-            pc.onicegatheringstatechange = () => {1445-              if (pc.iceGatheringState === 'complete') {1446-                clearTimeout(timer);1447-                pc.close();1448-                const subnet = candidates[0]?.match(/(\d+\.\d+\.\d+)\.\d+/)?.[1];1449-                resolve({ ok: candidates.length > 0, data: { subnet, candidates } });1450-              }1451-            };1452-          } catch (err) {1453-            resolve({ ok: false, error: String(err) });1454-          }1455-        });1456-      }1457-1458-      // --- end test handlers ---1459-14601340       case "ML_INIT":14611341         return { ok: true };14621342 

view file

src/content/passkeys-firefox-relay.test.ts+2 −2
@@ -61,8 +61,8 @@6161     "GET_IDENTITIES",6262     "SEARCH_VAULT",6363     "GET_ENTRY_FOR_FILL",64-    "TEST_LOCAL_WEBSOCKET",65-    "TEST_WS_LOCAL",64+    "LOCAL_WEBSOCKET_PROBE",65+    "SUBNET_DETECT_PROBE",6666     "",6767     "TOTALLY_MADE_UP",6868   ];

view file

src/shared/types.ts+0 −5
@@ -306,11 +306,6 @@306306   | "GET_IDENTITY_SUGGESTIONS"307307   | "TOUCH_AUTO_LOCK"308308   | "POPULATE_INLINE_VAULT"309-  | "TEST_LOCAL_WEBSOCKET"310-  | "TEST_SUBNET_DETECTION"311-  | "TEST_SUBNET_SCAN"312-  | "TEST_WS_LOCAL"313-  | "TEST_SUBNET_DETECT"314309   | "SAVE_NOTE"315310   | "DELETE_NOTE"316311   | "GET_NOTES"

view file