Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -1947,6 +1947,22 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { //nolint:gocyclo
m.showErrorNotif = false
return m, nil

case tui.InfoNotifyMsg:
dur := time.Duration(msg.Duration * float64(time.Second))
if dur <= 0 {
dur = 2 * time.Second
}
col := max(0, m.width-44)
m.errorNotification = overlay.NewInfo(
overlay.WithMessage(msg.Message),
overlay.WithKey(config.Keybinds.Global.DismissNotification),
overlay.WithPosition(0, col),
overlay.WithDismissMode(overlay.DismissAfterTimer),
overlay.WithDuration(dur),
)
m.showErrorNotif = true
return m, tea.Tick(dur, func(time.Time) tea.Msg { return clearErrorNotifMsg{} })

case tui.NotifyMsg:
return m, m.showErrorCmd(msg.Message)

Expand Down
4 changes: 4 additions & 0 deletions config/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,10 @@ type Draft struct {
InReplyTo string `json:"in_reply_to,omitempty"`
References []string `json:"references,omitempty"`
QuotedText string `json:"quoted_text,omitempty"`
SignSMIME bool `json:"sign_smime,omitempty"`
EncryptSMIME bool `json:"encrypt_smime,omitempty"`
SignPGP bool `json:"sign_pgp,omitempty"`
EncryptPGP bool `json:"encrypt_pgp,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
Expand Down
1 change: 1 addition & 0 deletions i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"attachments_none": "None",
"enter_to_add": "Enter to add",
"encrypt_smime": "Encrypt Email (S/MIME)",
"sign_smime": "Sign Email (S/MIME)",
"sign_pgp": "Sign Email (PGP)",
"encrypt_pgp": "Encrypt Email (PGP)",
"send": "Send",
Expand Down
65 changes: 65 additions & 0 deletions pgp/setup.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package pgp

import (
"os"
"path/filepath"
"strings"

"github.com/floatpane/matcha/config"
)

// HasSMIMESetup reports whether the account has S/MIME signing configured.
func HasSMIMESetup(acc *config.Account) bool {
return acc != nil && acc.SMIMECert != "" && acc.SMIMEKey != ""
}

// HasSMIMECertForRecipient reports whether a usable S/MIME certificate exists
// for the given recipient. For the account's own address it checks the
// configured S/MIME certificate; otherwise it looks in the certs directory.
func HasSMIMECertForRecipient(recipient string, acc *config.Account) bool {
if acc == nil {
return false
}
email := strings.ToLower(strings.TrimSpace(recipient))
if email == "" {
return false
}
if strings.EqualFold(email, acc.Email) && acc.SMIMECert != "" {
return true
}
cfgDir, err := config.GetConfigDir()
if err != nil {
return false
}
certPath := filepath.Join(cfgDir, "certs", email+".pem")
if _, err := os.Stat(certPath); err == nil {
return true
}
return false
}

// HasPGPSetup reports whether the account has PGP configured (file-based or
// YubiKey hardware key).
func HasPGPSetup(acc *config.Account) bool {
return acc != nil && (acc.PGPKeySource != "" || acc.PGPPublicKey != "")
}

// HasLocalKeyForRecipient reports whether a public key file for the recipient
// exists in the configured PGP directory.
func HasLocalKeyForRecipient(recipient string) (bool, error) {
email := strings.ToLower(strings.TrimSpace(recipient))
if email == "" {
return false, nil
}
cfgDir, err := config.GetConfigDir()
if err != nil {
return false, err
}
pgpDir := filepath.Join(cfgDir, "pgp")
for _, ext := range []string{".asc", ".gpg", ".pem"} {
if _, err := os.Stat(filepath.Join(pgpDir, email+ext)); err == nil {
return true, nil
}
}
return false, nil
}
Loading
Loading