feat: expand internationalization and add identity management
This release significantly expands internationalization support and adds comprehensive identity management features. Internationalization (i18n): - Add 5 new languages: Spanish, Italian, German, Dutch, Portuguese - Expand from 3 to 8 total supported languages - Redesign language switcher for better scalability (dropdown UI) - Complete translations for all features across all languages Identity Management: - Multiple sender identities with per-identity signatures - Sub-addressing support (user+tag@domain.com) - Context-aware tag suggestions for sub-addresses - Identity badges in email viewer and list - Full CRUD operations for managing identities Newsletter Management: - RFC 2369 List-Unsubscribe support (one-click unsubscribe) - HTTP and mailto unsubscribe methods - Security validation prevents XSS attacks - Two-step confirmation with persistent dismissal Security & Accessibility: - Dark mode email readability (intelligent color transformation) - WCAG 2.0 Level AA color contrast compliance - Comprehensive XSS prevention with validation utilities - Unit test coverage for security-critical code (57 validation tests) Testing: - Add unit tests for validation utilities - Add unit tests for email sanitization - Add unit tests for color transformation - Full test coverage for XSS attack vectors
This commit is contained in:
+11
-4
@@ -1,4 +1,5 @@
|
||||
import { AuthenticationResults } from './jmap/types';
|
||||
import { parseUnsubscribeUrls } from './validation';
|
||||
|
||||
/**
|
||||
* Parse Authentication-Results header to extract SPF, DKIM, DMARC results
|
||||
@@ -191,7 +192,11 @@ export function parseSpamLLM(header: string): { verdict: string; explanation: st
|
||||
*/
|
||||
interface ListHeaders {
|
||||
listId?: string;
|
||||
listUnsubscribe?: string;
|
||||
listUnsubscribe?: {
|
||||
http?: string;
|
||||
mailto?: string;
|
||||
preferred?: 'http' | 'mailto';
|
||||
};
|
||||
listHelp?: string;
|
||||
listPost?: string;
|
||||
}
|
||||
@@ -209,9 +214,11 @@ export function extractListHeaders(headers: Record<string, string | string[]>):
|
||||
const unsub = Array.isArray(headers['List-Unsubscribe'])
|
||||
? headers['List-Unsubscribe'][0]
|
||||
: headers['List-Unsubscribe'];
|
||||
// Extract URL from <url> format
|
||||
const match = unsub.match(/<([^>]+)>/);
|
||||
result.listUnsubscribe = match ? match[1] : unsub;
|
||||
|
||||
const parsed = parseUnsubscribeUrls(unsub);
|
||||
if (parsed.preferred) {
|
||||
result.listUnsubscribe = parsed;
|
||||
}
|
||||
}
|
||||
|
||||
if (headers['List-Help']) {
|
||||
|
||||
Reference in New Issue
Block a user