mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-10 22:20:14 +00:00
fix(cli): address code-review findings on OAuth PR
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* PKCE (Proof Key for Code Exchange, RFC 7636) helpers.
|
||||
*
|
||||
* The flow:
|
||||
* 1. Generate a high-entropy `code_verifier` (43–128 URL-safe chars).
|
||||
* 2. Send `code_challenge = base64url(SHA-256(code_verifier))` to
|
||||
* `/v1/oauth/authorize`.
|
||||
* 3. After the user consents, exchange the returned `code` + the
|
||||
* original `code_verifier` at `/v1/oauth/token`. The server hashes
|
||||
* the verifier and rejects the exchange if it doesn't match the
|
||||
* challenge that opened the flow.
|
||||
*
|
||||
* PKCE removes the need for a client secret — perfect for a CLI that
|
||||
* can't keep one.
|
||||
*/
|
||||
|
||||
import { createHash, randomBytes } from "node:crypto";
|
||||
|
||||
const VERIFIER_BYTES = 64; // 64 random bytes → 86 base64url chars (well within 43-128)
|
||||
|
||||
export interface PkcePair {
|
||||
/** Sent on the exchange; kept secret by the CLI between the two HTTP hops. */
|
||||
verifier: string;
|
||||
/** Sent on the authorize URL. */
|
||||
challenge: string;
|
||||
/** Always "S256" for HeyGen's backend (`code_challenge_method`). */
|
||||
method: "S256";
|
||||
}
|
||||
|
||||
export function generatePkcePair(): PkcePair {
|
||||
const verifier = base64UrlEncode(randomBytes(VERIFIER_BYTES));
|
||||
const challenge = base64UrlEncode(createHash("sha256").update(verifier).digest());
|
||||
return { verifier, challenge, method: "S256" };
|
||||
}
|
||||
|
||||
/** OAuth `state` parameter — a CSRF token bound to this flow. */
|
||||
export function generateState(): string {
|
||||
return base64UrlEncode(randomBytes(32));
|
||||
}
|
||||
|
||||
function base64UrlEncode(buf: Buffer): string {
|
||||
return buf.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
||||
}
|
||||
Reference in New Issue
Block a user