harden redemption, expiry limits and token storage

Findings from a pass over the plugin, smallest first:

Redemptions now run one at a time behind a gate. The status checks and the status
write that follows them were not atomic, so two requests arriving together with
the same one-use token could both mint a guest session. The spent-link check also
moved above the tagging step, so hammering an already-used link no longer re-tags
a whole series on every hit.

The configured maximum expiry is actually respected. Both the API and the picker
did Math.max(configured, 720), so setting the ceiling to anything under 30 days
was silently ignored. The picker now also hides the quick-pick durations that sit
above the ceiling.

The share URL, which carries the raw token, is dropped from the record when the
link is revoked or expires. Records are never deleted, so dead tokens were
accumulating in the store forever. Live links keep it so the dashboard can still
copy them, and the README claim that no token is ever written to disk is corrected
to say what the code actually does.

The HMAC key file is created 0600 instead of inheriting the default mask.
Cette révision appartient à :
Franciskid
2026-07-26 16:22:41 +02:00
Parent 36fc574d49
révision 5348b4e78b
6 fichiers modifiés avec 67 ajouts et 15 suppressions
+7 -4
Voir le fichier
@@ -33,8 +33,9 @@ real user or handing over a login that sees everything.
and records the share. Share a series or a season and the tag is applied to
the whole tree underneath it too - series, seasons and episodes - so the
guest can actually browse from the series page down into a season and an
episode, not just see a single locked node. The raw link token is shown to
you once and never stored, only a keyed HMAC hash of it is kept.
episode, not just see a single locked node. Lookups only ever go through a
keyed HMAC hash of the token, and the link itself is dropped from the record
once it is revoked or expired.
3. Whoever opens the link gets a throwaway guest user created on the spot,
restricted by that tag to the shared item and its tree, and is signed in
automatically. They land on the title's page.
@@ -92,8 +93,10 @@ only a keyed HMAC hash of the token plus the metadata needed to audit and clean
up the link. So:
1. raw tokens are never logged
2. raw tokens are never written to disk
3. the token is only returned in the creation response
2. only the token's HMAC hash is used to look a link up
3. the finished share URL is kept on the record while the link is live, so the
dashboard can re-copy it, and is dropped again the moment the link is revoked
or expires
4. token validation is a hash comparison
5. guest-user creation and teardown live behind explicit service calls
6. the real access boundary is the server-side tag policy; the web-client