#!/usr/bin/env python3 """WEVIA Auto-Renew — Selenium/Playwright automation for token renewal Uses existing browser sessions (cookies) to renew tokens on all platforms. Run: python3 /opt/weval-l99/wevia-auto-renew.py --target hf|meta|o365|all """ import asyncio, json, sys, os from datetime import datetime SECRETS = "/etc/weval/secrets.env" LOG = "/var/log/wevia-auto-renew.log" def load_secrets(): s = {} for l in open(SECRETS): l = l.strip() if '=' in l and not l.startswith('#'): k, v = l.split('=', 1) s[k.strip()] = v.strip().strip('"').strip("'") return s def save_secret(key, value): content = open(SECRETS).read() import re if re.search(f'^{key}=', content, re.M): content = re.sub(f'^{key}=.*$', f'{key}={value}', content, flags=re.M) else: content += f"\n{key}={value}" open(SECRETS, 'w').write(content) log(f"Secret {key} updated") def log(msg): with open(LOG, 'a') as f: f.write(f"[{datetime.now().strftime('%H:%M')}] {msg}\n") print(msg) async def renew_hf(): """Renew HuggingFace token via browser session""" from playwright.async_api import async_playwright async with async_playwright() as p: # Try with existing user data dir (keeps cookies) ctx = await p.chromium.launch_persistent_context( "/root/.wevia-browser", headless=True, executable_path="/usr/bin/chromium-browser", args=["--no-sandbox","--disable-dev-shm-usage"] ) pg = ctx.pages[0] if ctx.pages else await ctx.new_page() await pg.goto("https://huggingface.co/settings/tokens", timeout=15000) await pg.wait_for_timeout(3000) # Check if logged in content = await pg.content() if "Sign In" in content or "Log In" in content: log("HF: Not logged in → need Yacine credentials") # Try login with stored creds s = load_secrets() email = s.get("HF_EMAIL", "ymahboub@weval-consulting.com") pwd = s.get("HF_PASSWORD", "") if pwd: await pg.goto("https://huggingface.co/login", timeout=10000) await pg.fill('input[name="username"]', email) await pg.fill('input[name="password"]', pwd) await pg.click('button[type="submit"]') await pg.wait_for_timeout(3000) await pg.goto("https://huggingface.co/settings/tokens", timeout=10000) await pg.wait_for_timeout(2000) content = await pg.content() if "New token" in content or "Create" in content: log("HF: Logged in! Creating new token...") # Click create token btn = await pg.query_selector('button:has-text("New token"), a:has-text("New token"), button:has-text("Create")') if btn: await btn.click() await pg.wait_for_timeout(1000) # Fill name name_input = await pg.query_selector('input[placeholder*="name"], input[name="name"]') if name_input: await name_input.fill(f"wevia-auto-{datetime.now().strftime('%Y%m%d')}") # Select write permission write_btn = await pg.query_selector('label:has-text("Write"), input[value="write"]') if write_btn: await write_btn.click() # Submit submit = await pg.query_selector('button[type="submit"], button:has-text("Generate"), button:has-text("Create")') if submit: await submit.click() await pg.wait_for_timeout(2000) # Extract token token_el = await pg.query_selector('code, input[readonly], .token-value, pre') if token_el: token = await token_el.text_content() or await token_el.get_attribute("value") or "" token = token.strip() if token.startswith("hf_"): save_secret("HF_TOKEN", token) log(f"HF: NEW TOKEN CREATED: {token[:12]}...") await ctx.close() return True log("HF: Could not create token automatically") else: log("HF: Login page detected, no session") await ctx.close() return False async def renew_whatsapp(): """Check WhatsApp token via Meta Business""" from playwright.async_api import async_playwright async with async_playwright() as p: ctx = await p.chromium.launch_persistent_context( "/root/.wevia-browser", headless=True, executable_path="/usr/bin/chromium-browser", args=["--no-sandbox","--disable-dev-shm-usage"] ) pg = ctx.pages[0] if ctx.pages else await ctx.new_page() await pg.goto("https://business.facebook.com/settings/system-users", timeout=15000) await pg.wait_for_timeout(3000) content = await pg.content() if "Log in" in content or "login" in content.lower(): log("META: Not logged in → Yacine must login on browser first") else: log("META: Session active! Looking for token generation...") # Try to find generate token button gen = await pg.query_selector('button:has-text("Generate"), a:has-text("token")') if gen: log("META: Found token button") # Don't click automatically for safety await ctx.close() return False async def renew_o365(): """Reset O365 passwords via admin portal""" compromised = ["rodolftripp","sfgb518","phyleciaamato","kamrynnbonilla","jolineweatherly"] from playwright.async_api import async_playwright async with async_playwright() as p: ctx = await p.chromium.launch_persistent_context( "/root/.wevia-browser", headless=True, executable_path="/usr/bin/chromium-browser", args=["--no-sandbox","--disable-dev-shm-usage"] ) pg = ctx.pages[0] if ctx.pages else await ctx.new_page() await pg.goto("https://admin.microsoft.com/Adminportal/Home#/users", timeout=15000) await pg.wait_for_timeout(3000) content = await pg.content() if "Sign in" in content: log("O365: Not logged in → Yacine must login first") else: log(f"O365: Admin portal accessible! {len(compromised)} accounts to reset") for user in compromised: log(f" → Reset needed: {user}") await ctx.close() return False async def main(): target = sys.argv[1] if len(sys.argv) > 1 else "all" log(f"=== AUTO-RENEW START: {target} ===") results = {} if target in ["hf","all"]: results["hf"] = await renew_hf() if target in ["meta","whatsapp","all"]: results["whatsapp"] = await renew_whatsapp() if target in ["o365","all"]: results["o365"] = await renew_o365() log(f"Results: {results}") print(json.dumps(results)) if __name__ == "__main__": asyncio.run(main())