Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release 0.23.0 #13

Merged
merged 12 commits into from
Mar 10, 2024
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Changelog - Paw

## 0.23.0 - 10 March 2024

- storage: allow to set a storage root with `PAW_HOME` env var
- storage: add mock
- paw,ui: add initial support for item autofill
- paw,ui: add support to subtitle
- ui: improve unlock vault view
- ui: remove unused parameter

## 0.22.2 - 17 February 2024

- sshagent: fix SignWithFlags implementation
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ require (
golang.design/x/clipboard v0.7.0
golang.org/x/crypto v0.18.0
golang.org/x/image v0.15.0
golang.org/x/net v0.17.0
golang.org/x/sync v0.6.0
golang.org/x/term v0.16.0
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce
Expand Down Expand Up @@ -37,7 +38,6 @@ require (
github.com/yuin/goldmark v1.5.5 // indirect
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6 // indirect
golang.org/x/mobile v0.0.0-20230531173138-3c911d8e3eda // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/sys v0.16.0 // indirect
golang.org/x/text v0.14.0 // indirect
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
Expand Down
2 changes: 1 addition & 1 deletion internal/agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func (t Type) IsZero() bool {

const (
// CLI represents the agent started in CLI mode
CLI Type = "CLI"
CLI = "CLI"
// GUI represents the agent started in GUI mode
GUI = "GUI"
)
Expand Down
2 changes: 1 addition & 1 deletion internal/agent/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func Test_Client(t *testing.T) {
t.Run("interface", func(t *testing.T) {
at, err := client.Type()
require.NoError(t, err)
require.Equal(t, agent.CLI, at)
require.EqualValues(t, agent.CLI, at)

sid, err := client.Unlock(t.Name(), key, 0)
require.NoError(t, err)
Expand Down
20 changes: 3 additions & 17 deletions internal/cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,7 @@ import (
"lucor.dev/paw/internal/paw"
)

const (
sessionEnvName = "PAW_SESSION"
)

func New(s paw.Storage) {
func New(s paw.Storage) (Cmd, error) {

// Define the command to use
commands := []Cmd{
Expand Down Expand Up @@ -67,17 +63,7 @@ func New(s paw.Storage) {
// It will display the command usage if -help is specified
// and will exit in case of error
err := cmd.Parse(os.Args[3:])
if err != nil {
fmt.Fprintf(os.Stderr, "[✗] %s\n", err)
os.Exit(1)
}

// Finally run the command
err = cmd.Run(s)
if err != nil {
fmt.Fprintf(os.Stderr, "[✗] %s\n", err)
os.Exit(1)
}
return cmd, err
}

// Cmd wraps the methods for a paw cli command
Expand Down Expand Up @@ -311,7 +297,7 @@ func parseItemPath(path string, opts itemPathOptions) (itemPath, error) {
// it will use a session from the PAW_SESSION env variable if set,
// otherwise will ask for the vault's password
func loadVaultKey(s paw.Storage, vaultName string) (*paw.Key, error) {
sessionID := os.Getenv(sessionEnvName)
sessionID := os.Getenv(paw.ENV_SESSION)
if sessionID != "" {
key, err := loadVaultKeyWithSession(s, vaultName, sessionID)
if err == nil {
Expand Down
2 changes: 1 addition & 1 deletion internal/cli/cmd_lock.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ func (cmd *LockCmd) Run(s paw.Storage) error {
}

func (cmd *LockCmd) removeSSHKeysFromAgent(c agent.PawAgent, s paw.Storage) error {
os.Setenv(sessionEnvName, "")
os.Setenv(paw.ENV_SESSION, "")
key, err := loadVaultKey(s, cmd.vaultName)
if err != nil {
return err
Expand Down
4 changes: 3 additions & 1 deletion internal/cli/flag.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (
"fmt"
"io"
"os"

"lucor.dev/paw/internal/paw"
)

var flagSet = flag.NewFlagSet("paw", flag.ContinueOnError)
Expand Down Expand Up @@ -40,7 +42,7 @@ func newCommonFlags(o flagOpts) (*CommonFlags, error) {
// SetEnv sets the env variables according to the flag values
func (f *CommonFlags) SetEnv() {
if f.SessionID != "" {
os.Setenv(sessionEnvName, f.SessionID)
os.Setenv(paw.ENV_SESSION, f.SessionID)
}
}

Expand Down
23 changes: 23 additions & 0 deletions internal/paw/autofill.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package paw

import "net/url"

type MatchTypeAutofill int

const (
// DisabledAutofill disable the autofill feature
DisabledAutofill MatchTypeAutofill = 0
// ExactMatchAutofill match the exact URL along with the path (i.e. https://www.example.com/login but not https://www.example.com/login/1)
ExactMatchAutofill MatchTypeAutofill = 2
// DomainMatchAutofill match the domain only (i.e. https://example.com and https://example.com/login)
DomainMatchAutofill MatchTypeAutofill = 4
// SubdomainMatchAutofill match the subdomain only (i.e. https://www.example.com/login or https://www.example.com/auth but not https://dev.example.com/login)
SubdomainMatchAutofill MatchTypeAutofill = 8
)

type Autofill struct {
*url.URL `json:"url,omitempty"`
AllowHTTP bool `json:"allow_http,omitempty"`
MatchType MatchTypeAutofill `json:"match_type,omitempty"`
TLDPlusOne string `json:"tld_plus_one,omitempty"`
}
6 changes: 6 additions & 0 deletions internal/paw/env.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package paw

const (
ENV_HOME = "PAW_HOME" // The env var name can be used to override the Paw HOME directory
ENV_SESSION = "PAW_SESSION" // The env var name can be used to specify a Paw session ID
)
7 changes: 7 additions & 0 deletions internal/paw/item_login.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (

// Declare conformity to Item interface
var _ Item = (*Login)(nil)
var _ MetadataSubtitler = (*Login)(nil)

type Login struct {
*Password `json:"password,omitempty"`
Expand All @@ -22,13 +23,19 @@ type Login struct {
URL string `json:"url,omitempty"`
}

// Subtitle implements MetadataSubtitler.
func (l *Login) Subtitle() string {
return l.Username
}

func NewLogin() *Login {
now := time.Now()
return &Login{
Metadata: &Metadata{
Type: LoginItemType,
Created: now,
Modified: now,
Autofill: &Autofill{},
},
Note: &Note{},
Password: &Password{},
Expand Down
11 changes: 10 additions & 1 deletion internal/paw/item_metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,17 @@ import (
"golang.org/x/crypto/blake2b"
)

// MetadataSubtitler is the interface to implement to provide a subtitle to an item
type MetadataSubtitler interface {
Subtitle() string
}

// Item represents the basic paw identity
type Metadata struct {
// Title reprents the item name
// Name reprents the item name
Name string `json:"name,omitempty"`
// Subtitle represents the item subtitle
Subtitle string `json:"subtitle,omitempty"`
// Type represents the item type
Type ItemType `json:"type,omitempty"`
// Modified holds the modification date
Expand All @@ -24,6 +31,8 @@ type Metadata struct {
Created time.Time `json:"created,omitempty"`
// Icon
Favicon *Favicon `json:"favicon,omitempty"`
// Autofill
Autofill *Autofill `json:"autofill,omitempty"`
}

func (m *Metadata) ID() string {
Expand Down
5 changes: 5 additions & 0 deletions internal/paw/item_ssh_key.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ type SSHKey struct {
PublicKey string `json:"public_key,omitempty"`
}

// Subtitle implements MetadataSubtitler.
func (i *SSHKey) Subtitle() string {
return i.Comment
}

func NewSSHKey() *SSHKey {
now := time.Now()
return &SSHKey{
Expand Down
10 changes: 10 additions & 0 deletions internal/paw/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const (
keyFileName = "key.age"
vaultFileName = "vault.age"
lockFileName = "paw.lock"
logFileName = "paw.log"
socketFileName = "agent.sock"
namedPipe = `\\.\pipe\paw`
)
Expand All @@ -28,6 +29,7 @@ type Storage interface {
ConfigStorage
VaultStorage
ItemStorage
LogStorage
SocketAgentPath() string
LockFilePath() string
}
Expand Down Expand Up @@ -63,6 +65,10 @@ type ItemStorage interface {
StoreItem(vault *Vault, item Item) error
}

type LogStorage interface {
LogFilePath() string
}

func storageRootPath(s Storage) string {
return filepath.Join(s.Root(), storageRootName)
}
Expand Down Expand Up @@ -99,6 +105,10 @@ func lockFilePath(s Storage) string {
return filepath.Join(s.Root(), lockFileName)
}

func logFilePath(s Storage) string {
return filepath.Join(s.Root(), logFileName)
}

func encrypt(key *Key, w io.Writer, v interface{}) error {
encWriter, err := key.Encrypt(w)
if err != nil {
Expand Down
5 changes: 5 additions & 0 deletions internal/paw/storage_fyne.go
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,11 @@ func (s *FyneStorage) LockFilePath() string {
return lockFilePath(s)
}

// LogFilePath return the log file path
func (s *FyneStorage) LogFilePath() string {
return logFilePath(s)
}

func (s *FyneStorage) isExist(path string) bool {
ok, _ := storage.Exists(storage.NewFileURI(path))
return ok
Expand Down
Loading
Loading