mirror of
https://github.com/shuaiplus/nodewarden.git
synced 2026-06-21 05:10:41 +00:00
feat: enhance OnePassword CSV parsing with improved field handling and new category type support
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import type { CiphersImportPayload } from '@/lib/api/vault';
|
||||
import { addFolder, cardBrand, makeLoginCipher, nameFromUrl, normalizeUri, parseCsv, parseSerializedUris, txt, val } from '@/lib/import-format-shared';
|
||||
import { addFolder, cardBrand, makeLoginCipher, nameFromUrl, normalizeUri, parseCsv, parseSerializedUris, processKvp, txt, val } from '@/lib/import-format-shared';
|
||||
|
||||
export function parseChromeCsv(textRaw: string): CiphersImportPayload {
|
||||
const rows = parseCsv(textRaw);
|
||||
@@ -62,25 +62,37 @@ export function parseSafariCsv(textRaw: string): CiphersImportPayload {
|
||||
export function parseBitwardenCsv(textRaw: string): CiphersImportPayload {
|
||||
const rows = parseCsv(textRaw);
|
||||
const result: CiphersImportPayload = { ciphers: [], folders: [], folderRelationships: [] };
|
||||
const applyBitwardenCustomFields = (cipher: Record<string, unknown>, rawFields: unknown) => {
|
||||
const lines = String(rawFields || '')
|
||||
.split(/\r?\n/)
|
||||
.map((line) => line.trim())
|
||||
.filter(Boolean);
|
||||
for (const line of lines) {
|
||||
const delim = line.lastIndexOf(': ');
|
||||
if (delim < 0) continue;
|
||||
processKvp(cipher, line.slice(0, delim), line.slice(delim + 2), false);
|
||||
}
|
||||
};
|
||||
for (const row of rows) {
|
||||
const type = txt(row.type).toLowerCase() || 'login';
|
||||
if (type === 'note') {
|
||||
const idx =
|
||||
result.ciphers.push({
|
||||
type: 2,
|
||||
name: val(row.name, '--'),
|
||||
notes: val(row.notes),
|
||||
favorite: txt(row.favorite) === '1',
|
||||
reprompt: 0,
|
||||
key: null,
|
||||
login: null,
|
||||
card: null,
|
||||
identity: null,
|
||||
secureNote: { type: 0 },
|
||||
fields: null,
|
||||
passwordHistory: null,
|
||||
sshKey: null,
|
||||
}) - 1;
|
||||
if (type === 'note' || type === 'secure note' || type === 'securenote') {
|
||||
const cipher = {
|
||||
type: 2,
|
||||
name: val(row.name, '--'),
|
||||
notes: val(row.notes),
|
||||
favorite: txt(row.favorite) === '1',
|
||||
reprompt: Number(row.reprompt ?? 0) || 0,
|
||||
key: null,
|
||||
login: null,
|
||||
card: null,
|
||||
identity: null,
|
||||
secureNote: { type: 0 },
|
||||
fields: [],
|
||||
passwordHistory: null,
|
||||
sshKey: null,
|
||||
};
|
||||
applyBitwardenCustomFields(cipher, row.fields);
|
||||
const idx = result.ciphers.push(cipher) - 1;
|
||||
addFolder(result, row.folder, idx);
|
||||
continue;
|
||||
}
|
||||
@@ -88,11 +100,13 @@ export function parseBitwardenCsv(textRaw: string): CiphersImportPayload {
|
||||
cipher.name = val(row.name, '--');
|
||||
cipher.notes = val(row.notes);
|
||||
cipher.favorite = txt(row.favorite) === '1';
|
||||
cipher.reprompt = Number(row.reprompt ?? 0) || 0;
|
||||
applyBitwardenCustomFields(cipher, row.fields);
|
||||
const login = cipher.login as Record<string, unknown>;
|
||||
login.username = val(row.login_username);
|
||||
login.password = val(row.login_password);
|
||||
login.totp = val(row.login_totp);
|
||||
const uris = parseSerializedUris(row.login_uri || '');
|
||||
login.username = val(row.login_username, val(row.username));
|
||||
login.password = val(row.login_password, val(row.password));
|
||||
login.totp = val(row.login_totp, val(row.totp));
|
||||
const uris = parseSerializedUris(row.login_uri || row.uri || '');
|
||||
login.uris = uris.length ? uris.map((uri) => ({ uri, match: null })) : null;
|
||||
const idx = result.ciphers.push(cipher) - 1;
|
||||
addFolder(result, row.folder, idx);
|
||||
|
||||
Reference in New Issue
Block a user