fix(files): a token made as every session ends goes with them, and a file being shared holds its job

This commit is contained in:
2026-10-15 05:47:00 +02:00
parent 2efa7d5a75
commit 620f84dba4
5 changed files with 199 additions and 7 deletions
+12 -4
View File
@@ -1147,10 +1147,18 @@ def bump_session_epoch(db: Session, user: User) -> None:
"""Invalidate every EXISTING signed cookie for this account by advancing its epoch (SA4). Cookies
minted before the bump carry a now-stale epoch and are rejected by `current_user`. The account's
API tokens go with them (`apitokens.revoke_all`): a token minted from a stolen session must not
outlive the answer to that theft. Not committed — the caller commits it with its change."""
user.session_epoch = (user.session_epoch or 0) + 1
if user.id is not None:
apitokens.revoke_all(db, user.id)
outlive the answer to that theft. Not committed — the caller commits it with its change.
The user's row is locked before the tokens go, the lock `create_token` takes too: a token made at
the same moment either commits first and is deleted here, or waits and sees the new epoch."""
if user.id is None:
user.session_epoch = (user.session_epoch or 0) + 1
return
epoch = db.execute(
select(User.session_epoch).where(User.id == user.id).with_for_update()
).scalar_one()
user.session_epoch = (epoch or 0) + 1
apitokens.revoke_all(db, user.id)
def revoke_untrusted_preset_password(db: Session, user: User) -> None: