Buckets:
| 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 | |
| } | |
Xet Storage Details
- Size:
- 1.13 kB
- Xet hash:
- 4032ca871ee1d409eaf7c43c5e0f6b83715d1fcea084f4e8fecca3710f13ae5c
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.