diff --git a/packages/shared-analytics/src/utils/phone-hash.ts b/packages/shared-analytics/src/utils/phone-hash.ts index accb2c2..879dd2e 100644 --- a/packages/shared-analytics/src/utils/phone-hash.ts +++ b/packages/shared-analytics/src/utils/phone-hash.ts @@ -1,12 +1,10 @@ +import crypto from 'crypto'; + /** * Hash a phone number for analytics purposes - * Uses a consistent hashing algorithm to create a deterministic hash + * Uses SHA-256 for consistent, cryptographically strong hashing */ export function hashPhoneNumber(phoneNumber: string): string { - let hash = 0; - for (let i = 0; i < phoneNumber.length; i++) { - hash = ((hash << 5) - hash) + phoneNumber.charCodeAt(i); - hash |= 0; - } - return `hash_${Math.abs(hash)}`; + const hash = crypto.createHash('sha256').update(phoneNumber).digest('hex'); + return `sha256_${hash}`; } diff --git a/services/spamshield/src/services/spamshield.service.ts b/services/spamshield/src/services/spamshield.service.ts index da77c69..da578ac 100644 --- a/services/spamshield/src/services/spamshield.service.ts +++ b/services/spamshield/src/services/spamshield.service.ts @@ -210,10 +210,12 @@ export class SpamShieldService { const confidence = Math.min(matches.reduce((sum, m) => sum + m.score, 0), 1.0); const decision = confidence > 0.8 ? 'BLOCK' : confidence > 0.5 ? 'FLAG' : 'ALLOW'; + const encrypted = FieldEncryptionService.encrypt(validated); + const auditLog = await prisma.spamAuditLog.create({ data: { userId: 'system', - phoneNumber: validated, + phoneNumber: encrypted, decision: decision as any, reason: `Rule-based analysis`, ruleId: ruleMatchIds[0],