# Backend KretOS w Next.js

To jest osobna implementacja API KretOS w Next.js App Router i Node.js. Korzysta z tego samego PostgreSQL i migracji co wersja ASP.NET Core. Stara wersja C# pozostaje w repozytorium jako punkt odniesienia podczas wdrażania tej implementacji. Na produkcji uruchamiaj tylko jedną wersję API dla danej domeny.

## Wymagania

- Next.js 16.3.6.
- Node.js 20.9 lub nowszy; zalecany Node.js 22 LTS.
- PostgreSQL 15 lub nowszy.
- Prywatny, trwały katalog na instalatory i paczki.
- HTTPS w środowisku produkcyjnym.

## Uruchomienie lokalne

1. Skopiuj `.env.example` do `.env.local` i uzupełnij sekrety.
2. Utwórz bazę PostgreSQL i zastosuj migrację `database/migrations/001_initial.sql` z katalogu głównego repozytorium.
3. Zainstaluj zależności i uruchom serwer:

```sh
corepack pnpm install --frozen-lockfile
pnpm dev
```

Strona działa pod `/`, panel pod `/admin/`, a API pod `/api/v1/`. Ustaw `DATABASE_URL`, `TOKEN_HASH_KEY`, `ACCESS_CODE_HASH_KEY`, `ADMIN_TOTP_ENCRYPTION_KEY` i `ARTIFACT_SIGNING_PUBLIC_KEY`. Trzy klucze symetryczne muszą być różnymi losowymi wartościami 32-bajtowymi zakodowanymi w Base64. Klucz prywatny do podpisywania wydań pozostaje poza serwerem.

PowerShell tworzy każdy klucz symetryczny poleceniem:

```powershell
[Convert]::ToBase64String([Security.Cryptography.RandomNumberGenerator]::GetBytes(32))
```

## Pierwsze konto administratora

Po zastosowaniu migracji ustaw `DATABASE_URL` (lub zmienne `PGHOST`, `PGUSER`, `PGPASSWORD`), `ADMIN_TOTP_ENCRYPTION_KEY`, `BOOTSTRAP_ADMIN_USERNAME` i `BOOTSTRAP_ADMIN_PASSWORD`, a następnie uruchom:

```sh
pnpm bootstrap-admin
```

Hasło musi mieć 14–256 znaków. Narzędzie tworzy rolę SuperAdmin i wyświetla sekret MFA tylko raz. Dodaj go do aplikacji uwierzytelniającej. Sekret MFA jest zapisany w bazie w postaci zaszyfrowanej AES-256-GCM.

## Uruchomienie w Dockerze

Skopiuj `nextjs/.env.docker.example` do `.env` w katalogu głównym repozytorium, uzupełnij wartości i uruchom:

```sh
docker compose -f docker-compose.next.yml up --build -d
```

Compose tworzy PostgreSQL, stosuje migrację przy pierwszym uruchomieniu wolumenu i uruchamia Next.js. Porty są dostępne tylko lokalnie na serwerze. Po starcie ustaw `BOOTSTRAP_ADMIN_USERNAME` i `BOOTSTRAP_ADMIN_PASSWORD` w powłoce, a potem wykonaj:

```sh
docker compose -f docker-compose.next.yml exec -e BOOTSTRAP_ADMIN_USERNAME -e BOOTSTRAP_ADMIN_PASSWORD app node scripts/bootstrap-admin.mjs
```

Kontener Next.js nasłuchuje na porcie 3000. Katalog paczek jest trwałym wolumenem `/var/lib/kretos`. Kopie bazy, plików i konfiguracji sekretów przechowuj niezależnie. Kolejne migracje stosuj jako osobny krok wdrożenia.

## Uruchomienie na hostingu Node.js

Ustaw zmienne środowiskowe w panelu hostingu, zamontuj trwały katalog pod `STORAGE_ROOT` i uruchom:

```sh
corepack pnpm install --frozen-lockfile
pnpm build
pnpm start
```

Postaw aplikację za zaufanym proxy HTTPS. Proxy powinno przekazywać właściwy host i schemat HTTPS, nadpisywać `X-Real-IP` lub `X-Forwarded-For` oraz dopuszczać uploady do 1 GiB. Nie ufaj nagłówkom IP od niezaufanego klienta. Nie wystawiaj PostgreSQL do internetu.

## Trasy API

- `/api/v1/auth/activate`, `/refresh`, `/revoke`
- `/api/v1/core/versions`, `/core/versions/:id/download`
- `/api/v1/catalog/plugins`, `/plugins`, `/plugins/:id/download`
- `/api/v1/downloads/:ticket`
- `/admin/api/` — logowanie MFA, kody, urządzenia, sesje, publikacje, upload i audyt
- `/health`, `/health/ready`

Kody i tokeny są przechowywane jako HMAC-SHA-256. Aktywacja i rotacja sesji wykonują warunkowe aktualizacje PostgreSQL w transakcjach. Link pobierania jest jednorazowy i wygasa. Administrator loguje się hasłem PBKDF2-SHA-256 i TOTP, a panel używa ciasteczka HttpOnly, CSRF, walidacji Origin, uprawnień ról, blokady po błędnych logowaniach i logu audytowego. Pliki są zapisywane strumieniowo poza katalogiem publicznym; publikacja wymaga poprawnego SHA-256 i podpisu ECDSA.

## Testy i ograniczenia

Uruchom testy jednostkowe poleceniem `pnpm test`. Testy PostgreSQL obejmują między innymi 100 równoczesnych aktywacji, odrzucone kody, rotację i unieważnianie sesji oraz jednorazowe pobieranie. Wymagają testowej bazy z zastosowaną migracją i zmiennej `KRETOS_RUN_DB_TESTS=1`.

Limiter w tej wersji działa w pamięci procesu. Przed uruchomieniem wielu instancji przenieś go do Redis lub innej współdzielonej usługi. Lokalny storage jest przeznaczony dla pojedynczego hosta; przy skalowaniu użyj prywatnego object storage.
