// Copyright: © 2026 TWWIM UG. All rights reserved. (www.twwim.com) // // UTF-8-safe wrappers around atob. Vanilla atob() returns Latin-1 bytes, which // JSON.parse then mis-decodes for any non-ASCII payload (em-dashes, umlauts). // `base64UrlToUtf8` additionally normalises base64url -> base64 for JWT parts. export function base64ToUtf8(input: string): string { const binary = atob(input); const bytes = new Uint8Array(binary.length); for (let i = 0; i < binary.length; i++) { bytes[i] = binary.charCodeAt(i); } return new TextDecoder().decode(bytes); } export function base64UrlToUtf8(input: string): string { let normalised = input.replace(/-/g, '+').replace(/_/g, '/'); const padding = normalised.length % 4; if (padding) { normalised += '='.repeat(4 - padding); } return base64ToUtf8(normalised); }