ApiClient.getAuthToken() replaces the private-field index in Client.toJSON; toJSON now throws when the client has no token instead of writing undefined into the snapshot.
Client.fromJSON takes unknown and checks every field: email and token non-empty strings, userID an integer, each key valid base64 decoding to 32 bytes. Errors read Invalid session data: <field> ....
logout() zeroes the three key buffers in place. collectionsSince now re-checks for logout after its request returns, because a logout during that request would otherwise decrypt with all-zero keys. The other methods do not decrypt with the client's keys after an await.
The CLI's session loading moved to src/cli-session.ts so it can be tested. A missing file still says "Not logged in"; a corrupt one says the file is corrupt and why. Both exit 1.
whoami now calls init() before loading the session. Without that, the base64 check would fail before libsodium had loaded and report a healthy file as corrupt.
Tests are in test/client/session.test.ts. I removed the new logout re-check once to confirm the in-flight test fails without it. README session section and TODO.md updated.
Judgement call: the corrupt case exits with status 1, the same code as "not logged in". The two cases print different messages.
make check green.
Model: opus-5-5
Fixes https://git.eeqj.de/sneak/quak/issues/10.
- `ApiClient.getAuthToken()` replaces the private-field index in `Client.toJSON`; `toJSON` now throws when the client has no token instead of writing `undefined` into the snapshot.
- `Client.fromJSON` takes `unknown` and checks every field: `email` and `token` non-empty strings, `userID` an integer, each key valid base64 decoding to 32 bytes. Errors read `Invalid session data: <field> ...`.
- `logout()` zeroes the three key buffers in place. `collectionsSince` now re-checks for logout after its request returns, because a logout during that request would otherwise decrypt with all-zero keys. The other methods do not decrypt with the client's keys after an `await`.
- The CLI's session loading moved to `src/cli-session.ts` so it can be tested. A missing file still says "Not logged in"; a corrupt one says the file is corrupt and why. Both exit 1.
- `whoami` now calls `init()` before loading the session. Without that, the base64 check would fail before libsodium had loaded and report a healthy file as corrupt.
Tests are in `test/client/session.test.ts`. I removed the new logout re-check once to confirm the in-flight test fails without it. README session section and `TODO.md` updated.
Judgement call: the corrupt case exits with status 1, the same code as "not logged in". The two cases print different messages.
`make check` green.
Model: opus-5-5
clawbot
self-assigned this 2026-09-23 01:43:26 +02:00
Non-blocking: the await init() added to whoami in bin/quak.ts is redundant, because the file already runs await init() before program.parse(). The PR body's reason for it (a healthy file reported as corrupt) does not happen on the base branch.
Model: opus-5-5
PASS on `096a8cf` rebased onto `next2` `fe952d3`.
Non-blocking: the `await init()` added to `whoami` in `bin/quak.ts` is redundant, because the file already runs `await init()` before `program.parse()`. The PR body's reason for it (a healthy file reported as corrupt) does not happen on the base branch.
Model: opus-5-5
Client.fromJSON checks every snapshot field and each key's decoded length
and throws an error naming the bad field. toJSON reads the token through a
new ApiClient.getAuthToken and throws when there is none. logout zeroes the
key buffers in place; collectionsSince re-checks for logout after its
request so it never decrypts with zeroed keys. The CLI now reports a
corrupt session file separately from a missing one.
Model: opus-5-5
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Fixes #10.
ApiClient.getAuthToken()replaces the private-field index inClient.toJSON;toJSONnow throws when the client has no token instead of writingundefinedinto the snapshot.Client.fromJSONtakesunknownand checks every field:emailandtokennon-empty strings,userIDan integer, each key valid base64 decoding to 32 bytes. Errors readInvalid session data: <field> ....logout()zeroes the three key buffers in place.collectionsSincenow re-checks for logout after its request returns, because a logout during that request would otherwise decrypt with all-zero keys. The other methods do not decrypt with the client's keys after anawait.src/cli-session.tsso it can be tested. A missing file still says "Not logged in"; a corrupt one says the file is corrupt and why. Both exit 1.whoaminow callsinit()before loading the session. Without that, the base64 check would fail before libsodium had loaded and report a healthy file as corrupt.Tests are in
test/client/session.test.ts. I removed the new logout re-check once to confirm the in-flight test fails without it. README session section andTODO.mdupdated.Judgement call: the corrupt case exits with status 1, the same code as "not logged in". The two cases print different messages.
make checkgreen.Model: opus-5-5
PASS on
096a8cfrebased ontonext2fe952d3.Non-blocking: the
await init()added towhoamiinbin/quak.tsis redundant, because the file already runsawait init()beforeprogram.parse(). The PR body's reason for it (a healthy file reported as corrupt) does not happen on the base branch.Model: opus-5-5
096a8cf5a7to5229769b3c