Vlasnik izlazi iz DAL price za ovaj projekat - postaje samostalan proizvod. Preimenovanje je mehanicko (import putanje, imena fajlova/baze/UI naslova), NIJEDNA linija poslovne logike u internal/handler ili internal/service nije dirana - go build, go vet i go test ./... prolaze cisto pod novim imenom. - go.mod: module dal-license-server -> licence-server; 28 import linija u 13 .go fajlova usaglaseno - internal/config/config.go (+test): default DB_NAME licence_db - HTML sabloni (7 stranica) + 7 Playwright e2e spec fajlova: "DAL License Server" -> "Licence Server" u title/nav-brand, testovi usaglaseni u istom prolazu (nista ne moze da se razdvoji) - package.json/package-lock.json/.gitignore/.claude/project.json: ime projekta/binarnog fajla/work_dir - Usput: package.json je u repository.url nosio OTVORENU Gitea lozinku u cistom tekstu - uklonjena (URL sad bez kredencijala). Lozinka je i dalje u staroj git istoriji - preporuka: rotirati je posebno. - CLAUDE.md/README/API/TESTING/docs/SPEC/ARCHITECTURE/SETUP: naslovi, ASCII dijagrami, git clone URL, mysqldump primer, systemd predlozak u SETUP.md zamenjen stvarnim (obrazac terminia.service - journal log + graceful shutdown, ne stari minimalni predlozak) - Debrendiranje: "Univerzalni licencni server za sve DAL proizvode" -> "za vise proizvoda i klijenata"; potpis "Nenad Djukic / DAL d.o.o." -> "Nenad Djukic". NE dirano: nazivi ESIR/ARV/LIGHT_TICKET (tudji proizvodi, ne DAL brend), "DAL" kao stvaran naziv org-a u RBAC modelu (docs/loggerservice/README.md) - to je podatak, ne branding ovog servera. - docs/asp-terminia/, docs/loggerservice/: prozni pomeni imena servera Baza (dal_license_db -> licence_db) i deploy na 151 idu u posebnom koraku, posle preimenovanja Gitea repoa - vidi CLAUDE.md istorijsku belesku na dnu. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
5.0 KiB
5.0 KiB
Postojeće stanje (provereno na serveru 2026-07-24, read-only)
1. Server 151 — pristup i raspored
- SSH:
ssh root@157.180.119.151(host se javlja kaoMCLaud, Ubuntu; ključ~/.ssh/id_ed25519sa razvojne mašine; samo root). Hetzner, van LAN-a. - Na ISTOM serveru žive i drugi sistemi — ne dirati:
terminiaSaaS platforma za klubove (portovi 8091/8092) — IME SLIČNO, ali NIJE naš proizvod;- Gitea;
- ESIR backend (fiskalizacija).
2. licence-server (naš deo)
- Kod:
/root/projects/licence-server— Go, bez frameworka, MySQL. - Port: 8090 lokalno; javno preko nginx sajta
arv. - Javni URL (ovo firmware već koristi):
https://157.180.119.151/license/api/v1/- HTTPS 443, cert
/etc/nginx/ssl/arv.crt,server_name= IP → self-signed (zato firmware koristisetInsecure(); odluku štiti RSA potpis odgovora). - Na portu 80 je izložen samo validator API; ostalo redirect na 443.
- HTTPS 443, cert
- Produkcioni obim: 3 proizvoda (ESIR, ARV, LIGHT_TICKET — seed u
migrations/002_seed_products.sql), ~140 licenci, ~19 aktivacija. ŽIVO.
Kripto
- RSA-2048, potpis RSA-SHA256.
- Privatni ključ: na serveru (
crypto/+.envkonfiguracija) — NE čitati, NE kopirati, NE logovati. - Javni ključ:
crypto/public.pem— VEĆ ugrađen u firmware (licenca.cpp,LIC_PUBKEY). Ako se ključ ikad rotira, MORA i novi firmware — to je krupna odluka, ne radi se usput. - Potpis stiže kao string:
"signature": "RSA-SHA256:<base64>"uzlicenseobjekat. Potpisuje se serijalizacija license objekta kakvu server pošalje — klijent verifikuje SIROVE bajtove (ne re-serijalizuje). Svaka izmena serijalizacije na serveru lomi sve klijente u polju.
Klijentski API (bez autentikacije, rate-limited)
| Ruta | Telo zahteva | Odgovor |
|---|---|---|
POST /api/v1/activate |
{license_key, machine_fingerprint, app_version, os, hostname} |
{license:{... expires_at, grace_days, limits, features, customer ...}, signature} |
POST /api/v1/validate |
{license_key, machine_fingerprint} |
{valid, expires_at, revoked} |
POST /api/v1/deactivate |
(transfer/oslobađanje) | — |
Greške (JSON error polje): INVALID_KEY, ALREADY_ACTIVATED, KEY_EXPIRED,
KEY_REVOKED, PRODUCT_MISMATCH.
Admin API
- Header
X-API-Key(ključ u.env— od vlasnika se traži ključ ili da on sam klikne u dashboardu; agent NE vadi ključ iz.envbez izričite dozvole). - Kreira proizvode i licence. Postoji i htmx admin dashboard.
3. Firmware klijent — GOTOV (od FW 0.10.0)
Fajlovi u firmware repou (firmware/10_terminia/):
| Šta | Gde |
|---|---|
| Modul | licenca.h / licenca.cpp |
| Ugrađen javni ključ | licenca.cpp → LIC_PUBKEY (PEM) |
| NVS | namespace lic: raw (sirovi license JSON) + sig; ključ/URL u configu: licKey, licUrl (podrazumevano https://157.180.119.151/license/api/v1) |
| Web API (SPA) | /api/license (status), /api/license-save (ključ/URL), /api/license-activate, /api/license-check — sve samo admin |
| UI | SPA → Podešavanja → Uređaj → kartica „Licenca" (status, izdanje, korisnik, važi do, otisak uređaja, unos ključa, Aktiviraj, Proveri na serveru) |
Kako klijent radi (bitno za server stranu)
- Otisak:
machine_fingerprint = "sha256:" + sha256hex(MAC)gde je MAC oblikaAA:BB:CC:DD:EE:FF(velika slova, dvotačke). ⚠️ PRETPOSTAVKA — proveriti u Go kodu servera kako računa fingerprint za poređenje; ako se razlikuje, uskladiti NA SERVERU dokumentaciju/verifikaciju za ASP proizvod ILI javiti pa menjamo FW (zadatak Z2). - Aktivacija: POST
/activate; iz odgovora isecₐ SIROVE bajtovelicenseobjekta (brojanje zagrada, string-safe), verifikujesignatureRSA‑SHA256 javnim ključem, čuva sirovo+potpis u NVS. - Svaki start (offline): ponovo verifikuje potpis iz NVS + poredi
machine_fingerprintiz licence sa svojim + proveravaexpires_at(poređenje po datumuYYYY-MM-DD; prazno = trajna; nepouzdan sat → grejs, nikad pad). - Statusi na uređaju:
nema / vazi / grejs / los-potpis / drugi-uredjaj / istekla. - ENFORCEMENT NE POSTOJI — uređaj samo prikazuje status. Gašenje funkcija bez licence je odluka vlasnika (zadatak Z4).
Polja koja klijent čita iz license objekta
edition, customer (ili customer_name), expires_at, license_id (ili key),
grace_days, machine_fingerprint. Nepoznata dodatna polja ne smetaju (parsira se
ciljano). limits/features se JOŠ ne čitaju — planirano uz enforcement.
4. Šta NE postoji (i pripada zadacima)
- Proizvod „ASP-Terminia" na serveru — ne postoji (zadatak Z1).
- Nijedan ASP ključ — ne postoji (Z1/Z2).
- Domen
licenca.terminia.net+ Let's Encrypt — ne postoji (Z3; domen kupuje vlasnik). - Enforcement na uređaju +
features/limitssemantika za ASP (Z4/Z5). - FW potpisivanje
.bin+ katalog firmvera (Z6; preduslov za auto-OTA, vidi i ASP repo:serviseri/03-provisioning-i-fw-katalog.md).