From bd13b966d0d4279758985f99897cfdfb9a9ca35d Mon Sep 17 00:00:00 2001 From: rcourtman Date: Tue, 21 Oct 2025 11:38:23 +0000 Subject: [PATCH] feat: complete API token export/import with version handling Complete the API token export/import feature with proper version handling and backward compatibility: - Bump export format to version 4.1 to indicate API token support - Import API tokens when loading v4.1 exports - Handle version compatibility gracefully: - v4.1: Full support including API tokens - v4.0: Notice that tokens weren't included (backward compatible) - Other: Warning but best-effort import - Initialize empty array instead of nil for cleaner JSON This ensures API tokens are properly preserved when migrating or restoring Pulse instances while maintaining backward compatibility with older exports. --- internal/config/export.go | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/internal/config/export.go b/internal/config/export.go index e855195..0e74b35 100644 --- a/internal/config/export.go +++ b/internal/config/export.go @@ -84,8 +84,8 @@ func (c *ConfigPersistence) ExportConfig(passphrase string) (string, error) { if err != nil { return "", fmt.Errorf("failed to load api tokens: %w", err) } - if len(apiTokens) == 0 { - apiTokens = nil + if apiTokens == nil { + apiTokens = []APITokenRecord{} } // Load guest metadata (stored in data directory) @@ -99,7 +99,7 @@ func (c *ConfigPersistence) ExportConfig(passphrase string) (string, error) { // Create export data exportData := ExportData{ - Version: "4.0", + Version: "4.1", ExportedAt: time.Now(), Nodes: *nodes, Alerts: *alertConfig, @@ -153,9 +153,13 @@ func (c *ConfigPersistence) ImportConfig(encryptedData string, passphrase string } // Check version compatibility (warn but don't fail) - if exportData.Version != "4.0" { - // Log warning but continue - future versions might be compatible - fmt.Printf("Warning: Config was exported from version %s, current version is 4.0\n", exportData.Version) + switch exportData.Version { + case "4.1", "": + // current version, nothing to do + case "4.0": + fmt.Printf("Notice: Config was exported from version 4.0. API tokens were not included in that format.\n") + default: + fmt.Printf("Warning: Config was exported from unsupported version %s. Proceeding with best effort.\n", exportData.Version) } // Import all configurations if err := c.SaveNodesConfig(exportData.Nodes.PVEInstances, exportData.Nodes.PBSInstances, exportData.Nodes.PMGInstances); err != nil { @@ -182,6 +186,16 @@ func (c *ConfigPersistence) ImportConfig(encryptedData string, passphrase string return fmt.Errorf("failed to import system settings: %w", err) } + // Import API tokens for newer export formats + if exportData.Version == "4.1" { + if exportData.APITokens == nil { + exportData.APITokens = []APITokenRecord{} + } + if err := c.SaveAPITokens(exportData.APITokens); err != nil { + return fmt.Errorf("failed to import api tokens: %w", err) + } + } + // Import OIDC configuration if exportData.OIDC != nil { if err := c.SaveOIDCConfig(*exportData.OIDC); err != nil {