agentgui 1.0.210 → 1.0.211
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/package.json +1 -1
- package/server.js +24 -9
- package/static/js/agent-auth.js +2 -1
package/package.json
CHANGED
package/server.js
CHANGED
|
@@ -246,6 +246,9 @@ function extractOAuthFromFile(oauth2Path) {
|
|
|
246
246
|
}
|
|
247
247
|
|
|
248
248
|
function getGeminiOAuthCreds() {
|
|
249
|
+
if (process.env.GOOGLE_OAUTH_CLIENT_ID && process.env.GOOGLE_OAUTH_CLIENT_SECRET) {
|
|
250
|
+
return { clientId: process.env.GOOGLE_OAUTH_CLIENT_ID, clientSecret: process.env.GOOGLE_OAUTH_CLIENT_SECRET, custom: true };
|
|
251
|
+
}
|
|
249
252
|
const oauthRelPath = path.join('node_modules', '@google', 'gemini-cli-core', 'dist', 'src', 'code_assist', 'oauth2.js');
|
|
250
253
|
try {
|
|
251
254
|
const geminiPath = findCommand('gemini');
|
|
@@ -333,13 +336,24 @@ function geminiOAuthResultPage(title, message, success) {
|
|
|
333
336
|
</div></body></html>`;
|
|
334
337
|
}
|
|
335
338
|
|
|
336
|
-
|
|
339
|
+
function isRemoteRequest(req) {
|
|
340
|
+
return !!(req && (req.headers['x-forwarded-for'] || req.headers['x-forwarded-host'] || req.headers['x-forwarded-proto']));
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
async function startGeminiOAuth(req) {
|
|
337
344
|
const creds = getGeminiOAuthCreds();
|
|
338
345
|
if (!creds) throw new Error('Could not find Gemini CLI OAuth credentials. Install gemini CLI first.');
|
|
339
346
|
|
|
340
|
-
const
|
|
341
|
-
const
|
|
347
|
+
const useCustomClient = !!creds.custom;
|
|
348
|
+
const remote = isRemoteRequest(req);
|
|
349
|
+
let redirectUri;
|
|
350
|
+
if (useCustomClient && req) {
|
|
351
|
+
redirectUri = `${buildBaseUrl(req)}${BASE_URL}/oauth2callback`;
|
|
352
|
+
} else {
|
|
353
|
+
redirectUri = `http://localhost:${PORT}${BASE_URL}/oauth2callback`;
|
|
354
|
+
}
|
|
342
355
|
|
|
356
|
+
const state = crypto.randomBytes(32).toString('hex');
|
|
343
357
|
const client = new OAuth2Client({
|
|
344
358
|
clientId: creds.clientId,
|
|
345
359
|
clientSecret: creds.clientSecret,
|
|
@@ -352,6 +366,7 @@ async function startGeminiOAuth() {
|
|
|
352
366
|
state,
|
|
353
367
|
});
|
|
354
368
|
|
|
369
|
+
const mode = useCustomClient ? 'custom' : (remote ? 'cli-remote' : 'cli-local');
|
|
355
370
|
geminiOAuthPending = { client, redirectUri, state };
|
|
356
371
|
geminiOAuthState = { status: 'pending', error: null, email: null };
|
|
357
372
|
|
|
@@ -362,7 +377,7 @@ async function startGeminiOAuth() {
|
|
|
362
377
|
}
|
|
363
378
|
}, 5 * 60 * 1000);
|
|
364
379
|
|
|
365
|
-
return authUrl;
|
|
380
|
+
return { authUrl, mode };
|
|
366
381
|
}
|
|
367
382
|
|
|
368
383
|
async function exchangeGeminiOAuthCode(code, state) {
|
|
@@ -1130,8 +1145,8 @@ const server = http.createServer(async (req, res) => {
|
|
|
1130
1145
|
|
|
1131
1146
|
if (pathOnly === '/api/gemini-oauth/start' && req.method === 'POST') {
|
|
1132
1147
|
try {
|
|
1133
|
-
const
|
|
1134
|
-
sendJSON(req, res, 200, { authUrl });
|
|
1148
|
+
const result = await startGeminiOAuth(req);
|
|
1149
|
+
sendJSON(req, res, 200, { authUrl: result.authUrl, mode: result.mode });
|
|
1135
1150
|
} catch (e) {
|
|
1136
1151
|
console.error('[gemini-oauth] /api/gemini-oauth/start failed:', e);
|
|
1137
1152
|
sendJSON(req, res, 500, { error: e.message });
|
|
@@ -1188,10 +1203,10 @@ const server = http.createServer(async (req, res) => {
|
|
|
1188
1203
|
|
|
1189
1204
|
if (agentId === 'gemini') {
|
|
1190
1205
|
try {
|
|
1191
|
-
const
|
|
1206
|
+
const result = await startGeminiOAuth(req);
|
|
1192
1207
|
const conversationId = '__agent_auth__';
|
|
1193
1208
|
broadcastSync({ type: 'script_started', conversationId, script: 'auth-gemini', agentId: 'gemini', timestamp: Date.now() });
|
|
1194
|
-
broadcastSync({ type: 'script_output', conversationId, data: `\x1b[36mOpening Google OAuth in your browser...\x1b[0m\r\n\r\nIf it doesn't open automatically, visit:\r\n${authUrl}\r\n`, stream: 'stdout', timestamp: Date.now() });
|
|
1209
|
+
broadcastSync({ type: 'script_output', conversationId, data: `\x1b[36mOpening Google OAuth in your browser...\x1b[0m\r\n\r\nIf it doesn't open automatically, visit:\r\n${result.authUrl}\r\n`, stream: 'stdout', timestamp: Date.now() });
|
|
1195
1210
|
|
|
1196
1211
|
const pollId = setInterval(() => {
|
|
1197
1212
|
if (geminiOAuthState.status === 'success') {
|
|
@@ -1208,7 +1223,7 @@ const server = http.createServer(async (req, res) => {
|
|
|
1208
1223
|
|
|
1209
1224
|
setTimeout(() => clearInterval(pollId), 5 * 60 * 1000);
|
|
1210
1225
|
|
|
1211
|
-
sendJSON(req, res, 200, { ok: true, agentId, authUrl });
|
|
1226
|
+
sendJSON(req, res, 200, { ok: true, agentId, authUrl: result.authUrl, mode: result.mode });
|
|
1212
1227
|
return;
|
|
1213
1228
|
} catch (e) {
|
|
1214
1229
|
console.error('[gemini-oauth] /api/agents/gemini/auth failed:', e);
|
package/static/js/agent-auth.js
CHANGED
|
@@ -217,7 +217,8 @@
|
|
|
217
217
|
if (data.authUrl) {
|
|
218
218
|
window.open(data.authUrl, '_blank');
|
|
219
219
|
if (agentId === 'gemini') {
|
|
220
|
-
|
|
220
|
+
var needsPaste = data.mode === 'cli-remote';
|
|
221
|
+
if (needsPaste) showOAuthPasteModal();
|
|
221
222
|
cleanupOAuthPolling();
|
|
222
223
|
oauthPollInterval = setInterval(function() {
|
|
223
224
|
fetch(BASE + '/api/gemini-oauth/status').then(function(r) { return r.json(); }).then(function(status) {
|