new category flow

This commit is contained in:
nicwands
2026-03-03 17:09:29 -05:00
parent e843b7662d
commit e9e0abe380
12 changed files with 463 additions and 109 deletions

View File

@@ -33,7 +33,9 @@ export default class NotesAPI {
const key = Buffer.from(this.encryptionKey, 'hex')
if (key.length !== 32) {
throw new Error('Encryption key must be 64 hex characters (32 bytes)')
throw new Error(
'Encryption key must be 64 hex characters (32 bytes)',
)
}
const nonce = sodium.randombytes_buf(sodium.crypto_secretbox_NONCEBYTES)
@@ -42,7 +44,7 @@ export default class NotesAPI {
const ciphertext = sodium.crypto_secretbox_easy(
Buffer.from(message),
nonce,
key
key,
)
const combined = Buffer.concat([nonce, ciphertext])
@@ -56,20 +58,53 @@ export default class NotesAPI {
const key = Buffer.from(this.encryptionKey, 'hex')
if (key.length !== 32) {
throw new Error('Encryption key must be 64 hex characters (32 bytes)')
throw new Error(
'Encryption key must be 64 hex characters (32 bytes)',
)
}
let combined
try {
combined = Buffer.from(encryptedData, 'base64')
} catch (e) {
throw new Error('Invalid encrypted data: not valid base64')
}
if (
combined.length <
sodium.crypto_secretbox_NONCEBYTES +
sodium.crypto_secretbox_MACBYTES
) {
throw new Error('Invalid encrypted data: too short')
}
const combined = Buffer.from(encryptedData, 'base64')
const nonce = combined.slice(0, sodium.crypto_secretbox_NONCEBYTES)
const ciphertext = combined.slice(sodium.crypto_secretbox_NONCEBYTES)
const decrypted = sodium.crypto_secretbox_open_easy(
ciphertext,
nonce,
key
)
let decrypted
try {
decrypted = sodium.crypto_secretbox_open_easy(
ciphertext,
nonce,
key,
)
} catch (e) {
throw new Error('Decryption failed: wrong key or corrupted data')
}
return JSON.parse(decrypted.toString())
if (!decrypted) {
throw new Error('Decryption failed: no data returned')
}
const decryptedStr = Buffer.from(decrypted).toString('utf8')
try {
return JSON.parse(decryptedStr)
} catch (e) {
throw new Error(
`Decryption succeeded but invalid JSON: ${decryptedStr}`,
)
}
}
async init() {
@@ -81,6 +116,7 @@ export default class NotesAPI {
for (const encryptedNote of encryptedNotes) {
try {
const note = this._decrypt(encryptedNote.data || encryptedNote)
this.notesCache.set(note.id, note)
this.index.add(note.id, note.title + '\n' + note.content)
} catch (error) {