From e21c1c83bbee41029f4f38e3d9e93a87f4a2841d Mon Sep 17 00:00:00 2001 From: Francis Cao Date: Thu, 5 Feb 2026 08:56:12 -0800 Subject: [PATCH] configure salt rotation period using env vars. Closed #3427 --- src/app/api/send/route.ts | 7 ++++--- src/lib/crypto.ts | 9 +++++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/app/api/send/route.ts b/src/app/api/send/route.ts index a0becc2ac..c3aa9a00e 100644 --- a/src/app/api/send/route.ts +++ b/src/app/api/send/route.ts @@ -1,10 +1,10 @@ -import { startOfHour, startOfMonth } from 'date-fns'; +import { startOfHour } from 'date-fns'; import { isbot } from 'isbot'; import { serializeError } from 'serialize-error'; import { z } from 'zod'; import clickhouse from '@/lib/clickhouse'; import { COLLECTION_TYPE, EVENT_TYPE } from '@/lib/constants'; -import { hash, secret, uuid } from '@/lib/crypto'; +import { getSalt, hash, secret, uuid } from '@/lib/crypto'; import { getClientInfo, hasBlockedIp } from '@/lib/detect'; import { createToken, parseToken } from '@/lib/jwt'; import { fetchWebsite } from '@/lib/load'; @@ -130,7 +130,8 @@ export async function POST(request: Request) { const createdAt = timestamp ? new Date(timestamp * 1000) : new Date(); const now = Math.floor(Date.now() / 1000); - const sessionSalt = hash(startOfMonth(createdAt).toUTCString()); + const saltRotation = process.env.SALT_ROTATION || 'month'; + const sessionSalt = getSalt(saltRotation, createdAt); const visitSalt = hash(startOfHour(createdAt).toUTCString()); const sessionId = id ? uuid(sourceId, id) : uuid(sourceId, ip, userAgent, sessionSalt); diff --git a/src/lib/crypto.ts b/src/lib/crypto.ts index ee4c977fe..6dde8826d 100644 --- a/src/lib/crypto.ts +++ b/src/lib/crypto.ts @@ -1,4 +1,5 @@ import crypto from 'node:crypto'; +import { startOfDay, startOfMonth, startOfWeek } from 'date-fns'; import { v4, v5, v7 } from 'uuid'; const ALGORITHM = 'aes-256-gcm'; @@ -67,3 +68,11 @@ export function uuid(...args: any) { export function createAuthKey() { return crypto.randomBytes(16).toString('hex'); } + +export function getSalt(saltRotation: string, createdAt: Date): string { + return hash( + (saltRotation === 'day' ? startOfDay : saltRotation === 'week' ? startOfWeek : startOfMonth)( + createdAt, + ).toUTCString(), + ); +}