feat: enhance login URI handling with match options and improve UI components

This commit is contained in:
shuaiplus
2026-03-26 21:59:50 +08:00
parent fe0bd80f43
commit 89308fc8a6
9 changed files with 221 additions and 59 deletions
+12 -5
View File
@@ -367,12 +367,19 @@ async function encryptCustomFields(
return out;
}
async function encryptUris(uris: string[], enc: Uint8Array, mac: Uint8Array): Promise<Array<{ uri: string | null; match: null }>> {
const out: Array<{ uri: string | null; match: null }> = [];
for (const uri of uris || []) {
const trimmed = String(uri || '').trim();
async function encryptUris(
uris: VaultDraft['loginUris'],
enc: Uint8Array,
mac: Uint8Array
): Promise<Array<{ uri: string | null; match: number | null }>> {
const out: Array<{ uri: string | null; match: number | null }> = [];
for (const entry of uris || []) {
const trimmed = String(entry?.uri || '').trim();
if (!trimmed) continue;
out.push({ uri: await encryptTextValue(trimmed, enc, mac), match: null });
out.push({
uri: await encryptTextValue(trimmed, enc, mac),
match: typeof entry?.match === 'number' && Number.isFinite(entry.match) ? entry.match : null,
});
}
return out;
}
+12 -4
View File
@@ -97,7 +97,7 @@ export function buildEmptyImportDraft(type: number): VaultDraft {
loginUsername: '',
loginPassword: '',
loginTotp: '',
loginUris: [''],
loginUris: [{ uri: '', match: null }],
loginFido2Credentials: [],
cardholderName: '',
cardNumber: '',
@@ -167,9 +167,17 @@ export function importCipherToDraft(cipher: Record<string, unknown>, folderId: s
: [];
const urisRaw = Array.isArray(login.uris) ? login.uris : [];
const uris = urisRaw
.map((u) => asText((u as Record<string, unknown>)?.uri).trim())
.filter((u) => !!u);
draft.loginUris = uris.length ? uris : [''];
.map((u) => {
const row = (u || {}) as Record<string, unknown>;
const uri = asText(row.uri).trim();
const matchRaw = row.match;
return {
uri,
match: typeof matchRaw === 'number' && Number.isFinite(matchRaw) ? matchRaw : null,
};
})
.filter((u) => !!u.uri);
draft.loginUris = uris.length ? uris : [{ uri: '', match: null }];
} else if (type === 3) {
const card = (cipher.card || {}) as Record<string, unknown>;
draft.cardholderName = asText(card.cardholderName);
+14
View File
@@ -629,6 +629,13 @@ const messages: Record<Locale, Record<string, string>> = {
txt_user_deleted: "User deleted",
txt_user_status_updated: "User status updated",
txt_username: "Username",
txt_uri_match_default_base_domain: "Default (Base Domain)",
txt_uri_match_base_domain: "Base Domain",
txt_uri_match_host: "Host",
txt_uri_match_exact: "Exact",
txt_uri_match_never: "Never",
txt_uri_match_starts_with: "Starts With",
txt_uri_match_regular_expression: "Regular Expression",
txt_users: "Users",
txt_vault_synced: "Vault synced",
txt_verification_code: "Verification Code",
@@ -908,6 +915,13 @@ const zhCNOverrides: Record<string, string> = {
txt_last_edited_value: '最后编辑:{value}',
txt_created_value: '创建于:{value}',
txt_username: '用户名',
txt_uri_match_default_base_domain: '默认(基础域名)',
txt_uri_match_base_domain: '基础域名',
txt_uri_match_host: '主机',
txt_uri_match_exact: '精确',
txt_uri_match_never: '从不',
txt_uri_match_starts_with: '开始于',
txt_uri_match_regular_expression: '正则表达式',
txt_website: '网站',
txt_websites: '网站',
txt_open: '打开',
+7 -1
View File
@@ -28,9 +28,15 @@ export interface Folder {
export interface CipherLoginUri {
uri?: string | null;
match?: number | null;
decUri?: string;
}
export interface VaultDraftLoginUri {
uri: string;
match: number | null;
}
export interface CipherAttachment {
id?: string;
url?: string | null;
@@ -221,7 +227,7 @@ export interface VaultDraft {
loginUsername: string;
loginPassword: string;
loginTotp: string;
loginUris: string[];
loginUris: VaultDraftLoginUri[];
loginFido2Credentials: Array<Record<string, unknown>>;
cardholderName: string;
cardNumber: string;