@kaitranntt/ccs 5.10.0 → 5.11.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/VERSION +1 -1
- package/dist/cliproxy/account-manager.d.ts +97 -0
- package/dist/cliproxy/account-manager.d.ts.map +1 -0
- package/dist/cliproxy/account-manager.js +314 -0
- package/dist/cliproxy/account-manager.js.map +1 -0
- package/dist/cliproxy/auth-handler.d.ts +19 -1
- package/dist/cliproxy/auth-handler.d.ts.map +1 -1
- package/dist/cliproxy/auth-handler.js +71 -7
- package/dist/cliproxy/auth-handler.js.map +1 -1
- package/dist/types/config.d.ts +2 -0
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/config.js.map +1 -1
- package/dist/ui/assets/form-utils-Bjfa1DVH.js +20 -0
- package/dist/ui/assets/icons-D-Y22K9Z.js +1 -0
- package/dist/ui/assets/index-M5ru6OPu.js +9 -0
- package/dist/ui/assets/index-ZXu5MvSE.css +1 -0
- package/dist/ui/index.html +4 -4
- package/dist/web-server/routes.d.ts.map +1 -1
- package/dist/web-server/routes.js +129 -3
- package/dist/web-server/routes.js.map +1 -1
- package/package.json +1 -1
- package/dist/ui/assets/form-utils-CE1K85pW.js +0 -20
- package/dist/ui/assets/icons-DJoMkiyK.js +0 -1
- package/dist/ui/assets/index-BxRTPSHw.js +0 -9
- package/dist/ui/assets/index-ks0hk5dc.css +0 -1
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
5.
|
|
1
|
+
5.11.0
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Account Manager for CLIProxyAPI Multi-Account Support
|
|
3
|
+
*
|
|
4
|
+
* Manages multiple OAuth accounts per provider (Gemini, Codex, etc.).
|
|
5
|
+
* Each provider can have multiple accounts, with one designated as default.
|
|
6
|
+
*
|
|
7
|
+
* Account storage: ~/.ccs/cliproxy/accounts.json
|
|
8
|
+
* Token storage: ~/.ccs/cliproxy/auth/ (flat structure, CLIProxyAPI discovers by type field)
|
|
9
|
+
*/
|
|
10
|
+
import { CLIProxyProvider } from './types';
|
|
11
|
+
/** Account information */
|
|
12
|
+
export interface AccountInfo {
|
|
13
|
+
/** Account identifier (email or custom name) */
|
|
14
|
+
id: string;
|
|
15
|
+
/** Email address from OAuth (if available) */
|
|
16
|
+
email?: string;
|
|
17
|
+
/** Provider this account belongs to */
|
|
18
|
+
provider: CLIProxyProvider;
|
|
19
|
+
/** Whether this is the default account for the provider */
|
|
20
|
+
isDefault: boolean;
|
|
21
|
+
/** Token file name in auth directory */
|
|
22
|
+
tokenFile: string;
|
|
23
|
+
/** When account was added */
|
|
24
|
+
createdAt: string;
|
|
25
|
+
/** Last usage time */
|
|
26
|
+
lastUsedAt?: string;
|
|
27
|
+
}
|
|
28
|
+
/** Provider accounts configuration */
|
|
29
|
+
interface ProviderAccounts {
|
|
30
|
+
/** Default account ID for this provider */
|
|
31
|
+
default: string;
|
|
32
|
+
/** Map of account ID to account metadata */
|
|
33
|
+
accounts: Record<string, Omit<AccountInfo, 'id' | 'provider' | 'isDefault'>>;
|
|
34
|
+
}
|
|
35
|
+
/** Accounts registry structure */
|
|
36
|
+
interface AccountsRegistry {
|
|
37
|
+
/** Version for future migrations */
|
|
38
|
+
version: number;
|
|
39
|
+
/** Accounts organized by provider */
|
|
40
|
+
providers: Partial<Record<CLIProxyProvider, ProviderAccounts>>;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Get path to accounts registry file
|
|
44
|
+
*/
|
|
45
|
+
export declare function getAccountsRegistryPath(): string;
|
|
46
|
+
/**
|
|
47
|
+
* Load accounts registry
|
|
48
|
+
*/
|
|
49
|
+
export declare function loadAccountsRegistry(): AccountsRegistry;
|
|
50
|
+
/**
|
|
51
|
+
* Save accounts registry
|
|
52
|
+
*/
|
|
53
|
+
export declare function saveAccountsRegistry(registry: AccountsRegistry): void;
|
|
54
|
+
/**
|
|
55
|
+
* Get all accounts for a provider
|
|
56
|
+
*/
|
|
57
|
+
export declare function getProviderAccounts(provider: CLIProxyProvider): AccountInfo[];
|
|
58
|
+
/**
|
|
59
|
+
* Get default account for a provider
|
|
60
|
+
*/
|
|
61
|
+
export declare function getDefaultAccount(provider: CLIProxyProvider): AccountInfo | null;
|
|
62
|
+
/**
|
|
63
|
+
* Get specific account by ID
|
|
64
|
+
*/
|
|
65
|
+
export declare function getAccount(provider: CLIProxyProvider, accountId: string): AccountInfo | null;
|
|
66
|
+
/**
|
|
67
|
+
* Register a new account
|
|
68
|
+
* Called after successful OAuth to record the account
|
|
69
|
+
*/
|
|
70
|
+
export declare function registerAccount(provider: CLIProxyProvider, tokenFile: string, email?: string): AccountInfo;
|
|
71
|
+
/**
|
|
72
|
+
* Set default account for a provider
|
|
73
|
+
*/
|
|
74
|
+
export declare function setDefaultAccount(provider: CLIProxyProvider, accountId: string): boolean;
|
|
75
|
+
/**
|
|
76
|
+
* Remove an account
|
|
77
|
+
*/
|
|
78
|
+
export declare function removeAccount(provider: CLIProxyProvider, accountId: string): boolean;
|
|
79
|
+
/**
|
|
80
|
+
* Update last used timestamp for an account
|
|
81
|
+
*/
|
|
82
|
+
export declare function touchAccount(provider: CLIProxyProvider, accountId: string): void;
|
|
83
|
+
/**
|
|
84
|
+
* Get token file path for an account
|
|
85
|
+
*/
|
|
86
|
+
export declare function getAccountTokenPath(provider: CLIProxyProvider, accountId?: string): string | null;
|
|
87
|
+
/**
|
|
88
|
+
* Auto-discover accounts from existing token files
|
|
89
|
+
* Called during migration or first run to populate accounts registry
|
|
90
|
+
*/
|
|
91
|
+
export declare function discoverExistingAccounts(): void;
|
|
92
|
+
/**
|
|
93
|
+
* Get summary of all accounts across providers
|
|
94
|
+
*/
|
|
95
|
+
export declare function getAllAccountsSummary(): Record<CLIProxyProvider, AccountInfo[]>;
|
|
96
|
+
export {};
|
|
97
|
+
//# sourceMappingURL=account-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account-manager.d.ts","sourceRoot":"","sources":["../../src/cliproxy/account-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAG3C,0BAA0B;AAC1B,MAAM,WAAW,WAAW;IAC1B,gDAAgD;IAChD,EAAE,EAAE,MAAM,CAAC;IACX,8CAA8C;IAC9C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uCAAuC;IACvC,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,2DAA2D;IAC3D,SAAS,EAAE,OAAO,CAAC;IACnB,wCAAwC;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,6BAA6B;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,sBAAsB;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,sCAAsC;AACtC,UAAU,gBAAgB;IACxB,2CAA2C;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB,4CAA4C;IAC5C,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,GAAG,UAAU,GAAG,WAAW,CAAC,CAAC,CAAC;CAC9E;AAED,kCAAkC;AAClC,UAAU,gBAAgB;IACxB,oCAAoC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,qCAAqC;IACrC,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,gBAAgB,EAAE,gBAAgB,CAAC,CAAC,CAAC;CAChE;AAQD;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,CAEhD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,gBAAgB,CAiBvD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,IAAI,CAWrE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,WAAW,EAAE,CAc7E;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,WAAW,GAAG,IAAI,CAGhF;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAG5F;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,gBAAgB,EAC1B,SAAS,EAAE,MAAM,EACjB,KAAK,CAAC,EAAE,MAAM,GACb,WAAW,CA4Cb;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAWxF;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAgCpF;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAQhF;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,gBAAgB,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQjG;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,IAAI,IAAI,CA6E/C;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CAAC,gBAAgB,EAAE,WAAW,EAAE,CAAC,CAY/E"}
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Account Manager for CLIProxyAPI Multi-Account Support
|
|
4
|
+
*
|
|
5
|
+
* Manages multiple OAuth accounts per provider (Gemini, Codex, etc.).
|
|
6
|
+
* Each provider can have multiple accounts, with one designated as default.
|
|
7
|
+
*
|
|
8
|
+
* Account storage: ~/.ccs/cliproxy/accounts.json
|
|
9
|
+
* Token storage: ~/.ccs/cliproxy/auth/ (flat structure, CLIProxyAPI discovers by type field)
|
|
10
|
+
*/
|
|
11
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
12
|
+
if (k2 === undefined) k2 = k;
|
|
13
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
14
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
15
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
16
|
+
}
|
|
17
|
+
Object.defineProperty(o, k2, desc);
|
|
18
|
+
}) : (function(o, m, k, k2) {
|
|
19
|
+
if (k2 === undefined) k2 = k;
|
|
20
|
+
o[k2] = m[k];
|
|
21
|
+
}));
|
|
22
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
23
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
24
|
+
}) : function(o, v) {
|
|
25
|
+
o["default"] = v;
|
|
26
|
+
});
|
|
27
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
35
|
+
exports.getAllAccountsSummary = exports.discoverExistingAccounts = exports.getAccountTokenPath = exports.touchAccount = exports.removeAccount = exports.setDefaultAccount = exports.registerAccount = exports.getAccount = exports.getDefaultAccount = exports.getProviderAccounts = exports.saveAccountsRegistry = exports.loadAccountsRegistry = exports.getAccountsRegistryPath = void 0;
|
|
36
|
+
const fs = __importStar(require("fs"));
|
|
37
|
+
const path = __importStar(require("path"));
|
|
38
|
+
const config_generator_1 = require("./config-generator");
|
|
39
|
+
/** Default registry structure */
|
|
40
|
+
const DEFAULT_REGISTRY = {
|
|
41
|
+
version: 1,
|
|
42
|
+
providers: {},
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Get path to accounts registry file
|
|
46
|
+
*/
|
|
47
|
+
function getAccountsRegistryPath() {
|
|
48
|
+
return path.join((0, config_generator_1.getCliproxyDir)(), 'accounts.json');
|
|
49
|
+
}
|
|
50
|
+
exports.getAccountsRegistryPath = getAccountsRegistryPath;
|
|
51
|
+
/**
|
|
52
|
+
* Load accounts registry
|
|
53
|
+
*/
|
|
54
|
+
function loadAccountsRegistry() {
|
|
55
|
+
const registryPath = getAccountsRegistryPath();
|
|
56
|
+
if (!fs.existsSync(registryPath)) {
|
|
57
|
+
return { ...DEFAULT_REGISTRY };
|
|
58
|
+
}
|
|
59
|
+
try {
|
|
60
|
+
const content = fs.readFileSync(registryPath, 'utf-8');
|
|
61
|
+
const data = JSON.parse(content);
|
|
62
|
+
return {
|
|
63
|
+
version: data.version || 1,
|
|
64
|
+
providers: data.providers || {},
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return { ...DEFAULT_REGISTRY };
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
exports.loadAccountsRegistry = loadAccountsRegistry;
|
|
72
|
+
/**
|
|
73
|
+
* Save accounts registry
|
|
74
|
+
*/
|
|
75
|
+
function saveAccountsRegistry(registry) {
|
|
76
|
+
const registryPath = getAccountsRegistryPath();
|
|
77
|
+
const dir = path.dirname(registryPath);
|
|
78
|
+
if (!fs.existsSync(dir)) {
|
|
79
|
+
fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
80
|
+
}
|
|
81
|
+
fs.writeFileSync(registryPath, JSON.stringify(registry, null, 2) + '\n', {
|
|
82
|
+
mode: 0o600,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
exports.saveAccountsRegistry = saveAccountsRegistry;
|
|
86
|
+
/**
|
|
87
|
+
* Get all accounts for a provider
|
|
88
|
+
*/
|
|
89
|
+
function getProviderAccounts(provider) {
|
|
90
|
+
const registry = loadAccountsRegistry();
|
|
91
|
+
const providerAccounts = registry.providers[provider];
|
|
92
|
+
if (!providerAccounts) {
|
|
93
|
+
return [];
|
|
94
|
+
}
|
|
95
|
+
return Object.entries(providerAccounts.accounts).map(([id, meta]) => ({
|
|
96
|
+
id,
|
|
97
|
+
provider,
|
|
98
|
+
isDefault: id === providerAccounts.default,
|
|
99
|
+
...meta,
|
|
100
|
+
}));
|
|
101
|
+
}
|
|
102
|
+
exports.getProviderAccounts = getProviderAccounts;
|
|
103
|
+
/**
|
|
104
|
+
* Get default account for a provider
|
|
105
|
+
*/
|
|
106
|
+
function getDefaultAccount(provider) {
|
|
107
|
+
const accounts = getProviderAccounts(provider);
|
|
108
|
+
return accounts.find((a) => a.isDefault) || accounts[0] || null;
|
|
109
|
+
}
|
|
110
|
+
exports.getDefaultAccount = getDefaultAccount;
|
|
111
|
+
/**
|
|
112
|
+
* Get specific account by ID
|
|
113
|
+
*/
|
|
114
|
+
function getAccount(provider, accountId) {
|
|
115
|
+
const accounts = getProviderAccounts(provider);
|
|
116
|
+
return accounts.find((a) => a.id === accountId) || null;
|
|
117
|
+
}
|
|
118
|
+
exports.getAccount = getAccount;
|
|
119
|
+
/**
|
|
120
|
+
* Register a new account
|
|
121
|
+
* Called after successful OAuth to record the account
|
|
122
|
+
*/
|
|
123
|
+
function registerAccount(provider, tokenFile, email) {
|
|
124
|
+
const registry = loadAccountsRegistry();
|
|
125
|
+
// Initialize provider section if needed
|
|
126
|
+
if (!registry.providers[provider]) {
|
|
127
|
+
registry.providers[provider] = {
|
|
128
|
+
default: 'default',
|
|
129
|
+
accounts: {},
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
const providerAccounts = registry.providers[provider];
|
|
133
|
+
if (!providerAccounts) {
|
|
134
|
+
throw new Error('Failed to initialize provider accounts');
|
|
135
|
+
}
|
|
136
|
+
// Determine account ID
|
|
137
|
+
const accountId = email || 'default';
|
|
138
|
+
const isFirstAccount = Object.keys(providerAccounts.accounts).length === 0;
|
|
139
|
+
// Create or update account
|
|
140
|
+
providerAccounts.accounts[accountId] = {
|
|
141
|
+
email,
|
|
142
|
+
tokenFile,
|
|
143
|
+
createdAt: new Date().toISOString(),
|
|
144
|
+
lastUsedAt: new Date().toISOString(),
|
|
145
|
+
};
|
|
146
|
+
// Set as default if first account
|
|
147
|
+
if (isFirstAccount) {
|
|
148
|
+
providerAccounts.default = accountId;
|
|
149
|
+
}
|
|
150
|
+
saveAccountsRegistry(registry);
|
|
151
|
+
return {
|
|
152
|
+
id: accountId,
|
|
153
|
+
provider,
|
|
154
|
+
isDefault: accountId === providerAccounts.default,
|
|
155
|
+
email,
|
|
156
|
+
tokenFile,
|
|
157
|
+
createdAt: providerAccounts.accounts[accountId].createdAt,
|
|
158
|
+
lastUsedAt: providerAccounts.accounts[accountId].lastUsedAt,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
exports.registerAccount = registerAccount;
|
|
162
|
+
/**
|
|
163
|
+
* Set default account for a provider
|
|
164
|
+
*/
|
|
165
|
+
function setDefaultAccount(provider, accountId) {
|
|
166
|
+
const registry = loadAccountsRegistry();
|
|
167
|
+
const providerAccounts = registry.providers[provider];
|
|
168
|
+
if (!providerAccounts || !providerAccounts.accounts[accountId]) {
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
providerAccounts.default = accountId;
|
|
172
|
+
saveAccountsRegistry(registry);
|
|
173
|
+
return true;
|
|
174
|
+
}
|
|
175
|
+
exports.setDefaultAccount = setDefaultAccount;
|
|
176
|
+
/**
|
|
177
|
+
* Remove an account
|
|
178
|
+
*/
|
|
179
|
+
function removeAccount(provider, accountId) {
|
|
180
|
+
const registry = loadAccountsRegistry();
|
|
181
|
+
const providerAccounts = registry.providers[provider];
|
|
182
|
+
if (!providerAccounts || !providerAccounts.accounts[accountId]) {
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
185
|
+
// Get token file to delete
|
|
186
|
+
const tokenFile = providerAccounts.accounts[accountId].tokenFile;
|
|
187
|
+
const tokenPath = path.join((0, config_generator_1.getAuthDir)(), tokenFile);
|
|
188
|
+
// Delete token file
|
|
189
|
+
if (fs.existsSync(tokenPath)) {
|
|
190
|
+
try {
|
|
191
|
+
fs.unlinkSync(tokenPath);
|
|
192
|
+
}
|
|
193
|
+
catch {
|
|
194
|
+
// Ignore deletion errors
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
// Remove from registry
|
|
198
|
+
delete providerAccounts.accounts[accountId];
|
|
199
|
+
// Update default if needed
|
|
200
|
+
const remainingAccounts = Object.keys(providerAccounts.accounts);
|
|
201
|
+
if (providerAccounts.default === accountId && remainingAccounts.length > 0) {
|
|
202
|
+
providerAccounts.default = remainingAccounts[0];
|
|
203
|
+
}
|
|
204
|
+
saveAccountsRegistry(registry);
|
|
205
|
+
return true;
|
|
206
|
+
}
|
|
207
|
+
exports.removeAccount = removeAccount;
|
|
208
|
+
/**
|
|
209
|
+
* Update last used timestamp for an account
|
|
210
|
+
*/
|
|
211
|
+
function touchAccount(provider, accountId) {
|
|
212
|
+
const registry = loadAccountsRegistry();
|
|
213
|
+
const providerAccounts = registry.providers[provider];
|
|
214
|
+
if (providerAccounts?.accounts[accountId]) {
|
|
215
|
+
providerAccounts.accounts[accountId].lastUsedAt = new Date().toISOString();
|
|
216
|
+
saveAccountsRegistry(registry);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
exports.touchAccount = touchAccount;
|
|
220
|
+
/**
|
|
221
|
+
* Get token file path for an account
|
|
222
|
+
*/
|
|
223
|
+
function getAccountTokenPath(provider, accountId) {
|
|
224
|
+
const account = accountId ? getAccount(provider, accountId) : getDefaultAccount(provider);
|
|
225
|
+
if (!account) {
|
|
226
|
+
return null;
|
|
227
|
+
}
|
|
228
|
+
return path.join((0, config_generator_1.getAuthDir)(), account.tokenFile);
|
|
229
|
+
}
|
|
230
|
+
exports.getAccountTokenPath = getAccountTokenPath;
|
|
231
|
+
/**
|
|
232
|
+
* Auto-discover accounts from existing token files
|
|
233
|
+
* Called during migration or first run to populate accounts registry
|
|
234
|
+
*/
|
|
235
|
+
function discoverExistingAccounts() {
|
|
236
|
+
const authDir = (0, config_generator_1.getAuthDir)();
|
|
237
|
+
if (!fs.existsSync(authDir)) {
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
const registry = loadAccountsRegistry();
|
|
241
|
+
const files = fs.readdirSync(authDir);
|
|
242
|
+
for (const file of files) {
|
|
243
|
+
if (!file.endsWith('.json'))
|
|
244
|
+
continue;
|
|
245
|
+
const filePath = path.join(authDir, file);
|
|
246
|
+
try {
|
|
247
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
248
|
+
const data = JSON.parse(content);
|
|
249
|
+
// Skip if no type field
|
|
250
|
+
if (!data.type)
|
|
251
|
+
continue;
|
|
252
|
+
// Map token type values to internal provider names
|
|
253
|
+
// CLIProxyAPI uses different type values in tokens (e.g., "antigravity" vs "agy")
|
|
254
|
+
const typeToProvider = {
|
|
255
|
+
gemini: 'gemini',
|
|
256
|
+
antigravity: 'agy',
|
|
257
|
+
codex: 'codex',
|
|
258
|
+
qwen: 'qwen',
|
|
259
|
+
iflow: 'iflow',
|
|
260
|
+
};
|
|
261
|
+
const typeValue = data.type.toLowerCase();
|
|
262
|
+
const provider = typeToProvider[typeValue];
|
|
263
|
+
// Skip if unknown provider type
|
|
264
|
+
if (!provider) {
|
|
265
|
+
continue;
|
|
266
|
+
}
|
|
267
|
+
// Extract email if available
|
|
268
|
+
const email = data.email || undefined;
|
|
269
|
+
const accountId = email || 'default';
|
|
270
|
+
// Initialize provider section if needed
|
|
271
|
+
if (!registry.providers[provider]) {
|
|
272
|
+
registry.providers[provider] = {
|
|
273
|
+
default: accountId,
|
|
274
|
+
accounts: {},
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
const providerAccounts = registry.providers[provider];
|
|
278
|
+
if (!providerAccounts)
|
|
279
|
+
continue;
|
|
280
|
+
// Skip if account already registered
|
|
281
|
+
if (providerAccounts.accounts[accountId]) {
|
|
282
|
+
continue;
|
|
283
|
+
}
|
|
284
|
+
// Get file stats for creation time
|
|
285
|
+
const stats = fs.statSync(filePath);
|
|
286
|
+
// Register account
|
|
287
|
+
providerAccounts.accounts[accountId] = {
|
|
288
|
+
email,
|
|
289
|
+
tokenFile: file,
|
|
290
|
+
createdAt: stats.birthtime?.toISOString() || new Date().toISOString(),
|
|
291
|
+
lastUsedAt: stats.mtime?.toISOString(),
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
catch {
|
|
295
|
+
// Skip invalid files
|
|
296
|
+
continue;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
saveAccountsRegistry(registry);
|
|
300
|
+
}
|
|
301
|
+
exports.discoverExistingAccounts = discoverExistingAccounts;
|
|
302
|
+
/**
|
|
303
|
+
* Get summary of all accounts across providers
|
|
304
|
+
*/
|
|
305
|
+
function getAllAccountsSummary() {
|
|
306
|
+
const providers = ['gemini', 'codex', 'agy', 'qwen', 'iflow'];
|
|
307
|
+
const summary = {};
|
|
308
|
+
for (const provider of providers) {
|
|
309
|
+
summary[provider] = getProviderAccounts(provider);
|
|
310
|
+
}
|
|
311
|
+
return summary;
|
|
312
|
+
}
|
|
313
|
+
exports.getAllAccountsSummary = getAllAccountsSummary;
|
|
314
|
+
//# sourceMappingURL=account-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account-manager.js","sourceRoot":"","sources":["../../src/cliproxy/account-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
* Each provider has its own directory to avoid conflicts.
|
|
13
13
|
*/
|
|
14
14
|
import { CLIProxyProvider } from './types';
|
|
15
|
+
import { AccountInfo } from './account-manager';
|
|
15
16
|
/**
|
|
16
17
|
* Auth status for a provider
|
|
17
18
|
*/
|
|
@@ -26,6 +27,10 @@ export interface AuthStatus {
|
|
|
26
27
|
tokenFiles: string[];
|
|
27
28
|
/** When last authenticated (if known) */
|
|
28
29
|
lastAuth?: Date;
|
|
30
|
+
/** Accounts registered for this provider (multi-account support) */
|
|
31
|
+
accounts: AccountInfo[];
|
|
32
|
+
/** Default account ID */
|
|
33
|
+
defaultAccount?: string;
|
|
29
34
|
}
|
|
30
35
|
/**
|
|
31
36
|
* OAuth config for each provider
|
|
@@ -76,19 +81,32 @@ export declare function clearAuth(provider: CLIProxyProvider): boolean;
|
|
|
76
81
|
/**
|
|
77
82
|
* Trigger OAuth flow for provider
|
|
78
83
|
* Auto-detects headless environment and uses --no-browser flag accordingly
|
|
84
|
+
* @param provider - The CLIProxy provider to authenticate
|
|
85
|
+
* @param options - OAuth options
|
|
86
|
+
* @returns Account info if successful, null otherwise
|
|
79
87
|
*/
|
|
80
88
|
export declare function triggerOAuth(provider: CLIProxyProvider, options?: {
|
|
81
89
|
verbose?: boolean;
|
|
82
90
|
headless?: boolean;
|
|
83
|
-
|
|
91
|
+
account?: string;
|
|
92
|
+
}): Promise<AccountInfo | null>;
|
|
84
93
|
/**
|
|
85
94
|
* Ensure provider is authenticated
|
|
86
95
|
* Triggers OAuth flow if not authenticated
|
|
96
|
+
* @param provider - The CLIProxy provider
|
|
97
|
+
* @param options - Auth options including optional account
|
|
98
|
+
* @returns true if authenticated, false otherwise
|
|
87
99
|
*/
|
|
88
100
|
export declare function ensureAuth(provider: CLIProxyProvider, options?: {
|
|
89
101
|
verbose?: boolean;
|
|
90
102
|
headless?: boolean;
|
|
103
|
+
account?: string;
|
|
91
104
|
}): Promise<boolean>;
|
|
105
|
+
/**
|
|
106
|
+
* Initialize accounts registry from existing tokens
|
|
107
|
+
* Should be called on startup to populate accounts from existing token files
|
|
108
|
+
*/
|
|
109
|
+
export declare function initializeAccounts(): void;
|
|
92
110
|
/**
|
|
93
111
|
* Display auth status for all providers
|
|
94
112
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-handler.d.ts","sourceRoot":"","sources":["../../src/cliproxy/auth-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAQH,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"auth-handler.d.ts","sourceRoot":"","sources":["../../src/cliproxy/auth-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAQH,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EACL,WAAW,EAMZ,MAAM,mBAAmB,CAAC;AAsF3B;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,oBAAoB;IACpB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,oCAAoC;IACpC,aAAa,EAAE,OAAO,CAAC;IACvB,8BAA8B;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,6BAA6B;IAC7B,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,yCAAyC;IACzC,QAAQ,CAAC,EAAE,IAAI,CAAC;IAChB,oEAAoE;IACpE,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,yBAAyB;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,UAAU,mBAAmB;IAC3B,0BAA0B;IAC1B,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,mBAAmB;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,gDAAgD;IAChD,OAAO,EAAE,MAAM,CAAC;IAChB,sBAAsB;IACtB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,wBAAwB;IACxB,QAAQ,EAAE,MAAM,CAAC;CAClB;AA4CD;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,gBAAgB,GAAG,mBAAmB,CAM9E;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,MAAM,CAEtE;AA2CD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAkCnE;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,gBAAgB,GAAG,UAAU,CAoDpE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,UAAU,EAAE,CAG/C;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAkC7D;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAChC,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GACxE,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAgL7B;AA8CD;;;;;;GAMG;AACH,wBAAsB,UAAU,CAC9B,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GACxE,OAAO,CAAC,OAAO,CAAC,CAoBlB;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAkBxC"}
|
|
@@ -36,13 +36,14 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
36
36
|
return result;
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.displayAuthStatus = exports.ensureAuth = exports.triggerOAuth = exports.clearAuth = exports.getAllAuthStatus = exports.getAuthStatus = exports.isAuthenticated = exports.getProviderTokenDir = exports.getOAuthConfig = void 0;
|
|
39
|
+
exports.displayAuthStatus = exports.initializeAccounts = exports.ensureAuth = exports.triggerOAuth = exports.clearAuth = exports.getAllAuthStatus = exports.getAuthStatus = exports.isAuthenticated = exports.getProviderTokenDir = exports.getOAuthConfig = void 0;
|
|
40
40
|
const child_process_1 = require("child_process");
|
|
41
41
|
const fs = __importStar(require("fs"));
|
|
42
42
|
const path = __importStar(require("path"));
|
|
43
43
|
const progress_indicator_1 = require("../utils/progress-indicator");
|
|
44
44
|
const binary_manager_1 = require("./binary-manager");
|
|
45
45
|
const config_generator_1 = require("./config-generator");
|
|
46
|
+
const account_manager_1 = require("./account-manager");
|
|
46
47
|
/**
|
|
47
48
|
* OAuth callback ports used by CLIProxyAPI (hardcoded in binary)
|
|
48
49
|
* See: https://github.com/router-for-me/CLIProxyAPI/tree/main/internal/auth
|
|
@@ -297,12 +298,17 @@ function getAuthStatus(provider) {
|
|
|
297
298
|
}
|
|
298
299
|
}
|
|
299
300
|
}
|
|
301
|
+
// Get registered accounts for multi-account support
|
|
302
|
+
const accounts = (0, account_manager_1.getProviderAccounts)(provider);
|
|
303
|
+
const defaultAccount = (0, account_manager_1.getDefaultAccount)(provider);
|
|
300
304
|
return {
|
|
301
305
|
provider,
|
|
302
306
|
authenticated: tokenFiles.length > 0,
|
|
303
307
|
tokenDir,
|
|
304
308
|
tokenFiles,
|
|
305
309
|
lastAuth,
|
|
310
|
+
accounts,
|
|
311
|
+
defaultAccount: defaultAccount?.id,
|
|
306
312
|
};
|
|
307
313
|
}
|
|
308
314
|
exports.getAuthStatus = getAuthStatus;
|
|
@@ -352,6 +358,9 @@ exports.clearAuth = clearAuth;
|
|
|
352
358
|
/**
|
|
353
359
|
* Trigger OAuth flow for provider
|
|
354
360
|
* Auto-detects headless environment and uses --no-browser flag accordingly
|
|
361
|
+
* @param provider - The CLIProxy provider to authenticate
|
|
362
|
+
* @param options - OAuth options
|
|
363
|
+
* @returns Account info if successful, null otherwise
|
|
355
364
|
*/
|
|
356
365
|
async function triggerOAuth(provider, options = {}) {
|
|
357
366
|
const oauthConfig = getOAuthConfig(provider);
|
|
@@ -465,7 +474,7 @@ async function triggerOAuth(provider, options = {}) {
|
|
|
465
474
|
console.error(' - Make sure a browser is available');
|
|
466
475
|
console.error(' - Try running with --verbose for details');
|
|
467
476
|
}
|
|
468
|
-
resolve(
|
|
477
|
+
resolve(null);
|
|
469
478
|
}, timeoutMs);
|
|
470
479
|
authProcess.on('exit', (code) => {
|
|
471
480
|
clearTimeout(timeout);
|
|
@@ -475,7 +484,9 @@ async function triggerOAuth(provider, options = {}) {
|
|
|
475
484
|
if (!headless)
|
|
476
485
|
spinner.succeed(`Authenticated with ${oauthConfig.displayName}`);
|
|
477
486
|
console.log('[OK] Authentication successful');
|
|
478
|
-
|
|
487
|
+
// Register the account in accounts registry
|
|
488
|
+
const account = registerAccountFromToken(provider, tokenDir);
|
|
489
|
+
resolve(account);
|
|
479
490
|
}
|
|
480
491
|
else {
|
|
481
492
|
if (!headless)
|
|
@@ -491,7 +502,7 @@ async function triggerOAuth(provider, options = {}) {
|
|
|
491
502
|
console.error(' The OAuth flow may have been cancelled or callback port was in use');
|
|
492
503
|
console.error(` Try: pkill -f cli-proxy-api && ccs ${provider} --auth`);
|
|
493
504
|
}
|
|
494
|
-
resolve(
|
|
505
|
+
resolve(null);
|
|
495
506
|
}
|
|
496
507
|
}
|
|
497
508
|
else {
|
|
@@ -506,7 +517,7 @@ async function triggerOAuth(provider, options = {}) {
|
|
|
506
517
|
console.error('');
|
|
507
518
|
console.error('[i] No OAuth URL was displayed. Try with --verbose for details.');
|
|
508
519
|
}
|
|
509
|
-
resolve(
|
|
520
|
+
resolve(null);
|
|
510
521
|
}
|
|
511
522
|
});
|
|
512
523
|
authProcess.on('error', (error) => {
|
|
@@ -514,14 +525,53 @@ async function triggerOAuth(provider, options = {}) {
|
|
|
514
525
|
if (!headless)
|
|
515
526
|
spinner.fail('Authentication error');
|
|
516
527
|
console.error(`[X] Failed to start auth process: ${error.message}`);
|
|
517
|
-
resolve(
|
|
528
|
+
resolve(null);
|
|
518
529
|
});
|
|
519
530
|
});
|
|
520
531
|
}
|
|
521
532
|
exports.triggerOAuth = triggerOAuth;
|
|
533
|
+
/**
|
|
534
|
+
* Register account from newly created token file
|
|
535
|
+
* Scans auth directory for new token and extracts email
|
|
536
|
+
*/
|
|
537
|
+
function registerAccountFromToken(provider, tokenDir) {
|
|
538
|
+
try {
|
|
539
|
+
const files = fs.readdirSync(tokenDir);
|
|
540
|
+
const jsonFiles = files.filter((f) => f.endsWith('.json'));
|
|
541
|
+
// Find newest token file for this provider
|
|
542
|
+
let newestFile = null;
|
|
543
|
+
let newestMtime = 0;
|
|
544
|
+
for (const file of jsonFiles) {
|
|
545
|
+
const filePath = path.join(tokenDir, file);
|
|
546
|
+
if (!isTokenFileForProvider(filePath, provider))
|
|
547
|
+
continue;
|
|
548
|
+
const stats = fs.statSync(filePath);
|
|
549
|
+
if (stats.mtimeMs > newestMtime) {
|
|
550
|
+
newestMtime = stats.mtimeMs;
|
|
551
|
+
newestFile = file;
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
if (!newestFile) {
|
|
555
|
+
return null;
|
|
556
|
+
}
|
|
557
|
+
// Read token to extract email
|
|
558
|
+
const tokenPath = path.join(tokenDir, newestFile);
|
|
559
|
+
const content = fs.readFileSync(tokenPath, 'utf-8');
|
|
560
|
+
const data = JSON.parse(content);
|
|
561
|
+
const email = data.email || undefined;
|
|
562
|
+
// Register the account
|
|
563
|
+
return (0, account_manager_1.registerAccount)(provider, newestFile, email);
|
|
564
|
+
}
|
|
565
|
+
catch {
|
|
566
|
+
return null;
|
|
567
|
+
}
|
|
568
|
+
}
|
|
522
569
|
/**
|
|
523
570
|
* Ensure provider is authenticated
|
|
524
571
|
* Triggers OAuth flow if not authenticated
|
|
572
|
+
* @param provider - The CLIProxy provider
|
|
573
|
+
* @param options - Auth options including optional account
|
|
574
|
+
* @returns true if authenticated, false otherwise
|
|
525
575
|
*/
|
|
526
576
|
async function ensureAuth(provider, options = {}) {
|
|
527
577
|
// Check if already authenticated
|
|
@@ -529,14 +579,28 @@ async function ensureAuth(provider, options = {}) {
|
|
|
529
579
|
if (options.verbose) {
|
|
530
580
|
console.error(`[auth] ${provider} already authenticated`);
|
|
531
581
|
}
|
|
582
|
+
// Touch the account to update last used time
|
|
583
|
+
const defaultAccount = (0, account_manager_1.getDefaultAccount)(provider);
|
|
584
|
+
if (defaultAccount) {
|
|
585
|
+
(0, account_manager_1.touchAccount)(provider, options.account || defaultAccount.id);
|
|
586
|
+
}
|
|
532
587
|
return true;
|
|
533
588
|
}
|
|
534
589
|
// Not authenticated - trigger OAuth
|
|
535
590
|
const oauthConfig = getOAuthConfig(provider);
|
|
536
591
|
console.log(`[i] ${oauthConfig.displayName} authentication required`);
|
|
537
|
-
|
|
592
|
+
const account = await triggerOAuth(provider, options);
|
|
593
|
+
return account !== null;
|
|
538
594
|
}
|
|
539
595
|
exports.ensureAuth = ensureAuth;
|
|
596
|
+
/**
|
|
597
|
+
* Initialize accounts registry from existing tokens
|
|
598
|
+
* Should be called on startup to populate accounts from existing token files
|
|
599
|
+
*/
|
|
600
|
+
function initializeAccounts() {
|
|
601
|
+
(0, account_manager_1.discoverExistingAccounts)();
|
|
602
|
+
}
|
|
603
|
+
exports.initializeAccounts = initializeAccounts;
|
|
540
604
|
/**
|
|
541
605
|
* Display auth status for all providers
|
|
542
606
|
*/
|