fix(cli): address code-review findings on OAuth PR

This commit is contained in:
James
2026-05-28 05:59:24 +00:00
parent 8a9291c434
commit 81aff68397
20 changed files with 1722 additions and 125 deletions
+43
View File
@@ -0,0 +1,43 @@
/**
* PKCE (Proof Key for Code Exchange, RFC 7636) helpers.
*
* The flow:
* 1. Generate a high-entropy `code_verifier` (43128 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(/=+$/, "");
}