fix(auth): a cookie that lands after sign-out no longer signs the browser back in
A renewal answers with the session its request started with. Each session now carries an id; signing out, or signing in as someone else, revokes it (revoked_sessions, migration 0120), and a cookie carrying a revoked id is refused. A cookie from before session ids gets one drawn from the cookie itself. The race after log-out-everywhere fails closed and stays.
This commit is contained in:
@@ -190,6 +190,18 @@ class AuthToken(Base, TimestampMixin):
|
||||
used_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
|
||||
|
||||
|
||||
class RevokedSession(Base):
|
||||
"""The id of a browser session that signed out, or that a sign-in as someone else replaced
|
||||
(`auth.revoke_session`). A request still in flight then can answer with that session's cookie,
|
||||
re-signed by its renewal, after the sign-out cleared it; a cookie whose id is here is refused. A
|
||||
row outlives every cookie that could carry its id, then `revoke_session` drops it."""
|
||||
|
||||
__tablename__ = "revoked_sessions"
|
||||
|
||||
sid: Mapped[str] = mapped_column(String(32), primary_key=True)
|
||||
revoked_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), index=True)
|
||||
|
||||
|
||||
class Invite(Base, CanonicalEmailMixin):
|
||||
"""Access-request / whitelist row. Source of truth for who may sign in; the env
|
||||
ALLOWED_EMAILS/ADMIN_EMAILS act only as a bootstrap fallback (see auth.is_allowed)."""
|
||||
|
||||
Reference in New Issue
Block a user