oc-chatgpt-multi-auth 4.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +37 -0
- package/README.md +507 -0
- package/assets/opencode-logo-ornate-dark.svg +18 -0
- package/assets/readme-hero.svg +31 -0
- package/config/README.md +110 -0
- package/config/minimal-opencode.json +13 -0
- package/config/opencode-legacy.json +572 -0
- package/config/opencode-modern.json +240 -0
- package/dist/index.d.ts +45 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +971 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/accounts.d.ts +120 -0
- package/dist/lib/accounts.d.ts.map +1 -0
- package/dist/lib/accounts.js +579 -0
- package/dist/lib/accounts.js.map +1 -0
- package/dist/lib/auth/auth.d.ts +51 -0
- package/dist/lib/auth/auth.d.ts.map +1 -0
- package/dist/lib/auth/auth.js +180 -0
- package/dist/lib/auth/auth.js.map +1 -0
- package/dist/lib/auth/browser.d.ts +17 -0
- package/dist/lib/auth/browser.d.ts.map +1 -0
- package/dist/lib/auth/browser.js +83 -0
- package/dist/lib/auth/browser.js.map +1 -0
- package/dist/lib/auth/server.d.ts +10 -0
- package/dist/lib/auth/server.d.ts.map +1 -0
- package/dist/lib/auth/server.js +85 -0
- package/dist/lib/auth/server.js.map +1 -0
- package/dist/lib/auto-update-checker.d.ts +10 -0
- package/dist/lib/auto-update-checker.d.ts.map +1 -0
- package/dist/lib/auto-update-checker.js +129 -0
- package/dist/lib/auto-update-checker.js.map +1 -0
- package/dist/lib/cli.d.ts +9 -0
- package/dist/lib/cli.d.ts.map +1 -0
- package/dist/lib/cli.js +50 -0
- package/dist/lib/cli.js.map +1 -0
- package/dist/lib/config.d.ts +17 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +102 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/constants.d.ts +74 -0
- package/dist/lib/constants.d.ts.map +1 -0
- package/dist/lib/constants.js +74 -0
- package/dist/lib/constants.js.map +1 -0
- package/dist/lib/context-overflow.d.ts +27 -0
- package/dist/lib/context-overflow.d.ts.map +1 -0
- package/dist/lib/context-overflow.js +124 -0
- package/dist/lib/context-overflow.js.map +1 -0
- package/dist/lib/index.d.ts +13 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/index.js +13 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/lib/logger.d.ts +22 -0
- package/dist/lib/logger.d.ts.map +1 -0
- package/dist/lib/logger.js +175 -0
- package/dist/lib/logger.js.map +1 -0
- package/dist/lib/oauth-success.html +712 -0
- package/dist/lib/prompts/codex-opencode-bridge.d.ts +19 -0
- package/dist/lib/prompts/codex-opencode-bridge.d.ts.map +1 -0
- package/dist/lib/prompts/codex-opencode-bridge.js +152 -0
- package/dist/lib/prompts/codex-opencode-bridge.js.map +1 -0
- package/dist/lib/prompts/codex.d.ts +32 -0
- package/dist/lib/prompts/codex.d.ts.map +1 -0
- package/dist/lib/prompts/codex.js +262 -0
- package/dist/lib/prompts/codex.js.map +1 -0
- package/dist/lib/prompts/opencode-codex.d.ts +21 -0
- package/dist/lib/prompts/opencode-codex.d.ts.map +1 -0
- package/dist/lib/prompts/opencode-codex.js +91 -0
- package/dist/lib/prompts/opencode-codex.js.map +1 -0
- package/dist/lib/recovery/constants.d.ts +12 -0
- package/dist/lib/recovery/constants.d.ts.map +1 -0
- package/dist/lib/recovery/constants.js +25 -0
- package/dist/lib/recovery/constants.js.map +1 -0
- package/dist/lib/recovery/index.d.ts +12 -0
- package/dist/lib/recovery/index.d.ts.map +1 -0
- package/dist/lib/recovery/index.js +12 -0
- package/dist/lib/recovery/index.js.map +1 -0
- package/dist/lib/recovery/storage.d.ts +24 -0
- package/dist/lib/recovery/storage.d.ts.map +1 -0
- package/dist/lib/recovery/storage.js +354 -0
- package/dist/lib/recovery/storage.js.map +1 -0
- package/dist/lib/recovery/types.d.ts +116 -0
- package/dist/lib/recovery/types.d.ts.map +1 -0
- package/dist/lib/recovery/types.js +7 -0
- package/dist/lib/recovery/types.js.map +1 -0
- package/dist/lib/recovery.d.ts +31 -0
- package/dist/lib/recovery.d.ts.map +1 -0
- package/dist/lib/recovery.js +308 -0
- package/dist/lib/recovery.js.map +1 -0
- package/dist/lib/refresh-queue.d.ts +100 -0
- package/dist/lib/refresh-queue.d.ts.map +1 -0
- package/dist/lib/refresh-queue.js +196 -0
- package/dist/lib/refresh-queue.js.map +1 -0
- package/dist/lib/request/fetch-helpers.d.ts +81 -0
- package/dist/lib/request/fetch-helpers.d.ts.map +1 -0
- package/dist/lib/request/fetch-helpers.js +325 -0
- package/dist/lib/request/fetch-helpers.js.map +1 -0
- package/dist/lib/request/helpers/input-utils.d.ts +7 -0
- package/dist/lib/request/helpers/input-utils.d.ts.map +1 -0
- package/dist/lib/request/helpers/input-utils.js +213 -0
- package/dist/lib/request/helpers/input-utils.js.map +1 -0
- package/dist/lib/request/helpers/model-map.d.ts +28 -0
- package/dist/lib/request/helpers/model-map.d.ts.map +1 -0
- package/dist/lib/request/helpers/model-map.js +109 -0
- package/dist/lib/request/helpers/model-map.js.map +1 -0
- package/dist/lib/request/rate-limit-backoff.d.ts +17 -0
- package/dist/lib/request/rate-limit-backoff.d.ts.map +1 -0
- package/dist/lib/request/rate-limit-backoff.js +74 -0
- package/dist/lib/request/rate-limit-backoff.js.map +1 -0
- package/dist/lib/request/request-transformer.d.ts +93 -0
- package/dist/lib/request/request-transformer.d.ts.map +1 -0
- package/dist/lib/request/request-transformer.js +405 -0
- package/dist/lib/request/request-transformer.js.map +1 -0
- package/dist/lib/request/response-handler.d.ts +14 -0
- package/dist/lib/request/response-handler.d.ts.map +1 -0
- package/dist/lib/request/response-handler.js +90 -0
- package/dist/lib/request/response-handler.js.map +1 -0
- package/dist/lib/rotation.d.ts +121 -0
- package/dist/lib/rotation.d.ts.map +1 -0
- package/dist/lib/rotation.js +248 -0
- package/dist/lib/rotation.js.map +1 -0
- package/dist/lib/storage.d.ts +91 -0
- package/dist/lib/storage.d.ts.map +1 -0
- package/dist/lib/storage.js +323 -0
- package/dist/lib/storage.js.map +1 -0
- package/dist/lib/types.d.ts +185 -0
- package/dist/lib/types.d.ts.map +1 -0
- package/dist/lib/types.js +2 -0
- package/dist/lib/types.js.map +1 -0
- package/package.json +86 -0
- package/scripts/copy-oauth-success.js +37 -0
- package/scripts/install-opencode-codex-auth.js +193 -0
- package/scripts/test-all-models.sh +260 -0
- package/scripts/validate-model-map.sh +97 -0
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { generatePKCE } from "@openauthjs/openauth/pkce";
|
|
2
|
+
import { randomBytes } from "node:crypto";
|
|
3
|
+
// OAuth constants (from openai/codex)
|
|
4
|
+
export const CLIENT_ID = "app_EMoamEEZ73f0CkXaXp7hrann";
|
|
5
|
+
export const AUTHORIZE_URL = "https://auth.openai.com/oauth/authorize";
|
|
6
|
+
export const TOKEN_URL = "https://auth.openai.com/oauth/token";
|
|
7
|
+
export const REDIRECT_URI = "http://localhost:1455/auth/callback";
|
|
8
|
+
export const SCOPE = "openid profile email offline_access";
|
|
9
|
+
/**
|
|
10
|
+
* Generate a random state value for OAuth flow
|
|
11
|
+
* @returns Random hex string
|
|
12
|
+
*/
|
|
13
|
+
export function createState() {
|
|
14
|
+
return randomBytes(16).toString("hex");
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Parse authorization code and state from user input
|
|
18
|
+
* @param input - User input (URL, code#state, or just code)
|
|
19
|
+
* @returns Parsed authorization data
|
|
20
|
+
*/
|
|
21
|
+
export function parseAuthorizationInput(input) {
|
|
22
|
+
const value = (input || "").trim();
|
|
23
|
+
if (!value)
|
|
24
|
+
return {};
|
|
25
|
+
try {
|
|
26
|
+
const url = new URL(value);
|
|
27
|
+
return {
|
|
28
|
+
code: url.searchParams.get("code") ?? undefined,
|
|
29
|
+
state: url.searchParams.get("state") ?? undefined,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
// Invalid URL, try other parsing methods
|
|
34
|
+
}
|
|
35
|
+
if (value.includes("#")) {
|
|
36
|
+
const [code, state] = value.split("#", 2);
|
|
37
|
+
return { code, state };
|
|
38
|
+
}
|
|
39
|
+
if (value.includes("code=")) {
|
|
40
|
+
const params = new URLSearchParams(value);
|
|
41
|
+
return {
|
|
42
|
+
code: params.get("code") ?? undefined,
|
|
43
|
+
state: params.get("state") ?? undefined,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
return { code: value };
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Exchange authorization code for access and refresh tokens
|
|
50
|
+
* @param code - Authorization code from OAuth flow
|
|
51
|
+
* @param verifier - PKCE verifier
|
|
52
|
+
* @param redirectUri - OAuth redirect URI
|
|
53
|
+
* @returns Token result
|
|
54
|
+
*/
|
|
55
|
+
export async function exchangeAuthorizationCode(code, verifier, redirectUri = REDIRECT_URI) {
|
|
56
|
+
const res = await fetch(TOKEN_URL, {
|
|
57
|
+
method: "POST",
|
|
58
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
59
|
+
body: new URLSearchParams({
|
|
60
|
+
grant_type: "authorization_code",
|
|
61
|
+
client_id: CLIENT_ID,
|
|
62
|
+
code,
|
|
63
|
+
code_verifier: verifier,
|
|
64
|
+
redirect_uri: redirectUri,
|
|
65
|
+
}),
|
|
66
|
+
});
|
|
67
|
+
if (!res.ok) {
|
|
68
|
+
const text = await res.text().catch(() => "");
|
|
69
|
+
console.error("[openai-codex-plugin] code->token failed:", res.status, text);
|
|
70
|
+
return { type: "failed", reason: "http_error", statusCode: res.status, message: text || undefined };
|
|
71
|
+
}
|
|
72
|
+
const json = (await res.json());
|
|
73
|
+
if (!json?.access_token ||
|
|
74
|
+
!json?.refresh_token ||
|
|
75
|
+
typeof json?.expires_in !== "number") {
|
|
76
|
+
console.error("[openai-codex-plugin] token response missing fields:", json);
|
|
77
|
+
return { type: "failed", reason: "invalid_response", message: "Missing access_token, refresh_token, or expires_in" };
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
type: "success",
|
|
81
|
+
access: json.access_token,
|
|
82
|
+
refresh: json.refresh_token,
|
|
83
|
+
expires: Date.now() + json.expires_in * 1000,
|
|
84
|
+
idToken: json.id_token,
|
|
85
|
+
multiAccount: true,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Decode a JWT token to extract payload
|
|
90
|
+
* @param token - JWT token to decode
|
|
91
|
+
* @returns Decoded payload or null if invalid
|
|
92
|
+
*/
|
|
93
|
+
export function decodeJWT(token) {
|
|
94
|
+
try {
|
|
95
|
+
const parts = token.split(".");
|
|
96
|
+
if (parts.length !== 3)
|
|
97
|
+
return null;
|
|
98
|
+
const payload = parts[1] ?? "";
|
|
99
|
+
const normalized = payload.replace(/-/g, "+").replace(/_/g, "/");
|
|
100
|
+
const padded = normalized.padEnd(normalized.length + ((4 - (normalized.length % 4)) % 4), "=");
|
|
101
|
+
const decoded = Buffer.from(padded, "base64").toString("utf-8");
|
|
102
|
+
return JSON.parse(decoded);
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Refresh access token using refresh token
|
|
110
|
+
* @param refreshToken - Refresh token
|
|
111
|
+
* @returns Token result
|
|
112
|
+
*/
|
|
113
|
+
export async function refreshAccessToken(refreshToken) {
|
|
114
|
+
try {
|
|
115
|
+
const response = await fetch(TOKEN_URL, {
|
|
116
|
+
method: "POST",
|
|
117
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
118
|
+
body: new URLSearchParams({
|
|
119
|
+
grant_type: "refresh_token",
|
|
120
|
+
refresh_token: refreshToken,
|
|
121
|
+
client_id: CLIENT_ID,
|
|
122
|
+
}),
|
|
123
|
+
});
|
|
124
|
+
if (!response.ok) {
|
|
125
|
+
const text = await response.text().catch(() => "");
|
|
126
|
+
console.error("[openai-codex-plugin] Token refresh failed:", response.status, text);
|
|
127
|
+
return { type: "failed", reason: "http_error", statusCode: response.status, message: text || undefined };
|
|
128
|
+
}
|
|
129
|
+
const json = (await response.json());
|
|
130
|
+
if (!json?.access_token || typeof json?.expires_in !== "number") {
|
|
131
|
+
console.error("[openai-codex-plugin] Token refresh response missing fields:", json);
|
|
132
|
+
return { type: "failed", reason: "invalid_response", message: "Missing access_token or expires_in" };
|
|
133
|
+
}
|
|
134
|
+
const nextRefresh = json.refresh_token ?? refreshToken;
|
|
135
|
+
if (!nextRefresh) {
|
|
136
|
+
console.error("[openai-codex-plugin] Token refresh missing refresh token");
|
|
137
|
+
return { type: "failed", reason: "missing_refresh", message: "No refresh token in response or input" };
|
|
138
|
+
}
|
|
139
|
+
return {
|
|
140
|
+
type: "success",
|
|
141
|
+
access: json.access_token,
|
|
142
|
+
refresh: nextRefresh,
|
|
143
|
+
expires: Date.now() + json.expires_in * 1000,
|
|
144
|
+
idToken: json.id_token,
|
|
145
|
+
multiAccount: true,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
catch (error) {
|
|
149
|
+
const err = error;
|
|
150
|
+
console.error("[openai-codex-plugin] Token refresh error:", err);
|
|
151
|
+
return { type: "failed", reason: "network_error", message: err?.message };
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Create OAuth authorization flow
|
|
156
|
+
* @param options - Optional configuration for the flow
|
|
157
|
+
* @returns Authorization flow details
|
|
158
|
+
*/
|
|
159
|
+
export async function createAuthorizationFlow(options) {
|
|
160
|
+
const pkce = (await generatePKCE());
|
|
161
|
+
const state = createState();
|
|
162
|
+
const url = new URL(AUTHORIZE_URL);
|
|
163
|
+
url.searchParams.set("response_type", "code");
|
|
164
|
+
url.searchParams.set("client_id", CLIENT_ID);
|
|
165
|
+
url.searchParams.set("redirect_uri", REDIRECT_URI);
|
|
166
|
+
url.searchParams.set("scope", SCOPE);
|
|
167
|
+
url.searchParams.set("code_challenge", pkce.challenge);
|
|
168
|
+
url.searchParams.set("code_challenge_method", "S256");
|
|
169
|
+
url.searchParams.set("state", state);
|
|
170
|
+
url.searchParams.set("id_token_add_organizations", "true");
|
|
171
|
+
url.searchParams.set("codex_cli_simplified_flow", "true");
|
|
172
|
+
url.searchParams.set("originator", "codex_cli_rs");
|
|
173
|
+
// Force a fresh login screen when adding multiple accounts
|
|
174
|
+
// This helps prevent the browser from auto-using an existing session
|
|
175
|
+
if (options?.forceNewLogin) {
|
|
176
|
+
url.searchParams.set("prompt", "login");
|
|
177
|
+
}
|
|
178
|
+
return { pkce, state, url: url.toString() };
|
|
179
|
+
}
|
|
180
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../lib/auth/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser utilities for OAuth flow
|
|
3
|
+
* Handles platform-specific browser opening
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Gets the platform-specific command to open a URL in the default browser
|
|
7
|
+
* @returns Browser opener command for the current platform
|
|
8
|
+
*/
|
|
9
|
+
export declare function getBrowserOpener(): string;
|
|
10
|
+
/**
|
|
11
|
+
* Opens a URL in the default browser
|
|
12
|
+
* Silently fails if browser cannot be opened (user can copy URL manually)
|
|
13
|
+
* @param url - URL to open
|
|
14
|
+
* @returns True if a browser launch was attempted
|
|
15
|
+
*/
|
|
16
|
+
export declare function openBrowserUrl(url: string): boolean;
|
|
17
|
+
//# sourceMappingURL=browser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../../lib/auth/browser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAKzC;AAkCD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CA6BnD"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser utilities for OAuth flow
|
|
3
|
+
* Handles platform-specific browser opening
|
|
4
|
+
*/
|
|
5
|
+
import { spawn } from "node:child_process";
|
|
6
|
+
import fs from "node:fs";
|
|
7
|
+
import path from "node:path";
|
|
8
|
+
import { PLATFORM_OPENERS } from "../constants.js";
|
|
9
|
+
/**
|
|
10
|
+
* Gets the platform-specific command to open a URL in the default browser
|
|
11
|
+
* @returns Browser opener command for the current platform
|
|
12
|
+
*/
|
|
13
|
+
export function getBrowserOpener() {
|
|
14
|
+
const platform = process.platform;
|
|
15
|
+
if (platform === "darwin")
|
|
16
|
+
return PLATFORM_OPENERS.darwin;
|
|
17
|
+
if (platform === "win32")
|
|
18
|
+
return PLATFORM_OPENERS.win32;
|
|
19
|
+
return PLATFORM_OPENERS.linux;
|
|
20
|
+
}
|
|
21
|
+
function commandExists(command) {
|
|
22
|
+
if (!command)
|
|
23
|
+
return false;
|
|
24
|
+
// "start" is a shell builtin on Windows; rely on shell execution
|
|
25
|
+
if (process.platform === "win32" && command.toLowerCase() === "start") {
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
const pathValue = process.env.PATH || "";
|
|
29
|
+
const entries = pathValue.split(path.delimiter).filter(Boolean);
|
|
30
|
+
if (entries.length === 0)
|
|
31
|
+
return false;
|
|
32
|
+
if (process.platform === "win32") {
|
|
33
|
+
const pathext = (process.env.PATHEXT || ".EXE;.CMD;.BAT;.COM")
|
|
34
|
+
.split(";")
|
|
35
|
+
.filter(Boolean);
|
|
36
|
+
for (const entry of entries) {
|
|
37
|
+
for (const ext of pathext) {
|
|
38
|
+
const candidate = path.join(entry, `${command}${ext}`);
|
|
39
|
+
if (fs.existsSync(candidate))
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
for (const entry of entries) {
|
|
46
|
+
const candidate = path.join(entry, command);
|
|
47
|
+
if (fs.existsSync(candidate))
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Opens a URL in the default browser
|
|
54
|
+
* Silently fails if browser cannot be opened (user can copy URL manually)
|
|
55
|
+
* @param url - URL to open
|
|
56
|
+
* @returns True if a browser launch was attempted
|
|
57
|
+
*/
|
|
58
|
+
export function openBrowserUrl(url) {
|
|
59
|
+
try {
|
|
60
|
+
// Windows: use PowerShell Start-Process to avoid cmd/start quirks with URLs containing '&' or ':'
|
|
61
|
+
if (process.platform === "win32") {
|
|
62
|
+
const psUrl = url.replace(/`/g, "``").replace(/"/g, '""');
|
|
63
|
+
const child = spawn("powershell.exe", ["-NoLogo", "-NoProfile", "-Command", `Start-Process "${psUrl}"`], { stdio: "ignore" });
|
|
64
|
+
child.on("error", () => { });
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
const opener = getBrowserOpener();
|
|
68
|
+
if (!commandExists(opener)) {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
const child = spawn(opener, [url], {
|
|
72
|
+
stdio: "ignore",
|
|
73
|
+
shell: false,
|
|
74
|
+
});
|
|
75
|
+
child.on("error", () => { });
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
// Silently fail - user can manually open the URL from instructions
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=browser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser.js","sourceRoot":"","sources":["../../../lib/auth/browser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { OAuthServerInfo } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Start a small local HTTP server that waits for /auth/callback and returns the code
|
|
4
|
+
* @param options - OAuth state for validation
|
|
5
|
+
* @returns Promise that resolves to server info
|
|
6
|
+
*/
|
|
7
|
+
export declare function startLocalOAuthServer({ state }: {
|
|
8
|
+
state: string;
|
|
9
|
+
}): Promise<OAuthServerInfo>;
|
|
10
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../lib/auth/server.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAMnD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,eAAe,CAAC,CAyE5F"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import http from "node:http";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
// Resolve path to oauth-success.html (one level up from auth/ subfolder)
|
|
6
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
const successHtml = fs.readFileSync(path.join(__dirname, "..", "oauth-success.html"), "utf-8");
|
|
8
|
+
/**
|
|
9
|
+
* Start a small local HTTP server that waits for /auth/callback and returns the code
|
|
10
|
+
* @param options - OAuth state for validation
|
|
11
|
+
* @returns Promise that resolves to server info
|
|
12
|
+
*/
|
|
13
|
+
export function startLocalOAuthServer({ state }) {
|
|
14
|
+
const server = http.createServer((req, res) => {
|
|
15
|
+
try {
|
|
16
|
+
const url = new URL(req.url || "", "http://localhost");
|
|
17
|
+
if (url.pathname !== "/auth/callback") {
|
|
18
|
+
res.statusCode = 404;
|
|
19
|
+
res.end("Not found");
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
if (url.searchParams.get("state") !== state) {
|
|
23
|
+
res.statusCode = 400;
|
|
24
|
+
res.end("State mismatch");
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const code = url.searchParams.get("code");
|
|
28
|
+
if (!code) {
|
|
29
|
+
res.statusCode = 400;
|
|
30
|
+
res.end("Missing authorization code");
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
res.statusCode = 200;
|
|
34
|
+
res.setHeader("Content-Type", "text/html; charset=utf-8");
|
|
35
|
+
res.end(successHtml);
|
|
36
|
+
server._lastCode = code;
|
|
37
|
+
}
|
|
38
|
+
catch (err) {
|
|
39
|
+
console.error("[openai-codex-plugin] Request handler error:", err?.message ?? String(err));
|
|
40
|
+
res.statusCode = 500;
|
|
41
|
+
res.end("Internal error");
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
return new Promise((resolve) => {
|
|
45
|
+
server
|
|
46
|
+
.listen(1455, "127.0.0.1", () => {
|
|
47
|
+
resolve({
|
|
48
|
+
port: 1455,
|
|
49
|
+
ready: true,
|
|
50
|
+
close: () => server.close(),
|
|
51
|
+
waitForCode: async () => {
|
|
52
|
+
const POLL_INTERVAL_MS = 100;
|
|
53
|
+
const TIMEOUT_MS = 5 * 60 * 1000;
|
|
54
|
+
const maxIterations = Math.floor(TIMEOUT_MS / POLL_INTERVAL_MS);
|
|
55
|
+
const poll = () => new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));
|
|
56
|
+
for (let i = 0; i < maxIterations; i++) {
|
|
57
|
+
const lastCode = server._lastCode;
|
|
58
|
+
if (lastCode)
|
|
59
|
+
return { code: lastCode };
|
|
60
|
+
await poll();
|
|
61
|
+
}
|
|
62
|
+
console.error("[openai-codex-plugin] OAuth poll timeout after 5 minutes");
|
|
63
|
+
return null;
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
})
|
|
67
|
+
.on("error", (err) => {
|
|
68
|
+
console.error("[openai-codex-plugin] Failed to bind http://127.0.0.1:1455 (", err?.code, ") Falling back to manual paste.");
|
|
69
|
+
resolve({
|
|
70
|
+
port: 1455,
|
|
71
|
+
ready: false,
|
|
72
|
+
close: () => {
|
|
73
|
+
try {
|
|
74
|
+
server.close();
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
console.error("[openai-codex-plugin] Failed to close OAuth server:", err?.message ?? String(err));
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
waitForCode: async () => null,
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../../lib/auth/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface UpdateCheckResult {
|
|
2
|
+
hasUpdate: boolean;
|
|
3
|
+
currentVersion: string;
|
|
4
|
+
latestVersion: string | null;
|
|
5
|
+
updateCommand: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function checkForUpdates(force?: boolean): Promise<UpdateCheckResult>;
|
|
8
|
+
export declare function checkAndNotify(showToast?: (message: string, variant: "info" | "warning") => Promise<void>): Promise<void>;
|
|
9
|
+
export declare function clearUpdateCache(): void;
|
|
10
|
+
//# sourceMappingURL=auto-update-checker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-update-checker.d.ts","sourceRoot":"","sources":["../../lib/auto-update-checker.ts"],"names":[],"mappings":"AA6FA,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,OAAO,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,wBAAsB,eAAe,CAAC,KAAK,UAAQ,GAAG,OAAO,CAAC,iBAAiB,CAAC,CA+B/E;AAED,wBAAsB,cAAc,CAClC,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,GAC1E,OAAO,CAAC,IAAI,CAAC,CAkBf;AAED,wBAAgB,gBAAgB,IAAI,IAAI,CAQvC"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { createLogger } from "./logger.js";
|
|
5
|
+
const log = createLogger("update-checker");
|
|
6
|
+
const PACKAGE_NAME = "oc-chatgpt-multi-auth";
|
|
7
|
+
const NPM_REGISTRY_URL = `https://registry.npmjs.org/${PACKAGE_NAME}/latest`;
|
|
8
|
+
const CACHE_DIR = join(homedir(), ".opencode", "cache");
|
|
9
|
+
const CACHE_FILE = join(CACHE_DIR, "update-check-cache.json");
|
|
10
|
+
const CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000;
|
|
11
|
+
function getCurrentVersion() {
|
|
12
|
+
try {
|
|
13
|
+
const packageJsonPath = join(import.meta.dirname ?? __dirname, "..", "package.json");
|
|
14
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf8"));
|
|
15
|
+
return packageJson.version;
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return "0.0.0";
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function loadCache() {
|
|
22
|
+
try {
|
|
23
|
+
if (!existsSync(CACHE_FILE))
|
|
24
|
+
return null;
|
|
25
|
+
const content = readFileSync(CACHE_FILE, "utf8");
|
|
26
|
+
return JSON.parse(content);
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function saveCache(cache) {
|
|
33
|
+
try {
|
|
34
|
+
if (!existsSync(CACHE_DIR)) {
|
|
35
|
+
mkdirSync(CACHE_DIR, { recursive: true });
|
|
36
|
+
}
|
|
37
|
+
writeFileSync(CACHE_FILE, JSON.stringify(cache, null, 2), "utf8");
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
log.warn("Failed to save update cache", { error: error.message });
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function compareVersions(current, latest) {
|
|
44
|
+
const currentParts = current.split(".").map((p) => parseInt(p, 10) || 0);
|
|
45
|
+
const latestParts = latest.split(".").map((p) => parseInt(p, 10) || 0);
|
|
46
|
+
for (let i = 0; i < Math.max(currentParts.length, latestParts.length); i++) {
|
|
47
|
+
const c = currentParts[i] ?? 0;
|
|
48
|
+
const l = latestParts[i] ?? 0;
|
|
49
|
+
if (l > c)
|
|
50
|
+
return 1;
|
|
51
|
+
if (l < c)
|
|
52
|
+
return -1;
|
|
53
|
+
}
|
|
54
|
+
return 0;
|
|
55
|
+
}
|
|
56
|
+
async function fetchLatestVersion() {
|
|
57
|
+
try {
|
|
58
|
+
const controller = new AbortController();
|
|
59
|
+
const timeout = setTimeout(() => controller.abort(), 5000);
|
|
60
|
+
const response = await fetch(NPM_REGISTRY_URL, {
|
|
61
|
+
signal: controller.signal,
|
|
62
|
+
headers: { Accept: "application/json" },
|
|
63
|
+
});
|
|
64
|
+
clearTimeout(timeout);
|
|
65
|
+
if (!response.ok) {
|
|
66
|
+
log.debug("Failed to fetch npm registry", { status: response.status });
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
const data = (await response.json());
|
|
70
|
+
return data.version ?? null;
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
log.debug("Failed to check for updates", { error: error.message });
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
export async function checkForUpdates(force = false) {
|
|
78
|
+
const currentVersion = getCurrentVersion();
|
|
79
|
+
const cache = loadCache();
|
|
80
|
+
const now = Date.now();
|
|
81
|
+
if (!force && cache && now - cache.lastCheck < CHECK_INTERVAL_MS) {
|
|
82
|
+
const hasUpdate = cache.latestVersion ? compareVersions(currentVersion, cache.latestVersion) > 0 : false;
|
|
83
|
+
return {
|
|
84
|
+
hasUpdate,
|
|
85
|
+
currentVersion,
|
|
86
|
+
latestVersion: cache.latestVersion,
|
|
87
|
+
updateCommand: `npm update -g ${PACKAGE_NAME}`,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
const latestVersion = await fetchLatestVersion();
|
|
91
|
+
saveCache({
|
|
92
|
+
lastCheck: now,
|
|
93
|
+
latestVersion,
|
|
94
|
+
currentVersion,
|
|
95
|
+
});
|
|
96
|
+
const hasUpdate = latestVersion ? compareVersions(currentVersion, latestVersion) > 0 : false;
|
|
97
|
+
return {
|
|
98
|
+
hasUpdate,
|
|
99
|
+
currentVersion,
|
|
100
|
+
latestVersion,
|
|
101
|
+
updateCommand: `npm update -g ${PACKAGE_NAME}`,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
export async function checkAndNotify(showToast) {
|
|
105
|
+
try {
|
|
106
|
+
const result = await checkForUpdates();
|
|
107
|
+
if (result.hasUpdate && result.latestVersion) {
|
|
108
|
+
const message = `Update available: ${PACKAGE_NAME} v${result.latestVersion} (current: v${result.currentVersion})`;
|
|
109
|
+
log.info(message);
|
|
110
|
+
if (showToast) {
|
|
111
|
+
await showToast(`Plugin update available: v${result.latestVersion}. Run: ${result.updateCommand}`, "info");
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
log.debug("Update check failed", { error: error.message });
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
export function clearUpdateCache() {
|
|
120
|
+
try {
|
|
121
|
+
if (existsSync(CACHE_FILE)) {
|
|
122
|
+
writeFileSync(CACHE_FILE, "{}", "utf8");
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
// Ignore errors
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=auto-update-checker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-update-checker.js","sourceRoot":"","sources":["../../lib/auto-update-checker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare function promptAddAnotherAccount(currentCount: number): Promise<boolean>;
|
|
2
|
+
export type LoginMode = "add" | "fresh";
|
|
3
|
+
export interface ExistingAccountInfo {
|
|
4
|
+
accountId?: string;
|
|
5
|
+
email?: string;
|
|
6
|
+
index: number;
|
|
7
|
+
}
|
|
8
|
+
export declare function promptLoginMode(existingAccounts: ExistingAccountInfo[]): Promise<LoginMode>;
|
|
9
|
+
//# sourceMappingURL=cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../lib/cli.ts"],"names":[],"mappings":"AAGA,wBAAsB,uBAAuB,CAC3C,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,OAAO,CAAC,CAclB;AAED,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,OAAO,CAAC;AAExC,MAAM,WAAW,mBAAmB;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAcD,wBAAsB,eAAe,CACnC,gBAAgB,EAAE,mBAAmB,EAAE,GACtC,OAAO,CAAC,SAAS,CAAC,CAyBpB"}
|
package/dist/lib/cli.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { createInterface } from "node:readline/promises";
|
|
2
|
+
import { stdin as input, stdout as output } from "node:process";
|
|
3
|
+
export async function promptAddAnotherAccount(currentCount) {
|
|
4
|
+
const rl = createInterface({ input, output });
|
|
5
|
+
try {
|
|
6
|
+
console.log("\n⚠️ TIP: Use incognito/private browsing or log out of ChatGPT before adding another account.\n");
|
|
7
|
+
const answer = await rl.question(`Add another account? (${currentCount} added) (y/n): `);
|
|
8
|
+
const normalized = answer.trim().toLowerCase();
|
|
9
|
+
return normalized === "y" || normalized === "yes";
|
|
10
|
+
}
|
|
11
|
+
finally {
|
|
12
|
+
rl.close();
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
function formatAccountLabel(account, index) {
|
|
16
|
+
const num = index + 1;
|
|
17
|
+
if (account.email?.trim()) {
|
|
18
|
+
return `${num}. ${account.email}`;
|
|
19
|
+
}
|
|
20
|
+
if (account.accountId?.trim()) {
|
|
21
|
+
const suffix = account.accountId.length > 6 ? account.accountId.slice(-6) : account.accountId;
|
|
22
|
+
return `${num}. ${suffix}`;
|
|
23
|
+
}
|
|
24
|
+
return `${num}. Account`;
|
|
25
|
+
}
|
|
26
|
+
export async function promptLoginMode(existingAccounts) {
|
|
27
|
+
const rl = createInterface({ input, output });
|
|
28
|
+
try {
|
|
29
|
+
console.log(`\n${existingAccounts.length} account(s) saved:`);
|
|
30
|
+
for (const account of existingAccounts) {
|
|
31
|
+
console.log(` ${formatAccountLabel(account, account.index)}`);
|
|
32
|
+
}
|
|
33
|
+
console.log("");
|
|
34
|
+
while (true) {
|
|
35
|
+
const answer = await rl.question("(a)dd new account(s) or (f)resh start? [a/f]: ");
|
|
36
|
+
const normalized = answer.trim().toLowerCase();
|
|
37
|
+
if (normalized === "a" || normalized === "add") {
|
|
38
|
+
return "add";
|
|
39
|
+
}
|
|
40
|
+
if (normalized === "f" || normalized === "fresh") {
|
|
41
|
+
return "fresh";
|
|
42
|
+
}
|
|
43
|
+
console.log("Please enter 'a' to add accounts or 'f' to start fresh.");
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
finally {
|
|
47
|
+
rl.close();
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../lib/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,KAAK,IAAI,KAAK,EAAE,MAAM,IAAI,MAAM,EAAE,MAAM,cAAc,CAAC;AAEhE,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,YAAoB;IAEpB,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;IAC9C,IAAI,CAAC;QACH,OAAO,CAAC,GAAG,CACT,kGAAkG,CACnG,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,QAAQ,CAC9B,yBAAyB,YAAY,iBAAiB,CACvD,CAAC;QACF,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC/C,OAAO,UAAU,KAAK,GAAG,IAAI,UAAU,KAAK,KAAK,CAAC;IACpD,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;AACH,CAAC;AAUD,SAAS,kBAAkB,CAAC,OAA4B,EAAE,KAAa;IACrE,MAAM,GAAG,GAAG,KAAK,GAAG,CAAC,CAAC;IACtB,IAAI,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC;QAC1B,OAAO,GAAG,GAAG,KAAK,OAAO,CAAC,KAAK,EAAE,CAAC;IACpC,CAAC;IACD,IAAI,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC;QAC9F,OAAO,GAAG,GAAG,KAAK,MAAM,EAAE,CAAC;IAC7B,CAAC;IACD,OAAO,GAAG,GAAG,WAAW,CAAC;AAC3B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,gBAAuC;IAEvC,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;IAC9C,IAAI,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,KAAK,gBAAgB,CAAC,MAAM,oBAAoB,CAAC,CAAC;QAC9D,KAAK,MAAM,OAAO,IAAI,gBAAgB,EAAE,CAAC;YACvC,OAAO,CAAC,GAAG,CAAC,KAAK,kBAAkB,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACjE,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAEhB,OAAO,IAAI,EAAE,CAAC;YACZ,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,QAAQ,CAC9B,gDAAgD,CACjD,CAAC;YACF,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YAC/C,IAAI,UAAU,KAAK,GAAG,IAAI,UAAU,KAAK,KAAK,EAAE,CAAC;gBAC/C,OAAO,KAAK,CAAC;YACf,CAAC;YACD,IAAI,UAAU,KAAK,GAAG,IAAI,UAAU,KAAK,OAAO,EAAE,CAAC;gBACjD,OAAO,OAAO,CAAC;YACjB,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,yDAAyD,CAAC,CAAC;QACzE,CAAC;IACH,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;AACH,CAAC"}
|