🐛 fix(web): 补齐浏览器端连接导入导出

This commit is contained in:
Syngnat
2026-07-10 20:57:44 +08:00
parent 689467ec91
commit 69be54c1cf
9 changed files with 230 additions and 28 deletions

View File

@@ -149,6 +149,35 @@ func TestBuildExportedConnectionPackageWithoutSecretsUsesV2AppManagedAndImportsW
}
}
func TestExportConnectionsPayloadReturnsBrowserDownloadContent(t *testing.T) {
app := NewAppWithSecretStore(newFakeAppSecretStore())
app.configDir = t.TempDir()
saveConnectionForPackageExport(t, app, "conn-browser-export", "browser-secret")
result := app.ExportConnectionsPayload(ConnectionExportOptions{IncludeSecrets: false})
if !result.Success {
t.Fatalf("ExportConnectionsPayload returned failure: %+v", result)
}
raw, ok := result.Data.(string)
if !ok || strings.TrimSpace(raw) == "" {
t.Fatalf("expected browser download content, got %#v", result.Data)
}
if !isConnectionPackageV2AppManaged(raw) {
t.Fatalf("expected app-managed connection package, got %s", raw)
}
importApp := NewAppWithSecretStore(newFakeAppSecretStore())
importApp.configDir = t.TempDir()
imported, err := importApp.ImportConnectionsPayload(raw, "")
if err != nil {
t.Fatalf("ImportConnectionsPayload returned error: %v", err)
}
if len(imported.Connections) != 1 || imported.Connections[0].ID != "conn-browser-export" {
t.Fatalf("expected exported browser content to restore the connection, got %#v", imported.Connections)
}
}
func TestImportConnectionPackagePayloadOverwritesExistingSecrets(t *testing.T) {
app := NewAppWithSecretStore(newFakeAppSecretStore())
app.configDir = t.TempDir()

View File

@@ -1800,6 +1800,23 @@ func (a *App) ExportConnectionsPackage(options ConnectionExportOptions) connecti
return connection.QueryResult{Success: true, Message: a.appText("file.backend.message.export_completed", nil)}
}
// ExportConnectionsPayload builds a recovery package for browser clients. The browser is
// responsible for saving it locally because a Web Server process cannot open its file dialog.
func (a *App) ExportConnectionsPayload(options ConnectionExportOptions) connection.QueryResult {
content, err := a.buildExportedConnectionPackage(options)
if err != nil {
return connection.QueryResult{Success: false, Message: localizedConnectionPackageExportMessage(a.appText, err)}
}
if len(content) > connectionImportMaxFileBytes {
return connection.QueryResult{Success: false, Message: localizedConnectionPackageExportMessage(a.appText, errConnectionImportFileTooLarge)}
}
return connection.QueryResult{
Success: true,
Message: a.appText("file.backend.message.export_completed", nil),
Data: string(content),
}
}
func normalizeConnectionPackageExportFilename(filename string) string {
trimmed := strings.TrimSpace(filename)
if trimmed == "" {