forked from
slices.network/slices
Highly ambitious ATProtocol AppView service and sdks
1import type { PKCEChallenge } from "./types.ts";
2
3export class PKCEUtils {
4 static generateCodeVerifier(): string {
5 const array = new Uint8Array(32);
6 crypto.getRandomValues(array);
7 return btoa(String.fromCharCode.apply(null, Array.from(array)))
8 .replace(/\+/g, "-")
9 .replace(/\//g, "_")
10 .replace(/=/g, "");
11 }
12
13 static async generateCodeChallenge(verifier: string): Promise<string> {
14 const encoder = new TextEncoder();
15 const data = encoder.encode(verifier);
16 const digest = await crypto.subtle.digest("SHA-256", data);
17 return btoa(
18 String.fromCharCode.apply(null, Array.from(new Uint8Array(digest)))
19 )
20 .replace(/\+/g, "-")
21 .replace(/\//g, "_")
22 .replace(/=/g, "");
23 }
24
25 static async generatePKCEChallenge(): Promise<PKCEChallenge> {
26 const codeVerifier = this.generateCodeVerifier();
27 const codeChallenge = await this.generateCodeChallenge(codeVerifier);
28 return {
29 codeVerifier,
30 codeChallenge,
31 codeChallengeMethod: "S256",
32 };
33 }
34
35 static generateState(): string {
36 const array = new Uint8Array(16);
37 crypto.getRandomValues(array);
38 return btoa(String.fromCharCode.apply(null, Array.from(array)))
39 .replace(/\+/g, "-")
40 .replace(/\//g, "_")
41 .replace(/=/g, "");
42 }
43}