"""Add player authentication token reset support. Adds: * ``player.auth_token_issued_at`` — when the current auth token was issued * ``player.auth_reset_required`` — force re-authentication on next heartbeat * ``player_auth_config`` — single-row token reset interval policy Idempotent: safe to run on every container start. """ import sys sys.path.insert(0, '/app') from app.app import create_app from app.extensions import db from sqlalchemy import text app = create_app() with app.app_context(): print("Adding player authentication token reset support...") # 1. New columns on the player table. columns = [ ("auth_token_issued_at", "DATETIME"), ("auth_reset_required", "BOOLEAN DEFAULT 0"), ] for col_name, col_type in columns: try: db.session.execute(text(f"ALTER TABLE player ADD COLUMN {col_name} {col_type}")) db.session.commit() print(f"✓ '{col_name}' column added to player table.") except Exception as e: if 'duplicate column' in str(e).lower() or 'already exists' in str(e).lower(): print(f"✓ '{col_name}' column already exists, skipping.") else: print(f"✗ Error adding '{col_name}': {e}") raise # 2. Settings table holding the automatic reset interval. try: db.session.execute(text(""" CREATE TABLE IF NOT EXISTS player_auth_config ( id INTEGER PRIMARY KEY, reset_interval_days INTEGER NOT NULL DEFAULT 0, updated_at DATETIME, updated_by VARCHAR(255) ) """)) db.session.commit() print("✓ 'player_auth_config' table ready.") except Exception as e: print(f"✗ Error creating 'player_auth_config': {e}") raise # 3. Backfill: treat existing tokens as issued now so the interval starts # counting from the migration rather than expiring every player at once. try: result = db.session.execute(text( "UPDATE player SET auth_token_issued_at = CURRENT_TIMESTAMP " "WHERE auth_token_issued_at IS NULL" )) db.session.commit() print(f"✓ Backfilled auth_token_issued_at for {result.rowcount} player(s).") except Exception as e: print(f"⚠ Could not backfill auth_token_issued_at: {e}") db.session.rollback() print("Done.")