diff --git a/src/lib/ae_events/ae_events__event_presentation.ts b/src/lib/ae_events/ae_events__event_presentation.ts
index 8d803aac..459eae95 100644
--- a/src/lib/ae_events/ae_events__event_presentation.ts
+++ b/src/lib/ae_events/ae_events__event_presentation.ts
@@ -411,7 +411,9 @@ export async function update_ae_obj__event_presentation(
if (event_presentation_obj_update_result) {
if (try_cache) {
db_save_ae_obj_li__event_presentation({
- obj_type: 'event_presentation', obj_li: [event_presentation_obj_update_result]
+ obj_type: 'event_presentation',
+ obj_li: [event_presentation_obj_update_result],
+ log_lvl: log_lvl
});
}
return event_presentation_obj_update_result;
diff --git a/src/lib/ae_journals/ae_journals__journal_entry.ts b/src/lib/ae_journals/ae_journals__journal_entry.ts
index 3868027b..b7dfda0a 100644
--- a/src/lib/ae_journals/ae_journals__journal_entry.ts
+++ b/src/lib/ae_journals/ae_journals__journal_entry.ts
@@ -261,27 +261,90 @@ export async function delete_ae_obj_id__journal_entry(
// Updated 2025-03-15
+// export async function update_ae_obj__journal_entry(
+// {
+// api_cfg,
+// journal_entry_id,
+// data_kv,
+// params = {},
+// try_cache = true,
+// log_lvl = 0
+// }: {
+// api_cfg: any,
+// journal_entry_id: string,
+// data_kv: key_val,
+// params?: key_val,
+// try_cache?: boolean,
+// log_lvl?: number
+// }
+// ) {
+// if (log_lvl) {
+// console.log(`*** update_ae_obj__journal_entry() *** journal_entry_id=${journal_entry_id}`, data_kv);
+// }
+// ae_promises.update__journal_entry_obj = api.update_ae_obj_id_crud({
+// api_cfg: api_cfg,
+// obj_type: 'journal_entry',
+// obj_id: journal_entry_id,
+// fields: data_kv,
+// key: api_cfg.api_crud_super_key,
+// params: params,
+// return_obj: true,
+// log_lvl: log_lvl
+// })
+// .then(async function (journal_entry_obj_update_result) {
+// // if (journal_entry_obj_update_result) {
+// if (try_cache) {
+// db_save_ae_obj_li__journal_entry({
+// obj_type: 'journal_entry',
+// obj_li: [journal_entry_obj_update_result],
+// log_lvl: log_lvl
+// })
+// .then(function (result) {
+// return result;
+// })
+// .finally(function () {
+// return journal_entry_obj_update_result;
+// });
+// } else {
+// return journal_entry_obj_update_result;
+// }
+// // } else {
+// // return null;
+// // }
+// })
+// .catch(function (error) {
+// console.log('No results returned or failed.', error);
+// })
+// .finally(function () {
+// });
+
+// if (log_lvl) {
+// console.log('ae_promises.update__journal_entry_obj:', ae_promises.update__journal_entry_obj);
+// }
+// return await ae_promises.update__journal_entry_obj;
+// }
+
export async function update_ae_obj__journal_entry(
- {
- api_cfg,
- journal_entry_id,
- data_kv,
- params = {},
- try_cache = true,
- log_lvl = 0
- }: {
- api_cfg: any,
- journal_entry_id: string,
- data_kv: key_val,
- params?: key_val,
- try_cache?: boolean,
- log_lvl?: number
- }
- ) {
+ {
+ api_cfg,
+ journal_entry_id,
+ data_kv,
+ params = {},
+ try_cache = true,
+ log_lvl = 0,
+ }: {
+ api_cfg: any;
+ journal_entry_id: string;
+ data_kv: key_val;
+ params?: key_val,
+ try_cache?: boolean,
+ log_lvl?: number;
+ }) {
if (log_lvl) {
console.log(`*** update_ae_obj__journal_entry() *** journal_entry_id=${journal_entry_id}`, data_kv);
}
- ae_promises.update__journal_entry_obj = await api.update_ae_obj_id_crud({
+
+ const result = await api.update_ae_obj_id_crud({
api_cfg: api_cfg,
obj_type: 'journal_entry',
obj_id: journal_entry_id,
@@ -289,31 +352,24 @@ export async function update_ae_obj__journal_entry(
key: api_cfg.api_crud_super_key,
params: params,
return_obj: true,
- log_lvl: log_lvl
- })
- .then(async function (journal_entry_obj_update_result) {
- if (journal_entry_obj_update_result) {
- if (try_cache) {
- await db_save_ae_obj_li__journal_entry({
- obj_type: 'journal_entry', obj_li: [journal_entry_obj_update_result],
- log_lvl: log_lvl
- });
- }
- return journal_entry_obj_update_result;
- } else {
- return null;
- }
- })
- .catch(function (error) {
- console.log('No results returned or failed.', error);
- })
- .finally(function () {
+ log_lvl: log_lvl,
});
- if (log_lvl) {
- console.log('ae_promises.update__journal_entry_obj:', ae_promises.update__journal_entry_obj);
+ if (result) {
+ if (try_cache) {
+ console.log('Saving to DB...');
+ await db_save_ae_obj_li__journal_entry({
+ obj_type: 'journal_entry',
+ obj_li: [result],
+ log_lvl: log_lvl,
+ });
+ console.log('DB save completed.');
+ }
+ return result;
+ } else {
+ console.error('Failed to update journal entry.');
+ return null;
}
- return ae_promises.update__journal_entry_obj;
}
@@ -331,11 +387,14 @@ export async function db_save_ae_obj_li__journal_entry(
}
) {
if (log_lvl) {
- console.log(`*** db_save_ae_obj_li__journal_entry() ***`, log_lvl);
+ console.log(`*** db_save_ae_obj_li__journal_entry() *** obj_type=${obj_type}`, obj_li);
}
if (obj_li && obj_li.length) {
- obj_li.forEach(async function (obj: any) {
+ // let obj_li_id = obj_li.map((obj: any) => obj.journal_entry_id_random);
+ let obj_li_id: string[] = [];
+ for (const obj of obj_li) {
+ // obj_li.forEach(async function (obj: any) {
if (log_lvl) {
console.log(`ae_obj ${obj_type}:`, obj);
}
@@ -501,6 +560,7 @@ export async function db_save_ae_obj_li__journal_entry(
if (log_lvl) {
console.log(`Updated record with ID: ${obj_record.id}`);
}
+ obj_li_id.push(obj_record.id);
}
if (!id_random) {
console.log(`Failed to save record with ID: ${obj_record.id}`);
@@ -509,8 +569,9 @@ export async function db_save_ae_obj_li__journal_entry(
console.log(`Saved record with ID: ${obj_record.id}`);
}
}
- });
+ // });
+ }
- return true;
+ return obj_li_id;
}
}
diff --git a/src/lib/ae_journals/ae_journals_stores.ts b/src/lib/ae_journals/ae_journals_stores.ts
index 43dcf38a..d738b955 100644
--- a/src/lib/ae_journals/ae_journals_stores.ts
+++ b/src/lib/ae_journals/ae_journals_stores.ts
@@ -88,6 +88,7 @@ let journals_session_data_struct: key_val = {
tmp_obj: {},
},
entry: {
+ decrypt_kv: {}, // Essentially flag that the entry (content and history) can be decrypted.
edit: false,
edit_kv: {},
diff --git a/src/lib/ae_utils/ae_utils__crypto.ts b/src/lib/ae_utils/ae_utils__crypto.ts
index 40fdce30..34f63bf5 100644
--- a/src/lib/ae_utils/ae_utils__crypto.ts
+++ b/src/lib/ae_utils/ae_utils__crypto.ts
@@ -1,12 +1,13 @@
-let log_lvl = 1; // 0 = no logging, 1 = some logging, 2 = all logging
+let log_lvl = 0; // 0 = no logging, 1 = some logging, 2 = all logging
+// Updated 2025-05-08
async function generate_iv() {
const data = new Uint8Array(16);
crypto.getRandomValues(data);
return data;
}
-
+// Updated 2025-05-08
export let encrypt_content = async function encrypt_content(
content: string,
keyData: string
@@ -16,36 +17,52 @@ export let encrypt_content = async function encrypt_content(
const key = await crypto.subtle.importKey('raw', keyBytes, { name: 'AES-CBC' }, false, ['encrypt']);
const encodedContent = await crypto.subtle.encrypt({ name: 'AES-CBC', iv }, key, new TextEncoder().encode(content));
const base64 = btoa(String.fromCharCode(...new Uint8Array(encodedContent)));
- console.log('Base64 Encoded Content:', base64);
+ if (log_lvl) {
+ console.log(`IV: ${iv}; Encrypted:`, base64);
+ }
return { base64, iv };
}
+// Updated 2025-05-08
export let combine_iv_and_base64 = function combine_iv_and_base64(
base64: string,
iv: Uint8Array
) {
- console.log(`IV: ${iv}; Encrypted: ${base64}`);
+ if (log_lvl) {
+ console.log(`IV: ${iv}; Encrypted:`, base64);
+ }
// Combine the IV and encrypted content
const combined = Array.from(iv).map(byte => byte.toString(16).padStart(2, '0')).join('') + ':' + base64;
- console.log('Combined Data v1:', combined);
-
+ if (log_lvl) {
+ console.log('Combined IV and Base64:', combined);
+ }
// const ivBase64 = btoa(String.fromCharCode(...iv));
// const combined = `${ivBase64}:${base64}`;
// console.log('Combined IV and Base64 v2:', combined);
return combined;
}
+// Updated 2025-05-08
export let encrypt_wrapper = async function encrypt_wrapper(
content: string,
keyData: string
) {
+ if (!content) {
+ console.error('No content provided. Returning empty string.');
+ return '';
+ }
+ if (!keyData) {
+ console.error('No keyData provided. Returning empty string.');
+ return '';
+ }
const { base64, iv } = await encrypt_content(content, keyData);
const combined = combine_iv_and_base64(base64, iv);
return combined;
}
// This does not handle errors (invalid key/password) well.
+// Updated 2025-05-08
export let decrypt_content = async function decrypt_content(
base64Content: string,
iv: Uint8Array,
@@ -60,14 +77,19 @@ export let decrypt_content = async function decrypt_content(
return decodedContent;
}
+// Updated 2025-05-08
export let split_iv_and_base64 = function split_iv_and_base64(
combined: string
) {
+ if (!combined) {
+ console.error('No combined string provided. Returning empty object.');
+ return { iv: new Uint8Array(), base64: '' };
+ }
let [iv_hex, encrypted_base64_string] = combined.split(':');
let base64 = encrypted_base64_string
let iv = new Uint8Array(iv_hex.match(/.{1,2}/g).map(byte => parseInt(byte, 16)));
if (log_lvl) {
- console.log(`IV: ${iv}; Encrypted: ${base64}`);
+ console.log(`IV: ${iv}; Encrypted:`, base64);
}
// const [ivBase64, base64] = combined.split(':');
@@ -78,14 +100,21 @@ export let split_iv_and_base64 = function split_iv_and_base64(
return { iv, base64 };
}
+// Updated 2025-05-08
export let decrypt_wrapper = async function decrypt_wrapper(
combined: string,
keyData: string
) {
+ if (!combined) {
+ console.error('No combined string provided. Returning empty string.');
+ return '';
+ }
const { iv, base64 } = split_iv_and_base64(combined);
const decrypted = await decrypt_content(base64, iv, keyData);
- if (log_lvl) {
+ if (log_lvl > 1) {
console.log(`IV: ${iv}; Decrypted:`, decrypted);
+ } else if (log_lvl) {
+ console.log(`IV: ${iv}`);
}
return decrypted;
}
\ No newline at end of file
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 62478940..82ad1c67 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
@@ -1,6 +1,7 @@
@@ -1270,6 +1442,7 @@ function handle_cut_string(old_string: string) {
// Setting private to false will cause the update_journal_entry() function to decrypt the content. This will also copy it to tmp_entry_obj.content.
tmp_entry_obj.private = false;
+ // tmp_entry_obj.
// handle_decrypt_content();
update_journal_entry();
} else {
@@ -1299,28 +1472,50 @@ function handle_cut_string(old_string: string) {
decrypted_content = '';
// tmp_entry_obj.content = null;
} else if (tmp_entry_obj?.private && tmp_entry_obj?.content_encrypted) {
- if (confirm('Are you sure you want to decrypt the content to view/edit?')) {
- // trigger_decrypt = true;
- // handle_decrypt_content();
- // handle_decrypt_string(tmp_entry_obj?.content_encrypted, journal_key).then((result) => {
- // decrypted_content = result;
- // console.log('TEST: Decrypted content:', decrypted_content);
- // });
- decrypted_content = await ae_util.decrypt_wrapper(tmp_entry_obj?.content_encrypted, journal_key);
+ if (!$journals_loc?.entry?.decrypt_kv[$lq__journal_entry_obj?.journal_entry_id]) {
+ if (confirm('Are you sure you want to decrypt the content to view/edit?')) {
+ $journals_loc.entry.decrypt_kv[$lq__journal_entry_obj?.journal_entry_id] = true;
+ $journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id] = 'current';
- // decrypted_content = await handle_decrypt_string(tmp_entry_obj?.content_encrypted, journal_key);
- tmp_entry_obj.content = decrypted_content;
- console.log('TEST: Decrypted content:', decrypted_content);
+ if (!tmp_entry_obj?.content && tmp_entry_obj?.content_encrypted) {
+ console.log('TEST: Decrypting the content...');
+ tmp_entry_obj.content = await ae_util.decrypt_wrapper(tmp_entry_obj?.content_encrypted, journal_key);
+ tmp_entry_obj.content_md_html = handle_marked(tmp_entry_obj?.content);
+ }
+ if (!tmp_entry_obj?.history && tmp_entry_obj?.history_encrypted) {
+ console.log('TEST: Decrypting the history...');
+ tmp_entry_obj.history = await ae_util.decrypt_wrapper(tmp_entry_obj?.history_encrypted, journal_key);
+ tmp_entry_obj.history_md_html = handle_marked(tmp_entry_obj?.history);
+ }
+ // trigger_decrypt = true;
+ // handle_decrypt_content();
+ // handle_decrypt_string(tmp_entry_obj?.content_encrypted, journal_key).then((result) => {
+ // decrypted_content = result;
+ // console.log('TEST: Decrypted content:', decrypted_content);
+ // });
+ // decrypted_content = await ae_util.decrypt_wrapper(tmp_entry_obj?.content_encrypted, journal_key);
+
+ // // decrypted_content = await handle_decrypt_string(tmp_entry_obj?.content_encrypted, journal_key);
+ // tmp_entry_obj.content = decrypted_content;
+ // console.log('TEST: Decrypted content:', decrypted_content);
+ } else {
+ return false;
+ }
} else {
- return false;
+ $journals_loc.entry.decrypt_kv[$lq__journal_entry_obj?.journal_entry_id] = false;
+ $journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id] = false;
+ tmp_entry_obj.content = null;
+ tmp_entry_obj.content_md_html = null;
+ tmp_entry_obj.history = null;
+ tmp_entry_obj.history_md_html = null;
}
}
}}
- class:hidden={!$lq__journal_entry_obj?.private}
+ class:hidden={!$lq__journal_entry_obj?.private || !tmp_entry_obj?.content_encrypted}
class="btn-icon btn-icon-sm variant-soft-secondary hover:variant-filled-secondary transition"
title="Toggle viewing/editing of private encrypted content"
>
- {#if $lq__journal_entry_obj?.private && decrypted_content}
+ {#if $lq__journal_entry_obj?.private && tmp_entry_obj?.content}