fix(client): Prevent overwriting auth file on update

This commit is contained in:
hkfires
2025-09-18 22:43:33 +08:00
parent d9f8129a32
commit f17ec7ffd8
4 changed files with 33 additions and 17 deletions

View File

@@ -61,25 +61,31 @@ type GeminiWebClient struct {
modelsRegistered bool modelsRegistered bool
} }
func (c *GeminiWebClient) UnregisterClient() { c.unregisterClient(false) } func (c *GeminiWebClient) UnregisterClient() { c.unregisterClient(interfaces.UnregisterReasonReload) }
// UnregisterClientWithReason allows the watcher to avoid recreating deleted auth files. // UnregisterClientWithReason allows the watcher to avoid recreating deleted auth files.
func (c *GeminiWebClient) UnregisterClientWithReason(reason interfaces.UnregisterReason) { func (c *GeminiWebClient) UnregisterClientWithReason(reason interfaces.UnregisterReason) {
skipPersist := reason == interfaces.UnregisterReasonAuthFileRemoved c.unregisterClient(reason)
c.unregisterClient(skipPersist)
} }
func (c *GeminiWebClient) unregisterClient(skipPersist bool) { func (c *GeminiWebClient) unregisterClient(reason interfaces.UnregisterReason) {
if c.cookiePersistCancel != nil { if c.cookiePersistCancel != nil {
c.cookiePersistCancel() c.cookiePersistCancel()
c.cookiePersistCancel = nil c.cookiePersistCancel = nil
} }
if skipPersist { switch reason {
case interfaces.UnregisterReasonAuthFileRemoved:
if c.snapshotManager != nil && c.tokenFilePath != "" { if c.snapshotManager != nil && c.tokenFilePath != "" {
log.Debugf("skipping Gemini Web snapshot flush because auth file is missing: %s", filepath.Base(c.tokenFilePath)) log.Debugf("skipping Gemini Web snapshot flush because auth file is missing: %s", filepath.Base(c.tokenFilePath))
util.RemoveCookieSnapshots(c.tokenFilePath) util.RemoveCookieSnapshots(c.tokenFilePath)
} }
} else { case interfaces.UnregisterReasonAuthFileUpdated:
if c.snapshotManager != nil {
if err := c.snapshotManager.Persist(); err != nil {
log.Errorf("Failed to persist Gemini Web cookies for %s: %v", filepath.Base(c.tokenFilePath), err)
}
}
default:
// Flush cookie snapshot to main token file and remove snapshot // Flush cookie snapshot to main token file and remove snapshot
c.flushCookieSnapshotToMain() c.flushCookieSnapshotToMain()
} }

View File

@@ -507,26 +507,34 @@ func (c *QwenClient) SetUnavailable() {
} }
// UnregisterClient flushes cookie snapshot back into the main token file. // UnregisterClient flushes cookie snapshot back into the main token file.
func (c *QwenClient) UnregisterClient() { c.unregisterClient(false) } func (c *QwenClient) UnregisterClient() { c.unregisterClient(interfaces.UnregisterReasonReload) }
// UnregisterClientWithReason allows the watcher to skip persistence when the auth file is removed. // UnregisterClientWithReason allows the watcher to adjust persistence behaviour.
func (c *QwenClient) UnregisterClientWithReason(reason interfaces.UnregisterReason) { func (c *QwenClient) UnregisterClientWithReason(reason interfaces.UnregisterReason) {
skipPersist := reason == interfaces.UnregisterReasonAuthFileRemoved c.unregisterClient(reason)
c.unregisterClient(skipPersist)
} }
func (c *QwenClient) unregisterClient(skipPersist bool) { func (c *QwenClient) unregisterClient(reason interfaces.UnregisterReason) {
if c.snapshotManager == nil { if c.snapshotManager == nil {
return return
} }
if skipPersist { switch reason {
case interfaces.UnregisterReasonAuthFileRemoved:
if c.tokenFilePath != "" { if c.tokenFilePath != "" {
log.Debugf("skipping Qwen snapshot flush because auth file is missing: %s", filepath.Base(c.tokenFilePath)) log.Debugf("skipping Qwen snapshot flush because auth file is missing: %s", filepath.Base(c.tokenFilePath))
util.RemoveCookieSnapshots(c.tokenFilePath) util.RemoveCookieSnapshots(c.tokenFilePath)
} }
return case interfaces.UnregisterReasonAuthFileUpdated:
} if err := c.snapshotManager.Persist(); err != nil {
if err := c.snapshotManager.Flush(); err != nil { log.Errorf("Failed to persist Qwen cookies for %s: %v", filepath.Base(c.tokenFilePath), err)
log.Errorf("Failed to flush Qwen cookie snapshot to main for %s: %v", filepath.Base(c.tokenFilePath), err) }
case interfaces.UnregisterReasonShutdown, interfaces.UnregisterReasonReload:
if err := c.snapshotManager.Flush(); err != nil {
log.Errorf("Failed to flush Qwen cookie snapshot to main for %s: %v", filepath.Base(c.tokenFilePath), err)
}
default:
if err := c.snapshotManager.Flush(); err != nil {
log.Errorf("Failed to flush Qwen cookie snapshot to main for %s: %v", filepath.Base(c.tokenFilePath), err)
}
} }
} }

View File

@@ -72,4 +72,6 @@ const (
UnregisterReasonShutdown UnregisterReason = "shutdown" UnregisterReasonShutdown UnregisterReason = "shutdown"
// UnregisterReasonAuthFileRemoved indicates the underlying auth file was deleted. // UnregisterReasonAuthFileRemoved indicates the underlying auth file was deleted.
UnregisterReasonAuthFileRemoved UnregisterReason = "auth-file-removed" UnregisterReasonAuthFileRemoved UnregisterReason = "auth-file-removed"
// UnregisterReasonAuthFileUpdated indicates the auth file content was modified.
UnregisterReasonAuthFileUpdated UnregisterReason = "auth-file-updated"
) )

View File

@@ -465,7 +465,7 @@ func (w *Watcher) addOrUpdateClient(path string) {
if _, canUnregister := any(oldClient).(interface{ UnregisterClient() }); canUnregister { if _, canUnregister := any(oldClient).(interface{ UnregisterClient() }); canUnregister {
log.Debugf("unregistering old client for updated file: %s", filepath.Base(path)) log.Debugf("unregistering old client for updated file: %s", filepath.Base(path))
} }
unregisterClientWithReason(oldClient, interfaces.UnregisterReasonReload) unregisterClientWithReason(oldClient, interfaces.UnregisterReasonAuthFileUpdated)
} }
// Create new client (reads the file again internally; this is acceptable as the files are small and it keeps the change minimal) // Create new client (reads the file again internally; this is acceptable as the files are small and it keeps the change minimal)