diff --git a/agent/bitwarden/sync.go b/agent/bitwarden/sync.go index 33da748..bbe1a15 100644 --- a/agent/bitwarden/sync.go +++ b/agent/bitwarden/sync.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" "os" + "time" "github.com/quexten/goldwarden/agent/bitwarden/crypto" "github.com/quexten/goldwarden/agent/bitwarden/models" @@ -43,6 +44,7 @@ func DoFullSync(ctx context.Context, vault *vault.Vault, config *config.Config, return err } } else { + vault.SetLastSynced(time.Now().Unix()) log.Info("Sync successful, initializing keyring and vault...") } diff --git a/agent/bitwarden/websocket.go b/agent/bitwarden/websocket.go index 5330a01..118fbad 100644 --- a/agent/bitwarden/websocket.go +++ b/agent/bitwarden/websocket.go @@ -88,6 +88,7 @@ func connectToWebsocket(ctx context.Context, vault *vault.Vault, cfg *config.Con defer c.Close() websocketLog.Info("Connected to websocket server...") + vault.SetWebsocketConnected(true) done := make(chan struct{}) //handshake required for official bitwarden implementation @@ -101,7 +102,7 @@ func connectToWebsocket(ctx context.Context, vault *vault.Vault, cfg *config.Con websocketLog.Error("Error reading websocket message %s", err) return } - if len(message) < 3 { + if len(message) < 5 { //ignore empty messages continue } @@ -146,6 +147,8 @@ func connectToWebsocket(ctx context.Context, vault *vault.Vault, cfg *config.Con } else { vault.AddOrUpdateLogin(cipher) } + vault.SetLastSynced(time.Now().Unix()) + break case SyncCipherCreate: websocketLog.Warn("Create requested for cipher " + cipherid) @@ -166,6 +169,7 @@ func connectToWebsocket(ctx context.Context, vault *vault.Vault, cfg *config.Con } else { vault.AddOrUpdateLogin(cipher) } + vault.SetLastSynced(time.Now().Unix()) break case SyncSendCreate, SyncSendUpdate, SyncSendDelete: @@ -219,6 +223,7 @@ func connectToWebsocket(ctx context.Context, vault *vault.Vault, cfg *config.Con }() <-done + vault.SetWebsocketConnected(false) return nil } diff --git a/agent/vault/vault.go b/agent/vault/vault.go index 8431865..bf34515 100644 --- a/agent/vault/vault.go +++ b/agent/vault/vault.go @@ -14,21 +14,25 @@ import ( var vaultLog = logging.GetLogger("Goldwarden", "Vault") type Vault struct { - Keyring *crypto.Keyring - logins map[string]models.Cipher - secureNotes map[string]models.Cipher - sshKeyNoteIDs []string - envCredentials map[string]string - mu sync.Mutex + Keyring *crypto.Keyring + logins map[string]models.Cipher + secureNotes map[string]models.Cipher + sshKeyNoteIDs []string + envCredentials map[string]string + lastSynced int64 + websockedConnected bool + mu sync.Mutex } func NewVault(keyring *crypto.Keyring) *Vault { return &Vault{ - Keyring: keyring, - logins: make(map[string]models.Cipher), - secureNotes: make(map[string]models.Cipher), - sshKeyNoteIDs: make([]string, 0), - envCredentials: make(map[string]string), + Keyring: keyring, + logins: make(map[string]models.Cipher), + secureNotes: make(map[string]models.Cipher), + sshKeyNoteIDs: make([]string, 0), + envCredentials: make(map[string]string), + lastSynced: 0, + websockedConnected: false, } } @@ -403,3 +407,29 @@ func (vault *Vault) GetSecureNote(uuid string) (models.Cipher, error) { return models.Cipher{}, errors.New("cipher not found") } + +func (vault *Vault) SetLastSynced(lastSynced int64) { + vault.lockMutex() + vault.lastSynced = lastSynced + vault.unlockMutex() +} + +func (vault *Vault) GetLastSynced() int64 { + vault.lockMutex() + defer vault.unlockMutex() + + return vault.lastSynced +} + +func (vault *Vault) SetWebsocketConnected(connected bool) { + vault.lockMutex() + vault.websockedConnected = connected + vault.unlockMutex() +} + +func (vault *Vault) IsWebsocketConnected() bool { + vault.lockMutex() + defer vault.unlockMutex() + + return vault.websockedConnected +} diff --git a/cmd/vault.go b/cmd/vault.go index 2668ede..e207599 100644 --- a/cmd/vault.go +++ b/cmd/vault.go @@ -2,6 +2,7 @@ package cmd import ( "fmt" + "time" "github.com/quexten/goldwarden/ipc/messages" "github.com/spf13/cobra" @@ -110,7 +111,9 @@ var statusCmd = &cobra.Command{ fmt.Println("{") fmt.Println(" \"locked\":", status.Locked, ",") fmt.Println(" \"loginEntries\":", status.NumberOfLogins, ",") - fmt.Println(" \"noteEntries\":", status.NumberOfNotes) + fmt.Println(" \"noteEntries\":", status.NumberOfNotes, ",") + fmt.Println(" \"lastSynced\": \"" + time.Unix(status.LastSynced, 0).String() + "\",") + fmt.Println(" \"websocketConnected\":", status.WebsockedConnected) fmt.Println("}") default: println("Wrong response type") diff --git a/ipc/messages/vault.go b/ipc/messages/vault.go index dff39a6..9a38f6f 100644 --- a/ipc/messages/vault.go +++ b/ipc/messages/vault.go @@ -21,11 +21,11 @@ type VaultStatusRequest struct { } type VaultStatusResponse struct { - Locked bool - NumberOfLogins int - NumberOfNotes int - // todo websocket status - // todo last synced + Locked bool + NumberOfLogins int + NumberOfNotes int + LastSynced int64 + WebsockedConnected bool } func init() {