clavitor/clavis/clavis-vault/lib/importers_test.go

159 lines
4.5 KiB
Go

package lib
import (
"testing"
)
func TestDetectAndParse_ChromeCSV(t *testing.T) {
csv := "name,url,username,password\nGitHub,https://github.com,octocat,hunter2\nAWS,https://aws.amazon.com,admin,s3cret\n"
entries, ok := DetectAndParse([]byte(csv))
if !ok {
t.Fatal("should detect Chrome CSV")
}
if len(entries) != 2 {
t.Fatalf("expected 2 entries, got %d", len(entries))
}
if entries[0].Title != "GitHub" {
t.Errorf("title = %q", entries[0].Title)
}
if entries[0].Type != "credential" {
t.Errorf("type = %q", entries[0].Type)
}
if len(entries[0].URLs) == 0 || entries[0].URLs[0] != "https://github.com" {
t.Errorf("URL not parsed")
}
}
func TestDetectAndParse_FirefoxCSV(t *testing.T) {
csv := "url,username,password,httpRealm,formActionOrigin,guid,timeCreated,timeLastUsed,timePasswordChanged\nhttps://example.com,user@example.com,pass123,,,,,,1700000000000000\n"
entries, ok := DetectAndParse([]byte(csv))
if !ok {
t.Fatal("should detect Firefox CSV")
}
if len(entries) != 1 {
t.Fatalf("expected 1 entry, got %d", len(entries))
}
// Firefox stores timePasswordChanged as microseconds
if entries[0].SourceModified != 1700000000 {
t.Errorf("SourceModified = %d, want 1700000000", entries[0].SourceModified)
}
}
func TestDetectAndParse_BitwardenJSON(t *testing.T) {
json := `{"items":[{"name":"GitHub","type":1,"login":{"username":"octocat","password":"p@ss","uris":[{"uri":"https://github.com"}]},"revisionDate":"2024-01-15T10:00:00Z"}]}`
entries, ok := DetectAndParse([]byte(json))
if !ok {
t.Fatal("should detect Bitwarden JSON")
}
if len(entries) != 1 {
t.Fatalf("expected 1 entry, got %d", len(entries))
}
if entries[0].Title != "GitHub" {
t.Errorf("title = %q", entries[0].Title)
}
if entries[0].SourceModified == 0 {
t.Error("SourceModified should be parsed from revisionDate")
}
}
func TestDetectAndParse_BitwardenCard(t *testing.T) {
json := `{"items":[{"name":"Amex","type":3,"card":{"cardholderName":"Johan","number":"378282246310005","code":"1234","expMonth":"09","expYear":"28"}}]}`
entries, ok := DetectAndParse([]byte(json))
if !ok {
t.Fatal("should detect Bitwarden card")
}
if entries[0].Type != "card" {
t.Errorf("type = %q, want card", entries[0].Type)
}
// Card number and CVV should be auto-flagged L2
for _, f := range entries[0].Fields {
if f.Label == "Number" && !f.L2 {
t.Error("card number should be L2")
}
if f.Label == "CVV" && !f.L2 {
t.Error("CVV should be L2")
}
}
}
func TestDetectAndParse_unknown_format(t *testing.T) {
_, ok := DetectAndParse([]byte("this is not a known format"))
if ok {
t.Error("should not detect unknown format")
}
}
func TestAutoL2Fields_labels(t *testing.T) {
entries := []VaultData{
{
Title: "Bank",
Fields: []VaultField{
{Label: "Username", Value: "user", Kind: "text"},
{Label: "Card Number", Value: "4111111111111111", Kind: "text"},
{Label: "CVV", Value: "123", Kind: "text"},
{Label: "SSN", Value: "123-45-6789", Kind: "text"},
{Label: "API Key", Value: "sk_live_abc", Kind: "text"},
},
},
}
AutoL2Fields(entries)
expectations := map[string]bool{
"Username": false,
"Card Number": true,
"CVV": true,
"SSN": true,
"API Key": false,
}
for _, f := range entries[0].Fields {
want, ok := expectations[f.Label]
if !ok {
continue
}
if f.L2 != want {
t.Errorf("field %q: L2=%v, want %v", f.Label, f.L2, want)
}
}
}
func TestAutoL2Fields_title_match_marks_all(t *testing.T) {
entries := []VaultData{
{
Title: "Coinbase Wallet",
Fields: []VaultField{
{Label: "Email", Value: "me@example.com", Kind: "text"},
{Label: "Password", Value: "secret", Kind: "password"},
},
},
}
AutoL2Fields(entries)
for _, f := range entries[0].Fields {
if !f.L2 {
t.Errorf("field %q should be L2 (title matched crypto exchange)", f.Label)
}
}
}
func TestAutoL2Fields_multilingual(t *testing.T) {
entries := []VaultData{
{
Title: "Docs",
Fields: []VaultField{
{Label: "Paspoort", Value: "NL12345", Kind: "text"}, // Dutch
{Label: "Führerschein", Value: "DE12345", Kind: "text"}, // German
{Label: "身份证", Value: "CN12345", Kind: "text"}, // Chinese
{Label: "パスポート", Value: "JP12345", Kind: "text"}, // Japanese
{Label: "PESEL", Value: "PL12345", Kind: "text"}, // Polish
},
},
}
AutoL2Fields(entries)
for _, f := range entries[0].Fields {
if !f.L2 {
t.Errorf("field %q should be auto-detected as L2", f.Label)
}
}
}