From 92738c2d2c9cebd6590dfc40bc1ffee8093cfd7a Mon Sep 17 00:00:00 2001 From: koalasat Date: Thu, 8 May 2025 11:57:44 +0200 Subject: [PATCH] Validate ratign tokens --- .../src/components/Dialogs/Coordinator.tsx | 4 ++-- .../src/components/FederationTable/index.tsx | 4 ++-- frontend/src/services/RoboPool/index.ts | 2 +- frontend/src/utils/nostr.ts | 21 +++++++++++++++---- 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/frontend/src/components/Dialogs/Coordinator.tsx b/frontend/src/components/Dialogs/Coordinator.tsx index 12f85999..31c5cd5a 100644 --- a/frontend/src/components/Dialogs/Coordinator.tsx +++ b/frontend/src/components/Dialogs/Coordinator.tsx @@ -360,7 +360,7 @@ const CoordinatorDialog = ({ open = false, onClose, shortAlias }: Props): JSX.El const { clientVersion, page, settings, origin } = useContext(AppContext); const { federation } = useContext(FederationContext); - const [, setRating] = useState([0, 0]); + const [rating, setRating] = useState([0, 0]); const [averageRating, setAvergeRating] = useState(0); const [expanded, setExpanded] = useState<'summary' | 'stats' | 'policies' | undefined>(undefined); const [coordinator, setCoordinator] = useState( @@ -442,7 +442,7 @@ const CoordinatorDialog = ({ open = false, onClose, shortAlias }: Props): JSX.El disabled={settings.connection !== 'nostr'} /> - {`(${parseFloat((averageRating * 10).toFixed(1))})`} + {`(${rating[1]})`} diff --git a/frontend/src/components/FederationTable/index.tsx b/frontend/src/components/FederationTable/index.tsx index 22cecc5f..08e3ffa5 100644 --- a/frontend/src/components/FederationTable/index.tsx +++ b/frontend/src/components/FederationTable/index.tsx @@ -135,7 +135,7 @@ const FederationTable = ({ return { field: 'rating', headerName: t('Rating'), - width: mobile ? 60 : 170, + width: mobile ? 60 : 180, renderCell: (params: any) => { const coordinator = federation.getCoordinator(params.row.shortAlias); const coordinatorRating = ratings[coordinator.nostrHexPubkey]; @@ -166,7 +166,7 @@ const FederationTable = ({ }} /> - {`(${parseFloat((average * 10).toFixed(1))})`} + {`(${coordinatorRating[1]})`} )} diff --git a/frontend/src/services/RoboPool/index.ts b/frontend/src/services/RoboPool/index.ts index a2101e81..88a5725f 100644 --- a/frontend/src/services/RoboPool/index.ts +++ b/frontend/src/services/RoboPool/index.ts @@ -141,7 +141,7 @@ class RoboPool { const requestRatings = [ 'REQ', 'subscribeRatings', - { kinds: [31986], '#p': pubkeys, since: 1745509494 }, + { kinds: [31986], '#p': pubkeys, since: 1746316800 }, ]; this.messageHandlers.push((_url: string, messageEvent: MessageEvent) => { diff --git a/frontend/src/utils/nostr.ts b/frontend/src/utils/nostr.ts index 54e6cecc..a0409303 100644 --- a/frontend/src/utils/nostr.ts +++ b/frontend/src/utils/nostr.ts @@ -110,11 +110,15 @@ const eventToPublicOrder = (event: Event): { dTag: string; publicOrder: PublicOr export const verifyCoordinatorToken: (event: Event) => boolean = (event) => { const d = event.tags.find((t) => t[0] === 'd')?.[1]; const orderId = d?.split(':')?.[1]; - const signature = event.tags.find((t) => t[0] === 'sig')?.[1]; - const hash = `${event.pubkey}${orderId ?? ''}`; - const coordinatorPubKey = event.tags.find((t) => t[0] === 'p')?.[1]; - if (signature && coordinatorPubKey) { + const signatureHex = event.tags.find((t) => t[0] === 'sig')?.[1]; + const coordinatorPubKeyHex = event.tags.find((t) => t[0] === 'p')?.[1]; + const message = `${event.pubkey}${orderId ?? ''}`; + + if (signatureHex && coordinatorPubKeyHex) { try { + const signature = Uint8Array.from(hexToBytes(signatureHex)); + const coordinatorPubKey = Uint8Array.from(hexToBytes(coordinatorPubKeyHex)); + const hash = new TextEncoder().encode(message); return schnorr.verify(signature, hash, coordinatorPubKey); } catch (e) { return false; @@ -123,4 +127,13 @@ export const verifyCoordinatorToken: (event: Event) => boolean = (event) => { return false; }; +const hexToBytes: (hex: string) => Uint8Array = (hex) => { + if (hex.length % 2 !== 0) throw new Error('Hex must have an even lenght'); + const bytes = new Uint8Array(hex.length / 2); + for (let i = 0; i < bytes.length; i++) { + bytes[i] = parseInt(hex.substr(i * 2, 2), 16); + } + return bytes; +}; + export default eventToPublicOrder;