Files
netris-nestri/packages/auth/src/pkce.ts
2026-08-06 22:13:51 +03:00

39 lines
1.1 KiB
TypeScript

import { base64url } from 'jose';
function generateVerifier(length: number): string {
const buffer = new Uint8Array(length);
crypto.getRandomValues(buffer);
return base64url.encode(buffer);
}
async function generateChallenge(verifier: string, method: 'S256' | 'plain') {
if (method === 'plain') return verifier;
const encoder = new TextEncoder();
const data = encoder.encode(verifier);
const hash = await crypto.subtle.digest('SHA-256', data);
return base64url.encode(new Uint8Array(hash));
}
export async function generatePKCE(length: number = 64) {
if (length < 43 || length > 128) {
throw new Error('Code verifier length must be between 43 and 128 characters');
}
const verifier = generateVerifier(length);
const challenge = await generateChallenge(verifier, 'S256');
return {
verifier,
challenge,
method: 'S256'
};
}
export async function validatePKCE(
verifier: string,
challenge: string,
method: 'S256' | 'plain' = 'S256'
) {
const generatedChallenge = await generateChallenge(verifier, method);
// timing safe equals?
return generatedChallenge === challenge;
}