diff --git a/package-lock.json b/package-lock.json index 58b17da..7a10a90 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "@hono/node-server": "^1.19.6", "@noble/ed25519": "^3.0.0", + "@xtr-dev/rondevu-client": "^0.13.0", "better-sqlite3": "^12.4.1", "hono": "^4.10.4" }, @@ -23,9 +24,9 @@ } }, "node_modules/@cloudflare/workers-types": { - "version": "4.20251115.0", - "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20251115.0.tgz", - "integrity": "sha512-aM7jp7IfKhqKvfSaK1IhVTbSzxB6KQ4gX8e/W29tOuZk+YHlYXuRd/bMm4hWkfd7B1HWNWdsx1GTaEUoZIuVsw==", + "version": "4.20251209.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20251209.0.tgz", + "integrity": "sha512-O+cbUVwgb4NgUB39R1cITbRshlAAPy1UQV0l8xEy2xcZ3wTh3fMl9f5oBwLsVmE9JRhIZx6llCLOBVf53eI5xA==", "dev": true, "license": "MIT OR Apache-2.0" }, @@ -485,9 +486,9 @@ } }, "node_modules/@hono/node-server": { - "version": "1.19.6", - "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.6.tgz", - "integrity": "sha512-Shz/KjlIeAhfiuE93NDKVdZ7HdBVLQAfdbaXEaoAVO3ic9ibRSLGIQGkcBbFyuLr+7/1D5ZCINM8B+6IvXeMtw==", + "version": "1.19.7", + "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.7.tgz", + "integrity": "sha512-vUcD0uauS7EU2caukW8z5lJKtoGMokxNbJtBiwHgpqxEXokaHCBkQUmCHhjFB1VUTWdqj25QoMkMKzgjq+uhrw==", "license": "MIT", "engines": { "node": ">=18.14.1" @@ -572,15 +573,24 @@ } }, "node_modules/@types/node": { - "version": "24.10.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.1.tgz", - "integrity": "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==", + "version": "24.10.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.2.tgz", + "integrity": "sha512-WOhQTZ4G8xZ1tjJTvKOpyEVSGgOTvJAfDK3FNFgELyaTpzhdgHVHeqW8V+UJvzF5BT+/B54T/1S2K6gd9c7bbA==", "dev": true, "license": "MIT", "dependencies": { "undici-types": "~7.16.0" } }, + "node_modules/@xtr-dev/rondevu-client": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@xtr-dev/rondevu-client/-/rondevu-client-0.13.0.tgz", + "integrity": "sha512-oauCveLga4lploxpoW8U0Fd9Fyz+SAsNQzIDvAIG1fkAnAJu9eajmLsZ5JfzzDi7h2Ew1ClZ7MOrmlRfG4vaBg==", + "license": "MIT", + "dependencies": { + "@noble/ed25519": "^3.0.0" + } + }, "node_modules/acorn": { "version": "8.15.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", @@ -635,9 +645,9 @@ "license": "MIT" }, "node_modules/better-sqlite3": { - "version": "12.4.1", - "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-12.4.1.tgz", - "integrity": "sha512-3yVdyZhklTiNrtg+4WqHpJpFDd+WHTg2oM7UcR80GqL05AOV0xEJzc6qNvFYoEtE+hRp1n9MpN6/+4yhlGkDXQ==", + "version": "12.5.0", + "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-12.5.0.tgz", + "integrity": "sha512-WwCZ/5Diz7rsF29o27o0Gcc1Du+l7Zsv7SYtVPG0X3G/uUI1LqdxrQI7c9Hs2FWpqXXERjW9hp6g3/tH7DlVKg==", "hasInstallScript": true, "license": "MIT", "dependencies": { @@ -645,7 +655,7 @@ "prebuild-install": "^7.1.1" }, "engines": { - "node": "20.x || 22.x || 23.x || 24.x" + "node": "20.x || 22.x || 23.x || 24.x || 25.x" } }, "node_modules/bindings": { @@ -827,9 +837,9 @@ "license": "MIT" }, "node_modules/hono": { - "version": "4.10.6", - "resolved": "https://registry.npmjs.org/hono/-/hono-4.10.6.tgz", - "integrity": "sha512-BIdolzGpDO9MQ4nu3AUuDwHZZ+KViNm+EZ75Ae55eMXMqLVhDFqEMXxtUe9Qh8hjL+pIna/frs2j6Y2yD5Ua/g==", + "version": "4.10.8", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.10.8.tgz", + "integrity": "sha512-DDT0A0r6wzhe8zCGoYOmMeuGu3dyTAE40HHjwUsWFTEy5WxK1x2WDSsBPlEXgPbRIFY6miDualuUDbasPogIww==", "license": "MIT", "engines": { "node": ">=16.9.0" diff --git a/package.json b/package.json index 4c5f79f..037e01c 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "dependencies": { "@hono/node-server": "^1.19.6", "@noble/ed25519": "^3.0.0", + "@xtr-dev/rondevu-client": "^0.13.0", "better-sqlite3": "^12.4.1", "hono": "^4.10.4" } diff --git a/src/crypto.ts b/src/crypto.ts index 61298a0..b43b015 100644 --- a/src/crypto.ts +++ b/src/crypto.ts @@ -425,16 +425,24 @@ export async function validateServicePublish( } // Parse message format: "publish:{username}:{serviceFqn}:{timestamp}" + // Note: serviceFqn can contain colons (e.g., "chat:2.0.0@user"), so we need careful parsing const parts = message.split(':'); - if (parts.length !== 4 || parts[0] !== 'publish' || parts[1] !== username || parts[2] !== serviceFqn) { + if (parts.length < 4 || parts[0] !== 'publish' || parts[1] !== username) { return { valid: false, error: 'Invalid message format (expected: publish:{username}:{serviceFqn}:{timestamp})' }; } - const timestamp = parseInt(parts[3], 10); + // The timestamp is the last part + const timestamp = parseInt(parts[parts.length - 1], 10); if (isNaN(timestamp)) { return { valid: false, error: 'Invalid timestamp in message' }; } + // The serviceFqn is everything between username and timestamp + const extractedServiceFqn = parts.slice(2, parts.length - 1).join(':'); + if (extractedServiceFqn !== serviceFqn) { + return { valid: false, error: `Service FQN mismatch (expected: ${serviceFqn}, got: ${extractedServiceFqn})` }; + } + // Validate timestamp const timestampCheck = validateTimestamp(timestamp); if (!timestampCheck.valid) {