71a74e7166
Advances the guided-rotation goal without rotating anything. - internal/links: offline change-password URL generation — curated per-service table + RFC 8615 /.well-known/change-password + parent-domain fallback; derives a web host from a credential (git/netrc "user @ host", docker registry, aws) - internal/worklist: secrets-free rotation worklist (source, identity, auto/manual, link) + Markdown renderer - internal/tui: Bubble Tea walk-through (one credential per screen, open link, mark done/skip, progress) — READ-ONLY, enters/stores no secret - cmd: `incredigo worklist` (offline, stdout/--out) and `incredigo guide` (TUI) - tests: link derivation, worklist build/markdown + no-secret-column, TUI navigation/done/quit/view Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
56 lines
1.6 KiB
Go
56 lines
1.6 KiB
Go
package worklist
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
|
|
"incredigo/internal/discover"
|
|
)
|
|
|
|
func TestBuildAndMarkdown(t *testing.T) {
|
|
creds := []discover.Credential{
|
|
{Source: "git", Identity: "alice @ github.com", Kind: discover.KindToken},
|
|
{Source: "ssh", Identity: "id_ed25519", Kind: discover.KindPrivateKey},
|
|
{Source: "docker", Identity: "ghcr.io", Kind: discover.KindPassword},
|
|
}
|
|
items := Build(creds)
|
|
if len(items) != 3 {
|
|
t.Fatalf("got %d items, want 3", len(items))
|
|
}
|
|
// No drivers are registered yet, so everything is manual.
|
|
for _, it := range items {
|
|
if !it.Manual() {
|
|
t.Errorf("item %q unexpectedly has driver %q", it.Credential.Identity, it.Driver)
|
|
}
|
|
}
|
|
// github link is curated; ssh has no web page.
|
|
if items[0].Link.URL != "https://github.com/settings/tokens" {
|
|
t.Errorf("git link = %q", items[0].Link.URL)
|
|
}
|
|
if items[1].Link.URL != "" {
|
|
t.Errorf("ssh should have no link, got %q", items[1].Link.URL)
|
|
}
|
|
|
|
md := Markdown(items)
|
|
for _, want := range []string{
|
|
"# incredigo rotation worklist",
|
|
"3 credential(s)",
|
|
"https://github.com/settings/tokens",
|
|
"alice @ github.com",
|
|
"— (no web page)", // ssh row
|
|
} {
|
|
if !strings.Contains(md, want) {
|
|
t.Errorf("markdown missing %q\n---\n%s", want, md)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestMarkdownHasNoSecrets(t *testing.T) {
|
|
// Identities are pre-redacted; assert the renderer never invents a secret column.
|
|
items := Build([]discover.Credential{{Source: "aws", Identity: "default / AKIA***"}})
|
|
md := Markdown(items)
|
|
if strings.Contains(strings.ToLower(md), "password |") && strings.Contains(md, "secret value") {
|
|
t.Error("worklist must not contain a secret-value column")
|
|
}
|
|
}
|