feat(chromium): extract passwords from the account-synced store (#637)

Chromium keeps account-synced credentials in a separate "Login Data For Account" DB. Entries carry a Store field because the same credential can legitimately exist in both stores.
This commit is contained in:
slimwang authored and GitHub committed 2026-08-25 11:13:10 +08:00
1 parent 9624e50a4f
commit d2b2955d6c
12 files changed
+245 -16

No files matched your search

+5 -5
View File
@@ -20,7 +20,7 @@ var testTime = time.Date(2026, 1, 15, 10, 30, 0, 0, time.UTC)
func chromeData() *types.BrowserData {
return &types.BrowserData{
Passwords: []types.LoginEntry{
{URL: "https://example.com", Username: "alice", Password: "secret", CreatedAt: testTime},
{URL: "https://example.com", Username: "alice", Password: "secret", CreatedAt: testTime, Store: types.PasswordStoreAccount},
},
Cookies: []types.CookieEntry{
{
@@ -38,7 +38,7 @@ func chromeData() *types.BrowserData {
func firefoxData() *types.BrowserData {
return &types.BrowserData{
Passwords: []types.LoginEntry{
{URL: "https://reddit.com", Username: "bob", Password: "hunter2", CreatedAt: testTime},
{URL: "https://reddit.com", Username: "bob", Password: "hunter2", CreatedAt: testTime, Store: types.PasswordStoreLocal},
},
Cookies: []types.CookieEntry{
{
@@ -88,9 +88,9 @@ func TestWrite_CSV_Password(t *testing.T) {
records := readCSV(t, filepath.Join(dir, "password.csv"))
require.Len(t, records, 3) // header + 2 rows
assert.Equal(t, []string{"browser", "profile", "url", "username", "password", "created_at"}, records[0])
assert.Equal(t, []string{"Chrome", "Default", "https://example.com", "alice", "secret", "2026-01-15T10:30:00Z"}, records[1])
assert.Equal(t, []string{"Firefox", "abc123", "https://reddit.com", "bob", "hunter2", "2026-01-15T10:30:00Z"}, records[2])
assert.Equal(t, []string{"browser", "profile", "url", "username", "password", "created_at", "store"}, records[0])
assert.Equal(t, []string{"Chrome", "Default", "https://example.com", "alice", "secret", "2026-01-15T10:30:00Z", "account"}, records[1])
assert.Equal(t, []string{"Firefox", "abc123", "https://reddit.com", "bob", "hunter2", "2026-01-15T10:30:00Z", "local"}, records[2])
}
func TestWrite_CSV_Cookie(t *testing.T) {
+5 -5
View File
@@ -53,7 +53,7 @@ func TestStructCSVHeader(t *testing.T) {
entry any
expect []string
}{
{"LoginEntry", types.LoginEntry{}, []string{"url", "username", "password", "created_at"}},
{"LoginEntry", types.LoginEntry{}, []string{"url", "username", "password", "created_at", "store"}},
{"CookieEntry", types.CookieEntry{}, []string{"host", "path", "name", "value", "is_secure", "is_http_only", "has_expire", "is_persistent", "expire_at", "created_at", "same_site"}},
{"BookmarkEntry", types.BookmarkEntry{}, []string{"id", "name", "type", "url", "folder", "created_at"}},
{"HistoryEntry", types.HistoryEntry{}, []string{"url", "title", "visit_count", "last_visit"}},
@@ -77,8 +77,8 @@ func TestStructCSVRow(t *testing.T) {
}{
{
"LoginEntry",
types.LoginEntry{URL: "https://example.com", Username: "alice", Password: "secret", CreatedAt: refTime},
[]string{"https://example.com", "alice", "secret", "2026-01-15T10:30:00Z"},
types.LoginEntry{URL: "https://example.com", Username: "alice", Password: "secret", CreatedAt: refTime, Store: types.PasswordStoreLocal},
[]string{"https://example.com", "alice", "secret", "2026-01-15T10:30:00Z", "local"},
},
{
"CookieEntry",
@@ -107,7 +107,7 @@ func TestStructCSVRow(t *testing.T) {
{
"zero_time",
types.LoginEntry{URL: "https://a.com"},
[]string{"https://a.com", "", "", ""},
[]string{"https://a.com", "", "", "", ""},
},
}
for _, tt := range tests {
@@ -141,7 +141,7 @@ func TestRowMarshalJSON(t *testing.T) {
assert.Equal(t, "https://example.com", m["url"])
assert.Equal(t, "alice", m["username"])
assert.Equal(t, "secret", m["password"])
assert.Len(t, m, 6) // browser + profile + 4 entry fields
assert.Len(t, m, 7) // browser + profile + 5 entry fields
// Verify field order: browser, profile come before entry fields.
raw := string(data)