// PKCE utilities for OIDC flow function generateRandomString(length: number): string { const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' let text = '' for (let i = 0; i < length; i++) { text += possible.charAt(Math.floor(Math.random() * possible.length)) } return text } async function generateCodeChallenge(verifier: string): Promise { const encoder = new TextEncoder() const data = encoder.encode(verifier) const digest = await crypto.subtle.digest('SHA-256', data) const base64 = btoa(String.fromCharCode(...new Uint8Array(digest))) return base64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '') } export async function createPKCE(): Promise<{ verifier: string; challenge: string }> { const verifier = generateRandomString(128) const challenge = await generateCodeChallenge(verifier) return { verifier, challenge } } export function storePKCE(verifier: string): void { sessionStorage.setItem('pkce_verifier', verifier) } export function getPKCE(): string | null { return sessionStorage.getItem('pkce_verifier') } export function clearPKCE(): void { sessionStorage.removeItem('pkce_verifier') } export function storeToken(token: string): void { localStorage.setItem('access_token', token) } export function getToken(): string | null { return localStorage.getItem('access_token') } export function clearToken(): void { localStorage.removeItem('access_token') }