mirror of
https://github.com/cupcakearmy/cryptgeon.git
synced 2026-09-26 20:41:45 +00:00
3.4 KiB
3.4 KiB
Roadmap
Todo
- Add remaining shared tooling to the pnpm catalog (
vite,tsdown). - Move formatting, linting and type-checking + git hooks onto
vite-plus(oxlint, oxfmt, vitest). - Re-add CSP (
Content-Security-Policy) wired into the axum router (was incsp.rs, removed as unused).
Unified payload (drop the text/file union)
Follow-up iteration of the inner payload, parked as
v3.1(not part of core v3).
Everything becomes a file. Text is just a FileDTO with inline: true. The { type: "text" } | { type: "files" } union is removed.
# Inner layer (encrypted, client-only)
{ files: [
{ name: string, mime: string, size: number, data: bytes, inline?: boolean }
] }
FileDTOgainsinline?: boolean(defaultfalse).inline: true= the file was authored inline at compose time (e.g. an empty text file the user typed into). Purely a client/UI hint — rides inside the encrypted inner payload, the server never sees it.inline: truefiles render as an editable text editor; the rest render as binary file cards (upload/download).- Default composer state = one empty
inline:truetext file the user edits. NoisFiletoggle.
Impact by area
- Server / wire protocol /
api.ts: unchanged. Still an opaque encrypteddatablob in the outer msgpack envelope. - Shared codec:
NoteContentbecomes{ files: FileDTO[] }; drop the union +switch(type)inunpackContent.packContent(input: FileDTO[], password?). Breaking inner-msgpack schema → ok, pre-release. - Frontend (
Create.svelte— biggest): onefiles: FileDTO[]model; default emptyinlinetext file; editor binds a string, encodes to bytes on submit; add real files via upload (inline:false). - CLI:
send text "x"→files:[{ name:'note.txt', mime:'text/plain', data:utf8, inline:true }].send file a b→ droptypeunion.open/download prints text files, saves the rest. - Tests:
payload.test.tsrewritten to{ files:[...] }; playwrightswitch-file/text-fieldcomposer specs collapse + rework.
Watches
- text↔bytes round-trip in the editor (encoding, line-endings);
sizemust be set from the encoded bytes (matchesSIZE_LIMIT/ preview) — recompute after text→bytes;- pasted binary files keep
inline:false; only inline-authored text isinline:true.
Payload pipeline
flowchart TD
subgraph WRITE["CLIENT — encode / compress / encrypt"]
A[Text or Files] --> B{password?}
B -->|yes| C1[deriveKey password+salt<br>extra=encode salt,N,r,p]
B -->|no| C2[generateKey random 32B]
C2 --> D[URL fragment hex key]
C1 --> E
D --> E
A --> F[encode inner files]
F -->|encode content| G[inner msgpack]
G --> H[LZ4 compress]
H --> I[XChaCha20 encrypt]
I -->|data| J[POST msgpack meta+data]
C1 -->|extra| J
end
subgraph SERVER["SERVER — agnostic"]
J --> K{hash store: views, expiration, extra, data}
end
subgraph READ["CLIENT — read"]
L[meta/extra from PREVIEW] --> M{extra present?}
M -->|yes| N[deriveKey pw+salt]
M -->|no| O[key from URL hex fragment]
N --> P[DELETE get envelope data]
O --> P
P --> Q[XChaCha20 decrypt]
Q --> R[LZ4 decompress]
R --> S[msgpack decode files]
S -->|inline:true| T[edit / render text]
S -->|inline:false| U[save files]
end