mirror of
https://github.com/xtr-dev/rondevu-server.git
synced 2025-12-10 10:53:24 +00:00
Fix signature validation bug for serviceFqn with colons
The validateServicePublish function was incorrectly parsing the signature message when serviceFqn contained colons (e.g., 'chat:2.0.0@user'). Old logic: Split by ':' and expected exactly 4 parts Problem: serviceFqn 'chat:2.0.0@user' contains a colon, so we get 5 parts Fixed: - Allow parts.length >= 4 - Extract timestamp from the last part - Reconstruct serviceFqn from all middle parts (parts[2] to parts[length-2]) This fixes the '403 Invalid signature for username' error that was preventing service publication.
This commit is contained in:
42
package-lock.json
generated
42
package-lock.json
generated
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user