import crypto from 'crypto'; /** * Checksum length in hex characters (16 chars = 64 bits of entropy) */ export const CHECKSUM_LENGTH = 16; /** * Generate share link checksum for location * Uses HMAC-SHA256 for cryptographic integrity * * SECURITY: Prevents location ID enumeration while allowing stateless validation */ export function generateShareChecksum(locationId: string): string { const secret = process.env.SHARE_LINK_SECRET; if (!secret) { throw new Error('SHARE_LINK_SECRET environment variable not configured'); } return crypto .createHmac('sha256', secret) .update(locationId) .digest('hex') .substring(0, CHECKSUM_LENGTH); } /** * Generate combined location ID with checksum appended * @param locationId - The MongoDB location ID (24 chars) * @returns Combined ID: locationId + checksum (40 chars total) */ export function generateShareId(locationId: string): string { const checksum = generateShareChecksum(locationId); return locationId + checksum; }