feat: add parseSerializedUris function and update Bitwarden CSV parsing to handle multiple URIs

This commit is contained in:
shuaiplus
2026-03-17 09:03:14 +08:00
parent 3791f89a5c
commit 40fe9223ac
3 changed files with 34 additions and 4 deletions
+1 -1
View File
@@ -428,7 +428,7 @@ export async function buildBitwardenCsvString(args: BuildPlainJsonArgs): Promise
? (login.uris as Array<Record<string, unknown>>)
.map((uri) => normalizeString(uri.uri) || '')
.filter((uri) => !!uri)
.join(',')
.join('\n')
: '';
rows.push([
+30
View File
@@ -19,6 +19,36 @@ export function normalizeUri(raw: string): string | null {
return s.slice(0, 1000);
}
export function parseSerializedUris(raw: string): string[] {
const source = txt(raw);
if (!source) return [];
const newlineParts = source
.split(/\r?\n/)
.map((part) => txt(part))
.filter(Boolean);
const parts =
newlineParts.length > 1
? newlineParts
: source.includes(',')
? source
.split(/,(?=\s*(?:[a-z][a-z0-9+.-]*:\/\/|www\.|[a-z0-9.-]+\.[a-z]{2,}(?:[/:?#]|$)))/i)
.map((part) => txt(part))
.filter(Boolean)
: [source];
const seen = new Set<string>();
const uris: string[] = [];
for (const part of parts) {
const normalized = normalizeUri(part);
if (!normalized || seen.has(normalized)) continue;
seen.add(normalized);
uris.push(normalized);
}
return uris;
}
export function nameFromUrl(raw: string): string | null {
const uri = normalizeUri(raw);
if (!uri) return null;
+3 -3
View File
@@ -1,5 +1,5 @@
import type { CiphersImportPayload } from '@/lib/api/vault';
import { addFolder, cardBrand, makeLoginCipher, nameFromUrl, normalizeUri, parseCsv, txt, val } from '@/lib/import-format-shared';
import { addFolder, cardBrand, makeLoginCipher, nameFromUrl, normalizeUri, parseCsv, parseSerializedUris, txt, val } from '@/lib/import-format-shared';
export function parseChromeCsv(textRaw: string): CiphersImportPayload {
const rows = parseCsv(textRaw);
@@ -92,8 +92,8 @@ export function parseBitwardenCsv(textRaw: string): CiphersImportPayload {
login.username = val(row.login_username);
login.password = val(row.login_password);
login.totp = val(row.login_totp);
const uri = normalizeUri(row.login_uri || '');
login.uris = uri ? [{ uri, match: null }] : null;
const uris = parseSerializedUris(row.login_uri || '');
login.uris = uris.length ? uris.map((uri) => ({ uri, match: null })) : null;
const idx = result.ciphers.push(cipher) - 1;
addFolder(result, row.folder, idx);
}