feat: share env files as encrypted links #54

Merged
keb merged 25 commits from share-files into main 2026-10-13 14:55:22 +02:00
3 changed files with 31 additions and 7 deletions
Showing only changes of commit 5c97a8e249 - Show all commits

No files matched your search

+5
View File
@@ -13,6 +13,10 @@
// version (1) | uvarint length of the header | header (JSON) | age file
//
// The age file holds the files as deflated JSON.
//
// A change to the format gets the next version, and Read keeps reading
// every earlier one: links stay in chat and tickets for years. A
// version it doesn't know is from a newer lazysecrets.
package share
import (
@@ -36,6 +40,7 @@ import (
)
const (
// version is the format's, written first; see the package doc.
version = 1
// MaxLink keeps a link short enough for chat and tickets (Teams takes
// about 28 KB) and for passing it to a terminal window.
+3 -3
View File
@@ -137,13 +137,13 @@ func (m *Model) confirmShare(s sharing) {
})
}
// pickShareKey asks which secret to encrypt with, in Go to.
// pickShareKey asks which secret to encrypt with, in Go to, then shares
// with it.
func (m *Model) pickShareKey(s sharing) tea.Cmd {
cmd := m.openGoTo(tabSearch, true)
m.search.pick = func(m *Model, key ref.Ref) tea.Cmd {
s.key = key
m.confirmShare(s)
return nil
return m.seal(s) // the picker showed what's shared
}
m.search.pickTitle = shareTitle(s)
m.search.pickLines = append(m.sharedFiles(s), "",
+23 -4
View File
@@ -79,10 +79,7 @@ func shareFrom(t *testing.T, root string, paste bool) string {
}
d.keys("enter")
}
if !strings.Contains(d.screen(), ".env") || !strings.Contains(d.screen(), "db-password") {
t.Errorf("the files and key aren't shown before sharing:\n%s", d.screen())
}
d.keys("c")
// Picking it shares: the picker said what.
if !strings.HasPrefix(clip.content, "lazysecrets://share/") {
t.Fatalf("copied %q (%s)", clip.content, d.m.flash.text)
}
@@ -129,6 +126,28 @@ func TestShareFilesRoundTrip(t *testing.T) {
}
}
func TestShareWithShareKeyConfirms(t *testing.T) {
if _, err := exec.LookPath("git"); err != nil {
t.Skip("no git")
}
root := cloneWith(t, map[string]string{
".env": "A=1\n",
".lazysecrets.yaml": "share:\n key: https://" + kv + "/secrets/db-password\n",
})
clip := &fakeClipboard{}
d := newDriverOpts(t, Options{Clipboard: clip, ShareRules: demoRules}, fake.Azure(0), repo.New(repo.Settings{Dir: root}))
d.wait = scryptWait
d.keys("S", "f")
// The key wasn't picked: it shows which, before sharing.
if d.m.search != nil || d.m.prompt == nil || d.m.prompt.title != "Share .env" || !strings.Contains(d.screen(), "db-password") {
t.Fatalf("no confirmation:\n%s", d.screen())
}
d.keys("c")
if !strings.HasPrefix(clip.content, "lazysecrets://share/") {
t.Errorf("copied %q (%s)", clip.content, d.m.flash.text)
}
}
func TestShareLinkElsewhereAsksWhere(t *testing.T) {
if _, err := exec.LookPath("git"); err != nil {
t.Skip("no git")