diff --git a/src/lib/ae_journals/ae_journals__journal_entry.ts b/src/lib/ae_journals/ae_journals__journal_entry.ts index f72a4e7a..584034cb 100644 --- a/src/lib/ae_journals/ae_journals__journal_entry.ts +++ b/src/lib/ae_journals/ae_journals__journal_entry.ts @@ -342,10 +342,20 @@ export async function db_save_ae_obj_li__journal_entry( let content = obj.content ?? ''; // remove the most common zerowidth characters from the start of the file - let content_cleaned: string = content.replace(/^[\u200B\u200C\u200D\u200E\u200F\uFEFF]/,""); - let content_md_html: null|string = await marked.parse(content_cleaned ?? '') ?? null; + let content_cleaned: null|string = null; + let content_md_html: null|string = null; // await marked.parse(content_cleaned ?? '') ?? null; // let content_md_html_alt: null|string = await marked.parse(content_cleaned ?? '', { gfm: false }) ?? null; + if (obj.content_encrypted) { + // In theory "content" should be null if "content_encrypted" has a value. + content = null; // obj.content_encrypted; + content_cleaned = null; + content_md_html = null; + } else { + content_cleaned = content.replace(/^[\u200B\u200C\u200D\u200E\u200F\uFEFF]/,""); + content_md_html = await marked.parse(content_cleaned ?? '') ?? null; + } + let obj_record = { id: obj.journal_entry_id_random, journal_entry_id: obj.journal_entry_id_random, diff --git a/src/routes/journals/ae_comp__journal_entry_obj_id_view.svelte b/src/routes/journals/ae_comp__journal_entry_obj_id_view.svelte index 0bc9eb74..22432295 100644 --- a/src/routes/journals/ae_comp__journal_entry_obj_id_view.svelte +++ b/src/routes/journals/ae_comp__journal_entry_obj_id_view.svelte @@ -12,7 +12,7 @@ import { Globe, Group, MessageSquareWarning, Minus, NotebookPen, NotebookText, NotepadTextDashed, - Pencil, Plus, + Pencil, PenLine, Plus, RemoveFormatting, Search, Shapes, Share2, ShieldCheck, ShieldMinus, Siren, Skull, @@ -127,7 +127,9 @@ $effect(() => { console.log('TEST: tmp_entry_obj and orig_entry_obj available; marking tmp_entry_obj as changed'); // tmp_entry_obj_changed = JSON.stringify(tmp_entry_obj) != JSON.stringify($lq__journal_entry_obj); // tmp_entry_obj_changed = JSON.stringify(tmp_entry_obj) != JSON.stringify(orig_entry_obj); - tmp_entry_obj_changed = true; + // if (!decrypted_content) { + tmp_entry_obj_changed = true; + // } } else { console.log('TEST: tmp_entry_obj == orig_entry_obj'); tmp_entry_obj_changed = false; @@ -158,6 +160,7 @@ async function update_journal_entry() { alert_msg: tmp_entry_obj?.alert_msg, category_code: tmp_entry_obj?.category_code, content: tmp_entry_obj?.content, + content_encrypted: null, // This should only be generated below. group: tmp_entry_obj?.group, archive_on: tmp_entry_obj?.archive_on, name: tmp_entry_obj?.name, @@ -165,7 +168,8 @@ async function update_journal_entry() { }; if (tmp_entry_obj?.content && tmp_entry_obj?.private) { - content = $lq__journal_entry_obj?.content; + console.log('TEST: Saving encrypted content', tmp_entry_obj?.content); + content = tmp_entry_obj?.content; // Encrypt the content let encrypted_base64 = await ae_util.encrypt_content(content, test_key); @@ -177,6 +181,24 @@ async function update_journal_entry() { const combined_data = Array.from(encryption_iv).map(byte => byte.toString(16).padStart(2, '0')).join('') + ':' + encrypted_base64_content; data_kv.content_encrypted = combined_data; + data_kv.content = null; + decrypted_content = ''; + } else if (decrypted_content && !tmp_entry_obj?.private) { + console.log('TEST: Saving decrypted content', decrypted_content); + content = decrypted_content; + + data_kv.content = content; + decrypted_content = ''; + } else if (tmp_entry_obj?.content_encrypted && !tmp_entry_obj?.private) { + // alert('You must decrypt the content before saving it.'); + console.log('TEST: You must decrypt the content before saving it.'); + return false; + } else { + console.log('TEST: Saving content without encryption', tmp_entry_obj?.content); + // Clear content_encrypted again. Just in case. + // data_kv.content_encrypted = null; + decrypted_content = ''; + // tmp_entry_obj.content_encrypted = null; } // Call API to save the content @@ -252,14 +274,14 @@ async function change_journal_id() { // return decodedContent; // } -// Example usage -(async () => { - const keyData = "my-secret-key"; - const content = "This is my test content to encrypt and decrypt."; +// // Example usage +// (async () => { +// const keyData = "my-secret-key"; +// const content = "This is my test content to encrypt and decrypt."; - const { base64, iv } = await ae_util.encrypt_content(content, keyData); - await ae_util.decrypt_content(base64, iv, keyData); -})(); +// const { base64, iv } = await ae_util.encrypt_content(content, keyData); +// await ae_util.decrypt_content(base64, iv, keyData); +// })(); const test_key = "my-secret-key"; let content = "This is my test content to encrypt and decrypt."; @@ -270,9 +292,9 @@ let trigger_decrypt: boolean = $state(false); $effect(async () => { if (tmp_entry_obj?.content_encrypted && trigger_decrypt) { + trigger_decrypt = false; log_lvl = 1; - trigger_decrypt = false; let combined_data = tmp_entry_obj?.content_encrypted; let [encryption_iv_hex, encrypted_base64_content] = combined_data.split(':'); encryption_iv = new Uint8Array(encryption_iv_hex.match(/.{1,2}/g).map(byte => parseInt(byte, 16))); @@ -281,10 +303,14 @@ $effect(async () => { } let decrypted = await ae_util.decrypt_content(encrypted_base64_content, encryption_iv, test_key); + // decrypted_content = 'XXX '+decrypted+' XXX'; decrypted_content = decrypted; if (log_lvl) { console.log('Decrypted content:', decrypted_content); } + tmp_entry_obj.content = decrypted_content; + // orig_entry_obj.content = decrypted_content; + // tmp_entry_obj_changed = false; // tmp_entry_obj.content_encrypted = null; } @@ -332,12 +358,17 @@ $effect(async () => { } else { $journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id] = true; } + + // if ($ae_loc.trusted_access && !$journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id]) { + // trigger_decrypt = true; + // } }} class="btn btn-icon-sm inline-block" title="Toggle edit mode for this journal entry" > {#if $journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id]} - + + {:else} {/if} @@ -643,13 +674,50 @@ $effect(async () => { { - tmp_entry_obj.private = !$lq__journal_entry_obj?.private; - update_journal_entry(); + if ($ae_loc.edit_mode) { + if (tmp_entry_obj?.content_encrypted && tmp_entry_obj?.private) { + alert('You must decrypt the content before saving it!!'); + return false; + } + + if (tmp_entry_obj.private) { + if (confirm('Not private and decrypt?')) { + tmp_entry_obj.private = !$lq__journal_entry_obj?.private; + + + // } else { + update_journal_entry(); + // } + // update_journal_entry(); + } + } else { + tmp_entry_obj.private = !$lq__journal_entry_obj?.private; + update_journal_entry(); + } + } else { + if (tmp_entry_obj?.content_encrypted && !decrypted_content) { + trigger_decrypt = true; + // } else if (tmp_entry_obj?.content_encrypted && decrypted_content && tmp_entry_obj_changed) { + // // This is ok because it has not really changed? + // // decrypted_content = ''; + // alert('This journal entry has changed.'); + + } else if (tmp_entry_obj?.content_encrypted && decrypted_content) { + decrypted_content = ''; + tmp_entry_obj.content = null; + } + } + }} + ondblclick={() => { + // tmp_entry_obj.private = !$lq__journal_entry_obj?.private; + // update_journal_entry(); }} class="btn-icon-sm" title="Toggle private visibility of this journal entry" > - {#if $lq__journal_entry_obj?.private} + {#if $lq__journal_entry_obj?.private && decrypted_content} + + {:else if $lq__journal_entry_obj?.private} {:else} @@ -757,6 +825,7 @@ $effect(async () => { +{#if (!$journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id])} { @@ -765,15 +834,10 @@ $effect(async () => { $journals_loc.entry.edit = !$journals_loc.entry.edit; $journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id] = $journals_loc.entry.edit; } - - if ($ae_loc.trusted_access && $journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id]) { - trigger_decrypt = true; - } }} role={$ae_loc.edit_mode ? 'button' : 'article'} tabindex={$ae_loc.edit_mode ? 0 : -1} - class:hidden={!$ae_loc.trusted_access || $journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id]} class=" flex-grow flex flex-col items-center justify-center @@ -805,7 +869,15 @@ $effect(async () => { " id="rendered_journal_entry_content_{$lq__journal_entry_obj?.journal_entry_id}" > - {@html decrypted_content ?? $lq__journal_entry_obj?.content_md_html} + {#if decrypted_content?.length} + {@html decrypted_content} + {:else if $lq__journal_entry_obj?.content_encrypted} + + {@html $lq__journal_entry_obj?.content_encrypted} + + {:else} + {@html $lq__journal_entry_obj?.content_md_html} + {/if} +{:else if ($journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id])} + + + {#if ($lq__journal_entry_obj?.content_encrypted && !decrypted_content)} + + The entry must be decrypted before it can be edited. + + + {:else} + - - - { - if ($ae_loc.trusted_access && $ae_loc.edit_mode) { - // Toggle edit mode - $journals_loc.entry.edit = !$journals_loc.entry.edit; - $journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id] = $journals_loc.entry.edit; - } - }} - class:border-orange-200={$ae_loc.edit_mode} - class:hover:border-orange-500={$ae_loc.edit_mode} - class=" - flex-grow min-h-48 h-full w-full - p-2 - bg-slate-100 text-gray-900 - dark:bg-slate-900 dark:text-gray-100 - shadow-lg rounded-lg - border border-gray-200 dark:border-gray-700 - hover:border-gray-500 dark:hover:border-gray-500 - " + { + if ($ae_loc.trusted_access && $ae_loc.edit_mode) { + // Toggle edit mode + $journals_loc.entry.edit = !$journals_loc.entry.edit; + $journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id] = $journals_loc.entry.edit; + } + }} + disabled={tmp_entry_obj.content_encrypted && !decrypted_content} + class:border-orange-200={$ae_loc.edit_mode} + class:hover:border-orange-500={$ae_loc.edit_mode} + class=" + flex-grow min-h-48 h-full w-full + p-2 + bg-slate-100 text-gray-900 + dark:bg-slate-900 dark:text-gray-100 + shadow-lg rounded-lg + border border-gray-200 dark:border-gray-700 + hover:border-gray-500 dark:hover:border-gray-500 + " placeholder="Edit journal entry content here..." > - - { - update_journal_entry(); - }} - disabled={!tmp_entry_obj_changed} - class:variant-filled-error={tmp_entry_obj_changed} - class=" - btn btn-sm md:btn-md lg:btn-lg - min-w-72 w-full lg:min-w-96 - max-w-96 - hover:variant-outline-success - hover:variant-filled-success - " - > - Save Changes? - + + { + update_journal_entry(); + }} + disabled={!tmp_entry_obj_changed} + class:variant-filled-error={tmp_entry_obj_changed} + class=" + btn btn-sm md:btn-md lg:btn-lg + min-w-72 w-full lg:min-w-96 + max-w-96 + hover:variant-outline-success + hover:variant-filled-success + " + > + Save Changes? + - - {#if updated_idb} - - WARNING: IDB object has been updated since last load. - + + {#if updated_idb} + + WARNING: IDB object has been updated since last load. + + {/if} + + + + + {/if} - - - - - +{/if}