#!/usr/bin/env python3
"""Cleanly POST SetPassword to https://app.curogram.com/graphql via in-page fetch
(it did not 404). Single read of body. Reads creds from env. No secrets printed."""
import json, urllib.request
from websocket import create_connection

def read_key(k):
    for line in open("/home/claude/.config/amd-agent/credentials.env"):
        if line.startswith(k+"="): return line[len(k)+1:].rstrip("\n")
    return ""
OLD=read_key("CUROGRAM_AGENT_PASSWORD"); NEW=read_key("AMD_PASSWORD")

tabs=json.loads(urllib.request.urlopen("http://localhost:9223/json",timeout=8).read())
page=next(t for t in tabs if t.get("type")=="page" and "app.curogram.com" in (t.get("url") or "").lower())
ws=create_connection(page["webSocketDebuggerUrl"],timeout=25); _id=[0]
def call(method,params=None):
    _id[0]+=1; mid=_id[0]
    ws.send(json.dumps({"id":mid,"method":method,"params":params or {}}))
    while True:
        m=json.loads(ws.recv())
        if m.get("id")==mid:
            if "error" in m: raise RuntimeError(m["error"])
            return m.get("result",{})
call("Runtime.enable")
SETPW=("mutation SetPassword($oldPassword: Password!, $password: Password!, "
       "$passwordConfirmation: Password!) { setPassword(oldPassword: $oldPassword, "
       "password: $password, passwordConfirmation: $passwordConfirmation) }")
js="""
(async (q, oldp, newp) => {
  const m = document.cookie.match(/XSRF-TOKEN=([^;]+)/);
  const xsrf = m ? decodeURIComponent(m[1]) : '';
  const r = await fetch('https://app.curogram.com/graphql', {
    method:'POST', credentials:'include',
    headers:{'Content-Type':'application/json','Accept':'application/json',
      'X-Curogram-Frontend':'web', ...(xsrf?{'X-XSRF-TOKEN':xsrf}:{})},
    body: JSON.stringify({operationName:'SetPassword', query:q,
      variables:{oldPassword:oldp, password:newp, passwordConfirmation:newp}})
  });
  const txt = await r.text();
  let parsed=null; try{parsed=JSON.parse(txt);}catch(e){}
  return JSON.stringify({status:r.status, url:r.url, redirected:r.redirected,
    contentType:r.headers.get('content-type'),
    ok: r.status===200 && parsed && !parsed.errors,
    errors: parsed && parsed.errors ? JSON.stringify(parsed.errors).slice(0,300) : null,
    dataKeys: parsed && parsed.data ? Object.keys(parsed.data) : null,
    preview: txt.slice(0,160)});
})
"""
res=call("Runtime.evaluate",{"expression":f"({js})({json.dumps(SETPW)}, {json.dumps(OLD)}, {json.dumps(NEW)})",
    "awaitPromise":True,"returnByValue":True,"timeout":20000})
print(res.get("result",{}).get("value"))
ws.close()
