code wiki / _hdl_build / nx_studio_gate.nx
nx_studio_gate.nx
buildroot/runtime/_hdl_build/nx_studio_gate.nx
about
nx_studio_gate.nx -- OPAQUE-gated "Nishi Studio" surface (OPERATOR-ONLY) mounted at PATH /studio on
nishifamily.com (sites_v2 path-proxies /studio/* here; it forwards the full path, so routes are
/studio-prefixed). Faithful clone of the proven nx_opaque_login_daemon: RFC 9807 OPAQUE + no-cookie
X-Nishi-Session security INHERITED VERBATIM, OWN ISOLATED realm "nishi_studio". GET /studio/app serves
the studio / search-by-image surface ONLY to a valid session; NO valid token -> 401 (never a content
leak). The ONE clean public-behind-OPAQUE surface ([[feedback-one-gated-live-surface-no-dev-sprawl]]).
argv: [1]=port [2]=keys-path [3]=store-path [4]=budget [5]=argon2_m(opt;64MiB prod) [6]=t [7]=p [8]=allow_register(opt;default 1)
routes: GET /studio | /studio/ -> login page ; POST /studio/login ; POST /studio/register ; GET /studio/whoami ; GET /studio/app (PROTECTED)
license_tier: ORIGINAL
dependencies 2 imports · 0 importers
imports: nx_opaque_login.nxnx_http_form.nx
imported by: nobody (leaf or entry point)
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| none |
consts
| 13 | const SG_PROD_M: i64 = 65536 |
| 48 | const SG_LOGIN_HTML: *u8 = "<!doctype html><html><head><meta charset=utf-8><meta name=viewport content=\"width=device-width,initial-scale=1\"><title>Nishi Studio — login</title><style>body{font-family:system-ui,sans-serif;max-width:460px;margin:6vh auto;padding:0 18px;background:#0d1117;color:#e6edf3}h1{font-size:1.25rem}h3{margin:18px 0 4px}input{width:100%;padding:9px;margin:5px 0;box-sizing:border-box;border:1px solid #30363d;border-radius:6px;background:#161b22;color:#e6edf3}button{padding:9px 16px;margin:6px 6px 0 0;background:#238636;color:#fff;border:0;border-radius:6px;cursor:pointer}#m{margin:14px 0;padding:12px;background:#161b22;border-left:3px solid #238636;word-break:break-all;min-height:1.2em}</style></head><body><h1>Nishi Studio</h1><p style=\"color:#8b949e;font-size:.9rem\">Operator-only. Full OPAQUE (RFC 9807); no-cookie session.</p><div id=m>Register, then log in to enter the studio.</div><h3>Register</h3><input id=rh placeholder=handle><input id=rp type=password placeholder=passphrase><button onclick=reg()>Register</button><h3>Login</h3><input id=lh placeholder=handle><input id=lp type=password placeholder=passphrase><button onclick=login()>Login</button> <button onclick=enter()>Enter Studio</button><script>function $(i){return document.getElementById(i)}function M(t){$('m').textContent=t}async function P(p,b){var r=await fetch(p,{method:'POST',headers:{'Content-Type':'application/x-www-form-urlencoded'},body:b});var j={};try{j=await r.json()}catch(e){}return{ok:r.ok,s:r.status,j:j}}async function reg(){M('Registering\\u2026');var r=await P('/studio/register','handle='+encodeURIComponent($('rh').value)+'&pw='+encodeURIComponent($('rp').value));M(r.ok?('Registered. SAVE RECOVERY: '+r.j.mnemonic):('Register failed '+r.s))}async function login(){M('Logging in\\u2026');var r=await P('/studio/login','handle='+encodeURIComponent($('lh').value)+'&pw='+encodeURIComponent($('lp').value));if(r.ok){sessionStorage.setItem('nsess',r.j.token);M('Logged in. Click Enter Studio.')}else{M('Login failed '+r.s)}}async function enter(){var t=sessionStorage.getItem('nsess');if(!t){M('Log in first.');return}var r=await fetch('/studio/app',{headers:{'X-Nishi-Session':t}});if(r.ok){var h=await r.text();document.open();document.write(h);document.close()}else{M('Denied '+r.status+' \\u2014 login required.')}}</script></body></html>" as *u8 |
| 50 | const SG_STUDIO_HTML: *u8 = "<!doctype html><html><head><meta charset=utf-8><meta name=viewport content=\"width=device-width,initial-scale=1\"><title>Nishi Studio — Search by Image</title><style>body{font-family:system-ui,sans-serif;max-width:820px;margin:4vh auto;padding:0 18px;background:#0d1117;color:#e6edf3}h1{font-size:1.3rem}.tag{color:#2ea043;font-size:.8rem;border:1px solid #2ea043;border-radius:20px;padding:2px 10px;display:inline-block;vertical-align:middle}.card{background:#161b22;border:1px solid #30363d;border-radius:10px;padding:18px;margin:16px 0}.sub{color:#8b949e;font-size:.9rem}button{padding:9px 16px;background:#238636;color:#fff;border:0;border-radius:6px;cursor:pointer}</style></head><body><h1>Nishi Studio <span class=tag>operator-only · OPAQUE-gated</span></h1><p class=sub>You are authenticated. This surface is reachable only with your session \\u2014 not the internet, not others.</p><div class=card><h3>Search by Image</h3><p class=sub>Sovereign reverse-image search (perceptual dHash, brightness-invariant, per-site isolated). Pick an image to find its matches across the corpus.</p><input type=file id=qimg accept=image/*> <button onclick=go()>Search</button><div id=res style=\"margin-top:14px\" class=sub>Ready.</div></div><script>function go(){var f=document.getElementById('qimg').files[0];var d=document.getElementById('res');if(!f){d.textContent='Choose an image first.';return}d.textContent='Searching '+f.name+'\\u2026 (live search API wires in the next rung)'}</script></body></html>" as *u8 |
functions
| 15 | func sg_slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n } called by 1: main |
| 16 | func sg_atoi(s: *u8) -> i64 { var v: i64=0; var i: i64=0; while s[i]!=(0 as u8){ let c: i64=s[i] as i64; if c<48{return v} if c>57{return v} v=v*10+(c-48); i=i+1 } return v } called by 1: main |
| 17 | func sg_starts(buf: *u8, n: i64, pre: *u8) -> i64 { var i: i64=0; while pre[i]!=(0 as u8){ if i>=n {return 0} if buf[i]!=pre[i]{return 0} i=i+1 } return 1 } called by 1: main |
| 18 | func sg_find(buf: *u8, n: i64, needle: *u8, nl: i64) -> i64 |
| 24 | func sg_cat(dst: *u8, off: i64, s: *u8) -> i64 { var o: i64=off; var i: i64=0; while s[i]!=(0 as u8){dst[o]=s[i]; o=o+1; i=i+1} return o } |
| 25 | func sg_catb(dst: *u8, off: i64, src: *u8, n: i64) -> i64 { var o: i64=off; var i: i64=0; while i<n {dst[o]=src[i]; o=o+1; i=i+1} return o } |
| 26 | func sg_itoa(dst: *u8, off: i64, v: i64) -> i64 { let t: *u8=sys_mmap(28); var m: i64=v; var k: i64=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} var o: i64=off; var q: i64=k-1; while q>=0{dst[o]=t[q];o=o+1;q=q-1} return o } called by 1: sg_send |
| 27 | func sg_hex(dst: *u8, off: i64, src: *u8, n: i64) -> i64 { let hx: *u8="0123456789abcdef" as *u8; var o: i64=off; var i: i64=0; while i<n { let c: i64=(src[i] as i64)&0xff; dst[o]=hx[(c>>4)&15]; dst[o+1]=hx[c&15]; o=o+2; i=i+1 } return o } called by 1: main |
| 29 | func sg_send(cfd: i64, status: *u8, ctype: *u8, body: *u8, blen: i64) -> i64 |
| 38 | func sg_hdr_val(req: *u8, hend: i64, name: *u8, nl: i64, out: *u8, cap: i64) -> i64 |
| 52 | func main(argc: i64, argv: *i64) -> i64 |