@vybestack/llxprt-code 0.1.23 → 0.2.2-nightly.250908.7b895396
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/README.md +21 -17
- package/dist/package.json +4 -3
- package/dist/src/auth/anthropic-oauth-provider.d.ts +50 -3
- package/dist/src/auth/anthropic-oauth-provider.js +287 -63
- package/dist/src/auth/anthropic-oauth-provider.js.map +1 -1
- package/dist/src/auth/gemini-oauth-provider.d.ts +34 -3
- package/dist/src/auth/gemini-oauth-provider.js +308 -14
- package/dist/src/auth/gemini-oauth-provider.js.map +1 -1
- package/dist/src/auth/migration.d.ts +26 -0
- package/dist/src/auth/migration.js +54 -0
- package/dist/src/auth/migration.js.map +1 -0
- package/dist/src/auth/oauth-manager.d.ts +24 -0
- package/dist/src/auth/oauth-manager.js +179 -14
- package/dist/src/auth/oauth-manager.js.map +1 -1
- package/dist/src/auth/oauth-manager.spec.js +10 -8
- package/dist/src/auth/oauth-manager.spec.js.map +1 -1
- package/dist/src/auth/qwen-oauth-provider.d.ts +59 -3
- package/dist/src/auth/qwen-oauth-provider.js +263 -41
- package/dist/src/auth/qwen-oauth-provider.js.map +1 -1
- package/dist/src/config/config.js +11 -10
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/extension.d.ts +1 -1
- package/dist/src/config/extension.js +1 -1
- package/dist/src/gemini.js +33 -11
- package/dist/src/gemini.js.map +1 -1
- package/dist/src/generated/git-commit.d.ts +1 -1
- package/dist/src/generated/git-commit.js +1 -1
- package/dist/src/integration-tests/base-url-behavior.integration.test.js +4 -1
- package/dist/src/integration-tests/base-url-behavior.integration.test.js.map +1 -1
- package/dist/src/integration-tests/compression-settings-apply.integration.test.js +85 -332
- package/dist/src/integration-tests/compression-settings-apply.integration.test.js.map +1 -1
- package/dist/src/integration-tests/ephemeral-settings.integration.test.js +5 -16
- package/dist/src/integration-tests/ephemeral-settings.integration.test.js.map +1 -1
- package/dist/src/integration-tests/model-params-isolation.integration.test.js +8 -2
- package/dist/src/integration-tests/model-params-isolation.integration.test.js.map +1 -1
- package/dist/src/integration-tests/modelParams.integration.test.js +4 -1
- package/dist/src/integration-tests/modelParams.integration.test.js.map +1 -1
- package/dist/src/integration-tests/provider-switching.integration.test.js +4 -1
- package/dist/src/integration-tests/provider-switching.integration.test.js.map +1 -1
- package/dist/src/integration-tests/retry-settings.integration.test.d.ts +6 -0
- package/dist/src/integration-tests/retry-settings.integration.test.js +56 -0
- package/dist/src/integration-tests/retry-settings.integration.test.js.map +1 -0
- package/dist/src/providers/index.d.ts +1 -1
- package/dist/src/providers/logging/LoggingProviderWrapper.test.js +58 -47
- package/dist/src/providers/logging/LoggingProviderWrapper.test.js.map +1 -1
- package/dist/src/providers/logging/multi-provider-logging.integration.test.js +130 -68
- package/dist/src/providers/logging/multi-provider-logging.integration.test.js.map +1 -1
- package/dist/src/providers/logging/performance.test.js +39 -16
- package/dist/src/providers/logging/performance.test.js.map +1 -1
- package/dist/src/providers/provider-gemini-switching.test.js +4 -1
- package/dist/src/providers/provider-gemini-switching.test.js.map +1 -1
- package/dist/src/providers/provider-switching.integration.test.js +12 -3
- package/dist/src/providers/provider-switching.integration.test.js.map +1 -1
- package/dist/src/providers/providerConfigUtils.js +2 -4
- package/dist/src/providers/providerConfigUtils.js.map +1 -1
- package/dist/src/providers/providerManagerInstance.js +24 -49
- package/dist/src/providers/providerManagerInstance.js.map +1 -1
- package/dist/src/services/BuiltinCommandLoader.js +4 -0
- package/dist/src/services/BuiltinCommandLoader.js.map +1 -1
- package/dist/src/storage/ConversationStorage.test.js +10 -7
- package/dist/src/storage/ConversationStorage.test.js.map +1 -1
- package/dist/src/test-utils/mockCommandContext.js +2 -0
- package/dist/src/test-utils/mockCommandContext.js.map +1 -1
- package/dist/src/ui/App.e2e.test.d.ts +6 -0
- package/dist/src/ui/App.e2e.test.js +37 -0
- package/dist/src/ui/App.e2e.test.js.map +1 -0
- package/dist/src/ui/App.js +51 -4
- package/dist/src/ui/App.js.map +1 -1
- package/dist/src/ui/commands/authCommand.d.ts +9 -1
- package/dist/src/ui/commands/authCommand.js +109 -31
- package/dist/src/ui/commands/authCommand.js.map +1 -1
- package/dist/src/ui/commands/clearCommand.js +2 -0
- package/dist/src/ui/commands/clearCommand.js.map +1 -1
- package/dist/src/ui/commands/ideCommand.js +26 -0
- package/dist/src/ui/commands/ideCommand.js.map +1 -1
- package/dist/src/ui/commands/keyCommand.js +16 -54
- package/dist/src/ui/commands/keyCommand.js.map +1 -1
- package/dist/src/ui/commands/keyCommand.test.js +3 -3
- package/dist/src/ui/commands/keyCommand.test.js.map +1 -1
- package/dist/src/ui/commands/keyfileCommand.js +42 -32
- package/dist/src/ui/commands/keyfileCommand.js.map +1 -1
- package/dist/src/ui/commands/logoutCommand.d.ts +7 -0
- package/dist/src/ui/commands/logoutCommand.js +70 -0
- package/dist/src/ui/commands/logoutCommand.js.map +1 -0
- package/dist/src/ui/commands/modelCommand.js +16 -0
- package/dist/src/ui/commands/modelCommand.js.map +1 -1
- package/dist/src/ui/commands/profileCommand.js +31 -25
- package/dist/src/ui/commands/profileCommand.js.map +1 -1
- package/dist/src/ui/commands/profileCommand.test.js +15 -16
- package/dist/src/ui/commands/profileCommand.test.js.map +1 -1
- package/dist/src/ui/commands/providerCommand.js +10 -7
- package/dist/src/ui/commands/providerCommand.js.map +1 -1
- package/dist/src/ui/commands/setCommand.js +43 -19
- package/dist/src/ui/commands/setCommand.js.map +1 -1
- package/dist/src/ui/commands/setCommand.test.js +5 -7
- package/dist/src/ui/commands/setCommand.test.js.map +1 -1
- package/dist/src/ui/commands/setupGithubCommand.d.ts +2 -0
- package/dist/src/ui/commands/setupGithubCommand.js +123 -23
- package/dist/src/ui/commands/setupGithubCommand.js.map +1 -1
- package/dist/src/ui/commands/setupGithubCommand.test.js +94 -1
- package/dist/src/ui/commands/setupGithubCommand.test.js.map +1 -1
- package/dist/src/ui/commands/statusCommand.d.ts +7 -0
- package/dist/src/ui/commands/statusCommand.js +71 -0
- package/dist/src/ui/commands/statusCommand.js.map +1 -0
- package/dist/src/ui/commands/types.d.ts +1 -0
- package/dist/src/ui/commands/types.js.map +1 -1
- package/dist/src/ui/components/ContextIndicator.ui.test.js +19 -46
- package/dist/src/ui/components/ContextIndicator.ui.test.js.map +1 -1
- package/dist/src/ui/components/Footer.d.ts +1 -1
- package/dist/src/ui/components/Footer.js +7 -7
- package/dist/src/ui/components/Footer.js.map +1 -1
- package/dist/src/ui/components/Footer.responsive.test.js +28 -25
- package/dist/src/ui/components/Footer.responsive.test.js.map +1 -1
- package/dist/src/ui/components/OAuthCodeDialog.d.ts +5 -0
- package/dist/src/ui/components/OAuthCodeDialog.js +31 -1
- package/dist/src/ui/components/OAuthCodeDialog.js.map +1 -1
- package/dist/src/ui/components/OAuthCodeDialog.test.d.ts +6 -0
- package/dist/src/ui/components/OAuthCodeDialog.test.js +60 -0
- package/dist/src/ui/components/OAuthCodeDialog.test.js.map +1 -0
- package/dist/src/ui/contexts/KeypressContext.js +23 -1
- package/dist/src/ui/contexts/KeypressContext.js.map +1 -1
- package/dist/src/ui/contexts/KeypressContext.test.js +58 -2
- package/dist/src/ui/contexts/KeypressContext.test.js.map +1 -1
- package/dist/src/ui/contexts/SessionContext.d.ts +2 -0
- package/dist/src/ui/contexts/SessionContext.js +9 -1
- package/dist/src/ui/contexts/SessionContext.js.map +1 -1
- package/dist/src/ui/contexts/TodoContext.js +2 -2
- package/dist/src/ui/contexts/TodoContext.js.map +1 -1
- package/dist/src/ui/hooks/atCommandProcessor.js +0 -2
- package/dist/src/ui/hooks/atCommandProcessor.js.map +1 -1
- package/dist/src/ui/hooks/atCommandProcessor.test.js +21 -6
- package/dist/src/ui/hooks/atCommandProcessor.test.js.map +1 -1
- package/dist/src/ui/hooks/slashCommandProcessor.js +2 -0
- package/dist/src/ui/hooks/slashCommandProcessor.js.map +1 -1
- package/dist/src/ui/hooks/useAuthCommand.js +6 -5
- package/dist/src/ui/hooks/useAuthCommand.js.map +1 -1
- package/dist/src/ui/hooks/useGeminiStream.js +47 -63
- package/dist/src/ui/hooks/useGeminiStream.js.map +1 -1
- package/dist/src/ui/hooks/useProviderDialog.js +2 -5
- package/dist/src/ui/hooks/useProviderDialog.js.map +1 -1
- package/dist/src/ui/hooks/useToolScheduler.test.js +60 -24
- package/dist/src/ui/hooks/useToolScheduler.test.js.map +1 -1
- package/dist/src/ui/utils/platformConstants.d.ts +2 -0
- package/dist/src/ui/utils/platformConstants.js +2 -0
- package/dist/src/ui/utils/platformConstants.js.map +1 -1
- package/dist/src/ui/utils/secureInputHandler.js +18 -7
- package/dist/src/ui/utils/secureInputHandler.js.map +1 -1
- package/dist/src/ui/utils/secureInputHandler.test.js +20 -0
- package/dist/src/ui/utils/secureInputHandler.test.js.map +1 -1
- package/dist/src/utils/privacy/ConversationDataRedactor.d.ts +3 -3
- package/dist/src/utils/privacy/ConversationDataRedactor.js +16 -12
- package/dist/src/utils/privacy/ConversationDataRedactor.js.map +1 -1
- package/dist/src/utils/privacy/ConversationDataRedactor.test.js +115 -72
- package/dist/src/utils/privacy/ConversationDataRedactor.test.js.map +1 -1
- package/dist/src/validateNonInterActiveAuth.js +8 -17
- package/dist/src/validateNonInterActiveAuth.js.map +1 -1
- package/dist/src/zed-integration/schema.d.ts +194 -91
- package/dist/src/zed-integration/schema.js +7 -1
- package/dist/src/zed-integration/schema.js.map +1 -1
- package/dist/src/zed-integration/zedIntegration.d.ts +1 -3
- package/dist/src/zed-integration/zedIntegration.js +454 -198
- package/dist/src/zed-integration/zedIntegration.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -3
@@ -1,33 +1,327 @@
|
|
1
1
|
/**
|
2
2
|
* Gemini OAuth Provider Implementation
|
3
3
|
*
|
4
|
-
*
|
5
|
-
*
|
4
|
+
* Bridges to the existing Google OAuth infrastructure in oauth2.ts
|
5
|
+
* while maintaining compatibility with the LOGIN_WITH_GOOGLE flow.
|
6
6
|
*/
|
7
|
+
import { clearOauthClientCache, OAuthError, OAuthErrorFactory, GracefulErrorHandler, RetryHandler, shouldLaunchBrowser, DebugLogger, } from '@vybestack/llxprt-code-core';
|
8
|
+
import { promises as fs } from 'node:fs';
|
9
|
+
import path from 'node:path';
|
10
|
+
import os from 'node:os';
|
11
|
+
var InitializationState;
|
12
|
+
(function (InitializationState) {
|
13
|
+
InitializationState["NotStarted"] = "not-started";
|
14
|
+
InitializationState["InProgress"] = "in-progress";
|
15
|
+
InitializationState["Completed"] = "completed";
|
16
|
+
InitializationState["Failed"] = "failed";
|
17
|
+
})(InitializationState || (InitializationState = {}));
|
7
18
|
export class GeminiOAuthProvider {
|
8
19
|
name = 'gemini';
|
9
20
|
currentToken = null;
|
21
|
+
tokenStore;
|
22
|
+
initializationState = InitializationState.NotStarted;
|
23
|
+
initializationPromise;
|
24
|
+
initializationError;
|
25
|
+
errorHandler;
|
26
|
+
retryHandler;
|
27
|
+
logger;
|
28
|
+
constructor(tokenStore) {
|
29
|
+
this.tokenStore = tokenStore;
|
30
|
+
this.retryHandler = new RetryHandler();
|
31
|
+
this.errorHandler = new GracefulErrorHandler(this.retryHandler);
|
32
|
+
this.logger = new DebugLogger('llxprt:auth:gemini');
|
33
|
+
if (!tokenStore) {
|
34
|
+
console.warn(`DEPRECATION: ${this.name} OAuth provider created without TokenStore. ` +
|
35
|
+
`Token persistence will not work. Please update your code.`);
|
36
|
+
}
|
37
|
+
// DO NOT call initializeToken() - lazy initialization pattern
|
38
|
+
}
|
39
|
+
/**
|
40
|
+
* Lazy initialization with proper state management
|
41
|
+
* Ensures initialization only happens once and handles concurrent calls
|
42
|
+
*/
|
43
|
+
async ensureInitialized() {
|
44
|
+
// If already completed, return immediately
|
45
|
+
if (this.initializationState === InitializationState.Completed) {
|
46
|
+
return;
|
47
|
+
}
|
48
|
+
// If failed, allow retry by resetting to NotStarted
|
49
|
+
if (this.initializationState === InitializationState.Failed) {
|
50
|
+
this.initializationState = InitializationState.NotStarted;
|
51
|
+
this.initializationPromise = undefined;
|
52
|
+
this.initializationError = undefined;
|
53
|
+
}
|
54
|
+
// If not started, start initialization
|
55
|
+
if (this.initializationState === InitializationState.NotStarted) {
|
56
|
+
this.initializationState = InitializationState.InProgress;
|
57
|
+
this.initializationPromise = this.initializeToken();
|
58
|
+
}
|
59
|
+
// Wait for initialization to complete (handles concurrent calls)
|
60
|
+
if (this.initializationPromise) {
|
61
|
+
try {
|
62
|
+
await this.initializationPromise;
|
63
|
+
this.initializationState = InitializationState.Completed;
|
64
|
+
}
|
65
|
+
catch (error) {
|
66
|
+
this.initializationState = InitializationState.Failed;
|
67
|
+
this.initializationError =
|
68
|
+
error instanceof OAuthError
|
69
|
+
? error
|
70
|
+
: OAuthErrorFactory.fromUnknown(this.name, error, 'ensureInitialized');
|
71
|
+
throw this.initializationError;
|
72
|
+
}
|
73
|
+
}
|
74
|
+
}
|
75
|
+
async initializeToken() {
|
76
|
+
if (!this.tokenStore) {
|
77
|
+
return;
|
78
|
+
}
|
79
|
+
return this.errorHandler.handleGracefully(async () => {
|
80
|
+
// Try to load from new location first
|
81
|
+
let savedToken = await this.tokenStore.getToken('gemini');
|
82
|
+
if (!savedToken) {
|
83
|
+
// Try to migrate from legacy locations
|
84
|
+
savedToken = await this.migrateFromLegacyTokens();
|
85
|
+
}
|
86
|
+
if (savedToken) {
|
87
|
+
this.currentToken = savedToken;
|
88
|
+
}
|
89
|
+
}, undefined, // No fallback needed - graceful failure is acceptable
|
90
|
+
this.name, 'initializeToken');
|
91
|
+
}
|
10
92
|
async initiateAuth() {
|
11
|
-
|
12
|
-
|
13
|
-
|
93
|
+
await this.ensureInitialized();
|
94
|
+
return this.errorHandler.wrapMethod(async () => {
|
95
|
+
// Import the existing Google OAuth infrastructure
|
96
|
+
const coreModule = await import('@vybestack/llxprt-code-core');
|
97
|
+
const { getOauthClient, AuthType } = coreModule;
|
98
|
+
// Create a minimal config for OAuth - use type assertion for test environment
|
99
|
+
// Type assertion is needed since we're creating a partial Config for test mode
|
100
|
+
const config = {
|
101
|
+
getProxy: () => undefined,
|
102
|
+
isBrowserLaunchSuppressed: () => !shouldLaunchBrowser(),
|
103
|
+
};
|
104
|
+
// Use the existing Google OAuth infrastructure to get a client
|
105
|
+
let client;
|
106
|
+
try {
|
107
|
+
client = await getOauthClient(AuthType.LOGIN_WITH_GOOGLE, config);
|
108
|
+
}
|
109
|
+
catch (error) {
|
110
|
+
// Handle browser auth cancellation or other auth failures
|
111
|
+
if (error instanceof Error) {
|
112
|
+
// Check for specific cancellation messages
|
113
|
+
if (error.message.includes('cancelled') ||
|
114
|
+
error.message.includes('denied') ||
|
115
|
+
error.message.includes('access_denied') ||
|
116
|
+
error.message.includes('user_cancelled')) {
|
117
|
+
// CRITICAL FIX: Trigger fallback flow instead of failing
|
118
|
+
this.logger.debug(() => `Browser auth cancelled, triggering fallback: ${error.message}`);
|
119
|
+
// Show fallback instructions to user
|
120
|
+
console.log('\n' + '─'.repeat(60));
|
121
|
+
console.log('Browser authentication was cancelled.');
|
122
|
+
console.log('Fallback options:');
|
123
|
+
console.log('1. Use API key: /keyfile <path-to-your-gemini-key>');
|
124
|
+
console.log('2. Set environment: export GEMINI_API_KEY=<your-key>');
|
125
|
+
console.log('3. Try OAuth again: /auth gemini enable');
|
126
|
+
console.log('─'.repeat(60));
|
127
|
+
// Throw a user-friendly error that doesn't hang the system
|
128
|
+
throw OAuthErrorFactory.authenticationRequired(this.name, {
|
129
|
+
reason: 'Browser authentication was cancelled. Please use one of the fallback options shown above.',
|
130
|
+
});
|
131
|
+
}
|
132
|
+
}
|
133
|
+
// Re-throw other authentication errors
|
134
|
+
throw error;
|
135
|
+
}
|
136
|
+
// The client should now have valid credentials
|
137
|
+
// Extract and cache the token
|
138
|
+
const credentials = client.credentials;
|
139
|
+
if (credentials && credentials.access_token) {
|
140
|
+
const token = this.credentialsToOAuthToken(credentials);
|
141
|
+
if (token && this.tokenStore) {
|
142
|
+
try {
|
143
|
+
await this.tokenStore.saveToken('gemini', token);
|
144
|
+
this.currentToken = token;
|
145
|
+
}
|
146
|
+
catch (saveError) {
|
147
|
+
throw OAuthErrorFactory.storageError(this.name, saveError instanceof Error ? saveError : undefined, {
|
148
|
+
operation: 'saveToken',
|
149
|
+
});
|
150
|
+
}
|
151
|
+
}
|
152
|
+
}
|
153
|
+
else {
|
154
|
+
throw OAuthErrorFactory.authenticationRequired(this.name, {
|
155
|
+
reason: 'No valid credentials received from Google OAuth',
|
156
|
+
});
|
157
|
+
}
|
158
|
+
}, this.name, 'initiateAuth')();
|
14
159
|
}
|
15
160
|
async getToken() {
|
16
|
-
|
161
|
+
await this.ensureInitialized();
|
162
|
+
return this.errorHandler.handleGracefully(async () => {
|
163
|
+
// Try to get from memory first
|
164
|
+
let token = await this.refreshIfNeeded();
|
165
|
+
if (!token) {
|
166
|
+
// Try to get from existing Google OAuth infrastructure
|
167
|
+
token = await this.getTokenFromGoogleOAuth();
|
168
|
+
// Cache it if found
|
169
|
+
if (token && this.tokenStore) {
|
170
|
+
try {
|
171
|
+
await this.tokenStore.saveToken('gemini', token);
|
172
|
+
this.currentToken = token;
|
173
|
+
}
|
174
|
+
catch (error) {
|
175
|
+
// Non-critical - we can still return the token
|
176
|
+
this.logger.debug(() => `Failed to cache token from Google OAuth: ${error}`);
|
177
|
+
}
|
178
|
+
}
|
179
|
+
}
|
180
|
+
return token;
|
181
|
+
}, null, // Return null on error
|
182
|
+
this.name, 'getToken');
|
17
183
|
}
|
18
184
|
async refreshIfNeeded() {
|
185
|
+
await this.ensureInitialized();
|
19
186
|
if (!this.currentToken) {
|
20
187
|
return null;
|
21
188
|
}
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
189
|
+
return this.errorHandler.handleGracefully(async () => {
|
190
|
+
// Check if token needs refresh (30 second buffer)
|
191
|
+
const now = Date.now() / 1000;
|
192
|
+
const expiresAt = this.currentToken.expiry;
|
193
|
+
if (expiresAt && expiresAt <= now + 30) {
|
194
|
+
// Token is expired or expires soon
|
195
|
+
// Since actual Gemini OAuth refresh is handled by the GeminiProvider itself,
|
196
|
+
// we clear the expired token and return null to signal re-authentication is needed
|
197
|
+
this.currentToken = null;
|
198
|
+
if (this.tokenStore) {
|
199
|
+
try {
|
200
|
+
await this.tokenStore.removeToken('gemini');
|
201
|
+
}
|
202
|
+
catch (error) {
|
203
|
+
throw OAuthErrorFactory.storageError(this.name, error instanceof Error ? error : undefined, {
|
204
|
+
operation: 'removeExpiredToken',
|
205
|
+
});
|
206
|
+
}
|
207
|
+
}
|
208
|
+
return null;
|
209
|
+
}
|
210
|
+
return this.currentToken;
|
211
|
+
}, null, // Return null on error
|
212
|
+
this.name, 'refreshIfNeeded');
|
213
|
+
}
|
214
|
+
async logout() {
|
215
|
+
await this.ensureInitialized();
|
216
|
+
// NO ERROR SUPPRESSION - let it fail loudly
|
217
|
+
// Clear current token
|
218
|
+
this.currentToken = null;
|
219
|
+
// Remove from new token storage location - THIS MUST SUCCEED
|
220
|
+
if (this.tokenStore) {
|
221
|
+
await this.tokenStore.removeToken('gemini');
|
222
|
+
}
|
223
|
+
// Remove from legacy token locations
|
224
|
+
await this.clearLegacyTokens();
|
225
|
+
// CRITICAL SECURITY FIX: Clear OAuth client cache to prevent session leakage
|
226
|
+
// This ensures that subsequent authentication attempts require re-authentication
|
227
|
+
try {
|
228
|
+
clearOauthClientCache();
|
229
|
+
}
|
230
|
+
catch (error) {
|
231
|
+
// Log warning but don't fail logout if cache clearing fails
|
232
|
+
this.logger.debug(() => `Failed to clear OAuth client cache during Gemini logout: ${error}`);
|
233
|
+
}
|
234
|
+
}
|
235
|
+
/**
|
236
|
+
* Converts Google OAuth Credentials to our OAuthToken format
|
237
|
+
*/
|
238
|
+
credentialsToOAuthToken(creds) {
|
239
|
+
if (!creds.access_token) {
|
240
|
+
return null;
|
241
|
+
}
|
242
|
+
const token = {
|
243
|
+
access_token: creds.access_token,
|
244
|
+
refresh_token: creds.refresh_token || undefined,
|
245
|
+
// Google OAuth uses expiry_date (milliseconds), we need expiry (seconds)
|
246
|
+
expiry: creds.expiry_date
|
247
|
+
? Math.floor(creds.expiry_date / 1000)
|
248
|
+
: Math.floor(Date.now() / 1000) + 3600,
|
249
|
+
token_type: 'Bearer',
|
250
|
+
scope: creds.scope || undefined,
|
251
|
+
};
|
252
|
+
// Add id_token if available (some tests expect this)
|
253
|
+
if (creds.id_token && typeof creds === 'object' && creds.id_token) {
|
254
|
+
token.id_token = creds.id_token;
|
29
255
|
}
|
30
|
-
return
|
256
|
+
return token;
|
257
|
+
}
|
258
|
+
/**
|
259
|
+
* Gets token from the existing Google OAuth infrastructure
|
260
|
+
*/
|
261
|
+
async getTokenFromGoogleOAuth() {
|
262
|
+
return this.errorHandler.handleGracefully(async () => {
|
263
|
+
// Try to read from the existing OAuth credentials file
|
264
|
+
const credPath = path.join(os.homedir(), '.llxprt', 'oauth_creds.json');
|
265
|
+
const credsJson = await fs.readFile(credPath, 'utf8');
|
266
|
+
const creds = JSON.parse(credsJson);
|
267
|
+
if (creds.refresh_token || creds.access_token) {
|
268
|
+
return this.credentialsToOAuthToken(creds);
|
269
|
+
}
|
270
|
+
return null;
|
271
|
+
}, null, // Return null if we can't read the file
|
272
|
+
this.name, 'getTokenFromGoogleOAuth');
|
273
|
+
}
|
274
|
+
/**
|
275
|
+
* Migrates tokens from legacy locations to new format
|
276
|
+
*/
|
277
|
+
async migrateFromLegacyTokens() {
|
278
|
+
return this.errorHandler.handleGracefully(async () => {
|
279
|
+
// Try to get token from existing Google OAuth
|
280
|
+
const token = await this.getTokenFromGoogleOAuth();
|
281
|
+
if (token && this.tokenStore) {
|
282
|
+
try {
|
283
|
+
// Save to new location
|
284
|
+
await this.tokenStore.saveToken('gemini', token);
|
285
|
+
this.logger.debug(() => 'Successfully migrated Gemini token from legacy location');
|
286
|
+
return token;
|
287
|
+
}
|
288
|
+
catch (error) {
|
289
|
+
throw OAuthErrorFactory.storageError(this.name, error instanceof Error ? error : undefined, {
|
290
|
+
operation: 'migrateToken',
|
291
|
+
});
|
292
|
+
}
|
293
|
+
}
|
294
|
+
return token;
|
295
|
+
}, null, // Return null if migration fails
|
296
|
+
this.name, 'migrateFromLegacyTokens');
|
297
|
+
}
|
298
|
+
/**
|
299
|
+
* Clears tokens from all legacy locations
|
300
|
+
*/
|
301
|
+
async clearLegacyTokens() {
|
302
|
+
const legacyPaths = [
|
303
|
+
// Legacy OAuth credentials file
|
304
|
+
path.join(os.homedir(), '.llxprt', 'oauth_creds.json'),
|
305
|
+
// Legacy Google accounts file
|
306
|
+
path.join(os.homedir(), '.llxprt', 'google_accounts.json'),
|
307
|
+
];
|
308
|
+
// Use Promise.allSettled to continue even if some paths fail
|
309
|
+
const results = await Promise.allSettled(legacyPaths.map(async (legacyPath) => {
|
310
|
+
try {
|
311
|
+
await fs.unlink(legacyPath);
|
312
|
+
this.logger.debug(() => `Cleared legacy token file: ${legacyPath}`);
|
313
|
+
}
|
314
|
+
catch (error) {
|
315
|
+
// File doesn't exist or can't be removed - that's fine for legacy cleanup
|
316
|
+
this.logger.debug(() => `Could not remove legacy token file ${legacyPath}: ${error}`);
|
317
|
+
}
|
318
|
+
}));
|
319
|
+
// Log any unexpected failures for debugging
|
320
|
+
results.forEach((result, index) => {
|
321
|
+
if (result.status === 'rejected') {
|
322
|
+
this.logger.debug(() => `Legacy cleanup failed for ${legacyPaths[index]}: ${result.reason}`);
|
323
|
+
}
|
324
|
+
});
|
31
325
|
}
|
32
326
|
}
|
33
327
|
//# sourceMappingURL=gemini-oauth-provider.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"gemini-oauth-provider.js","sourceRoot":"","sources":["../../../src/auth/gemini-oauth-provider.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
1
|
+
{"version":3,"file":"gemini-oauth-provider.js","sourceRoot":"","sources":["../../../src/auth/gemini-oauth-provider.ts"],"names":[],"mappings":"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"}
|
@@ -0,0 +1,26 @@
|
|
1
|
+
/**
|
2
|
+
* @license
|
3
|
+
* Copyright 2025 Vybestack LLC
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
5
|
+
*/
|
6
|
+
/**
|
7
|
+
* @plan PLAN-20250823-AUTHFIXES.P16
|
8
|
+
* @requirement REQ-004.2
|
9
|
+
* Migration utilities for OAuth token storage modernization
|
10
|
+
*
|
11
|
+
* This module handles migration of tokens from legacy storage formats
|
12
|
+
* to the new standardized TokenStore persistence system.
|
13
|
+
*/
|
14
|
+
import { OAuthProvider } from './oauth-manager.js';
|
15
|
+
import { TokenStore } from '@vybestack/llxprt-code-core';
|
16
|
+
/**
|
17
|
+
* Migrate any in-memory tokens to persistent storage
|
18
|
+
*
|
19
|
+
* @param providers - Map of OAuth provider instances
|
20
|
+
* @param tokenStore - Token persistence store
|
21
|
+
*/
|
22
|
+
export declare function migrateInMemoryTokens(providers: Map<string, OAuthProvider>, tokenStore: TokenStore): Promise<void>;
|
23
|
+
/**
|
24
|
+
* Display migration notice to users about OAuth token storage changes
|
25
|
+
*/
|
26
|
+
export declare function showMigrationNotice(): void;
|
@@ -0,0 +1,54 @@
|
|
1
|
+
/**
|
2
|
+
* @license
|
3
|
+
* Copyright 2025 Vybestack LLC
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
5
|
+
*/
|
6
|
+
/**
|
7
|
+
* Migrate any in-memory tokens to persistent storage
|
8
|
+
*
|
9
|
+
* @param providers - Map of OAuth provider instances
|
10
|
+
* @param tokenStore - Token persistence store
|
11
|
+
*/
|
12
|
+
export async function migrateInMemoryTokens(providers, tokenStore) {
|
13
|
+
for (const [name, provider] of providers) {
|
14
|
+
try {
|
15
|
+
// Check for in-memory token
|
16
|
+
const token = await provider.getToken();
|
17
|
+
if (token) {
|
18
|
+
const stored = await tokenStore.getToken(name);
|
19
|
+
if (!stored) {
|
20
|
+
// Migrate to storage
|
21
|
+
await tokenStore.saveToken(name, token);
|
22
|
+
console.log(`Migrated ${name} token to persistent storage`);
|
23
|
+
}
|
24
|
+
}
|
25
|
+
}
|
26
|
+
catch (_error) {
|
27
|
+
// Skip providers that don't have valid tokens
|
28
|
+
// This is expected during normal operation
|
29
|
+
continue;
|
30
|
+
}
|
31
|
+
}
|
32
|
+
}
|
33
|
+
/**
|
34
|
+
* Display migration notice to users about OAuth token storage changes
|
35
|
+
*/
|
36
|
+
export function showMigrationNotice() {
|
37
|
+
console.log(`
|
38
|
+
LLXPRT OAuth Token Storage Migration
|
39
|
+
====================================
|
40
|
+
|
41
|
+
Your OAuth tokens are now stored in standardized locations:
|
42
|
+
- Anthropic: ~/.llxprt/oauth/anthropic.json
|
43
|
+
- Gemini: ~/.llxprt/oauth/gemini.json
|
44
|
+
- Qwen: ~/.llxprt/oauth/qwen.json
|
45
|
+
|
46
|
+
If you experience authentication issues, please re-login:
|
47
|
+
- llxprt auth login anthropic
|
48
|
+
- llxprt auth login gemini
|
49
|
+
- llxprt auth login qwen
|
50
|
+
|
51
|
+
Legacy Gemini tokens in ~/.llxprt/oauth_creds.json are no longer used.
|
52
|
+
`);
|
53
|
+
}
|
54
|
+
//# sourceMappingURL=migration.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"migration.js","sourceRoot":"","sources":["../../../src/auth/migration.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAcH;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,SAAqC,EACrC,UAAsB;IAEtB,KAAK,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,SAAS,EAAE,CAAC;QACzC,IAAI,CAAC;YACH,4BAA4B;YAC5B,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,CAAC;YACxC,IAAI,KAAK,EAAE,CAAC;gBACV,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;gBAC/C,IAAI,CAAC,MAAM,EAAE,CAAC;oBACZ,qBAAqB;oBACrB,MAAM,UAAU,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;oBACxC,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,8BAA8B,CAAC,CAAC;gBAC9D,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,MAAM,EAAE,CAAC;YAChB,8CAA8C;YAC9C,2CAA2C;YAC3C,SAAS;QACX,CAAC;IACH,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB;IACjC,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;CAeb,CAAC,CAAC;AACH,CAAC"}
|
@@ -60,11 +60,29 @@ export declare class OAuthManager {
|
|
60
60
|
*/
|
61
61
|
getAuthStatus(): Promise<AuthStatus[]>;
|
62
62
|
/**
|
63
|
+
* @plan PLAN-20250823-AUTHFIXES.P14
|
64
|
+
* @requirement REQ-002
|
65
|
+
* @pseudocode lines 51-68
|
63
66
|
* Check if authenticated with a specific provider (required by precedence resolver)
|
64
67
|
* @param providerName - Name of the provider
|
65
68
|
* @returns True if authenticated, false otherwise
|
66
69
|
*/
|
67
70
|
isAuthenticated(providerName: string): Promise<boolean>;
|
71
|
+
/**
|
72
|
+
* @plan PLAN-20250823-AUTHFIXES.P14
|
73
|
+
* @requirement REQ-002.1
|
74
|
+
* @pseudocode lines 4-37
|
75
|
+
* Logout from a specific provider by clearing stored tokens
|
76
|
+
* @param providerName - Name of the provider to logout from
|
77
|
+
*/
|
78
|
+
logout(providerName: string): Promise<void>;
|
79
|
+
/**
|
80
|
+
* @plan PLAN-20250823-AUTHFIXES.P14
|
81
|
+
* @requirement REQ-002
|
82
|
+
* @pseudocode lines 39-49
|
83
|
+
* Logout from all providers by clearing all stored tokens
|
84
|
+
*/
|
85
|
+
logoutAll(): Promise<void>;
|
68
86
|
/**
|
69
87
|
* Get OAuth token for a specific provider
|
70
88
|
* Compatible with precedence resolver - returns access token string
|
@@ -107,4 +125,10 @@ export declare class OAuthManager {
|
|
107
125
|
* @returns True if compatible, false otherwise
|
108
126
|
*/
|
109
127
|
private isQwenCompatibleUrl;
|
128
|
+
/**
|
129
|
+
* CRITICAL FIX: Clear all auth caches for a provider after logout
|
130
|
+
* This method finds and clears auth caches from both BaseProvider and provider-specific implementations
|
131
|
+
* @param providerName - Name of the provider to clear caches for
|
132
|
+
*/
|
133
|
+
private clearProviderAuthCaches;
|
110
134
|
}
|