mirror of
https://github.com/shuaiplus/nodewarden.git
synced 2026-06-20 21:00:41 +00:00
feat: add support for SSH key fingerprint normalization and compatibility
This commit is contained in:
+5
-2
@@ -251,7 +251,7 @@ function importCipherToDraft(cipher: Record<string, unknown>, folderId: string |
|
||||
const sshKey = (cipher.sshKey || {}) as Record<string, unknown>;
|
||||
draft.sshPrivateKey = asText(sshKey.privateKey);
|
||||
draft.sshPublicKey = asText(sshKey.publicKey);
|
||||
draft.sshFingerprint = asText(sshKey.fingerprint);
|
||||
draft.sshFingerprint = asText(sshKey.keyFingerprint ?? sshKey.fingerprint);
|
||||
}
|
||||
|
||||
return draft;
|
||||
@@ -703,11 +703,14 @@ export default function App() {
|
||||
};
|
||||
}
|
||||
if (cipher.sshKey) {
|
||||
const encryptedFingerprint = cipher.sshKey.keyFingerprint || cipher.sshKey.fingerprint || '';
|
||||
nextCipher.sshKey = {
|
||||
...cipher.sshKey,
|
||||
decPrivateKey: await decryptField(cipher.sshKey.privateKey || '', itemEnc, itemMac),
|
||||
decPublicKey: await decryptField(cipher.sshKey.publicKey || '', itemEnc, itemMac),
|
||||
decFingerprint: await decryptField(cipher.sshKey.fingerprint || '', itemEnc, itemMac),
|
||||
keyFingerprint: encryptedFingerprint || null,
|
||||
fingerprint: encryptedFingerprint || null,
|
||||
decFingerprint: await decryptField(encryptedFingerprint, itemEnc, itemMac),
|
||||
};
|
||||
}
|
||||
if (cipher.fields) {
|
||||
|
||||
@@ -1461,9 +1461,33 @@ function folderName(id: string | null | undefined): string {
|
||||
{selectedCipher.sshKey && (
|
||||
<div className="card">
|
||||
<h4>{t('txt_ssh_key')}</h4>
|
||||
<div className="kv-line"><span>{t('txt_private_key')}</span><strong>{maskSecret(selectedCipher.sshKey.decPrivateKey || '')}</strong></div>
|
||||
<div className="kv-line"><span>{t('txt_public_key')}</span><strong>{selectedCipher.sshKey.decPublicKey || ''}</strong></div>
|
||||
<div className="kv-line"><span>{t('txt_fingerprint')}</span><strong>{selectedCipher.sshKey.decFingerprint || ''}</strong></div>
|
||||
<div className="kv-row">
|
||||
<span className="kv-label">{t('txt_private_key')}</span>
|
||||
<div className="kv-main">
|
||||
<strong className="value-ellipsis" title={maskSecret(selectedCipher.sshKey.decPrivateKey || '')}>
|
||||
{maskSecret(selectedCipher.sshKey.decPrivateKey || '')}
|
||||
</strong>
|
||||
</div>
|
||||
<div className="kv-actions" />
|
||||
</div>
|
||||
<div className="kv-row">
|
||||
<span className="kv-label">{t('txt_public_key')}</span>
|
||||
<div className="kv-main">
|
||||
<strong className="value-ellipsis" title={selectedCipher.sshKey.decPublicKey || ''}>
|
||||
{selectedCipher.sshKey.decPublicKey || ''}
|
||||
</strong>
|
||||
</div>
|
||||
<div className="kv-actions" />
|
||||
</div>
|
||||
<div className="kv-row">
|
||||
<span className="kv-label">{t('txt_fingerprint')}</span>
|
||||
<div className="kv-main">
|
||||
<strong className="value-ellipsis" title={selectedCipher.sshKey.decFingerprint || ''}>
|
||||
{selectedCipher.sshKey.decFingerprint || ''}
|
||||
</strong>
|
||||
</div>
|
||||
<div className="kv-actions" />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
@@ -971,10 +971,13 @@ export async function createCipher(
|
||||
country: await encryptTextValue(draft.identCountry, enc, mac),
|
||||
};
|
||||
} else if (type === 5) {
|
||||
const encryptedFingerprint = await encryptTextValue(draft.sshFingerprint, enc, mac);
|
||||
payload.sshKey = {
|
||||
privateKey: await encryptTextValue(draft.sshPrivateKey, enc, mac),
|
||||
publicKey: await encryptTextValue(draft.sshPublicKey, enc, mac),
|
||||
fingerprint: await encryptTextValue(draft.sshFingerprint, enc, mac),
|
||||
keyFingerprint: encryptedFingerprint,
|
||||
// Keep legacy alias for backward compatibility with previously exported/edited items.
|
||||
fingerprint: encryptedFingerprint,
|
||||
};
|
||||
} else if (type === 2) {
|
||||
payload.secureNote = { type: 0 };
|
||||
@@ -1063,10 +1066,13 @@ export async function updateCipher(
|
||||
country: await encryptTextValue(draft.identCountry, keys.enc, keys.mac),
|
||||
};
|
||||
} else if (type === 5) {
|
||||
const encryptedFingerprint = await encryptTextValue(draft.sshFingerprint, keys.enc, keys.mac);
|
||||
payload.sshKey = {
|
||||
privateKey: await encryptTextValue(draft.sshPrivateKey, keys.enc, keys.mac),
|
||||
publicKey: await encryptTextValue(draft.sshPublicKey, keys.enc, keys.mac),
|
||||
fingerprint: await encryptTextValue(draft.sshFingerprint, keys.enc, keys.mac),
|
||||
keyFingerprint: encryptedFingerprint,
|
||||
// Keep legacy alias for backward compatibility with previously exported/edited items.
|
||||
fingerprint: encryptedFingerprint,
|
||||
};
|
||||
} else if (type === 2) {
|
||||
payload.secureNote = { type: 0 };
|
||||
|
||||
@@ -257,7 +257,9 @@ function mapCipherEncrypted(cipher: Cipher): Record<string, unknown> {
|
||||
? {
|
||||
privateKey: cipher.sshKey.privateKey ?? null,
|
||||
publicKey: cipher.sshKey.publicKey ?? null,
|
||||
fingerprint: cipher.sshKey.fingerprint ?? null,
|
||||
keyFingerprint: cipher.sshKey.keyFingerprint ?? cipher.sshKey.fingerprint ?? null,
|
||||
// Keep legacy alias for compatibility with older importers.
|
||||
fingerprint: cipher.sshKey.keyFingerprint ?? cipher.sshKey.fingerprint ?? null,
|
||||
}
|
||||
: null;
|
||||
|
||||
@@ -304,7 +306,22 @@ async function mapCipherPlain(cipher: Cipher, userEnc: Uint8Array, userMac: Uint
|
||||
|
||||
out.card = cipher.card ? await deepDecryptUnknown(cipher.card, keyParts.enc, keyParts.mac) : null;
|
||||
out.identity = cipher.identity ? await deepDecryptUnknown(cipher.identity, keyParts.enc, keyParts.mac) : null;
|
||||
out.sshKey = cipher.sshKey ? await deepDecryptUnknown(cipher.sshKey, keyParts.enc, keyParts.mac) : null;
|
||||
if (cipher.sshKey) {
|
||||
const fingerprint = await decryptMaybe(
|
||||
cipher.sshKey.keyFingerprint ?? cipher.sshKey.fingerprint ?? null,
|
||||
keyParts.enc,
|
||||
keyParts.mac
|
||||
);
|
||||
out.sshKey = {
|
||||
privateKey: await decryptMaybe(cipher.sshKey.privateKey ?? null, keyParts.enc, keyParts.mac),
|
||||
publicKey: await decryptMaybe(cipher.sshKey.publicKey ?? null, keyParts.enc, keyParts.mac),
|
||||
keyFingerprint: fingerprint,
|
||||
// Keep legacy alias for compatibility with older importers.
|
||||
fingerprint,
|
||||
};
|
||||
} else {
|
||||
out.sshKey = null;
|
||||
}
|
||||
out.secureNote = cipher.secureNote
|
||||
? {
|
||||
type: normalizeNumber((cipher.secureNote as { type?: unknown }).type, 0),
|
||||
|
||||
@@ -112,6 +112,7 @@ export interface CipherIdentity {
|
||||
export interface CipherSshKey {
|
||||
privateKey?: string | null;
|
||||
publicKey?: string | null;
|
||||
keyFingerprint?: string | null;
|
||||
fingerprint?: string | null;
|
||||
decPrivateKey?: string;
|
||||
decPublicKey?: string;
|
||||
|
||||
Reference in New Issue
Block a user