diff --git a/internal/cli/app.go b/internal/cli/app.go index b964d8b..21a5e1e 100644 --- a/internal/cli/app.go +++ b/internal/cli/app.go @@ -1,10 +1,16 @@ package cli -import "fmt" +import ( + "fmt" -type App struct{} + "email-mcp/internal/secretstore" +) -func NewApp() *App { +type App struct { + store secretstore.Store +} + +func NewApp(_ ...any) *App { return &App{} } diff --git a/internal/secretstore/store.go b/internal/secretstore/store.go new file mode 100644 index 0000000..fd1120a --- /dev/null +++ b/internal/secretstore/store.go @@ -0,0 +1,33 @@ +package secretstore + +import ( + "context" + "fmt" + "strings" +) + +const DefaultAccountKey = "default" + +type Credential struct { + Host string `json:"host"` + Username string `json:"username"` + Password string `json:"password"` +} + +func (c Credential) Validate() error { + if strings.TrimSpace(c.Host) == "" { + return fmt.Errorf("imap host is required") + } + if strings.TrimSpace(c.Username) == "" { + return fmt.Errorf("username is required") + } + if strings.TrimSpace(c.Password) == "" { + return fmt.Errorf("password is required") + } + return nil +} + +type Store interface { + Save(ctx context.Context, key string, cred Credential) error + Load(ctx context.Context, key string) (Credential, error) +} diff --git a/internal/secretstore/store_test.go b/internal/secretstore/store_test.go new file mode 100644 index 0000000..4ac06df --- /dev/null +++ b/internal/secretstore/store_test.go @@ -0,0 +1,11 @@ +package secretstore + +import "testing" + +func TestCredentialValidateRequiresAllFields(t *testing.T) { + cred := Credential{Host: "imap.example.com", Username: "alice"} + + if err := cred.Validate(); err == nil { + t.Fatal("expected validation error when password is missing") + } +}