mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 19:04:02 +00:00
fix(voice): validate Codex OAuth and report unknown usage
This commit is contained in:
1 parent
881e24485c
commit
a398a25934
8 files changed
+265
-19
No files matched your search
@@ -1,5 +1,10 @@
|
||||
import { spawn } from 'node:child_process';
|
||||
import { accessSync, constants as fsConstants, readFileSync } from 'node:fs';
|
||||
import {
|
||||
accessSync,
|
||||
constants as fsConstants,
|
||||
readFileSync,
|
||||
statSync,
|
||||
} from 'node:fs';
|
||||
import os from 'node:os';
|
||||
import path from 'node:path';
|
||||
|
||||
@@ -16,22 +21,88 @@ export function codexAuthPath({
|
||||
);
|
||||
}
|
||||
|
||||
/** An optional operator lock that refuses the metered API-key voice lane. */
|
||||
export function preferCodexOAuth(environment = process.env) {
|
||||
if (!Object.hasOwn(environment, 'GEV_PREFER_CODEX_OAUTH')) return false;
|
||||
const value = String(environment.GEV_PREFER_CODEX_OAUTH || '')
|
||||
.trim()
|
||||
.toLowerCase();
|
||||
if (['1', 'true', 'yes', 'on'].includes(value)) return true;
|
||||
if (['0', 'false', 'no', 'off'].includes(value)) return false;
|
||||
throw new Error(
|
||||
'GEV_PREFER_CODEX_OAUTH must be true or false. Refusing to choose a voice auth mode.',
|
||||
);
|
||||
}
|
||||
|
||||
export function readCodexOAuthAccessToken({
|
||||
authPath = codexAuthPath(),
|
||||
readFile = readFileSync,
|
||||
statFile = statSync,
|
||||
nowMs = Date.now(),
|
||||
} = {}) {
|
||||
const unavailable =
|
||||
'ChatGPT sign-in is unavailable. Sign in to Codex or the ChatGPT desktop app and try again.';
|
||||
let parsed;
|
||||
try {
|
||||
parsed = JSON.parse(readFile(authPath, 'utf8'));
|
||||
} catch {
|
||||
throw new Error(
|
||||
'ChatGPT sign-in is unavailable. Sign in to Codex or the ChatGPT desktop app and try again.',
|
||||
);
|
||||
throw new Error(unavailable);
|
||||
}
|
||||
const token = String(parsed?.tokens?.access_token || '').trim();
|
||||
if (!token) {
|
||||
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
||||
throw new Error(unavailable);
|
||||
}
|
||||
const mode = String(parsed.auth_mode || '')
|
||||
.trim()
|
||||
.toLowerCase();
|
||||
const chatGptMode = mode
|
||||
? mode === 'chatgpt' || mode === 'chatgptauthtokens'
|
||||
: typeof parsed.OPENAI_API_KEY !== 'string';
|
||||
const token = parsed.tokens?.access_token;
|
||||
const refresh = parsed.tokens?.refresh_token;
|
||||
if (
|
||||
!chatGptMode ||
|
||||
typeof token !== 'string' ||
|
||||
!token.trim() ||
|
||||
typeof refresh !== 'string' ||
|
||||
!refresh.trim()
|
||||
) {
|
||||
throw new Error(unavailable);
|
||||
}
|
||||
|
||||
// This only checks token shape and expiry. OpenAI verifies the signature when
|
||||
// minting the short-lived Realtime credential; we never modify auth.json.
|
||||
const parts = token.split('.');
|
||||
if (
|
||||
parts.length !== 3 ||
|
||||
parts.some((part) => !/^[A-Za-z0-9_-]+$/.test(part))
|
||||
) {
|
||||
throw new Error(unavailable);
|
||||
}
|
||||
let payload;
|
||||
try {
|
||||
payload = JSON.parse(Buffer.from(parts[1], 'base64url').toString('utf8'));
|
||||
} catch {
|
||||
throw new Error(unavailable);
|
||||
}
|
||||
if (!payload || typeof payload !== 'object' || Array.isArray(payload)) {
|
||||
throw new Error(unavailable);
|
||||
}
|
||||
let expiresAtMs;
|
||||
if (Object.hasOwn(payload, 'exp')) {
|
||||
if (typeof payload.exp !== 'number' || !Number.isFinite(payload.exp)) {
|
||||
throw new Error(unavailable);
|
||||
}
|
||||
expiresAtMs = payload.exp * 1000;
|
||||
} else {
|
||||
try {
|
||||
expiresAtMs = statFile(authPath).mtimeMs + 60 * 60 * 1000;
|
||||
} catch {
|
||||
throw new Error(unavailable);
|
||||
}
|
||||
}
|
||||
if (!Number.isFinite(expiresAtMs) || expiresAtMs <= nowMs + 60_000) {
|
||||
throw new Error(
|
||||
'ChatGPT sign-in is unavailable. Sign in to Codex or the ChatGPT desktop app and try again.',
|
||||
'ChatGPT sign-in has expired. Run codex login and try again.',
|
||||
);
|
||||
}
|
||||
return token;
|
||||
|
||||
Reference in new issue
Block a user