From 349ebd756210c210ce39e06204dd22e4e9990b81 Mon Sep 17 00:00:00 2001 From: Turbootzz Date: Fri, 24 Oct 2025 13:45:17 +0200 Subject: [PATCH] solved issues --- .env.example | 3 ++- cmd/api/main.go | 8 +++++++- internal/vaultwarden/auth.go | 9 ++++++--- internal/vaultwarden/client_cli.go | 15 +++++++++++---- 4 files changed, 26 insertions(+), 9 deletions(-) diff --git a/.env.example b/.env.example index 1bbcc4e..807ff4d 100644 --- a/.env.example +++ b/.env.example @@ -1,11 +1,12 @@ # Server Configuration API_PORT=8080 -ENVIRONMENT=production # IMPORTANT: Set to 'production' in production! +ENVIRONMENT=development # IMPORTANT: Change to 'production' for production deployments! # Security - REQUIRED API_KEY=CHANGE-THIS-USE-32-CHARS-MINIMUM!! # CORS Configuration +# IMPORTANT: Update this for production deployments CORS_ALLOWED_ORIGINS=http://localhost:3000 # Vaultwarden Configuration - REQUIRED diff --git a/cmd/api/main.go b/cmd/api/main.go index fdd9d46..74ed204 100644 --- a/cmd/api/main.go +++ b/cmd/api/main.go @@ -30,10 +30,16 @@ func main() { // Initialize Vaultwarden client var vaultClient *vaultwarden.Client - if cfg.VaultwardenClientID != "" && cfg.VaultwardenSecret != "" { + if cfg.VaultwardenClientID != "" || cfg.VaultwardenSecret != "" { + if cfg.VaultwardenClientID == "" || cfg.VaultwardenSecret == "" { + logger.Error.Fatal("Both VaultwardenClientID and VaultwardenSecret must be provided for API key authentication") + } logger.Info.Println("Using API key authentication (recommended)") vaultClient = vaultwarden.NewClientWithAuth(cfg.VaultwardenURL, cfg.VaultwardenClientID, cfg.VaultwardenSecret, cfg.CacheTTL) } else { + if cfg.VaultwardenToken == "" { + logger.Error.Fatal("VaultwardenToken must be provided for legacy session token authentication") + } logger.Warn.Println("Using session token authentication (legacy - token will expire!)") vaultClient = vaultwarden.NewClient(cfg.VaultwardenURL, cfg.VaultwardenToken, cfg.CacheTTL) } diff --git a/internal/vaultwarden/auth.go b/internal/vaultwarden/auth.go index 44fb541..3ac04f5 100644 --- a/internal/vaultwarden/auth.go +++ b/internal/vaultwarden/auth.go @@ -120,10 +120,13 @@ func (am *AuthManager) refreshAccessToken() (string, error) { return "", fmt.Errorf("failed to decode token response: %w", err) } - // Store the token am.accessToken = tokenResp.AccessToken - // Refresh 5 minutes before expiry to avoid edge cases - am.tokenExpiry = time.Now().Add(time.Duration(tokenResp.ExpiresIn-300) * time.Second) + + expiryBuffer := 300 + if tokenResp.ExpiresIn < expiryBuffer { + expiryBuffer = tokenResp.ExpiresIn / 2 + } + am.tokenExpiry = time.Now().Add(time.Duration(tokenResp.ExpiresIn-expiryBuffer) * time.Second) logger.Info.Printf("Successfully obtained access token (expires in %d seconds)", tokenResp.ExpiresIn) diff --git a/internal/vaultwarden/client_cli.go b/internal/vaultwarden/client_cli.go index ba21bff..dd50060 100644 --- a/internal/vaultwarden/client_cli.go +++ b/internal/vaultwarden/client_cli.go @@ -3,6 +3,7 @@ package vaultwarden import ( "encoding/json" "fmt" + "os" "os/exec" "strings" @@ -38,13 +39,15 @@ func (c *Client) FetchSecretViaCLI(name string) (string, error) { } } - cmd := exec.Command("bw", "get", "item", name, "--session", c.token) + cmd := exec.Command("bw", "get", "item", name) + cmd.Env = append(os.Environ(), fmt.Sprintf("BW_SESSION=%s", c.token)) output, err := cmd.Output() if err != nil { logger.Info.Printf("Exact match failed, searching for: %s", name) - searchCmd := exec.Command("bw", "list", "items", "--search", name, "--session", c.token) + searchCmd := exec.Command("bw", "list", "items", "--search", name) + searchCmd.Env = append(os.Environ(), fmt.Sprintf("BW_SESSION=%s", c.token)) searchOutput, searchErr := searchCmd.Output() if searchErr != nil { return "", fmt.Errorf("failed to search for item: %w", searchErr) @@ -59,7 +62,10 @@ func (c *Client) FetchSecretViaCLI(name string) (string, error) { return "", fmt.Errorf("secret not found: %s", name) } - // Use the first matching item + if len(items) > 1 { + logger.Warn.Printf("Multiple items found for '%s', using first match: '%s' (ID: %s)", name, items[0].Name, items[0].ID) + } + output, err = json.Marshal(items[0]) if err != nil { return "", fmt.Errorf("failed to marshal item: %w", err) @@ -98,7 +104,8 @@ func (c *Client) extractValueFromItem(item BitwardenItem) (string, error) { } func (c *Client) SyncVault() error { - cmd := exec.Command("bw", "sync", "--session", c.token) + cmd := exec.Command("bw", "sync") + cmd.Env = append(os.Environ(), fmt.Sprintf("BW_SESSION=%s", c.token)) output, err := cmd.CombinedOutput() if err != nil { return fmt.Errorf("failed to sync vault: %w, output: %s", err, output)