"""add token_epoch to users Revision ID: k1l2m3n4o5p6 Revises: j0k1l2m3n4o5 Create Date: 2026-08-26 00:00:00.000000 Adds a monotonic session-generation counter so credential changes can revoke every token issued before them. Previously, changing the master password left all outstanding access and refresh tokens valid — a stolen refresh token kept working for its full 7-day lifetime after the victim changed their password. The response said "Please log in again" but nothing enforced it. Every JWT now carries an `epoch` claim. require_jwt (and /refresh) compare it against users.token_epoch and reject on mismatch. change_password and /recover increment the column, which invalidates every previously issued token at once. A counter rather than a timestamp: JWT `iat` has one-second granularity, so a token minted in the same second as the password change could otherwise slip through the comparison. Existing tokens predate the claim and decode with epoch 0, which matches the server_default — so deploying this does not sign everyone out. The first password change moves them to 1 and invalidates them as intended. """ from alembic import op import sqlalchemy as sa revision = 'k1l2m3n4o5p6' down_revision = 'j0k1l2m3n4o5' branch_labels = None depends_on = None def upgrade(): op.add_column( 'users', sa.Column( 'token_epoch', sa.Integer, nullable=False, server_default='0', ), ) def downgrade(): op.drop_column('users', 'token_epoch')