import { config } from './config' export const AUTH_COOKIE_NAME = 'auth_token' const SECRET_KEY = config.auth.secret // Helper to generate a random nonce function generateNonce() { return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15) } // Helper to create a signed token (simplified JWT-like structure) export async function createToken(username: string) { const header = { alg: 'HS256', typ: 'JWT' } const payload = { sub: username, iat: Date.now(), exp: Date.now() + 24 * 60 * 60 * 1000, // 24 hours nonce: generateNonce() // Ensure token is different every time } const encodedHeader = btoa(JSON.stringify(header)) const encodedPayload = btoa(JSON.stringify(payload)) const data = `${encodedHeader}.${encodedPayload}` const key = await crypto.subtle.importKey( 'raw', new TextEncoder().encode(SECRET_KEY), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign'] ) const signature = await crypto.subtle.sign( 'HMAC', key, new TextEncoder().encode(data) ) // Convert signature to base64 const signatureArray = Array.from(new Uint8Array(signature)) const encodedSignature = btoa(String.fromCharCode.apply(null, signatureArray)) return `${data}.${encodedSignature}` } // Helper to verify token export async function verifyToken(token: string) { try { const parts = token.split('.') if (parts.length !== 3) return false const [encodedHeader, encodedPayload, encodedSignature] = parts const data = `${encodedHeader}.${encodedPayload}` const key = await crypto.subtle.importKey( 'raw', new TextEncoder().encode(SECRET_KEY), { name: 'HMAC', hash: 'SHA-256' }, false, ['verify'] ) const signature = new Uint8Array( atob(encodedSignature).split('').map(c => c.charCodeAt(0)) ) const isValid = await crypto.subtle.verify( 'HMAC', key, signature, new TextEncoder().encode(data) ) if (!isValid) return false const payload = JSON.parse(atob(encodedPayload)) if (payload.exp < Date.now()) return false return true } catch (e) { return false } }