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
4 changed files with 25 additions and 10 deletions
Showing only changes of commit 7d6a095e42 - Show all commits

No files matched your search

+3 -3
View File
@@ -118,9 +118,9 @@ read the clipboard over SSH.
lazysecrets finds the vault in your accounts (one Resource Graph query per
account) and jumps to it, asking which account to use when several can see
it. Links say what, not what to do: opening a link to a secret asks whether
to just go to it, also copy or show its value, or (`y`) copy its value
without going there.
it, ending on a secret's details as `enter` on it would. Links say what,
not what to do: opening a link to a secret asks whether to just go to it,
also copy or show its value, or (`y`) copy its value without going there.
## In scripts
+1 -1
View File
@@ -217,7 +217,7 @@ func (m *Model) jumpTo(r ref.Ref, n store.Node) tea.Cmd {
case 1:
m.startNav(r, actGo, choices[0].sourceRow)
default:
m.chooseSource("Several accounts can see "+r.ContainerName(), r, actGo, choices)
m.chooseSource("Several accounts can see "+r.ContainerName(), r, actGo, choices, false)
}
return nil
}
+19 -5
View File
@@ -46,6 +46,9 @@ type nav struct {
// quiet gives up without a word: going back to where lazysecrets
// was left, which may be gone.
quiet bool
// link ends on the object's details, as enter on it would: opening
// a link to it opens it, rather than just finding it in its list.
link bool
}
type resolvedMsg struct {
@@ -401,23 +404,30 @@ func (m *Model) handleResolved(msg resolvedMsg) {
for i := range msg.choices {
msg.choices[i].label = "Open in " + msg.choices[i].label
}
m.chooseSource("Scope "+msg.ref.Scope+" is in several workspaces", msg.ref, msg.act, msg.choices)
m.chooseSource("Scope "+msg.ref.Scope+" is in several workspaces", msg.ref, msg.act, msg.choices, true)
case len(msg.others) > 0:
var choices []choice
for _, row := range append([]string{msg.sourceRow}, msg.others...) {
choices = append(choices, choice{label: "Open with " + m.sourceLabel(row), sourceRow: row})
}
m.chooseSource("Several accounts can see "+msg.ref.ContainerName(), msg.ref, msg.act, choices)
m.chooseSource("Several accounts can see "+msg.ref.ContainerName(), msg.ref, msg.act, choices, true)
case msg.linked != nil:
m.addLinked(*msg.linked)
m.startNav(msg.ref, msg.act, linksRowID)
m.startLinkNav(msg.ref, msg.act, linksRowID)
default:
m.startNav(msg.ref, msg.act, msg.sourceRow)
m.startLinkNav(msg.ref, msg.act, msg.sourceRow)
}
}
// startLinkNav opens a link: like startNav, ending on its object's
// details.
func (m *Model) startLinkNav(r ref.Ref, act linkAction, sourceRow string) {
m.startNav(r, act, sourceRow)
m.nav.link = true
}
// chooseSource asks where to open r.
func (m *Model) chooseSource(title string, r ref.Ref, act linkAction, choices []choice) {
func (m *Model) chooseSource(title string, r ref.Ref, act linkAction, choices []choice, link bool) {
var opts []option
for i, c := range choices {
key := ""
@@ -427,6 +437,7 @@ func (m *Model) chooseSource(title string, r ref.Ref, act linkAction, choices []
row := c.sourceRow
opts = append(opts, option{key: key, label: c.label, run: func(m *Model) tea.Cmd {
m.startNav(r, act, row)
m.nav.link = link
return nil
}})
}
@@ -577,6 +588,9 @@ func (m *Model) advanceNav() bool {
m.pendingCmd = m.toggleReveal()
}
}
if n.link {
m.focus = paneDetail // after: copying acts on the focused pane
}
return true
}
return false
+2 -1
View File
@@ -40,7 +40,8 @@ func TestOpenSecretLink(t *testing.T) {
if src, c, s := d.selected(); src != "platform-prod" || c != "kv-app-prod" || s != "api-key" {
t.Fatalf("opened %s/%s/%s", src, c, s)
}
if d.m.focus != paneSecrets || d.m.detail.State() != panes.ValueHidden {
// Opened: on its details, as enter on it would; its value hidden.
if d.m.focus != paneDetail || d.m.detail.State() != panes.ValueHidden {
t.Errorf("focus %d, value state %d", d.m.focus, d.m.detail.State())
}
}