package main import ( "net/netip" "os" "path/filepath" "strings" "testing" "time" ) func TestPasswordGeneratorRespectsMinimums(t *testing.T) { o := PWOptions{Length: 20, MinLower: 2, MinUpper: 2, MinDigits: 2, MinSymbols: 2, NoAmbig: true, NoSeq: true, NoRepeat: true, SymbolSet: "!@#$%"} p, err := generateOne(o) if err != nil { t.Fatal(err) } if len(p) != 20 { t.Fatalf("length=%d", len(p)) } var lo, up, di, sy int for _, c := range p { switch { case strings.ContainsRune(lower, c): lo++ case strings.ContainsRune(upper, c): up++ case strings.ContainsRune(digits, c): di++ default: sy++ } } if lo < 2 || up < 2 || di < 2 || sy < 2 { t.Fatalf("class minimums not met: %q", p) } } func TestOneTimeClipDisappearsAfterReveal(t *testing.T) { r := newRoom("test", 10) c := &Clip{ID: "x", Room: "test", Content: "secret", Secret: true, OneTime: true, CreatedAt: time.Now().UTC()} r.add(c) if _, ok := r.reveal("x"); !ok { t.Fatal("first reveal failed") } if _, ok := r.reveal("x"); ok { t.Fatal("one-time clip still exists") } } func TestExpiredClipIsPruned(t *testing.T) { r := newRoom("test", 10) exp := time.Now().UTC().Add(-time.Minute) r.add(&Clip{ID: "old", Room: "test", Content: "x", ExpiresAt: &exp, CreatedAt: time.Now().UTC().Add(-time.Hour)}) if got := r.history(10); len(got) != 0 { t.Fatalf("expected expired clip to be pruned, got %d", len(got)) } } func TestFilenameIsReducedToBase(t *testing.T) { name, err := cleanOriginalName("../../payload.exe") if err != nil { t.Fatal(err) } if name != "payload.exe" { t.Fatalf("unexpected name %q", name) } } func TestIPv4PrefixLastAndMask(t *testing.T) { p, err := netip.ParsePrefix("10.20.30.40/24") if err != nil { t.Fatal(err) } if got := prefixLast(p.Masked()).String(); got != "10.20.30.255" { t.Fatalf("last=%s", got) } if got := prefixMask4(24); got != "255.255.255.0" { t.Fatalf("mask=%s", got) } } func TestParseSRVName(t *testing.T) { svc, proto, name := parseSRVName("_ldap._tcp.example.local") if svc != "ldap" || proto != "tcp" || name != "example.local" { t.Fatalf("got %q %q %q", svc, proto, name) } } func TestClipboardPersistsRoomsSecretsAndEmptyRooms(t *testing.T) { dir := t.TempDir() path := filepath.Join(dir, "clipboard.json") store := newClipboardStore(20, path, true) if err := store.createRoom("alpha"); err != nil { t.Fatal(err) } if err := store.createRoom("empty-room"); err != nil { t.Fatal(err) } store.room("alpha").add(&Clip{ID: "normal", Room: "alpha", Type: "text", Content: "hello", CreatedAt: time.Now().UTC()}) store.room("alpha").add(&Clip{ID: "secret", Room: "alpha", Type: "password", Content: "P@ssw0rd!", Secret: true, CreatedAt: time.Now().UTC()}) if err := store.save(); err != nil { t.Fatal(err) } reloaded := newClipboardStore(20, path, true) if err := reloaded.load(); err != nil { t.Fatal(err) } if _, ok := reloaded.getRoom("empty-room"); !ok { t.Fatal("empty room was not persisted") } r, ok := reloaded.getRoom("alpha") if !ok { t.Fatal("alpha room missing after reload") } r.mu.RLock() defer r.mu.RUnlock() if len(r.clips) != 2 { t.Fatalf("expected 2 clips after reload, got %d", len(r.clips)) } if !r.clips[1].Secret || r.clips[1].Content != "P@ssw0rd!" { t.Fatal("secret was not persisted correctly") } } func TestClipboardClearKeepsRoomDeleteRemovesRoomPersistently(t *testing.T) { dir := t.TempDir() path := filepath.Join(dir, "clipboard.json") store := newClipboardStore(20, path, true) if err := store.createRoom("keep"); err != nil { t.Fatal(err) } store.room("keep").add(&Clip{ID: "x", Room: "keep", Content: "value", CreatedAt: time.Now().UTC()}) if err := store.save(); err != nil { t.Fatal(err) } if err := store.clearRoom("keep"); err != nil { t.Fatal(err) } reloaded := newClipboardStore(20, path, true) if err := reloaded.load(); err != nil { t.Fatal(err) } r, ok := reloaded.getRoom("keep") if !ok { t.Fatal("cleared room should still exist") } if got := len(r.history(10)); got != 0 { t.Fatalf("cleared room has %d clips", got) } if err := reloaded.deleteRoom("keep"); err != nil { t.Fatal(err) } reloadedAgain := newClipboardStore(20, path, true) if err := reloadedAgain.load(); err != nil { t.Fatal(err) } if _, ok := reloadedAgain.getRoom("keep"); ok { t.Fatal("deleted room reappeared after reload") } } func TestFileStorePersistsMetadataAndBlob(t *testing.T) { dir := t.TempDir() store := newFileStore(dir, 1024*1024) if err := os.MkdirAll(store.dir, 0o700); err != nil { t.Fatal(err) } id := "persisted-file" content := []byte("persistent file data") if err := os.WriteFile(store.filePath(id), content, 0o600); err != nil { t.Fatal(err) } store.files[id] = &FileMeta{ID: id, Name: "test.txt", Size: int64(len(content)), SHA256: "dummy", UploadedAt: time.Now().UTC()} store.mu.Lock() if err := store.saveLocked(); err != nil { store.mu.Unlock() t.Fatal(err) } store.mu.Unlock() reloaded := newFileStore(dir, 1024*1024) if err := reloaded.load(); err != nil { t.Fatal(err) } files := reloaded.list() if len(files) != 1 || files[0].ID != id { t.Fatalf("file metadata not restored: %#v", files) } got, err := os.ReadFile(reloaded.filePath(id)) if err != nil { t.Fatal(err) } if string(got) != string(content) { t.Fatalf("blob changed: %q", got) } }