diff --git a/src/identity.ts b/src/identity.ts index 112a12d..8a11b82 100644 --- a/src/identity.ts +++ b/src/identity.ts @@ -234,6 +234,30 @@ export class Contacts { this.contacts[hash].push(contact); } + public hasContact(nameOrHash: string | NodeHash): boolean { + if (typeof nameOrHash === "string") { + return Object.values(this.contacts) + .flat() + .some((contact) => contact.name.toLowerCase() === nameOrHash.toLowerCase()); + } else { + const hash = parseNodeHash(nameOrHash) as number; + return (this.contacts[hash] || []).length > 0; + } + } + + public getContactByName(name: string): Contact | null { + const contact = Object.values(this.contacts) + .flat() + .find((contact) => contact.name.toLowerCase() === name.toLowerCase()); + return contact || null; + } + + public getContacts(): Contact[] { + const contacts = Object.values(this.contacts).flat(); + contacts.sort((a, b) => a.name.localeCompare(b.name)); + return contacts; + } + public decrypt( src: NodeHash | PublicKey, dst: NodeHash, @@ -302,13 +326,54 @@ export class Contacts { } public addGroup(group: Group) { + // Remove any group with the same name (regardless of hash), the hash may + // have changed if the secret was changed, but the name is what identifies + // the group to the user. + for (const key of Object.keys(this.groups)) { + const hash = Number(key); + this.groups[hash] = this.groups[hash].filter((g) => g.name.toLowerCase() !== group.name.toLowerCase()); + if (this.groups[hash].length === 0) { + delete this.groups[hash]; + } + } + const hash = group.hash() as number; + if (!this.groups[hash]) { this.groups[hash] = []; } + this.groups[hash].push(group); } + public hasGroup(nameOrHash: string | NodeHash): boolean { + if (typeof nameOrHash === "string") { + return Object.values(this.groups) + .flat() + .some((group) => group.name.toLowerCase() === nameOrHash.toLowerCase()); + } else { + const hash = parseNodeHash(nameOrHash) as number; + return (this.groups[hash] || []).length > 0; + } + } + + public getGroupByName(name: string): Group | null { + const group = Object.values(this.groups) + .flat() + .find((group) => group.name.toLowerCase() === name.toLowerCase()); + return group || null; + } + + public getGroups(): Group[] { + const groups = Object.values(this.groups).flat(); + groups.sort((a, b) => { + if (a.name === "Public") return -1; + if (b.name === "Public") return 1; + return a.name.localeCompare(b.name); + }); + return groups; + } + public decryptGroupText( channelHash: NodeHash, hmac: Uint8Array,