From de05a02bb92855305ae61a737ab6bfb2f3f9a4ad Mon Sep 17 00:00:00 2001 From: Chris Duncan Date: Mon, 6 Jul 2026 00:58:52 -0700 Subject: [PATCH] Fix rolodex signature verification. --- src/lib/rolodex.ts | 97 +++++++++++++++++++++++----------------------- 1 file changed, 49 insertions(+), 48 deletions(-) diff --git a/src/lib/rolodex.ts b/src/lib/rolodex.ts index 40952de..4437e38 100644 --- a/src/lib/rolodex.ts +++ b/src/lib/rolodex.ts @@ -3,29 +3,30 @@ import { verify as nano25519_verify } from 'nano25519' import { Account } from './account' +import { utf8 } from './convert' import { Database } from './database' /** -* Represents a basic address book of Nano accounts. Multiple addresses can be -* saved under one nickname. -*/ + * Represents a basic address book of Nano accounts. Multiple addresses can be + * saved under one nickname. + */ export class Rolodex { /** - * @returns {'Rolodex'} - */ + * @returns {'Rolodex'} + */ static get DB_NAME (): 'Rolodex' { return 'Rolodex' } /** - * Adds an address to the rolodex under a specific nickname. - * - * If the name exists, add the address as a new association to that name. If - * the account exists under a different name, update the name. If no matches - * are found at all, add a new entry. - * - * @param {string} name - Contact alias for the address - * @param {string} address - Nano account address - * @returns {Promise} Promise for true if name and address are added to the rolodex, else false - */ + * Adds an address to the rolodex under a specific nickname. + * + * If the name exists, add the address as a new association to that name. If + * the account exists under a different name, update the name. If no matches + * are found at all, add a new entry. + * + * @param {string} name - Contact alias for the address + * @param {string} address - Nano account address + * @returns {Promise} Promise for true if name and address are added to the rolodex, else false + */ static async add (name: string, address: string): Promise { if (name == null || name === '') { throw new Error('Name is required for rolodex entries') @@ -85,11 +86,11 @@ export class Rolodex { } /** - * Removes a Nano address from its related contact in the rolodex. - * - * @param {string} address - Nano account address - * @returns {Promise} Promise for true if address successfully removed, else false - */ + * Removes a Nano address from its related contact in the rolodex. + * + * @param {string} address - Nano account address + * @returns {Promise} Promise for true if address successfully removed, else false + */ static async deleteAddress (address: string): Promise { const name = await this.getName(address) if (name == null) { @@ -111,11 +112,11 @@ export class Rolodex { } /** - * Removes a contact and its related Nano addresses from the rolodex. - * - * @param {string} name - Contact name to delete - * @returns {Promise} Promise for true if name and related addresses successfully removed, else false - */ + * Removes a contact and its related Nano addresses from the rolodex. + * + * @param {string} name - Contact name to delete + * @returns {Promise} Promise for true if name and related addresses successfully removed, else false + */ static async deleteName (name: string): Promise { const records = await this.getAddresses(name) records.push(name) @@ -123,11 +124,11 @@ export class Rolodex { } /** - * Gets all Nano account addresses associated with a name from the rolodex. - * - * @param {string} name - Alias to look up - * @returns {Promise} Promise for a list of Nano addresses associated with the name - */ + * Gets all Nano account addresses associated with a name from the rolodex. + * + * @param {string} name - Alias to look up + * @returns {Promise} Promise for a list of Nano addresses associated with the name + */ static async getAddresses (name: string): Promise { try { const records = await Database.get>(name, this.DB_NAME) @@ -142,10 +143,10 @@ export class Rolodex { } /** - * Gets all names stored in the rolodex. - * - * @returns {Promise} Promise for a list of all names stored in the rolodex - */ + * Gets all names stored in the rolodex. + * + * @returns {Promise} Promise for a list of all names stored in the rolodex + */ static async getAllNames (): Promise { try { const records = await Database.getAll(this.DB_NAME) @@ -157,11 +158,11 @@ export class Rolodex { } /** - * Gets the name associated with a specific Nano address from the rolodex. - * - * @param {string} address - Nano account address - * @returns {Promise} Promise for the name associated with the address, or null if not found - */ + * Gets the name associated with a specific Nano address from the rolodex. + * + * @param {string} address - Nano account address + * @returns {Promise} Promise for the name associated with the address, or null if not found + */ static async getName (address: string): Promise { try { const records = await Database.get>(address, this.DB_NAME) @@ -174,19 +175,19 @@ export class Rolodex { } /** - * Verifies whether the public key of any Nano address saved under a specific - * name in the rolodex was used to sign a specific string. - * - * @param {string} name - Alias to look up - * @param {string} signature - Signature to use for verification - * @param {string} data - Signed data to verify - * @returns {Promise} True if the signature was used to sign the data, else false - */ + * Verifies whether the public key of any Nano address saved under a specific + * name in the rolodex was used to sign a specific string. + * + * @param {string} name - Alias to look up + * @param {string} signature - Signature to use for verification + * @param {string} data - Signed data to verify + * @returns {Promise} True if the signature was used to sign the data, else false + */ static async verify (name: string, signature: string, data: string): Promise { const addresses = await this.getAddresses(name) for (const address of addresses) { const { publicKey } = new Account(address) - if (nano25519_verify(publicKey, signature, data)) { + if (nano25519_verify(signature, utf8.toHex(data), publicKey)) { return true } } -- 2.52.0