Fresh history cut from cynarAI/evoo antigravity-handoff/project-timeline (Voice First + project timeline). Brand docs/titles as evOo; keep @rakazo/* packages as tech debt. Excludes node_modules, caches, secrets, voice blobs.
59 lines
2.0 KiB
TypeScript
59 lines
2.0 KiB
TypeScript
import type { RakazoDesktop, RakazoDesktopOAuthCallback } from "@rakazo/contracts";
|
|
|
|
export type { RakazoDesktop, RakazoDesktopOAuthCallback } from "@rakazo/contracts";
|
|
|
|
declare global {
|
|
interface Window {
|
|
rakazoDesktop?: RakazoDesktop;
|
|
}
|
|
}
|
|
|
|
export function desktopBridge(): RakazoDesktop | undefined {
|
|
return typeof window === "undefined" ? undefined : window.rakazoDesktop;
|
|
}
|
|
|
|
/** The compact `code#state` form the manual paste flow already accepts. */
|
|
export function desktopOAuthCode(callback: RakazoDesktopOAuthCallback) {
|
|
return callback.state === undefined ? callback.code : `${callback.code}#${callback.state}`;
|
|
}
|
|
|
|
/**
|
|
* The authorize URL carries the attempt's PKCE state, so a captured code whose
|
|
* state differs belongs to a different attempt — a popup left open by a
|
|
* cancelled sign-in, say — and must not be spent on the current one.
|
|
*/
|
|
export function oauthStateOf(verificationUri: string): string | undefined {
|
|
try {
|
|
return new URL(verificationUri).searchParams.get("state") ?? undefined;
|
|
} catch {
|
|
return undefined;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Desktop sign-in redirects to a loopback URL the renderer never sees.
|
|
* The main process captures the code there so the browser flow's
|
|
* copy-and-paste step can be skipped. No-ops in a browser.
|
|
*
|
|
* Pass the attempt's state to ignore codes captured for any other attempt.
|
|
* Providers whose authorize URL carries no state cannot be correlated, so
|
|
* their codes are accepted as before.
|
|
*/
|
|
export function onDesktopOAuthCallback(
|
|
listener: (code: string) => void,
|
|
expectedState?: string,
|
|
): () => void {
|
|
const oauth = desktopBridge()?.oauth;
|
|
if (!oauth) return () => undefined;
|
|
return oauth.onCallback((callback) => {
|
|
if (expectedState !== undefined && callback.state !== expectedState) return;
|
|
listener(desktopOAuthCode(callback));
|
|
});
|
|
}
|
|
|
|
export function windowChromeKind(desktop?: RakazoDesktop): "spacer" | "darwin" | "controls" {
|
|
if (!desktop) return "spacer";
|
|
if (desktop.platform === "darwin") return "darwin";
|
|
return "controls";
|
|
}
|