import { createHash } from 'node:crypto' /** * The catalog's keys as voyager 3 stores them (migration 6000): 20-byte SHA-1s in bytea columns. * - identity_key: the identity's hash (lib/release/identity.ts gives it as 40 hex characters). * - release_key: one upload of an identity, unique: the identity, the owner group and the first article the window * saw of it. The same release sent twice (a tail release provisionally, then finished) hits the same row; a repost * starts at another article and is a release of its own (decision d). Deterministic, so no numbering under a lock. */ const HEX40 = /^[0-9a-f]{40}$/i function sha1(text: string): Buffer { return createHash('sha1').update(text).digest() } /** The identity key's bytes: 40 hex characters decoded, any other text (a spot's, a test's) hashed. */ export function identityKey(key: string): Buffer { return HEX40.test(key) ? Buffer.from(key, 'hex') : sha1(key) } /** The release key's bytes for an identity in a group, first seen at an article (null for releases without one: a spot's). */ export function releaseKey( identity: string, groupId: number | null, firstArticle: number | null ): Buffer { return sha1(`release\n${identity}\n${groupId ?? ''}\n${firstArticle ?? ''}`) } /** A stored key as hex, for logs, the API and release_merges.from_key. */ export function keyHex(key: Buffer | Uint8Array | string | null | undefined): string | null { if (key === null || key === undefined) return null return typeof key === 'string' ? key : Buffer.from(key).toString('hex') }