diff --git a/dist/index.html b/dist/index.html index 76f7aff..bb3c38a 100644 --- a/dist/index.html +++ b/dist/index.html @@ -4840,7 +4840,7 @@ function generateId() { * @typedef {Object} CredentialEntry * @property {string} id - Unique identifier * @property {string} title - Display name (e.g. "GitHub", "Gmail") -* @property {string} username - Login username or email +* @property {string} [username] - Login username or email (optional) * @property {string} encryptedPassword - AES-GCM encrypted password blob (JSON string) * @property {string} [url] - Website URL * @property {string} [notes] - Free-form notes @@ -4854,7 +4854,7 @@ function generateId() { * * @param {Object} data * @param {string} data.title -* @param {string} data.username +* @param {string} [data.username] * @param {string} data.encryptedPassword - Must already be encrypted * @param {string} [data.url] * @param {string} [data.notes] @@ -4867,7 +4867,7 @@ function createEntry(data) { return { id: generateId(), title: data.title.trim(), - username: data.username.trim(), + username: data.username?.trim() || "", encryptedPassword: data.encryptedPassword, url: data.url?.trim() || "", notes: data.notes?.trim() || "", @@ -4888,7 +4888,7 @@ function updateEntry$1(existing, data) { return { ...existing, title: data.title !== void 0 ? data.title.trim() : existing.title, - username: data.username !== void 0 ? data.username.trim() : existing.username, + username: data.username !== void 0 ? data.username?.trim() || "" : existing.username, encryptedPassword: data.encryptedPassword !== void 0 ? data.encryptedPassword : existing.encryptedPassword, url: data.url !== void 0 ? data.url.trim() : existing.url, notes: data.notes !== void 0 ? data.notes.trim() : existing.notes, @@ -4940,7 +4940,6 @@ function createGroup(name, color) { function validateEntry(data) { const errors = []; if (!data.title || !data.title.trim()) errors.push("Title is required"); - if (!data.username || !data.username.trim()) errors.push("Username is required"); if (!data.encryptedPassword) errors.push("Password is required"); return { valid: errors.length === 0, @@ -6110,7 +6109,7 @@ function EntryList($$anchor, $$props) { reset(tr); template_effect(() => { set_text(text_6, get(entry).title); - set_text(text_7, get(entry).username); + set_text(text_7, get(entry).username || "—"); set_text(text_8, get(entry).url || "—"); }); delegated("click", tr, () => $$props.onSelect(get(entry).id)); @@ -6138,10 +6137,11 @@ var root_1$5 = /* @__PURE__ */ from_html(`
Loading...
`); var root_3$3 = /* @__PURE__ */ from_html(`
`); var root_4$3 = /* @__PURE__ */ from_html(`
Entry not found
`); -var root_6$3 = /* @__PURE__ */ from_html(`
URL
`); -var root_7$1 = /* @__PURE__ */ from_html(`
Notes
`); -var root_8 = /* @__PURE__ */ from_html(``); -var root_5$2 = /* @__PURE__ */ from_html(`

Username
Password
`, 1); +var root_6$3 = /* @__PURE__ */ from_html(`
Username
`); +var root_7$1 = /* @__PURE__ */ from_html(`
URL
`); +var root_8 = /* @__PURE__ */ from_html(`
Notes
`); +var root_9 = /* @__PURE__ */ from_html(``); +var root_5$2 = /* @__PURE__ */ from_html(`

Password
`, 1); var root$4 = /* @__PURE__ */ from_html(`
`); function EntryDetail($$anchor, $$props) { push($$props, true); @@ -6244,15 +6244,24 @@ function EntryDetail($$anchor, $$props) { reset(div_7); reset(div_6); var div_8 = sibling(div_6, 2); - var div_9 = child(div_8); - var div_10 = sibling(child(div_9), 2); - var span = child(div_10); - var text_4 = child(span, true); - reset(span); - var button_2 = sibling(span, 2); - reset(div_10); - reset(div_9); - var div_11 = sibling(div_9, 2); + var node_2 = child(div_8); + var consequent_4 = ($$anchor) => { + var div_9 = root_6$3(); + var div_10 = sibling(child(div_9), 2); + var span = child(div_10); + var text_4 = child(span, true); + reset(span); + var button_2 = sibling(span, 2); + reset(div_10); + reset(div_9); + template_effect(() => set_text(text_4, get(entry).username)); + delegated("click", button_2, () => copyToClipboard(get(entry).username, "Username")); + append($$anchor, div_9); + }; + if_block(node_2, ($$render) => { + if (get(entry).username) $$render(consequent_4); + }); + var div_11 = sibling(node_2, 2); var div_12 = sibling(child(div_11), 2); var span_1 = child(div_12); var text_5 = child(span_1, true); @@ -6263,9 +6272,9 @@ function EntryDetail($$anchor, $$props) { var button_4 = sibling(button_3, 2); reset(div_12); reset(div_11); - var node_2 = sibling(div_11, 2); - var consequent_4 = ($$anchor) => { - var div_13 = root_6$3(); + var node_3 = sibling(div_11, 2); + var consequent_5 = ($$anchor) => { + var div_13 = root_7$1(); var div_14 = sibling(child(div_13), 2); var a = child(div_14); var text_7 = child(a, true); @@ -6280,12 +6289,12 @@ function EntryDetail($$anchor, $$props) { delegated("click", button_5, () => copyToClipboard(get(entry).url, "URL")); append($$anchor, div_13); }; - if_block(node_2, ($$render) => { - if (get(entry).url) $$render(consequent_4); + if_block(node_3, ($$render) => { + if (get(entry).url) $$render(consequent_5); }); - var node_3 = sibling(node_2, 2); - var consequent_5 = ($$anchor) => { - var div_15 = root_7$1(); + var node_4 = sibling(node_3, 2); + var consequent_6 = ($$anchor) => { + var div_15 = root_8(); var div_16 = sibling(child(div_15), 2); var text_8 = child(div_16, true); reset(div_16); @@ -6293,8 +6302,8 @@ function EntryDetail($$anchor, $$props) { template_effect(() => set_text(text_8, get(entry).notes)); append($$anchor, div_15); }; - if_block(node_3, ($$render) => { - if (get(entry).notes) $$render(consequent_5); + if_block(node_4, ($$render) => { + if (get(entry).notes) $$render(consequent_6); }); reset(div_8); var div_17 = sibling(div_8, 2); @@ -6306,9 +6315,9 @@ function EntryDetail($$anchor, $$props) { reset(span_3); reset(div_17); reset(div_5); - var node_4 = sibling(div_5, 2); - var consequent_6 = ($$anchor) => { - var div_18 = root_8(); + var node_5 = sibling(div_5, 2); + var consequent_7 = ($$anchor) => { + var div_18 = root_9(); var div_19 = child(div_18); var p = sibling(child(div_19), 2); var strong = sibling(child(p)); @@ -6335,12 +6344,11 @@ function EntryDetail($$anchor, $$props) { delegated("click", button_7, () => set(showDeleteConfirm, false)); append($$anchor, div_18); }; - if_block(node_4, ($$render) => { - if (get(showDeleteConfirm)) $$render(consequent_6); + if_block(node_5, ($$render) => { + if (get(showDeleteConfirm)) $$render(consequent_7); }); template_effect(($0, $1) => { set_text(text_3, get(entry).title); - set_text(text_4, get(entry).username); set_text(text_5, get(passwordVisible) ? get(decryptedPassword) : "••••••••••••"); set_text(text_6, get(passwordVisible) ? "🙈" : "👁"); set_text(text_9, `Created: ${$0 ?? ""}`); @@ -6348,7 +6356,6 @@ function EntryDetail($$anchor, $$props) { }, [() => new Date(get(entry).createdAt).toLocaleString(), () => new Date(get(entry).updatedAt).toLocaleString()]); delegated("click", button, () => $$props.onEdit(get(entry).id)); delegated("click", button_1, () => set(showDeleteConfirm, true)); - delegated("click", button_2, () => copyToClipboard(get(entry).username, "Username")); delegated("click", button_3, () => set(passwordVisible, !get(passwordVisible))); delegated("click", button_4, () => copyToClipboard(get(decryptedPassword), "Password")); append($$anchor, fragment); @@ -6372,7 +6379,7 @@ var root_3$2 = /* @__PURE__ */ from_html(`
`); var root_4$2 = /* @__PURE__ */ from_html(`
`); var root_6$2 = /* @__PURE__ */ from_html(``); -var root_2$2 = /* @__PURE__ */ from_html(`
`, 1); +var root_2$2 = /* @__PURE__ */ from_html(`
`, 1); var root$2 = /* @__PURE__ */ from_html(`
`); function EntryForm($$anchor, $$props) { push($$props, true); diff --git a/src/components/EntryDetail.svelte b/src/components/EntryDetail.svelte index 7c50c63..ce3ae76 100644 --- a/src/components/EntryDetail.svelte +++ b/src/components/EntryDetail.svelte @@ -100,13 +100,15 @@
-
- Username -
- {entry.username} - + {#if entry.username} +
+ Username +
+ {entry.username} + +
-
+ {/if}
Password diff --git a/src/components/EntryForm.svelte b/src/components/EntryForm.svelte index f136a12..dc74872 100644 --- a/src/components/EntryForm.svelte +++ b/src/components/EntryForm.svelte @@ -118,7 +118,7 @@
- +
diff --git a/src/components/EntryList.svelte b/src/components/EntryList.svelte index 97dc646..9a3842b 100644 --- a/src/components/EntryList.svelte +++ b/src/components/EntryList.svelte @@ -87,7 +87,7 @@ {entry.title} - {entry.username} + {entry.username || '—'} {entry.url || '—'} diff --git a/src/lib/models/schema.js b/src/lib/models/schema.js index 87fb88f..0c9cda4 100644 --- a/src/lib/models/schema.js +++ b/src/lib/models/schema.js @@ -21,7 +21,7 @@ export function generateId() { * @typedef {Object} CredentialEntry * @property {string} id - Unique identifier * @property {string} title - Display name (e.g. "GitHub", "Gmail") - * @property {string} username - Login username or email + * @property {string} [username] - Login username or email (optional) * @property {string} encryptedPassword - AES-GCM encrypted password blob (JSON string) * @property {string} [url] - Website URL * @property {string} [notes] - Free-form notes @@ -36,7 +36,7 @@ export function generateId() { * * @param {Object} data * @param {string} data.title - * @param {string} data.username + * @param {string} [data.username] * @param {string} data.encryptedPassword - Must already be encrypted * @param {string} [data.url] * @param {string} [data.notes] @@ -49,7 +49,7 @@ export function createEntry(data) { return { id: generateId(), title: data.title.trim(), - username: data.username.trim(), + username: data.username?.trim() || '', encryptedPassword: data.encryptedPassword, url: data.url?.trim() || '', notes: data.notes?.trim() || '', @@ -71,7 +71,7 @@ export function updateEntry(existing, data) { return { ...existing, title: data.title !== undefined ? data.title.trim() : existing.title, - username: data.username !== undefined ? data.username.trim() : existing.username, + username: data.username !== undefined ? (data.username?.trim() || '') : existing.username, encryptedPassword: data.encryptedPassword !== undefined ? data.encryptedPassword : existing.encryptedPassword, url: data.url !== undefined ? data.url.trim() : existing.url, notes: data.notes !== undefined ? data.notes.trim() : existing.notes, @@ -119,7 +119,7 @@ export function createGroup(name, color) { export function validateEntry(data) { const errors = [] if (!data.title || !data.title.trim()) errors.push('Title is required') - if (!data.username || !data.username.trim()) errors.push('Username is required') + if (!data.encryptedPassword) errors.push('Password is required') return { valid: errors.length === 0, errors } }