Dokumentationen / Yta
Åtkomstspärren
YtaStartsideportalenLåser startsideportalens demo bakom en delad kod så att den kan ligga på en publik adress utan att vara öppen. Ingången /portal och devportalen /portal/dev ligger utanför spärren; projektportalen på roten har ingen spärr alls (ADR-040).
källa: apps/portal/src/middleware.ts, apps/projekt/src/atkomst/uppdaterad: 2026-10-19
Ansvar
- Spärra allt i startsideportalen utom en kort, stängd lista öppna vägar, före routningen, så att en ny yta inte kan glömma spärren.
- Hålla ingången /portal och devportalen /portal/dev öppna, så att beskrivningen av systemet går att läsa och hämta – också av verktyg som inte kan mata in en kod.
- Vara avstängd när ACCESS_CODE är osatt, så att lokal utveckling inte kräver en kod.
- Hålla koden borta ur kakan – den bär ett SHA-256-avtryck, inte klartext.
- Validera ?vidare= mot öppen vidarebefordran innan den följs.
- Aldrig utge sig för att vara autentisering, och aldrig vara behörighet i projektportalen. Spärren säger ingenting om vem användaren är.
Filer
| Sökväg | Roll |
|---|---|
| apps/portal/src/middleware.ts | Spärren för startsideportalen. Kör i edge-runtime, före all routning. Vägarna är appens egna – Next tar bort basvägen /portal före middleware och lägger på den i omdirigeringen. |
| apps/portal/src/atkomst/kod.ts | arOppenVag, atkomstkod, fingeravtryck, likaSakert. Fri från Node-API:er så middleware kan använda den. sakerVidare kommer ur @startsidan/gemensamt. |
| apps/portal/src/atkomst/actions.ts | lasUpp: jämför koden, sätter kakan, skickar vidare. |
| apps/portal/src/atkomst/kod.test.ts | Tester på avtryck, jämförelse, vidarebefordran och de öppna vägarna. |
| apps/portal/src/app/las-upp/page.tsx | Upplåsningssidan, /portal/las-upp. Satt till noindex. |
| packages/gemensamt/src/felforsok.ts | Spärren mot gissningar: tio fel per adress och tio minuter, med den adress Traefik lägger sist i X-Forwarded-For. Delas med projektportalens konton och skrivnyckel, men räknas per app. |
API
| Namn | Signatur | Beskrivning |
|---|---|---|
| arOppenVag | (pathname: string) => boolean | Ligger vägen utanför spärren? Vägen är appens egen, utan /portal. Listan är stängd: / (ingången), /dev, /api/health och /las-upp – var och en med allt under sig, utom roten. |
| atkomstkod | () => string | undefined | Koden ur miljön. Osatt eller tom betyder att spärren är avstängd. |
| fingeravtryck | (kod: string) => Promise<string> | SHA-256 i hex med prefix, så avtrycket bara betyder något här. |
| likaSakert | (a: string, b: string) => boolean | Jämförelse som tar lika lång tid oavsett var strängarna skiljer sig. |
| sakerVidare | (vidare: unknown) => string | Ur @startsidan/gemensamt/vidare. Släpper bara igenom interna vägar. Faller tillbaka på /. |
| lasUpp | (formData: FormData) => Promise<void> | Server action bakom upplåsningsformuläret. |
Kontrakt
Detta är inte autentisering. Alla som kommer in delar samma kod, och rollen väljs fortfarande fritt på /portal. En modul som behöver veta vem användaren är ska vänta på SAML-sessionen i fas 4 – läs aldrig åtkomstkakan som en identitet. Projektportalens konton (ADR-039) är aldrig identiteten här.
| Väg | Läge | Varför |
|---|---|---|
| /portal | Öppen | Prototypens ingång berättar vad prototypen är. Den visar inte demon, bara vägen in i den. |
| /portal/dev och allt under | Öppen | Portalen, designsystemet, dokumentationen, llms.txt och spec.json ska gå att läsa av både människor och verktyg. |
| /portal/api/health | Öppen | Dokploys healthcheck för start-portal markerar annars containern som sjuk. |
| /portal/las-upp | Öppen | Det är sidan man låser upp på. |
| /portal/start och allt under | Låst | Själva demon. |
| /portal/verktyg/*, /portal/sidor/* | Låst | Modulvyerna och sidorna i skalet. |
| /portal/flode/<namn> | Låst | Fokuslägena är demon i helskärm. |
| /portal/api/flows/*, /portal/api/min-ai | Låst | AI-anropen kostar pengar. |
| /portal/api/mock/*, /portal/api/kompetens/* | Låst | Demons data om påhittade personer. |
| Allt utanför /portal | Ingen spärr | Projektportalen (ADR-040). Öppen med flit; ändringsloggen, ritningen, organisationen och pitchen kräver ett konto (ADR-039). |
| /start, /dev, /verktyg … (gamla) | Omledning | Projektportalens next.config leder varje gammal adress permanent (308) till sin nya under /portal; utskickade länkar ska alltid fungera. |
- ACCESS_CODE måste sättas i Dokploy innan domänen delas. Osatt = öppet, utan varning. Variabeln listas bara under start-portal i docker-compose.yml.
- /portal och /portal/dev är publika. Skriv dem därefter: namn på kommunens medarbetare och projektets deltagare får stå där, känsliga personuppgifter aldrig.
- Allt får hämtas men inget indexeras: robots.txt är öppen, så att AI-tjänster kan läsa en länk, och varje sida sätter noindex. noindex verkar bara på en sida som får hämtas (ADR-012, ändrat 20 oktober 2026).
- Byts koden loggas alla ut – avtrycket i kakan matchar inte längre. Det är den enda vägen att återkalla åtkomst.
- Middleware kör i edge-runtime: atkomst/kod.ts får bara använda Web Crypto, aldrig node:crypto.
Beroenden och beslut
Kvarstår
- Ingen utloggning ur spärren – bara kakans 30 dagar eller ett kodbyte.
- Kakan har sökvägen / och syns därför också för projektportalen, som inte läser den.
- Formulärets POST är verifierad i webbläsare, inte i test. Middleware och den delade logiken är verifierade i container respektive vitest.