Compare commits

...

4 Commits

Author SHA1 Message Date
celestial-vault 0519f058a0 fix types and linter errors: 2025-06-20 17:37:05 -07:00
celestial-vault 81edf1f4f7 merge conflicts 2025-06-20 17:33:39 -07:00
Elephant Lumps a5bf6fcb92 changeset 2025-05-26 15:34:33 -07:00
Elephant Lumps 91415c6128 migrate authStateChanges 2025-05-26 15:33:55 -07:00
9 changed files with 77 additions and 25 deletions
+5
View File
@@ -0,0 +1,5 @@
---
"claude-dev": minor
---
Migrate authStateChanged to protobus
+19
View File
@@ -19,4 +19,23 @@ service AccountService {
// Subscribe to auth callback events (when authentication tokens are received)
rpc subscribeToAuthCallback(EmptyRequest) returns (stream String);
// Handles authentication state changes from the Firebase context.
// Updates the user info in global state and returns the updated value.
rpc authStateChanged(AuthStateChangedRequest) returns (AuthStateChanged);
}
message AuthStateChangedRequest {
Metadata metadata = 1;
UserInfo user = 2;
}
message AuthStateChanged {
optional UserInfo user = 1;
}
message UserInfo {
optional string display_name = 1;
optional string email = 2;
optional string photo_url = 3;
}
@@ -0,0 +1,23 @@
import { AuthStateChangedRequest, AuthStateChanged } from "@shared/proto/account"
import type { Controller } from "../index"
import { updateGlobalState } from "../../storage/state"
/**
* Handles authentication state changes from the Firebase context.
* Updates the user info in global state and returns the updated value.
* @param controller The controller instance
* @param request The auth state change request
* @returns The updated user info
*/
export async function authStateChanged(controller: Controller, request: AuthStateChangedRequest): Promise<AuthStateChanged> {
try {
// Store the user info directly in global state
await updateGlobalState(controller.context, "userInfo", request.user)
// Return the same user info
return AuthStateChanged.create({ user: request.user })
} catch (error) {
console.error(`Failed to update auth state: ${error}`)
throw error
}
}
+2 -6
View File
@@ -20,6 +20,7 @@ import { ChatSettings } from "@shared/ChatSettings"
import { ExtensionMessage, ExtensionState, Platform } from "@shared/ExtensionMessage"
import { HistoryItem } from "@shared/HistoryItem"
import { McpMarketplaceCatalog } from "@shared/mcp"
import { UserInfo } from "@shared/UserInfo"
import { TelemetrySetting } from "@shared/TelemetrySetting"
import { WebviewMessage } from "@shared/WebviewMessage"
import { fileExistsAtPath } from "@utils/fs"
@@ -124,7 +125,7 @@ export class Controller {
}
}
async setUserInfo(info?: { displayName: string | null; email: string | null; photoURL: string | null }) {
async setUserInfo(info?: UserInfo) {
await updateGlobalState(this.context, "userInfo", info)
}
@@ -204,11 +205,6 @@ export class Controller {
*/
async handleWebviewMessage(message: WebviewMessage) {
switch (message.type) {
case "authStateChanged":
await this.setUserInfo(message.user || undefined)
await this.postStateToWebview()
break
case "fetchUserCreditsData": {
await this.fetchUserCreditsData()
break
+2 -5
View File
@@ -10,6 +10,7 @@ import { McpServer, McpMarketplaceCatalog, McpDownloadResponse, McpViewTab } fro
import { TelemetrySetting } from "./TelemetrySetting"
import type { BalanceResponse, UsageTransaction, PaymentTransaction } from "../shared/ClineAccount"
import { ClineRulesToggles } from "./cline-rules"
import { UserInfo } from "./UserInfo"
// webview will hold state
export interface ExtensionMessage {
@@ -91,11 +92,7 @@ export interface ExtensionState {
terminalOutputLineLimit: number
defaultTerminalProfile?: string
uriScheme?: string
userInfo?: {
displayName: string | null
email: string | null
photoURL: string | null
}
userInfo?: UserInfo
version: string
distinctId: string
globalClineRulesToggles: ClineRulesToggles
+3 -3
View File
@@ -1,5 +1,5 @@
export interface UserInfo {
displayName: string | null
email: string | null
photoURL: string | null
displayName?: string
email?: string
photoURL?: string
}
-1
View File
@@ -9,7 +9,6 @@ import { McpViewTab } from "./mcp"
export interface WebviewMessage {
type:
| "requestVsCodeLmModels"
| "authStateChanged"
| "fetchMcpMarketplace"
| "searchCommits"
| "telemetrySetting"
@@ -30,6 +30,7 @@ import {
import { McpMarketplaceCatalog, McpServer, McpViewTab } from "../../../src/shared/mcp"
import { convertTextMateToHljs } from "../utils/textMateToHljs"
import { OpenRouterCompatibleModelInfo } from "@shared/proto/models"
import { UserInfo } from "@shared/proto/account"
interface ExtensionStateContextType extends ExtensionState {
didHydrateState: boolean
@@ -81,6 +82,7 @@ interface ExtensionStateContextType extends ExtensionState {
// Refresh functions
refreshOpenRouterModels: () => void
setUserInfo: (userInfo?: UserInfo) => void
// Navigation state setters
setShowMcp: (value: boolean) => void
@@ -835,6 +837,7 @@ export const ExtensionStateContextProvider: React.FC<{
setTotalTasksSize,
refreshOpenRouterModels,
onRelinquishControl,
setUserInfo: (userInfo?: UserInfo) => setState((prevState) => ({ ...prevState, userInfo })),
}
return <ExtensionStateContext.Provider value={contextValue}>{children}</ExtensionStateContext.Provider>
+20 -10
View File
@@ -4,6 +4,8 @@ import { EmptyRequest } from "@shared/proto/common"
import { initializeApp } from "firebase/app"
import { User, getAuth, signInWithCustomToken, signOut } from "firebase/auth"
import React, { createContext, useCallback, useContext, useEffect, useState } from "react"
import { useExtensionState } from "./ExtensionStateContext"
import { AuthStateChanged, AuthStateChangedRequest } from "@shared/proto/account"
// Firebase configuration from extension
const firebaseConfig = {
@@ -28,6 +30,7 @@ const FirebaseAuthContext = createContext<FirebaseAuthContextType | undefined>(u
export const FirebaseAuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
const [user, setUser] = useState<User | null>(null)
const [isInitialized, setIsInitialized] = useState(false)
const { setUserInfo } = useExtensionState()
// Initialize Firebase
const app = initializeApp(firebaseConfig)
@@ -45,16 +48,23 @@ export const FirebaseAuthProvider: React.FC<{ children: React.ReactNode }> = ({
return
}
// Sync auth state with extension
vscode.postMessage({
type: "authStateChanged",
user: user
? {
displayName: user.displayName,
email: user.email,
photoURL: user.photoURL,
}
: null,
})
AccountServiceClient.authStateChanged(
AuthStateChangedRequest.create({
user: user
? {
displayName: user.displayName ?? undefined,
email: user.email ?? undefined,
photoURL: user.photoURL ?? undefined,
}
: undefined,
}),
)
.then((response: AuthStateChanged) => {
setUserInfo(response.user)
})
.catch((error) => {
console.error("Error updating auth state via gRPC:", error)
})
})
return () => unsubscribe()