Commit Graph
5 Commits
Author SHA1 Message Date
sneak 3c46db56d5 Carry file size, thumbnail size, and deletion flag through decryptFile (closes #37)
check / check (push) Successful in 24s
Foundation unit for the cache/API design. Three fields arrived on the wire
but decryptFile dropped them:

- Live files now set `file.size` from `info.fileSize` and `thumbnail.size`
  from `info.thumbSize`, left `undefined` when the server omits `info`.
- A deleted file is returned as a new `EnteFileTombstone` (`id`,
  `collectionID`, `updationTime`, `isDeleted: true`) with no decryption,
  since the server no longer holds ciphertext for it.

decryptFile now returns `EnteFile | EnteFileTombstone`. Rather than making
EnteFile's structural fields optional — which would force `?.`/guards across
every consumer under strict tsc and break the build — a tombstone is a
distinct minimal type, and `EnteFile.isDeleted?: false` is the discriminant
(a live file is never deleted). This keeps all existing consumers untouched;
they still receive fully-populated `EnteFile` values.

client.ts is the only direct caller: it now routes every row through
decryptFile and drops results whose `isDeleted` is set. listFiles still
returns live files only, so its observable behaviour is unchanged.

Model: opus-4-8
2026-09-22 08:54:01 +00:00
sneak 59e0aa7d47 Red: shared collections arrive as sealed boxes with no keyDecryptionNonce
Collections shared with the account are not encrypted with the master
key: the sharer only knows the recipient's public key, so the server
delivers encryptedKey as crypto_box_seal to that key and omits
keyDecryptionNonce entirely. decryptCollection assumed the owned-only
wire format and crashed on fromBase64(undefined) for any account with
an incoming shared album, taking down listCollections and every
command built on it (backup, backup-metadata, ...).

The previous "shared" fixture was unfaithful (secretbox + nonce with a
foreign ownerID, a shape the server never sends), which is why the
suite stayed green. These tests model the real wire format and change
decryptCollection to take the full key material {masterKey, publicKey,
secretKey} so it can unseal shared collection keys.
2026-06-10 11:41:36 -07:00
sneak d8a4b0291e Rename quack to quak
German for 'quack', matching the Ente (German for 'duck') naming. All
references updated: package name, CLI binary, X-Client-Package header,
test descriptions, temp dir prefixes, README, Makefile docker tag.
2026-05-13 18:02:55 -07:00
sneak 44718a92a9 Fix file metadata decryption: use secretstream blob, not secretbox
File metadata is encrypted as a single-chunk secretstream blob (the
'decryptionHeader' is the secretstream init header, not a secretbox
nonce). Collection keys and names correctly use secretbox.

Adds decryptBlob(ciphertext, header, key) to the crypto module as a
convenience wrapper for single-chunk secretstream decryption (init +
pull + verify TAG_FINAL).

Live-tested: collection names and file metadata (titles, types, dates)
decrypt correctly from the real Ente API.
2026-05-13 17:38:18 -07:00
sneak f81216333e Phase 5 red: collection and file decryption tests
10 tests covering decryptCollection (key + name decryption from raw
server JSON, type mapping, isShared, missing name, wrong key) and
decryptFile (key + metadata decryption, fileType number-to-string
mapping, file/thumbnail header passthrough, wrong key).

Adds src/model/types.ts with both raw (server) and decrypted (library)
type definitions. src/model/decrypt.ts has throwing stubs.
2026-05-13 17:12:46 -07:00