Mercurial
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>"; }