ident
All repositories: gitoria
2.8 KB
// lib/selector.hl — THE IDENTITY SELECTOR (piece 3 of 6, ticket #26; CONCEPT.md "Flow 2: identity selector"// and "Decided 2026-09-24"). Statics only, the server realm. Its two CORS endpoints are lib/api.hl// (apiSelectorIdentities, apiSelectorChoose; the CORS answers and the caller check: lib/api-helpers.hl);// the browser half is selector.js (served at /selector.js).//// GET /api/selector/identities?key=<api key> → { signedIn, identities: [{ id, name }] }// POST /api/selector/choose?key=<api key> { identity: <id from the list> } → { code }// OPTIONS /api/selector/choose?key=… the CORS preflight of the POST//// CORS: ident answers ONLY a request whose Origin header is one of the app's registered// origins AND whose key is that app's API key. Then (and only then) the answer carries// `Access-Control-Allow-Origin: <that exact origin>` and `…-Allow-Credentials: true`// (never `*`). Anything else is a 403 without those headers: the browser hands the page// nothing, and nothing is written.// The ident user is the one of the `identsid` cookie the browser sends along (credentials;// SameSite=Lax, so it only travels from the SAME SITE — our apps; other ports of the same// host count). Function routes get no session: it is resolved from the cookie (hybriel #18).//// THE LIST'S ids are not ident's identity ids: each is sha256(app's secret hash : identity)// cut to 32 hex — stable for one app, different for every app, not guessable, and it// means nothing outside this selector. The CODE of a choice follows the login button's// rules exactly (lib/apps.hl issueCode: single use, 60 s, this app only); the host's server// trades it with POST /api/exchange (key + secret) for the app-specific identity id.import { sha256 } from 'hl:crypto'import { issueCode } from './apps.hl'import { identityRecords } from './identities.hl'import { labelOf } from './identities-helpers.hl'// (since mission 009 the identity's id is its UUID, so every pick id changed once then)static pickOf = (appRec, identityRec) => { return sha256(appRec.secretHash + ':' + identityRec.id).slice(0, 32) }// the account's identities for the app's page: the id to pick it by and the identity// name (CONCEPT.md: "that one is shown in the selector"; blank → the list's fallback)static selectorList = (appRec, accountId) => {out = []let n = 1for (r of identityRecords(accountId)) {out.push({ id = pickOf(appRec, r) name = labelOf(r, n) })n = n + 1}return out}// THE CHOICE: the account's identity whose pick id is `pick` gets a one-time code for the app. Answers the// code, or null (no such identity).static codeOfPick = (appRec, accountId, pick) => {for (r of identityRecords(accountId)) {if (pickOf(appRec, r) == pick) {return issueCode(appRec.id, r.id)}}return null}
Branches
- mainmain branch
Latest commits
- 5fdbb6b2ident mission 009: report — scratch folder notemre
- 74235815ident mission 009 (4/4): docs (README files map + same-output test, STATUS, LOG), report, tests/letcount.py + realdata-baseline/comparemre
- fe183516ident mission 009 (3/4): let only where reassigned — 293 never-reassigned lets are plain declarations; kept: reassigned, loop bodies, names of a file member, a name declared twice in one function; same outputmre
- d2e7f91bident mission 009 (2/4): one lib file per topic (login, accounts, identities, apps, invites, selector, notify + helpers, util), function routes as thin wrappers in lib/api.hl, project.hl = the map; same outputmre
- 91017164ident mission 009 (1/4): file moves — the root .hl files into lib/ (api.hl → lib/api-helpers.hl), styles.hl → components/styles.hl; imports adjusted, no other changemre
- f8bdcbc2ident: Hybriel master 06617221 (plugin allocators 3a781359 + 413f60e4, mpackdb 2cb7ae5e, http1 773de63e); all gates greenmre
- ff78726cident: Hybriel master 190aa11d (fc838894 GC correctness, #127, #126 closure scopes); gates all greenmre
- a3a7d21aident: Hybriel master 8efba065 (#126 GC by bytes, #48 lambda params copy); session-writing lambdas take &sessionmre
- 98226b41antcolony#40: mission references point to the moved missionsmre
- ff805b9aantcolony#40: history (LOG.md), worker briefs (missions/) and reports moved here from antcolony, numbered per project; old numbers in antcolony docs/mission-map.mdmre
- 51a7bcdfident: Hybriel master 73267707 (#122); /code uses the new page() signature; pending address passed as parameter; once-checksmre
- 836f644fident#24: installable app (manifest, service worker, data-free offline /start), own iconmre
- 8bebbbf2deploy.sh: back up live storage/.sessions/.env before every deploy (newest 5 kept)mre
- cc063ea2deploy.sh: never send .git or .gitignore to Byrodinmre
- 81b15b7bState of 2026-09-27, before the move to gitoriamre