view connectors/auth_test_page.c @ 280:49e9e591c9bb

Add persistent dictation, prewarmed WebRTC speech input, Copilot SDK routing, animated conversation lifecycle controls, parking, and architecture coverage.
author MrJuneJune <me@mrjunejune.com>
date Tue, 18 Aug 2026 19:14:53 -0700
parents b3b547563ec7
children
line wrap: on
line source

#include "connectors/auth_test_page.h"

const char *Connector_Auth_Test_Page(void)
{
  return
      "<!doctype html><html lang=\"en\"><head><meta charset=\"utf-8\">"
      "<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">"
      "<title>Zenbu Connector Test</title><style>"
      ":root{color-scheme:dark;font-family:system-ui,sans-serif;background:#111;"
      "color:#eee}main{max-width:820px;margin:32px auto;padding:24px}"
      "section{margin:20px 0;padding:16px;border:1px solid #444;border-radius:8px}"
      "button,a,input,textarea{margin:4px;padding:9px}input,textarea{width:95%}"
      "button,a{display:inline-block}pre{min-height:140px;padding:16px;"
      "overflow:auto;background:#1d1d1d;border:1px solid #444;border-radius:8px}"
      "</style></head><body><main><h1>Zenbu connector test</h1>"
      "<section><h2>1. Authentication</h2>"
      "<a href=\"http://127.0.0.1:6969/login\" target=\"_blank\">Zenbu login</a>"
      "<button id=\"check\">Check Zenbu session</button>"
      "<button id=\"oauth\" disabled>Connect Google account</button></section>"
      "<section><h2>2. Google account</h2>"
      "<label>Account ID<input id=\"account\" placeholder=\"google:...\"></label>"
      "<button id=\"drive-list\">List Drive files</button>"
      "<button id=\"drive-create\">Create test Google Doc</button>"
      "<button id=\"gmail-list\">List Gmail messages</button></section>"
      "<section><h2>3. Gmail write test</h2>"
      "<label>To<input id=\"to\" type=\"email\"></label>"
      "<label>Subject<input id=\"subject\" value=\"Zenbu connector test\"></label>"
      "<label>Message<textarea id=\"message\" rows=\"4\">Hello from Zenbu.</textarea></label>"
      "<button id=\"gmail-draft\">Create draft</button>"
      "<button id=\"gmail-send\">Send with confirmation</button></section>"
      "<pre id=\"output\">Check the Zenbu session first.</pre></main><script>"
      "const $=s=>document.querySelector(s),out=$('#output'),oauth=$('#oauth');"
      "let csrf='';const params=new URLSearchParams(location.search);"
      "$('#account').value=params.get('account_id')||localStorage.zenbuAccount||'';"
      "if(params.get('email'))$('#to').value=params.get('email');"
      "const show=v=>out.textContent=typeof v==='string'?v:JSON.stringify(v,null,2);"
      "const account=()=>{const v=$('#account').value.trim();"
      "if(!v)throw new Error('Connect Google or enter an account ID');"
      "if(!/^[A-Za-z0-9_.:-]+$/.test(v))throw new Error('Invalid account ID');"
      "localStorage.zenbuAccount=v;return v};"
      "async function result(response){const text=await response.text();"
      "let body;try{body=JSON.parse(text)}catch{body=text}"
      "show({status:response.status,body});return{response,body}}"
      "async function read(path){return result(await fetch(path,{credentials:'include'}))}"
      "async function mutate(path,body,key,confirmation){"
      "const headers={'Content-Type':'application/json','X-CSRF-Token':csrf,"
      "'Idempotency-Key':key};if(confirmation)"
      "headers['X-Connector-Confirmation']=confirmation;"
      "return result(await fetch(path,{method:'POST',credentials:'include',"
      "headers,body:JSON.stringify(body)}))}"
      "$('#check').onclick=async()=>{oauth.disabled=true;csrf='';"
      "const r=await read('/v1/auth/session');"
      "if(r.response.ok&&r.body.authenticated){csrf=r.body.csrfToken;"
      "oauth.disabled=false}};"
      "oauth.onclick=async()=>{const r=await result(await fetch("
      "'/v1/oauth/google/start',{method:'POST',credentials:'include',"
      "headers:{'X-CSRF-Token':csrf}}));"
      "if(r.response.ok&&r.body.authorization_url)"
      "location.assign(r.body.authorization_url)};"
      "$('#drive-list').onclick=()=>read('/v1/accounts/'+account()+"
      "'/drive/files?pageSize=10&fields=files(id,name,mimeType),nextPageToken');"
      "$('#gmail-list').onclick=()=>read('/v1/accounts/'+account()+"
      "'/gmail/messages?maxResults=10');"
      "$('#drive-create').onclick=()=>mutate('/v1/accounts/'+account()+"
      "'/drive/files',{name:'Zenbu test '+new Date().toISOString(),"
      "mimeType:'application/vnd.google-apps.document'},crypto.randomUUID());"
      "function rawMessage(){const mime='To: '+$('#to').value+'\\r\\nSubject: '+"
      "$('#subject').value+'\\r\\nContent-Type: text/plain; charset=UTF-8\\r\\n\\r\\n'+"
      "$('#message').value;const bytes=new TextEncoder().encode(mime);let binary='';"
      "for(const byte of bytes)binary+=String.fromCharCode(byte);"
      "return btoa(binary).replaceAll('+','-').replaceAll('/','_').replace(/=+$/,'')}"
      "$('#gmail-draft').onclick=()=>mutate('/v1/accounts/'+account()+"
      "'/gmail/drafts',{message:{raw:rawMessage()}},crypto.randomUUID());"
      "$('#gmail-send').onclick=async()=>{if(!csrf){show('Check session first');return}"
      "const path='/v1/accounts/'+account()+'/gmail/send',body={raw:rawMessage()},"
      "key=crypto.randomUUID();let r=await mutate(path,body,key);"
      "if(r.response.status!==409||r.body.error!=='confirmation_required')return;"
      "if(!confirm('Send this email through Gmail?'))return;"
      "const confirmation=await result(await fetch('/v1/confirmations',{"
      "method:'POST',credentials:'include',headers:{'Content-Type':'application/json',"
      "'X-CSRF-Token':csrf},body:JSON.stringify({request_digest:r.body.request_digest})}));"
      "if(!confirmation.response.ok)return;"
      "await mutate(path,body,key,confirmation.body.confirmation_token)};"
      "</script></body></html>";
}