mirror of
https://github.com/cline/cline.git
synced 2026-09-16 21:01:52 +08:00
added back account page and relying more heavily on the firebase custom token to ensure persistent login
This commit is contained in:
@@ -90,6 +90,11 @@
|
||||
"title": "Settings",
|
||||
"icon": "$(settings-gear)"
|
||||
},
|
||||
{
|
||||
"command": "cline.accountLoginClicked",
|
||||
"title": "Account",
|
||||
"icon": "$(account)"
|
||||
},
|
||||
{
|
||||
"command": "cline.openInNewTab",
|
||||
"title": "Open In New Tab",
|
||||
@@ -122,6 +127,11 @@
|
||||
"command": "cline.settingsButtonClicked",
|
||||
"group": "navigation@5",
|
||||
"when": "view == claude-dev.SidebarProvider"
|
||||
},
|
||||
{
|
||||
"command": "cline.accountLoginClicked",
|
||||
"group": "navigation@6",
|
||||
"when": "view == claude-dev.SidebarProvider"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -947,25 +947,24 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
return true
|
||||
}
|
||||
|
||||
async handleAuthCallback(token: string, apiKey: string) {
|
||||
async handleAuthCallback(customToken: string, apiKey: string) {
|
||||
try {
|
||||
// First sign in with Firebase to trigger auth state change
|
||||
await this.authManager.signInWithCustomToken(token)
|
||||
|
||||
// Then store the token securely
|
||||
await this.storeSecret("authToken", token)
|
||||
// Store the custom token for future re-authentication
|
||||
await this.storeSecret("authToken", customToken)
|
||||
await this.storeSecret("clineApiKey", apiKey)
|
||||
|
||||
// Sign in with Firebase using the custom token
|
||||
await this.authManager.signInWithCustomToken(customToken)
|
||||
|
||||
const clineProvider: ApiProvider = "cline"
|
||||
await this.updateGlobalState("apiProvider", clineProvider)
|
||||
|
||||
// Update API configuration with the new provider and auth token
|
||||
// Update API configuration with the new provider and API key
|
||||
const { apiConfiguration } = await this.getState()
|
||||
const updatedConfig = {
|
||||
...apiConfiguration,
|
||||
apiProvider: clineProvider,
|
||||
clineApiKey: apiKey,
|
||||
authToken: token,
|
||||
}
|
||||
|
||||
if (this.cline) {
|
||||
@@ -977,6 +976,9 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
||||
} catch (error) {
|
||||
console.error("Failed to handle auth callback:", error)
|
||||
vscode.window.showErrorMessage("Failed to log in to Cline")
|
||||
// Clean up stored tokens on failure
|
||||
await this.storeSecret("authToken", undefined)
|
||||
await this.storeSecret("clineApiKey", undefined)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
import { initializeApp } from "firebase/app"
|
||||
import { Auth, User, getAuth, onAuthStateChanged, signInWithCustomToken, signOut } from "firebase/auth"
|
||||
import {
|
||||
Auth,
|
||||
User,
|
||||
browserLocalPersistence,
|
||||
getAuth,
|
||||
onAuthStateChanged,
|
||||
setPersistence,
|
||||
signInWithCustomToken,
|
||||
signOut,
|
||||
} from "firebase/auth"
|
||||
import * as vscode from "vscode"
|
||||
import { ClineProvider } from "../../core/webview/ClineProvider"
|
||||
import { firebaseConfig } from "./config"
|
||||
@@ -22,6 +31,15 @@ export class FirebaseAuthManager {
|
||||
this.auth = getAuth(app)
|
||||
console.log("Firebase app initialized", { appConfig: firebaseConfig })
|
||||
|
||||
// Set persistence to LOCAL to maintain auth state across sessions
|
||||
setPersistence(this.auth, browserLocalPersistence)
|
||||
.then(() => {
|
||||
console.log("Firebase persistence set to LOCAL")
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error setting persistence:", error)
|
||||
})
|
||||
|
||||
// Auth state listener
|
||||
onAuthStateChanged(this.auth, this.handleAuthStateChange.bind(this))
|
||||
console.log("Auth state change listener added")
|
||||
@@ -38,22 +56,46 @@ export class FirebaseAuthManager {
|
||||
return
|
||||
}
|
||||
|
||||
// Check if we already have an active user session from Firebase's persistence
|
||||
const currentUser = this.auth.currentUser
|
||||
if (currentUser) {
|
||||
console.log("Found existing Firebase session")
|
||||
await provider.setUserInfo({
|
||||
displayName: currentUser.displayName,
|
||||
email: currentUser.email,
|
||||
photoURL: currentUser.photoURL,
|
||||
})
|
||||
console.log("Existing session restored")
|
||||
return
|
||||
}
|
||||
|
||||
// If no active session, try to sign in with stored custom token
|
||||
const storedToken = await provider.getSecret("authToken")
|
||||
if (storedToken) {
|
||||
console.log("Found stored auth token, attempting to restore session")
|
||||
console.log("Found stored custom token, attempting to restore session")
|
||||
try {
|
||||
await this.signInWithCustomToken(storedToken)
|
||||
console.log("Session restored successfully")
|
||||
console.log("Session restored successfully with custom token")
|
||||
} catch (error) {
|
||||
console.error("Failed to restore session, clearing token:", error)
|
||||
console.error("Failed to restore session with custom token:", error)
|
||||
await provider.setAuthToken(undefined)
|
||||
await provider.setUserInfo(undefined)
|
||||
// Attempt to sign out to ensure clean state
|
||||
try {
|
||||
await this.signOut()
|
||||
} catch (signOutError) {
|
||||
console.error("Error during cleanup after failed session restore:", signOutError)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.log("No stored auth token found")
|
||||
console.log("No stored custom token found")
|
||||
}
|
||||
}
|
||||
|
||||
getCurrentUser(): User | null {
|
||||
return this.auth.currentUser
|
||||
}
|
||||
|
||||
private async handleAuthStateChange(user: User | null) {
|
||||
console.log("Auth state changed", { user })
|
||||
const provider = this.providerRef.deref()
|
||||
@@ -64,8 +106,6 @@ export class FirebaseAuthManager {
|
||||
|
||||
if (user) {
|
||||
console.log("User signed in", { userId: user.uid })
|
||||
const idToken = await user.getIdToken()
|
||||
await provider.setAuthToken(idToken)
|
||||
// Store public user info in state
|
||||
await provider.setUserInfo({
|
||||
displayName: user.displayName,
|
||||
|
||||
@@ -5,7 +5,7 @@ import { validateApiConfiguration, validateModelId } from "../../utils/validate"
|
||||
import { vscode } from "../../utils/vscode"
|
||||
import ApiOptions from "./ApiOptions"
|
||||
import SettingsButton from "../common/SettingsButton"
|
||||
const IS_DEV = false // FIXME: use flags when packaging
|
||||
const IS_DEV = true // FIXME: use flags when packaging
|
||||
|
||||
type SettingsViewProps = {
|
||||
onDone: () => void
|
||||
|
||||
Reference in New Issue
Block a user