( email: string, token: string )
| 30 | * Verify an unsubscribe token for an email address and return email type |
| 31 | */ |
| 32 | export function verifyUnsubscribeToken( |
| 33 | email: string, |
| 34 | token: string |
| 35 | ): { valid: boolean; emailType?: string } { |
| 36 | try { |
| 37 | const parts = token.split(':') |
| 38 | if (parts.length < 2) return { valid: false } |
| 39 | |
| 40 | if (parts.length === 2) { |
| 41 | const [salt, expectedHash] = parts |
| 42 | const hash = sha256Hex(`${email}:${salt}:${env.BETTER_AUTH_SECRET}`) |
| 43 | |
| 44 | return { valid: hash === expectedHash, emailType: 'marketing' } |
| 45 | } |
| 46 | |
| 47 | const [salt, expectedHash, emailType] = parts |
| 48 | if (!salt || !expectedHash || !emailType) return { valid: false } |
| 49 | |
| 50 | const hash = sha256Hex(`${email}:${salt}:${emailType}:${env.BETTER_AUTH_SECRET}`) |
| 51 | |
| 52 | return { valid: hash === expectedHash, emailType } |
| 53 | } catch (error) { |
| 54 | logger.error('Error verifying unsubscribe token:', error) |
| 55 | return { valid: false } |
| 56 | } |
| 57 | } |
| 58 | |
| 59 | /** |
| 60 | * Check if an email type is transactional |
no test coverage detected