code wiki / _hdl_build / nx_ad_banner_gated_daemon.nx
nx_ad_banner_gated_daemon.nx
buildroot/runtime/_hdl_build/nx_ad_banner_gated_daemon.nx
about
nx_ad_banner_gated_daemon.nx -- the BANNER BUILDER served BEHIND THE OPAQUE FAMILY GATE. The builder form
page loads, but GENERATION (POST /ad/banner) is gated: it requires a valid no-cookie OPAQUE family session
(X-Nishi-Session header, validated via olg_whoami against the SAME realm/keys as /login). A first-party
inline script attaches the session token (sessionStorage 'nsess', set by the login page) on submit and
injects the returned banner -- the banner OUTPUT stays 0-third-party-JS. Unauthenticated -> 401 + a login
hint, so a non-family visitor can see the tool but cannot generate. The clean live wiring (a /ad proxy route
on sites.elf -> this daemon) is handed to the publisher/hosting. argv: [1]=port [2]=keys [3]=store
[4]=argon2_m(opt). Composes nx_opaque_login (session) + nx_ad_banner_builder (abb_render). license_tier: ORIGINAL
dependencies 3 imports · 0 importers
imports: nx_opaque_login.nxnx_ad_banner_builder.nxnx_syscalls.nx
imported by: nobody (leaf or entry point)
structs
| none |
consts
| 12 | const GBB_MAGIC_262144: i64 = 262144 |
| 13 | const GBB_MAGIC_65536: i64 = 65536 |
| 14 | const GBB_MAGIC_65535: i64 = 65535 |
| 15 | const GBB_MAGIC_1024: i64 = 1024 |
| 16 | const GBB_MAGIC_32768: i64 = 32768 |
| 19 | const GBB_PAGE: *u8 = "<!doctype html><html><head><meta charset='utf-8'><meta name='viewport' content='width=device-width,initial-scale=1'><title>Nishi Banner Builder</title><style>body{font-family:system-ui,sans-serif;max-width:760px;margin:4vh auto;padding:0 18px;color:#16202e}h1{font-size:1.3rem}form{display:grid;gap:10px}label{display:grid;gap:3px;font-size:.85rem;color:#445}input,select{padding:8px;border:1px solid #b9c2d6;border-radius:6px;font-size:.95rem}button{padding:10px 18px;background:#0b2545;color:#fff;border:0;border-radius:6px;font-size:1rem;cursor:pointer;justify-self:start}.prev{margin:18px 0;padding:20px;background:#eef2f7;border-radius:10px;display:flex;justify-content:center;min-height:60px}textarea{width:100%;min-height:90px;font-family:ui-monospace,monospace;font-size:.8rem;border:1px solid #b9c2d6;border-radius:6px;padding:8px;box-sizing:border-box}.note{color:#667;font-size:.9rem}</style></head><body><h1>Nishi Banner Builder</h1><p class='note'>Generate a static or animated banner for the one-ad-per-page slot. No third-party scripts, no trackers, no external images — ever. Generating requires a Nishi Family sign-in.</p><form id='f'><label>Business / sponsor<input name='business' required></label><label>Headline<input name='headline'></label><label>Body line<input name='body'></label><label>Call-to-action<input name='cta'></label><label>Click link (https:// or /path)<input name='link'></label><label>Size<select name='size'><option>rectangle 300x250</option><option>leaderboard 728x90</option><option>mobile 320x50</option><option>skyscraper 160x600</option><option>halfpage 300x600</option><option>billboard 970x250</option></select></label><label>Theme<select name='theme'><option>light</option><option>dark</option><option>warm</option></select></label><label>Kind<select name='kind'><option>static</option><option>dynamic (animated)</option></select></label><button type='submit'>Generate banner</button></form><h2 style='font-size:1.05rem'>Preview</h2><div class='prev' id='prev'>Fill the form and Generate.</div><h2 style='font-size:1.05rem'>Banner HTML (copy into the ad slot)</h2><textarea id='out' readonly></textarea><script>var f=document.getElementById('f'),pv=document.getElementById('prev'),ot=document.getElementById('out');f.addEventListener('submit',function(e){e.preventDefault();var b=new URLSearchParams(new FormData(f)).toString();pv.textContent='Generating\\u2026';fetch('/ad/banner',{method:'POST',headers:{'X-Nishi-Session':sessionStorage.getItem('nsess')||'','Content-Type':'application/x-www-form-urlencoded'},body:b}).then(function(r){if(r.status===401){pv.innerHTML='Please <a href=\"/login\">sign in</a> as Nishi Family to generate.';return null}return r.text()}).then(function(t){if(t){pv.innerHTML=t;ot.value=t}}).catch(function(err){pv.textContent='error: '+err})});</script></body></html>" |
functions
| 21 | func gbb_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } |
| 22 | func gbb_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 } |
| 23 | func gbb_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 } |
| 24 | func gbb_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 } |
| 25 | func gbb_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 } |
| 26 | func gbb_find(buf: *u8, n: i64, needle: *u8, nl: i64) -> i64 { if nl == 0 { return 0 } var i: i64 = 0; while i + nl <= n { var j: i64 = 0; var ok: i64 = 1; while j < nl { if buf[i + j] != needle[j] { ok = 0; j = nl } else { j = j + 1 } } if ok == 1 { return i } i = i + 1 } return 0 - 1 } |
| 27 | func gbb_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 } |
| 29 | func gbb_hdr_val(req: *u8, hend: i64, name: *u8, nl: i64, out: *u8, cap: i64) -> i64 |
| 38 | func gbb_send(cfd: i64, status: *u8, ctype: *u8, body: *u8, blen: i64) -> i64 |
| 48 | func main(argc: i64, argv: *i64) -> i64 |