code wiki / _hdl_build / nx_project_serve.nx
nx_project_serve.nx
buildroot/runtime/_hdl_build/nx_project_serve.nx
about
nx_project_serve.nx -- the /project GATEWAY core (pure request->response; sockets live in the _daemon
wrapper, the gate drives THIS core with real tokens and no sockets -- the relate_serve idiom).
Sits behind the sites.elf proxy row `nishifamily.com /project 8028 gated` (fail-closed 302 on down).
Per request: resolve the OPAQUE no-cookie X-Nishi-Session token -> uid (olg_whoami, realm
nishi_site_admin, the SAME keys/store the /login minter uses) -> handle (uid-hex over the login
daemon's index file) -> person (data-driven map rows in serve.conf) -> the ROLE-SCOPED project page
via pj_html_build (owner/team all tasks, contractor own-only, non-member 403 DENY -- fail-closed).
Token-less top-level navigation -> the sessionStorage bootstrap (a bare 302 would loop: no-cookie navs
carry no header). Present-but-invalid token -> 302 /login. /project/demo -> the public demo tenant.
serve.conf (hot, per-request): `store <prefix>` `pid <id>` `demo <person>` `map <handle> <person>`.
license_tier: ORIGINAL
dependencies 4 imports · 2 importers
imports: nx_opaque_login.nxnx_hub_gw_decide.nxnx_site_lock_lib.nxnx_project.nx
imported by: nx_project_serve_daemon.nxnx_project_serve_gate.nx
structs
| none |
consts
| 16 | const PSV_MAGIC_719468: i64 = 719468 |
| 17 | const PSV_MAGIC_146097: i64 = 146097 |
| 18 | const PSV_MAGIC_146096: i64 = 146096 |
| 19 | const PSV_MAGIC_1460: i64 = 1460 |
| 20 | const PSV_MAGIC_36524: i64 = 36524 |
| 21 | const PSV_MAGIC_86400: i64 = 86400 |
| 22 | const PSV_MAGIC_65536: i64 = 65536 |
| 23 | const PSV_MAGIC_8192: i64 = 8192 |
| 24 | const PSV_MAGIC_262144: i64 = 262144 |
| 25 | const PSV_MAGIC_1024: i64 = 1024 |
| 26 | const PSV_MAGIC_16384: i64 = 16384 |
| 27 | const PSV_MAGIC_131072: i64 = 131072 |
| 28 | const PSV_MAGIC_16400: i64 = 16400 |
| 29 | const PSV_MAGIC_16383: i64 = 16383 |
| 31 | const PSV_BOOTSTRAP: *u8 = "<!DOCTYPE html><html lang='en'><head><meta charset='utf-8'><meta name='viewport' content='width=device-width, initial-scale=1'><title>Nishi Project</title></head><body><main style='max-width:48rem;margin:8vh auto;padding:1.5rem;font:1.1rem/1.6 system-ui,sans-serif'><h1>Nishi Project</h1><p id='project-status' role='status' aria-live='polite'>Opening your project…</p><button id='project-retry' type='button' hidden>Retry</button><details><summary>Release notes</summary><p>Session recovery · 8 September 2026. Access and connection failures retain your session. Sign-in returns to the project you requested.</p></details><noscript>Enable JavaScript to use the existing secure session handoff.</noscript></main><script>(function(){var status=document.getElementById('project-status');var retry=document.getElementById('project-retry');var destination=location.pathname+location.search+location.hash;function show(message){status.textContent=message;retry.hidden=false;retry.disabled=false}function signin(){location.assign('/login?return='+encodeURIComponent(destination))}async function load(){retry.disabled=true;retry.hidden=true;status.textContent='Opening your project…';var token;try{token=sessionStorage.getItem('nsess')}catch(e){show('Browser session storage is unavailable. Enable it for this site, then retry.');return}if(!token){signin();return}try{var r=await fetch(location.pathname+location.search,{headers:{'X-Nishi-Session':token},credentials:'omit',cache:'no-store',redirect:'manual'});if(r.type==='opaqueredirect'||r.status===401){signin();return}if(r.status===403){show('Access denied for this project. Your session has been kept. Ask the project owner to check your membership.');return}if(!r.ok){show('Project service returned HTTP '+r.status+'. Your session has been kept. Retry when the service is available.');return}if(!(r.headers.get('content-type')||'').toLowerCase().includes('text/html')){show('The project service returned an unexpected response. Your session has been kept.');return}var html=await r.text();if(!html){show('The project service returned an empty page. Your session has been kept.');return}document.open();document.write(html);document.close()}catch(e){show('Unable to reach the project service. Your session has been kept. Check your connection and retry.')}}retry.addEventListener('click',load);return load()})();</script></body></html>" |
| 32 | const PSV_DENY: *u8 = "<!DOCTYPE html><html lang='en'><head><meta charset='utf-8'><title>Nishi Project - no access</title></head><body><h1>Not a member of this project</h1><p>Your login is valid, but this account has no membership record on the project. Ask the project owner to add you.</p><p><a href='/login'>switch account</a></p></body></html>" |
functions
| 35 | func ps_read_file(path: *u8, out: *u8, cap: i64) -> i64 called by 1: psv_handle |
| 52 | func ps_hex(dst: *u8, off: i64, src: *u8, n: i64) -> i64 |
| 67 | func ps_idx_lookup(idxbuf: *u8, idxlen: i64, uidhex: *u8, uxn: i64, out_h: *u8) -> i64 |
| 93 | func ps_conf_pair(b: *u8, n: i64, key: *u8, out1: *u8, out2: *u8) -> i64 |
| 121 | func ps_proj_store(b: *u8, n: i64, pid: *u8, out: *u8, cap: i64) -> i64 |
| 151 | func ps_pid_ok(s: *u8) -> i64 called by 1: psv_handle |
| 170 | func ps_picker(confbuf: *u8, cl: i64, person: *u8, hb: *u8) -> i64 |
| 220 | func ps_map(b: *u8, n: i64, handle: *u8, out: *u8, cap: i64) -> i64 |
| 257 | func ps_civil(z0: i64, out: *i64) -> i64 called by 1: ps_today |
| 284 | func ps_today(out: *u8) -> i64 |
| 305 | func ps_resp(resp: *u8, status: *u8, ctype: *u8, body: *u8, blen: i64) -> i64 |
| 319 | func ps_redirect(resp: *u8, loc: *u8) -> i64 |
| 327 | func ps_text(resp: *u8, status: *u8, msg: *u8) -> i64 |
| 333 | func psv_st_new(ctx: *NxAuthContext, confpath: *u8, idxpath: *u8) -> *i64 |
| 355 | func psv_handle(st: *i64, req: *u8, rn: i64, resp: *u8) -> i64 called by 2: psv_selftestpsv_daemon calls 19: hgw_pathps_read_fileps_textps_todayslk_eqps_conf_pair+13 |
| 431 | func psv_req(dst: *u8, path: *u8, tok: *u8) -> i64 |
| 445 | func psv_selftest() -> i64 |
| 683 | func psv_daemon(argc: i64, argv: *i64) -> i64 |