from __future__ import annotations import os import sqlite3 from datetime import datetime, timezone from pathlib import Path DB_PATH = Path(os.getenv("AUTH_DB_PATH", "auth_service.sqlite3")).expanduser() def now_iso() -> str: return datetime.now(timezone.utc).isoformat() def connect() -> sqlite3.Connection: conn = sqlite3.connect(DB_PATH) conn.row_factory = sqlite3.Row return conn def approve(conn: sqlite3.Connection, request_id: int) -> None: row = conn.execute( "SELECT id, phone, password_hash, salt, status FROM registration_requests WHERE id = ?", (request_id,), ).fetchone() if row is None: print(f"request #{request_id} not found") return if row["status"] != "pending": print(f"request #{request_id} already {row['status']}") return try: conn.execute( "INSERT INTO users(phone, password_hash, salt, created_at) VALUES(?, ?, ?, ?)", (row["phone"], row["password_hash"], row["salt"], now_iso()), ) conn.execute( "UPDATE registration_requests SET status='approved', reviewed_at=?, review_note=? WHERE id=?", (now_iso(), "approved in manual_review", request_id), ) conn.commit() print(f"approved request #{request_id} ({row['phone']})") except sqlite3.IntegrityError: conn.execute( "UPDATE registration_requests SET status='rejected', reviewed_at=?, review_note=? WHERE id=?", (now_iso(), "phone already exists", request_id), ) conn.commit() print(f"rejected request #{request_id}: phone already exists") def reject(conn: sqlite3.Connection, request_id: int, note: str) -> None: row = conn.execute( "SELECT id, status, phone FROM registration_requests WHERE id = ?", (request_id,), ).fetchone() if row is None: print(f"request #{request_id} not found") return if row["status"] != "pending": print(f"request #{request_id} already {row['status']}") return conn.execute( "UPDATE registration_requests SET status='rejected', reviewed_at=?, review_note=? WHERE id=?", (now_iso(), note, request_id), ) conn.commit() print(f"rejected request #{request_id} ({row['phone']})") def main() -> None: if not DB_PATH.exists(): print(f"db not found: {DB_PATH}") return with connect() as conn: rows = conn.execute( """ SELECT id, phone, invite_code, created_at FROM registration_requests WHERE status='pending' ORDER BY id ASC """ ).fetchall() if not rows: print("no pending requests") return print(f"pending requests: {len(rows)}") for row in rows: print("-" * 64) print( f"#{row['id']} phone={row['phone']} invite={row['invite_code']} " f"created_at={row['created_at']}" ) answer = input("approve this request? [y/N/r]: ").strip().lower() if answer == "y": approve(conn, int(row["id"])) elif answer == "r": note = input("reject reason: ").strip() or "rejected manually" reject(conn, int(row["id"]), note) else: print("skip") if __name__ == "__main__": main()