opencode-gemini-cli-oauth 1.1.22 → 1.2.3
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/dist/constants.d.ts +9 -20
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +19 -36
- package/dist/constants.js.map +1 -1
- package/dist/index.d.ts +4 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -14
- package/dist/index.js.map +1 -1
- package/dist/oauth.d.ts +27 -0
- package/dist/oauth.d.ts.map +1 -0
- package/dist/oauth.js +170 -0
- package/dist/oauth.js.map +1 -0
- package/dist/plugin.d.ts +11 -28
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +111 -115
- package/dist/plugin.js.map +1 -1
- package/dist/types.d.ts +5 -44
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -2
- package/dist/types.js.map +1 -1
- package/package.json +24 -21
- package/dist/auth/account-manager.d.ts +0 -16
- package/dist/auth/account-manager.d.ts.map +0 -1
- package/dist/auth/account-manager.js +0 -66
- package/dist/auth/account-manager.js.map +0 -1
- package/dist/auth/oauth.d.ts +0 -27
- package/dist/auth/oauth.d.ts.map +0 -1
- package/dist/auth/oauth.js +0 -92
- package/dist/auth/oauth.js.map +0 -1
- package/dist/cli/setup.d.ts +0 -3
- package/dist/cli/setup.d.ts.map +0 -1
- package/dist/cli/setup.js +0 -272
- package/dist/cli/setup.js.map +0 -1
- package/dist/index-minimal.d.ts +0 -2
- package/dist/index-minimal.d.ts.map +0 -1
- package/dist/index-minimal.js +0 -7
- package/dist/index-minimal.js.map +0 -1
- package/dist/index-simple.d.ts +0 -5
- package/dist/index-simple.d.ts.map +0 -1
- package/dist/index-simple.js +0 -10
- package/dist/index-simple.js.map +0 -1
- package/dist/plugin-minimal.d.ts +0 -21
- package/dist/plugin-minimal.d.ts.map +0 -1
- package/dist/plugin-minimal.js +0 -31
- package/dist/plugin-minimal.js.map +0 -1
- package/dist/plugin-simple.d.ts +0 -28
- package/dist/plugin-simple.d.ts.map +0 -1
- package/dist/plugin-simple.js +0 -124
- package/dist/plugin-simple.js.map +0 -1
- package/dist/storage/storage.d.ts +0 -56
- package/dist/storage/storage.d.ts.map +0 -1
- package/dist/storage/storage.js +0 -144
- package/dist/storage/storage.js.map +0 -1
package/dist/plugin.js
CHANGED
|
@@ -1,130 +1,126 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* @license
|
|
4
3
|
* Copyright 2025 Yusuf
|
|
5
4
|
* SPDX-License-Identifier: MIT
|
|
5
|
+
*
|
|
6
|
+
* OpenCode Gemini CLI OAuth Plugin
|
|
7
|
+
*
|
|
8
|
+
* This plugin intercepts requests to Google's Generative AI API
|
|
9
|
+
* and injects the OAuth token from the Gemini CLI.
|
|
6
10
|
*/
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
o["default"] = v;
|
|
22
|
-
});
|
|
23
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
24
|
-
var ownKeys = function(o) {
|
|
25
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
26
|
-
var ar = [];
|
|
27
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
28
|
-
return ar;
|
|
29
|
-
};
|
|
30
|
-
return ownKeys(o);
|
|
31
|
-
};
|
|
32
|
-
return function (mod) {
|
|
33
|
-
if (mod && mod.__esModule) return mod;
|
|
34
|
-
var result = {};
|
|
35
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
36
|
-
__setModuleDefault(result, mod);
|
|
37
|
-
return result;
|
|
38
|
-
};
|
|
39
|
-
})();
|
|
40
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
|
-
exports.default = loadPlugin;
|
|
42
|
-
const fs = __importStar(require("fs"));
|
|
43
|
-
const oauth_1 = require("./auth/oauth"); // Remove .js
|
|
44
|
-
const LOG_FILE = '/tmp/gemini_plugin_debug.log';
|
|
45
|
-
function log(message) {
|
|
46
|
-
const timestamp = new Date().toISOString();
|
|
47
|
-
const logMessage = `[${timestamp}] ${message}\n`;
|
|
48
|
-
try {
|
|
49
|
-
fs.appendFileSync(LOG_FILE, logMessage);
|
|
50
|
-
}
|
|
51
|
-
catch (e) {
|
|
52
|
-
// Fallback to console if fs fails
|
|
53
|
-
console.log(message);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
async function loadPlugin(context) {
|
|
57
|
-
log('🚀 [GeminiPlugin v1.1.22] CJS Loader Started...');
|
|
58
|
-
console.log('🚀 [GeminiPlugin v1.1.22] Console Log Test');
|
|
59
|
-
// 1. Capture original fetcher
|
|
60
|
-
const nextFetch = (context.client && context.client.fetch)
|
|
61
|
-
? context.client.fetch.bind(context.client)
|
|
62
|
-
: globalThis.fetch.bind(globalThis);
|
|
63
|
-
// 2. Define the interceptor
|
|
64
|
-
const interceptedFetch = async (input, init) => {
|
|
65
|
-
const urlStr = typeof input === 'string' ? input : input instanceof URL ? input.href : input.url;
|
|
66
|
-
log(`📡 Intercepting: ${urlStr}`);
|
|
11
|
+
import { getAccessToken, verifyCredentials, getUserInfo, hasCredentials, } from "./oauth.js";
|
|
12
|
+
import { PROVIDER_ID } from "./constants.js";
|
|
13
|
+
/**
|
|
14
|
+
* Create the Gemini CLI OAuth plugin
|
|
15
|
+
*/
|
|
16
|
+
export const GeminiCliOAuthPlugin = async (input) => {
|
|
17
|
+
console.log("[gemini-cli-oauth] Plugin v1.2.2 initialized");
|
|
18
|
+
const { client } = input;
|
|
19
|
+
// Get the original fetch function
|
|
20
|
+
const originalFetch = globalThis.fetch;
|
|
21
|
+
/**
|
|
22
|
+
* Custom fetch that injects OAuth token
|
|
23
|
+
*/
|
|
24
|
+
const authenticatedFetch = async (url, init) => {
|
|
67
25
|
try {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
newInit.headers = headers;
|
|
74
|
-
let targetInput = input;
|
|
75
|
-
if (typeof input === 'string' && input.includes('key=')) {
|
|
76
|
-
const urlObj = new URL(input);
|
|
77
|
-
urlObj.searchParams.delete('key');
|
|
78
|
-
targetInput = urlObj.toString();
|
|
26
|
+
// Normalize URL to string for checking
|
|
27
|
+
const urlStr = typeof url === "string" ? url : url instanceof URL ? url.href : url.url;
|
|
28
|
+
// Only intercept requests to Google's generative language API
|
|
29
|
+
if (!urlStr.includes("googleapis.com")) {
|
|
30
|
+
return originalFetch(url, init);
|
|
79
31
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
32
|
+
console.log(`[gemini-cli-oauth] Intercepting: ${urlStr}`);
|
|
33
|
+
// Get valid access token (refreshes if needed)
|
|
34
|
+
const token = await getAccessToken();
|
|
35
|
+
// Prepare new headers
|
|
36
|
+
// If 'url' is a Request object, we need to be careful not to consume it or lose its body.
|
|
37
|
+
// Easiest way is to fall back to the (url, init) signature if possible, or clone the request.
|
|
38
|
+
let finalUrl = url;
|
|
39
|
+
let finalInit = { ...init };
|
|
40
|
+
// If it's a Request object, we should probably construct a new init from it
|
|
41
|
+
if (url instanceof Request) {
|
|
42
|
+
finalInit = {
|
|
43
|
+
...finalInit,
|
|
44
|
+
method: url.method,
|
|
45
|
+
headers: new Headers(url.headers),
|
|
46
|
+
body: url.body, // This might be used already? Fetch handling of Request body is tricky.
|
|
47
|
+
// Note: @ai-sdk/google usually uses (url string, init object)
|
|
48
|
+
};
|
|
49
|
+
// Reset finalUrl to string to avoid dual-init issues
|
|
50
|
+
finalUrl = url.url;
|
|
51
|
+
}
|
|
52
|
+
const headers = new Headers(finalInit.headers);
|
|
53
|
+
headers.set("Authorization", `Bearer ${token}`);
|
|
54
|
+
// Remove API key from headers if present
|
|
55
|
+
headers.delete("x-goog-api-key");
|
|
56
|
+
// Update init
|
|
57
|
+
finalInit.headers = headers;
|
|
58
|
+
// Clean URL params (remove ?key=...)
|
|
59
|
+
let cleanUrl = typeof finalUrl === 'string' ? finalUrl : finalUrl.toString();
|
|
60
|
+
if (cleanUrl.includes("key=")) {
|
|
61
|
+
const u = new URL(cleanUrl);
|
|
62
|
+
u.searchParams.delete("key");
|
|
63
|
+
cleanUrl = u.toString();
|
|
84
64
|
}
|
|
85
|
-
|
|
86
|
-
log(`✅ Response: ${response.status}`);
|
|
87
|
-
return response;
|
|
65
|
+
return originalFetch(cleanUrl, finalInit);
|
|
88
66
|
}
|
|
89
67
|
catch (error) {
|
|
90
|
-
|
|
91
|
-
|
|
68
|
+
console.error("[gemini-cli-oauth] OAuth error:", error);
|
|
69
|
+
// Fallback: try request without auth injection (might work if key is valid)
|
|
70
|
+
return originalFetch(url, init);
|
|
92
71
|
}
|
|
93
72
|
};
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
instructions: "Please run 'opencode-gemini-setup' in your terminal.",
|
|
112
|
-
method: "auto",
|
|
113
|
-
callback: async () => {
|
|
114
|
-
try {
|
|
115
|
-
const valid = await oauth_1.oauth.verifyCredentials();
|
|
116
|
-
if (valid) {
|
|
117
|
-
return { type: "success", email: (await oauth_1.oauth.getUserInfo()).email };
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
catch (_a) { }
|
|
121
|
-
return { type: "failed", error: "Run 'opencode-gemini-setup' first." };
|
|
122
|
-
}
|
|
123
|
-
};
|
|
124
|
-
}
|
|
73
|
+
/**
|
|
74
|
+
* Auth hook
|
|
75
|
+
*/
|
|
76
|
+
const authHook = {
|
|
77
|
+
provider: PROVIDER_ID,
|
|
78
|
+
loader: async (_getAuth, _provider) => {
|
|
79
|
+
console.log("[gemini-cli-oauth] Loader called");
|
|
80
|
+
// Check credentials silently
|
|
81
|
+
hasCredentials().then(has => {
|
|
82
|
+
if (!has && client?.tui?.showToast) {
|
|
83
|
+
client.tui.showToast({
|
|
84
|
+
body: {
|
|
85
|
+
title: "Gemini CLI OAuth",
|
|
86
|
+
message: "No credentials. Run 'gemini auth login'.",
|
|
87
|
+
variant: "warning",
|
|
88
|
+
},
|
|
89
|
+
}).catch(() => { });
|
|
125
90
|
}
|
|
126
|
-
|
|
127
|
-
|
|
91
|
+
});
|
|
92
|
+
return {
|
|
93
|
+
// Dummy API key to satisfy OpenCode/SDK validation
|
|
94
|
+
apiKey: "AIzaSyDummyTokenForGeminiCliOAuthBypassValidation",
|
|
95
|
+
// Custom fetch that injects OAuth token
|
|
96
|
+
fetch: authenticatedFetch,
|
|
97
|
+
};
|
|
98
|
+
},
|
|
99
|
+
methods: [
|
|
100
|
+
{
|
|
101
|
+
type: "oauth",
|
|
102
|
+
label: "Google Account (via Gemini CLI)",
|
|
103
|
+
authorize: async () => {
|
|
104
|
+
return {
|
|
105
|
+
url: "",
|
|
106
|
+
instructions: "Run 'gemini auth login' in your terminal.",
|
|
107
|
+
method: "auto",
|
|
108
|
+
callback: async () => {
|
|
109
|
+
const isValid = await verifyCredentials();
|
|
110
|
+
if (isValid) {
|
|
111
|
+
const userInfo = await getUserInfo();
|
|
112
|
+
return { type: "success", key: `GEMINI_CLI_OAUTH_${userInfo.email}` };
|
|
113
|
+
}
|
|
114
|
+
return { type: "failed" };
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
],
|
|
120
|
+
};
|
|
121
|
+
return {
|
|
122
|
+
auth: authHook,
|
|
128
123
|
};
|
|
129
|
-
}
|
|
124
|
+
};
|
|
125
|
+
export default GeminiCliOAuthPlugin;
|
|
130
126
|
//# sourceMappingURL=plugin.js.map
|
package/dist/plugin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -14,39 +14,6 @@ export interface OAuthCredentials {
|
|
|
14
14
|
expiry_date: number;
|
|
15
15
|
id_token?: string;
|
|
16
16
|
}
|
|
17
|
-
/**
|
|
18
|
-
* Google account information
|
|
19
|
-
*/
|
|
20
|
-
export interface GoogleAccount {
|
|
21
|
-
email: string;
|
|
22
|
-
name?: string;
|
|
23
|
-
picture?: string;
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Account pool entry
|
|
27
|
-
*/
|
|
28
|
-
export interface AccountPoolEntry {
|
|
29
|
-
email: string;
|
|
30
|
-
credentials: OAuthCredentials;
|
|
31
|
-
lastUsed: number;
|
|
32
|
-
requestCount: number;
|
|
33
|
-
rateLimitUntil?: number;
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* Account pool storage
|
|
37
|
-
*/
|
|
38
|
-
export interface AccountPool {
|
|
39
|
-
accounts: AccountPoolEntry[];
|
|
40
|
-
currentIndex: number;
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* Plugin configuration
|
|
44
|
-
*/
|
|
45
|
-
export interface PluginConfig {
|
|
46
|
-
enableMultiAccount: boolean;
|
|
47
|
-
autoRotateOnRateLimit: boolean;
|
|
48
|
-
debugMode: boolean;
|
|
49
|
-
}
|
|
50
17
|
/**
|
|
51
18
|
* Token refresh result
|
|
52
19
|
*/
|
|
@@ -57,17 +24,11 @@ export interface TokenRefreshResult {
|
|
|
57
24
|
error?: string;
|
|
58
25
|
}
|
|
59
26
|
/**
|
|
60
|
-
*
|
|
27
|
+
* User info from Google
|
|
61
28
|
*/
|
|
62
|
-
export interface
|
|
63
|
-
|
|
64
|
-
|
|
29
|
+
export interface UserInfo {
|
|
30
|
+
email: string;
|
|
31
|
+
name?: string;
|
|
32
|
+
picture?: string;
|
|
65
33
|
}
|
|
66
|
-
/**
|
|
67
|
-
* OpenCode auth loader function signature
|
|
68
|
-
*/
|
|
69
|
-
export type AuthLoader = (getAuth: () => Promise<any>, provider: string) => Promise<{
|
|
70
|
-
apiKey: string;
|
|
71
|
-
fetch: typeof fetch;
|
|
72
|
-
}>;
|
|
73
34
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB"}
|
package/dist/types.js
CHANGED
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
|
package/package.json
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-gemini-cli-oauth",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.3",
|
|
4
4
|
"description": "OpenCode plugin for Gemini CLI OAuth authentication - use Google account quota without API keys",
|
|
5
|
-
"main": "dist/index.js",
|
|
6
|
-
"types": "dist/index.d.ts",
|
|
7
|
-
"
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
"
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"license": "MIT",
|
|
9
|
+
"author": "Yusuf",
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "git+https://github.com/yusuf/opencode-gemini-cli-oauth.git"
|
|
12
13
|
},
|
|
13
14
|
"keywords": [
|
|
14
15
|
"opencode",
|
|
@@ -18,27 +19,29 @@
|
|
|
18
19
|
"ai",
|
|
19
20
|
"plugin"
|
|
20
21
|
],
|
|
21
|
-
"
|
|
22
|
-
"
|
|
22
|
+
"engines": {
|
|
23
|
+
"node": ">=20.0.0"
|
|
23
24
|
},
|
|
24
25
|
"files": [
|
|
25
|
-
"dist",
|
|
26
|
-
"
|
|
27
|
-
"
|
|
26
|
+
"dist/",
|
|
27
|
+
"README.md",
|
|
28
|
+
"LICENSE"
|
|
28
29
|
],
|
|
29
|
-
"
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
"
|
|
30
|
+
"scripts": {
|
|
31
|
+
"build": "tsc -p tsconfig.build.json",
|
|
32
|
+
"dev": "tsc --watch",
|
|
33
|
+
"clean": "rm -rf dist",
|
|
34
|
+
"prepublishOnly": "npm run clean && npm run build"
|
|
33
35
|
},
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
+
"peerDependencies": {
|
|
37
|
+
"typescript": "^5"
|
|
36
38
|
},
|
|
37
39
|
"devDependencies": {
|
|
40
|
+
"@opencode-ai/plugin": "^0.15.30",
|
|
38
41
|
"@types/node": "^22.10.5",
|
|
39
42
|
"typescript": "^5.7.2"
|
|
40
43
|
},
|
|
41
|
-
"
|
|
42
|
-
"
|
|
44
|
+
"dependencies": {
|
|
45
|
+
"@ai-sdk/google": "^3.0.10"
|
|
43
46
|
}
|
|
44
47
|
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright 2025 Yusuf
|
|
4
|
-
* SPDX-License-Identifier: MIT
|
|
5
|
-
*/
|
|
6
|
-
export declare const accountManager: {
|
|
7
|
-
/**
|
|
8
|
-
* Initialize account pool
|
|
9
|
-
*/
|
|
10
|
-
initialize(): Promise<void>;
|
|
11
|
-
/**
|
|
12
|
-
* Get access token
|
|
13
|
-
*/
|
|
14
|
-
getCurrentAccessToken(): Promise<string>;
|
|
15
|
-
};
|
|
16
|
-
//# sourceMappingURL=account-manager.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"account-manager.d.ts","sourceRoot":"","sources":["../../src/auth/account-manager.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,eAAO,MAAM,cAAc;IACzB;;OAEG;kBACiB,OAAO,CAAC,IAAI,CAAC;IAwBjC;;OAEG;6BAC4B,OAAO,CAAC,MAAM,CAAC;CA+B/C,CAAC"}
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* @license
|
|
4
|
-
* Copyright 2025 Yusuf
|
|
5
|
-
* SPDX-License-Identifier: MIT
|
|
6
|
-
*/
|
|
7
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
-
exports.accountManager = void 0;
|
|
9
|
-
const storage_1 = require("../storage/storage");
|
|
10
|
-
const oauth_1 = require("./oauth");
|
|
11
|
-
exports.accountManager = {
|
|
12
|
-
/**
|
|
13
|
-
* Initialize account pool
|
|
14
|
-
*/
|
|
15
|
-
async initialize() {
|
|
16
|
-
const credentials = await storage_1.StorageManager.readOAuthCredentials();
|
|
17
|
-
if (!credentials)
|
|
18
|
-
return;
|
|
19
|
-
const userInfo = await oauth_1.oauth.getUserInfo();
|
|
20
|
-
const pool = await storage_1.StorageManager.readAccountPool();
|
|
21
|
-
const existingAccount = pool.accounts.find((acc) => acc.email === userInfo.email);
|
|
22
|
-
if (existingAccount) {
|
|
23
|
-
await storage_1.StorageManager.updateAccountInPool(userInfo.email, {
|
|
24
|
-
credentials,
|
|
25
|
-
lastUsed: Date.now(),
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
else {
|
|
29
|
-
const newEntry = {
|
|
30
|
-
email: userInfo.email,
|
|
31
|
-
credentials,
|
|
32
|
-
lastUsed: Date.now(),
|
|
33
|
-
requestCount: 0,
|
|
34
|
-
};
|
|
35
|
-
await storage_1.StorageManager.upsertAccountInPool(newEntry);
|
|
36
|
-
}
|
|
37
|
-
},
|
|
38
|
-
/**
|
|
39
|
-
* Get access token
|
|
40
|
-
*/
|
|
41
|
-
async getCurrentAccessToken() {
|
|
42
|
-
const account = await storage_1.StorageManager.getCurrentAccount();
|
|
43
|
-
if (!account) {
|
|
44
|
-
return await oauth_1.oauth.getAccessToken();
|
|
45
|
-
}
|
|
46
|
-
const now = Date.now();
|
|
47
|
-
const expiryTime = account.credentials.expiry_date || 0;
|
|
48
|
-
const needsRefresh = expiryTime - now < 5 * 60 * 1000;
|
|
49
|
-
if (needsRefresh) {
|
|
50
|
-
const refreshResult = await oauth_1.oauth.refreshAccessToken(account.credentials.refresh_token);
|
|
51
|
-
if (refreshResult.success && refreshResult.accessToken) {
|
|
52
|
-
const updatedCredentials = {
|
|
53
|
-
...account.credentials,
|
|
54
|
-
access_token: refreshResult.accessToken,
|
|
55
|
-
expiry_date: refreshResult.expiryDate || Date.now() + 3600 * 1000,
|
|
56
|
-
};
|
|
57
|
-
await storage_1.StorageManager.updateAccountInPool(account.email, {
|
|
58
|
-
credentials: updatedCredentials,
|
|
59
|
-
});
|
|
60
|
-
return refreshResult.accessToken;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
return account.credentials.access_token;
|
|
64
|
-
}
|
|
65
|
-
};
|
|
66
|
-
//# sourceMappingURL=account-manager.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"account-manager.js","sourceRoot":"","sources":["../../src/auth/account-manager.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAEH,gDAAoD;AACpD,mCAAgC;AAGnB,QAAA,cAAc,GAAG;IAC5B;;OAEG;IACH,KAAK,CAAC,UAAU;QACd,MAAM,WAAW,GAAG,MAAM,wBAAc,CAAC,oBAAoB,EAAE,CAAC;QAChE,IAAI,CAAC,WAAW;YAAE,OAAO;QAEzB,MAAM,QAAQ,GAAG,MAAM,aAAK,CAAC,WAAW,EAAE,CAAC;QAC3C,MAAM,IAAI,GAAG,MAAM,wBAAc,CAAC,eAAe,EAAE,CAAC;QACpD,MAAM,eAAe,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,KAAK,QAAQ,CAAC,KAAK,CAAC,CAAC;QAElF,IAAI,eAAe,EAAE,CAAC;YACpB,MAAM,wBAAc,CAAC,mBAAmB,CAAC,QAAQ,CAAC,KAAK,EAAE;gBACvD,WAAW;gBACX,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE;aACrB,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,MAAM,QAAQ,GAAqB;gBACjC,KAAK,EAAE,QAAQ,CAAC,KAAK;gBACrB,WAAW;gBACX,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE;gBACpB,YAAY,EAAE,CAAC;aAChB,CAAC;YACF,MAAM,wBAAc,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,qBAAqB;QACzB,MAAM,OAAO,GAAG,MAAM,wBAAc,CAAC,iBAAiB,EAAE,CAAC;QAEzD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,MAAM,aAAK,CAAC,cAAc,EAAE,CAAC;QACtC,CAAC;QAED,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,WAAW,IAAI,CAAC,CAAC;QACxD,MAAM,YAAY,GAAG,UAAU,GAAG,GAAG,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;QAEtD,IAAI,YAAY,EAAE,CAAC;YACjB,MAAM,aAAa,GAAG,MAAM,aAAK,CAAC,kBAAkB,CAAC,OAAO,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC;YAExF,IAAI,aAAa,CAAC,OAAO,IAAI,aAAa,CAAC,WAAW,EAAE,CAAC;gBACvD,MAAM,kBAAkB,GAAqB;oBAC3C,GAAG,OAAO,CAAC,WAAW;oBACtB,YAAY,EAAE,aAAa,CAAC,WAAW;oBACvC,WAAW,EAAE,aAAa,CAAC,UAAU,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI;iBAClE,CAAC;gBAEF,MAAM,wBAAc,CAAC,mBAAmB,CAAC,OAAO,CAAC,KAAK,EAAE;oBACtD,WAAW,EAAE,kBAAkB;iBAChC,CAAC,CAAC;gBAEH,OAAO,aAAa,CAAC,WAAW,CAAC;YACnC,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC,WAAW,CAAC,YAAY,CAAC;IAC1C,CAAC;CACF,CAAC"}
|
package/dist/auth/oauth.d.ts
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright 2025 Yusuf
|
|
4
|
-
* SPDX-License-Identifier: MIT
|
|
5
|
-
*/
|
|
6
|
-
import type { TokenRefreshResult } from '../types';
|
|
7
|
-
export declare const oauth: {
|
|
8
|
-
/**
|
|
9
|
-
* Get access token from stored credentials
|
|
10
|
-
*/
|
|
11
|
-
getAccessToken(): Promise<string>;
|
|
12
|
-
/**
|
|
13
|
-
* Refresh access token
|
|
14
|
-
*/
|
|
15
|
-
refreshAccessToken(refreshToken: string, retryCount?: number): Promise<TokenRefreshResult>;
|
|
16
|
-
/**
|
|
17
|
-
* Verify credentials
|
|
18
|
-
*/
|
|
19
|
-
verifyCredentials(): Promise<boolean>;
|
|
20
|
-
/**
|
|
21
|
-
* Get user info
|
|
22
|
-
*/
|
|
23
|
-
getUserInfo(): Promise<{
|
|
24
|
-
email: string;
|
|
25
|
-
}>;
|
|
26
|
-
};
|
|
27
|
-
//# sourceMappingURL=oauth.d.ts.map
|
package/dist/auth/oauth.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../../src/auth/oauth.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAUH,OAAO,KAAK,EAAoB,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAOrE,eAAO,MAAM,KAAK;IAChB;;OAEG;sBACqB,OAAO,CAAC,MAAM,CAAC;IA4BvC;;OAEG;qCAEa,MAAM,wBAEnB,OAAO,CAAC,kBAAkB,CAAC;IAkC9B;;OAEG;yBACwB,OAAO,CAAC,OAAO,CAAC;IAU3C;;OAEG;mBACkB,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;CAKhD,CAAC"}
|
package/dist/auth/oauth.js
DELETED
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* @license
|
|
4
|
-
* Copyright 2025 Yusuf
|
|
5
|
-
* SPDX-License-Identifier: MIT
|
|
6
|
-
*/
|
|
7
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
-
exports.oauth = void 0;
|
|
9
|
-
const google_auth_library_1 = require("google-auth-library");
|
|
10
|
-
const constants_1 = require("../constants");
|
|
11
|
-
const storage_1 = require("../storage/storage");
|
|
12
|
-
const client = new google_auth_library_1.OAuth2Client({
|
|
13
|
-
clientId: constants_1.OAUTH_CLIENT_ID,
|
|
14
|
-
clientSecret: constants_1.OAUTH_CLIENT_SECRET,
|
|
15
|
-
});
|
|
16
|
-
exports.oauth = {
|
|
17
|
-
/**
|
|
18
|
-
* Get access token from stored credentials
|
|
19
|
-
*/
|
|
20
|
-
async getAccessToken() {
|
|
21
|
-
const credentials = await storage_1.StorageManager.readOAuthCredentials();
|
|
22
|
-
if (!credentials) {
|
|
23
|
-
throw new Error('No OAuth credentials found. Please authenticate using Gemini CLI: gemini auth login');
|
|
24
|
-
}
|
|
25
|
-
const now = Date.now();
|
|
26
|
-
const expiryTime = credentials.expiry_date || 0;
|
|
27
|
-
const needsRefresh = expiryTime - now < constants_1.TOKEN_EXPIRY_BUFFER_MS;
|
|
28
|
-
if (needsRefresh) {
|
|
29
|
-
const refreshResult = await this.refreshAccessToken(credentials.refresh_token);
|
|
30
|
-
if (!refreshResult.success) {
|
|
31
|
-
throw new Error(`Failed to refresh access token: ${refreshResult.error}. Please re-authenticate`);
|
|
32
|
-
}
|
|
33
|
-
return refreshResult.accessToken;
|
|
34
|
-
}
|
|
35
|
-
return credentials.access_token;
|
|
36
|
-
},
|
|
37
|
-
/**
|
|
38
|
-
* Refresh access token
|
|
39
|
-
*/
|
|
40
|
-
async refreshAccessToken(refreshToken, retryCount = 0) {
|
|
41
|
-
try {
|
|
42
|
-
client.setCredentials({ refresh_token: refreshToken });
|
|
43
|
-
const { credentials } = await client.refreshAccessToken();
|
|
44
|
-
if (!credentials.access_token) {
|
|
45
|
-
throw new Error('No access token returned from refresh');
|
|
46
|
-
}
|
|
47
|
-
const existingCreds = await storage_1.StorageManager.readOAuthCredentials();
|
|
48
|
-
const updatedCreds = {
|
|
49
|
-
...existingCreds,
|
|
50
|
-
access_token: credentials.access_token,
|
|
51
|
-
expiry_date: credentials.expiry_date || Date.now() + 3600 * 1000,
|
|
52
|
-
token_type: credentials.token_type || 'Bearer',
|
|
53
|
-
};
|
|
54
|
-
await storage_1.StorageManager.writeOAuthCredentials(updatedCreds);
|
|
55
|
-
return {
|
|
56
|
-
success: true,
|
|
57
|
-
accessToken: credentials.access_token,
|
|
58
|
-
expiryDate: credentials.expiry_date || undefined,
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
catch (error) {
|
|
62
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
63
|
-
if (retryCount < constants_1.MAX_REFRESH_RETRIES) {
|
|
64
|
-
await new Promise((resolve) => setTimeout(resolve, 1000 * (retryCount + 1)));
|
|
65
|
-
return this.refreshAccessToken(refreshToken, retryCount + 1);
|
|
66
|
-
}
|
|
67
|
-
return { success: false, error: errorMessage };
|
|
68
|
-
}
|
|
69
|
-
},
|
|
70
|
-
/**
|
|
71
|
-
* Verify credentials
|
|
72
|
-
*/
|
|
73
|
-
async verifyCredentials() {
|
|
74
|
-
try {
|
|
75
|
-
const token = await this.getAccessToken();
|
|
76
|
-
const tokenInfo = await client.getTokenInfo(token);
|
|
77
|
-
return !!tokenInfo.email;
|
|
78
|
-
}
|
|
79
|
-
catch (error) {
|
|
80
|
-
return false;
|
|
81
|
-
}
|
|
82
|
-
},
|
|
83
|
-
/**
|
|
84
|
-
* Get user info
|
|
85
|
-
*/
|
|
86
|
-
async getUserInfo() {
|
|
87
|
-
const token = await this.getAccessToken();
|
|
88
|
-
const tokenInfo = await client.getTokenInfo(token);
|
|
89
|
-
return { email: tokenInfo.email || 'unknown' };
|
|
90
|
-
}
|
|
91
|
-
};
|
|
92
|
-
//# sourceMappingURL=oauth.js.map
|
package/dist/auth/oauth.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"oauth.js","sourceRoot":"","sources":["../../src/auth/oauth.ts"],"names":[],"mappings":"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"}
|