- Ensured content is decrypted before allowing conversion to plain text. - Added detailed diagnostic logging to reactive effects to debug loop issues. - Integrated background sync skip logic to preserve decrypted state.
99 lines
3.3 KiB
TypeScript
99 lines
3.3 KiB
TypeScript
import { ae_util } from '$lib/ae_utils/ae_utils';
|
|
import type { ae_JournalEntry, ae_Journal } from '$lib/types/ae_types';
|
|
|
|
/**
|
|
* Result structure for decryption operations.
|
|
*/
|
|
export interface DecryptionResult {
|
|
success: boolean;
|
|
content?: string;
|
|
history?: string;
|
|
error?: string;
|
|
}
|
|
|
|
/**
|
|
* Decrypts a journal entry's content and history using the provided or stored passcode.
|
|
*
|
|
* @param entry The journal entry object to decrypt.
|
|
* @param journal The parent journal object (provides base passcode and private_passcode).
|
|
* @param typed_passcode Optional: A user-entered passcode override.
|
|
* @returns A Promise resolving to a DecryptionResult.
|
|
*/
|
|
export async function decrypt_journal_entry(
|
|
entry: ae_JournalEntry,
|
|
journal: ae_Journal,
|
|
typed_passcode?: string
|
|
): Promise<DecryptionResult> {
|
|
|
|
// Safety check: if not encrypted, return as-is
|
|
if (!entry.content_encrypted) {
|
|
return {
|
|
success: true,
|
|
content: entry.content ?? '',
|
|
history: entry.history ?? ''
|
|
};
|
|
}
|
|
|
|
// Determine which key to use
|
|
let journal_key = typed_passcode;
|
|
let key_source = 'user_typed';
|
|
|
|
// If no override, try the private passcode stored on the journal object
|
|
if (!journal_key?.length) {
|
|
journal_key = journal.private_passcode;
|
|
key_source = 'journal_private_passcode';
|
|
}
|
|
|
|
if (!journal_key) {
|
|
console.warn('decrypt_journal_entry: No key available. Source:', key_source);
|
|
return {
|
|
success: false,
|
|
error: 'No passcode provided or available for decryption.'
|
|
};
|
|
}
|
|
|
|
// Aether standard: combine the journal's public passcode with the private key
|
|
const decrypt_key = `${journal.passcode ?? ''}:${journal_key}`;
|
|
|
|
console.log(`decrypt_journal_entry: Attempting decryption. Source: ${key_source}`);
|
|
// console.log(`decrypt_journal_entry: Key: ${decrypt_key}`); // Log ONLY for deep debugging
|
|
|
|
try {
|
|
// Decrypt Primary Content
|
|
const result = await ae_util.decrypt_wrapper(entry.content_encrypted, decrypt_key);
|
|
|
|
if (result === false) {
|
|
console.error('decrypt_journal_entry: Decryption wrapper returned false.');
|
|
return {
|
|
success: false,
|
|
error: 'Decryption failed. Incorrect passcode or corrupted data.'
|
|
};
|
|
}
|
|
|
|
const decrypted_text = typeof result === 'string' ? result : '';
|
|
let decrypted_history = '';
|
|
|
|
// Decrypt History (if it exists)
|
|
if (entry.history_encrypted) {
|
|
const h_res = await ae_util.decrypt_wrapper(entry.history_encrypted, decrypt_key);
|
|
if (h_res !== false) {
|
|
decrypted_history = typeof h_res === 'string' ? h_res : '';
|
|
}
|
|
}
|
|
|
|
console.log(`decrypt_journal_entry: SUCCESS. Source: ${key_source}, Content length: ${decrypted_text.length}. Preview: ${decrypted_text.substring(0, 30).replace(/\n/g, ' ')}...`);
|
|
return {
|
|
success: true,
|
|
content: decrypted_text,
|
|
history: decrypted_history
|
|
};
|
|
|
|
} catch (err: any) {
|
|
console.error('decrypt_journal_entry error:', err);
|
|
return {
|
|
success: false,
|
|
error: `System error during decryption: ${err.message}`
|
|
};
|
|
}
|
|
}
|