import { createHash, randomBytes } from 'crypto'; | |
/** | |
* Generate a cryptographically secure random string | |
*/ | |
export function generateRandomString(length: number): string { | |
const bytes = randomBytes(Math.ceil(length / 2)); | |
return bytes.toString('hex').slice(0, length); | |
} | |
/** | |
* Create a code challenge for PKCE (Proof Key for Code Exchange) | |
*/ | |
export async function createCodeChallenge(codeVerifier: string): Promise<string> { | |
const hash = createHash('sha256'); | |
hash.update(codeVerifier); | |
const digest = hash.digest(); | |
// Convert to base64url (URL-safe base64 without padding) | |
return digest | |
.toString('base64') | |
.replace(/\+/g, '-') | |
.replace(/\//g, '_') | |
.replace(/=/g, ''); | |
} | |
/** | |
* Parse cookies from cookie header string | |
*/ | |
export function parseCookies(cookieHeader: string): Record<string, string> { | |
const cookies: Record<string, string> = {}; | |
if (!cookieHeader) return cookies; | |
cookieHeader.split(';').forEach(cookie => { | |
const [name, ...rest] = cookie.trim().split('='); | |
if (name && rest.length > 0) { | |
cookies[name] = rest.join('='); | |
} | |
}); | |
return cookies; | |
} | |