# ONOXSOFT License Server — Tasarım Spesifikasyonu

**Tarih:** 2026-05-13
**Durum:** Spec — implementation öncesi onay bekliyor
**Hedef Phase:** L0-L6 (~7 ay solo part-time, Phase 1 GA paralelinde)

---

## 1. Bağlam ve Hedef

ONOXSOFT, Türkiye hosting pazarına satılacak ticari kontrol paneli üreticisi (TPMK tescilli marka). Ürün adı **Onoxsoft Panel**. Lisans modeli **cPanel benzeri** — sunucu IP'sine bağlı, yıllık abonelik, müşteri panelden satın alır, lisans key görmez.

Bu doküman lisans sistemine ait iki bileşeni spec'ler:
1. **License Server** — `onox.com.tr` adresinde yeni Laravel projesi (satış + doğrulama + müşteri portalı)
2. **License Client** — mevcut PANELTR projesinde sertleştirilmiş istemci

**Ticari hedef:** crack/reverse-proxy bypass'a karşı dayanıklı, müşteri için key girmesiz sade UX, hosting firmasının kendi müşterilerini etkilemeyen yumuşak failure davranışı.

---

## 2. Locked Decisions (Brainstorming Çıktısı)

| Karar | Değer | Gerekçe |
|---|---|---|
| Mimari | 2 ayrı codebase (License Server + Panel) | Server authority + client separation |
| Satış modeli | Plan C — tam self-service SaaS | Iyzico kart ödeme + e-Fatura otomasyonu |
| Lisans modeli | cPanel benzeri, IP-based | Müşteri key görmez/girmez; panelden alır |
| IP binding | Plan A+B karma — IP primary + machine-id secondary | cPanel kolaylığı + crack zorluğu |
| Aktivasyon | Purchase Intent Token (HMAC-imzalı) | Müşteri key yönetmez, panel kendisi halleder |
| Doğrulama | 6 saatlik heartbeat + JWT exp 25 saat + 72h grace | Düşük yük, offline-friendly, makul tepki |
| Failure | Postfix + Dovecot + panel login durur; PHP-FPM/Apache/DB/DNS ayakta | Hosting firması müşterilerini kaybetmez |
| Tech stack | Laravel 11 + Inertia + Vue 3 + Tailwind (PANELTR aynı) | Kod paylaşımı |
| İmza | Ed25519 (modern, hızlı, küçük key) | RSA'dan üstün |
| Obfuscation | ionCube (sadece license-checking dosyalar) | Lisans bölümü kapalı, geri kalan AGPL-3.0 community |
| Hosting | Hetzner CX32 (~€8/ay) | Test/prod aynı provider, AlmaLinux 9 |
| Marka | "Onoxsoft Panel" (Onoxsoft değil), şirket "ONOXSOFT" | TPMK tescili, doğru kullanım |

---

## 3. Mimari Topoloji

```
┌─────────────────────────────────────────────────────────┐
│  onox.com.tr — Onoxsoft License Server                  │
│  (yeni Laravel 11 + Inertia + Vue projesi)              │
│                                                          │
│  ┌──────────────┐  ┌──────────────┐  ┌────────────────┐│
│  │ Public site  │  │ Customer     │  │ Admin panel    ││
│  │ + checkout   │  │ portal       │  │ (revenue, CRUD)││
│  │ (Iyzico)     │  │ /portal      │  │ /admin         ││
│  └──────────────┘  └──────────────┘  └────────────────┘│
│  ┌──────────────────────────────────────────────────┐  │
│  │ Verification API (panel ↔ server)                │  │
│  │  POST /api/v1/activate                            │  │
│  │  POST /api/v1/heartbeat                           │  │
│  │  POST /api/v1/transfer-ip                         │  │
│  │  GET  /api/v1/license/check?intent=TOKEN          │  │
│  │  POST /api/v1/crack-report                        │  │
│  └──────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────┘
                          ▲
                  signed JWT (Ed25519) + TLS pinning
                          │
┌─────────────────────────┴───────────────────────────────┐
│  Müşteri Sunucusu — Onoxsoft Panel (PANELTR)            │
│                                                          │
│  ┌──────────────────────────────────────────────────┐  │
│  │ OnoxsoftLicenseClient                            │  │
│  │  - Heartbeat cron (6 saatlik)                    │  │
│  │  - JWT cache: /etc/onoxsoft/license.jwt          │  │
│  │  - TLS pinning + Ed25519 signature verify        │  │
│  │  - HMAC cache tamper detection                   │  │
│  │  - Time warp detection                           │  │
│  │  - Honeypot endpoints                            │  │
│  │  - Code integrity check (boot)                   │  │
│  └──────────────────────────────────────────────────┘  │
│                                                          │
│  Lisans geçersiz → KillSwitch:                          │
│    Postfix + Dovecot DOWN                                │
│    PHP-FPM + Apache + DB + DNS UP                        │
│    Login → "Lisans Satın Al" sayfası                    │
└─────────────────────────────────────────────────────────┘
```

---

## 4. Branding Düzeltmesi (Zorunlu)

| Yer | Şimdi (yanlış) | Olacak (doğru) |
|---|---|---|
| Şirket | — | **ONOXSOFT** (TPMK tescilli) |
| Ana site | — | **onox.com.tr** |
| Ürün adı | "Onoxsoft Panel" | **Onoxsoft Panel** |
| Komut prefix | `onx-*` | `onx-*` (zaten doğru, kalır) |
| Config path | `/etc/onoxsoft` | `/etc/onoxsoft` (zaten doğru) |
| Doküman, e-posta, UI metinleri | "ONOX" | "Onoxsoft Panel" |
| package.json `name` | `onox-panel` | `onoxsoft-panel` |
| config/app.php `name` | `Onoxsoft Panel` | `Onoxsoft Panel` |

**Migration adımı:** PANELTR'de `Grep -r "ONOX[^S]" --include="*.{vue,php,md,json}"` ile tüm yerler bulunur, manuel review + replace.

---

## 5. Failure Davranışı (Lisans Geçersizken)

### Servis Etkisi

| Servis | Davranış | Sebep |
|---|---|---|
| Panel admin login | ⛔ Yasak | Yönetim kilitleme |
| Panel customer login | ⛔ Yasak | Yönetim kilitleme |
| "Lisans Satın Al" sayfası | ✅ Açık | Çözüm yolu açık olmalı |
| Panel API endpoints | ⛔ 402 Payment Required | Otomasyon engelleme |
| Postfix (SMTP) | ⛔ `systemctl stop` | Mail kritik feature, kapalı = ödeme baskısı |
| Dovecot (IMAP/POP3) | ⛔ `systemctl stop` | Aynı sebep |
| Apache / Nginx | ✅ AYAKTA | Müşteri siteleri çalışmaya devam |
| PHP-FPM (tüm versiyonlar) | ✅ AYAKTA | Müşteri PHP siteleri çalışır |
| MariaDB | ✅ AYAKTA | Müşteri DB'leri çalışır |
| PowerDNS | ✅ AYAKTA | DNS sorguları çalışır |
| Pure-FTPd / SFTP | ✅ AYAKTA | Müşteri dosya erişimi çalışır |
| Cron'lar (backup, AutoSSL) | ✅ AYAKTA | Data koruması |
| `onx-*` sysapi script'leri | ⛔ Reddedilir | Yeni hesap oluşturma engellenir |

**Mantık:** Hosting firmasının **müşterilerine hizmeti** kesintisiz, ama kendi **yönetim arayüzü ve mail** kapalı. cPanel/Plesk yaklaşımı.

### Grace Period Tablosu

| Durum | Sonuç |
|---|---|
| Heartbeat son 6 saat ✓ | Normal çalış |
| 6-25 saat heartbeat yok | JWT cache ile devam |
| 25-72 saat heartbeat yok | Banner uyarı, normal çalış |
| 72 saat+ heartbeat yok | KillSwitch |
| Lisans expire | 24 saat ön uyarı → KillSwitch |
| Tamper/crack tespit | Anında KillSwitch + rapor |

---

## 6. Purchase Intent Flow

### Aktivasyon Adımları (müşteri tarafı)

```
1. Müşteri panel kurar (curl|bash installer)
2. Panel ilk açılışta KillSwitch'te (mail down, login → buy)
3. Panel'de "Lisans Satın Al" tıklar
4. Panel `purchase_intent` token üretir (HMAC-imzalı):
   {
     ip:           "1.2.3.4",
     machine_id:   "abcd...",   // /etc/machine-id
     hostname:     "host.com",
     panel_version:"1.0.0",
     exp:          1h
   }
5. Browser yönlendirilir:
   https://onox.com.tr/buy?intent=BASE64URL_TOKEN
6. onox.com.tr token'ı verify eder, IP + machine-id pre-fill
7. Müşteri:
   - Plan seçer (Trial / Lite / Pro / Unlimited / Enterprise)
   - Kayıt olur veya login yapar
   - KVKK + sözleşme onayı
   - Iyzico ile 3D-Secure ödeme
8. Ödeme onayı → server license oluşturur:
   {
     customer_id:        N,
     tier:               'pro',
     bound_ip:           '1.2.3.4',
     bound_machine_id:   'abcd...',
     bound_hostname:     'host.com',
     intent_token:       'TOKEN'
   }
9. Müşteri "Lisans aktif" sayfasına yönlendirilir
10. Panel her 30 saniyede `GET /api/v1/license/check?intent=TOKEN` poller
11. License bulunur → server signed JWT döner (Ed25519)
12. Panel JWT'yi verify eder, `/etc/onoxsoft/license.jwt`'ye yazar
13. KillSwitch deactivate (Postfix + Dovecot start)
14. Panel canlı, müşteri panele döner
```

### Purchase Intent Token Formatı

```json
{
  "v": 1,
  "ip": "1.2.3.4",
  "mid": "machine-id-hex-string",
  "host": "panel.example.com",
  "pv": "1.0.0",
  "ts": 1747159200,
  "exp": 1747162800,
  "nonce": "random-32-bytes-base64",
  "sig": "HMAC-SHA256-with-PANEL_INTENT_SECRET"
}
```

Panel `PANEL_INTENT_SECRET` ile imzalar, License Server bu secret'ı bilmediği için imzayı doğrulayamaz — **sadece** content'i kullanır (IP, machine-id pre-fill). Replay koruması için `nonce` server'da `purchase_intents` tablosuna kaydedilir, ikinci kullanım reddedilir.

### License JWT Formatı (server'dan panel'e)

```json
{
  "iss": "onox.com.tr",
  "sub": "license-uuid-here",
  "aud": "onoxsoft-panel",
  "iat": 1747159200,
  "exp": 1747249200,
  "license": {
    "tier": "pro",
    "account_limit": 100,
    "features": ["mail_server", "plugins", "whmcs_plugin", "ai_assistant"],
    "bound_ip": "1.2.3.4",
    "bound_machine_id": "abcd...",
    "bound_hostname": "panel.example.com",
    "expires_at": "2027-05-13T00:00:00Z",
    "customer_email": "admin@example.com"
  }
}
```

**İmza algoritması:** EdDSA (Ed25519).
**Panel doğrulama:** `config/onoxsoft/license-pubkey.pem` (build time embedded).

---

## 7. License Server İç Mimarisi

### Repo Yapısı

```
C:\xampp\htdocs\ONOXSOFT-LICENSE\
├── app/
│   ├── Domain/
│   │   ├── Customer/                    # Müşteri (hosting firması) hesabı
│   │   │   ├── Models/Customer.php
│   │   │   └── Services/CustomerOnboardingService.php
│   │   ├── License/                     # Lisans CRUD + binding
│   │   │   ├── Models/License.php
│   │   │   ├── Models/LicenseBinding.php
│   │   │   ├── Services/LicenseIssuer.php
│   │   │   └── Services/JwtSigner.php   # Ed25519
│   │   ├── Order/                       # Sipariş + ödeme
│   │   │   ├── Models/Order.php
│   │   │   ├── Models/Payment.php
│   │   │   ├── Services/IyzicoGateway.php
│   │   │   └── Services/InvoiceGenerator.php
│   │   ├── Verify/                      # Panel ↔ server API
│   │   │   ├── Services/VerifyService.php
│   │   │   ├── Actions/ActivateAction.php
│   │   │   ├── Actions/HeartbeatAction.php
│   │   │   └── Actions/TransferIpAction.php
│   │   ├── Billing/                     # e-Fatura (Phase L5)
│   │   │   └── Services/ParasutAdapter.php
│   │   └── Security/                    # Crack tespit
│   │       ├── Models/CrackReport.php
│   │       └── Services/CrackDetector.php
│   ├── Http/
│   │   ├── Controllers/
│   │   │   ├── PublicController.php     # /, /fiyatlar, /ozellikler
│   │   │   ├── BuyController.php        # /buy?intent=...
│   │   │   ├── AuthController.php       # /giris, /kayit
│   │   │   ├── Portal/                  # Müşteri portali
│   │   │   ├── Admin/                   # Admin (sen)
│   │   │   └── Api/V1/                  # Verification API
│   │   └── Middleware/
│   │       └── VerifyApiSignature.php   # Panel→server isteklerini doğrula
│   ├── Jobs/
│   │   ├── ProcessIyzicoCallbackJob.php
│   │   ├── GenerateInvoiceJob.php
│   │   └── SendLicenseConfirmationJob.php
│   └── Console/Commands/
│       ├── LicenseExpiryReminderCommand.php
│       └── StaleBindingsCleanupCommand.php
├── resources/js/Pages/
│   ├── Public/{Home,Pricing,Features}.vue
│   ├── Buy/{Index,Success,Failure}.vue
│   ├── Auth/{Login,Register,ForgotPassword}.vue
│   ├── Portal/{Dashboard,Licenses,Invoices,Settings}.vue
│   └── Admin/{Dashboard,Customers,Licenses,Orders,CrackReports}.vue
├── routes/{web,api}.php
├── database/migrations/
└── config/onoxsoft/
    └── license-private.pem               # env'den yüklenir, .gitignore
```

### DB Schema

```sql
-- Customer (hosting firması)
CREATE TABLE customers (
    id BIGINT PRIMARY KEY,
    email VARCHAR(255) UNIQUE NOT NULL,
    email_verified_at TIMESTAMP NULL,
    password VARCHAR(255) NOT NULL,
    name VARCHAR(255) NOT NULL,
    company VARCHAR(255) NULL,
    tax_number VARCHAR(20) NULL,         -- VKN/TCKN
    phone VARCHAR(20) NULL,
    billing_address JSON NULL,
    kvkk_consented_at TIMESTAMP NULL,
    two_factor_secret TEXT NULL,
    remember_token VARCHAR(100) NULL,
    created_at TIMESTAMP,
    updated_at TIMESTAMP
);

-- License (1 customer N license)
CREATE TABLE licenses (
    id BIGINT PRIMARY KEY,
    uuid CHAR(36) UNIQUE NOT NULL,
    customer_id BIGINT FK NOT NULL,
    tier ENUM('trial','lite','pro','unlimited','enterprise') NOT NULL,
    status ENUM('active','suspended','expired','revoked') NOT NULL,
    account_limit INT NOT NULL,
    features JSON NOT NULL,
    purchased_at TIMESTAMP NOT NULL,
    expires_at TIMESTAMP NOT NULL,
    last_heartbeat_at TIMESTAMP NULL,
    revoked_at TIMESTAMP NULL,
    revoked_reason TEXT NULL,
    INDEX idx_status (status, expires_at)
);

-- Binding (1 license = 1 aktif binding; geçmiş binding'ler 'stale')
CREATE TABLE license_bindings (
    id BIGINT PRIMARY KEY,
    license_id BIGINT FK NOT NULL,
    bound_ip VARCHAR(45) NOT NULL,
    bound_machine_id VARCHAR(64) NOT NULL,
    bound_hostname VARCHAR(253) NULL,
    panel_version VARCHAR(20) NULL,
    first_seen_at TIMESTAMP NOT NULL,
    last_seen_at TIMESTAMP NOT NULL,
    status ENUM('active','stale','revoked') NOT NULL,
    INDEX idx_lookup (license_id, bound_ip, bound_machine_id, status)
);

-- Audit
CREATE TABLE license_audit (
    id BIGINT PRIMARY KEY,
    license_id BIGINT FK NOT NULL,
    event ENUM('activate','heartbeat','ip_transfer','suspend','revoke','crack_detected','expired') NOT NULL,
    payload JSON NULL,
    ip VARCHAR(45) NULL,
    user_agent VARCHAR(500) NULL,
    created_at TIMESTAMP NOT NULL,
    INDEX idx_license (license_id, created_at DESC)
);

-- Order (ödeme + sipariş)
CREATE TABLE orders (
    id BIGINT PRIMARY KEY,
    customer_id BIGINT FK NOT NULL,
    license_id BIGINT FK NULL,            -- ödeme onaylanınca atanır
    amount_cents BIGINT NOT NULL,
    currency CHAR(3) DEFAULT 'TRY',
    status ENUM('pending','paid','failed','refunded') NOT NULL,
    iyzico_payment_id VARCHAR(64) NULL,
    iyzico_basket_id VARCHAR(64) NULL,
    intent_token VARCHAR(255) NULL,        -- purchase_intents tablosuna FK
    created_at TIMESTAMP,
    paid_at TIMESTAMP NULL
);

-- Invoice (e-Fatura)
CREATE TABLE invoices (
    id BIGINT PRIMARY KEY,
    order_id BIGINT FK NOT NULL,
    number VARCHAR(32) UNIQUE NOT NULL,    -- "ONX2026000001"
    parasut_id VARCHAR(64) NULL,
    pdf_path VARCHAR(500) NULL,
    sent_at TIMESTAMP NULL,
    total_cents BIGINT NOT NULL,
    tax_cents BIGINT NOT NULL,
    created_at TIMESTAMP
);

-- Crack Reports
CREATE TABLE crack_reports (
    id BIGINT PRIMARY KEY,
    license_id BIGINT FK NULL,             -- crack lisans bağlı olmayabilir
    signal ENUM('tamper','tls_pin_fail','time_warp','honeypot_hit','dual_install','integrity_fail') NOT NULL,
    severity ENUM('low','medium','high','critical') NOT NULL,
    payload JSON NOT NULL,
    reported_ip VARCHAR(45) NULL,
    reviewed_at TIMESTAMP NULL,
    reviewer_id BIGINT NULL,
    action_taken VARCHAR(255) NULL,
    created_at TIMESTAMP
);

-- Purchase Intents
CREATE TABLE purchase_intents (
    id BIGINT PRIMARY KEY,
    token VARCHAR(255) UNIQUE NOT NULL,
    panel_ip VARCHAR(45) NOT NULL,
    panel_machine_id VARCHAR(64) NOT NULL,
    panel_hostname VARCHAR(253) NULL,
    panel_version VARCHAR(20) NULL,
    customer_id BIGINT FK NULL,            -- müşteri kayıt olunca atanır
    order_id BIGINT FK NULL,                -- ödeme yapılınca atanır
    expires_at TIMESTAMP NOT NULL,
    consumed_at TIMESTAMP NULL,
    created_at TIMESTAMP
);
```

### API Endpoints (Panel ↔ License Server)

| Method | Path | Body | Response | Açıklama |
|---|---|---|---|---|
| POST | `/api/v1/activate` | `{intent_token, ip, machine_id, hostname, panel_version}` | `{license_jwt, expires_at}` | İlk aktivasyon |
| POST | `/api/v1/heartbeat` | `{license_uuid, ip, machine_id, panel_version, signature}` | `{license_jwt}` veya `{status:'expired'}` | 6 saatlik check |
| POST | `/api/v1/transfer-ip` | `{license_uuid, new_ip, new_machine_id, current_signature}` | `{license_jwt}` veya `{error}` | Müşteri portalinden |
| GET | `/api/v1/license/check?intent=TOKEN` | — | `{status, license_jwt?}` | Polling endpoint |
| POST | `/api/v1/crack-report` | `{license_uuid?, signal, payload, signature}` | `{recorded:true}` | Panel'den crack rapor |

**Auth:** Tüm endpoint'lerde panel `License-UUID` + `License-Signature` header gönderir, signature panel'in private key'iyle imzalı (her panel kuruluşunda otomatik üretilir).

**Rate limit:** IP başına 10/dakika, license başına 60/saat.

---

## 8. Panel License Client (PANELTR Sertleştirme)

### Yeni/Güncellenen Dosyalar

```
C:\xampp\htdocs\PANELTR\app\Domain\License\
├── Services/
│   ├── LicenseManager.php              [GÜNCELLE — mevcut]
│   ├── OnoxsoftLicenseClient.php       [YENİ — HTTP istemci]
│   ├── JwtVerifier.php                 [YENİ — Ed25519 verify]
│   ├── MachineFingerprint.php          [YENİ — /etc/machine-id okur]
│   ├── PurchaseIntentBuilder.php       [YENİ — intent token]
│   ├── KillSwitch.php                  [YENİ — failure davranışı]
│   ├── IntegrityChecker.php            [YENİ — code tamper detect]
│   └── HoneypotMonitor.php             [YENİ — sahte endpoint takip]
├── Actions/
│   ├── ActivateLicenseAction.php
│   ├── TransferIpAction.php
│   └── EnforceLicenseAction.php
└── Console/Commands/
    ├── HeartbeatCommand.php            [GÜNCELLE — mevcut]
    └── EnforceCommand.php              [YENİ — manuel enforce]

C:\xampp\htdocs\PANELTR\app\Http\Middleware\
└── EnforceLicense.php                  [GÜNCELLE — KillSwitch entegre]

C:\xampp\htdocs\PANELTR\config\onoxsoft\
├── license-pubkey.pem                  [YENİ — Ed25519 public key, build embedded]
├── tls-pinned.json                     [YENİ — cert SHA256'lar]
└── integrity.json                      [YENİ — kritik dosyaların SHA256'sı]

/etc/onoxsoft/                          [target server runtime]
├── license.jwt                         [signed JWT cache — root:root 0600]
├── license.hmac                        [JWT'nin HMAC'i — tamper detection]
└── machine.fp                          [okunmuş machine-id snapshot]
```

### Buy Sayfası (panel'de)

`GET /lisans/satin-al` — auth gerektirmez, tek erişilebilir sayfa lisans yokken.

**İçerik:**
- Hero: "Onoxsoft Panel — Lisans Gerekli"
- Mevcut sunucu durumu kartı (IP, hostname, machine-id, kopyalanabilir)
- 5 paket kartı: Trial (ücretsiz, 5 hesap) / Lite (₺315/ay, 30) / Pro (₺675/ay, 100) / Unlimited (₺1.125/ay) / Enterprise (₺3.555/ay multi-server)
- "Satın Al" butonu → `POST /lisans/intent` (purchase intent) → `https://onox.com.tr/buy?intent=TOKEN` redirect
- Sağ panel: "Lisansım zaten var, doğrula" → manuel polling tetikler
- Alt: destek e-postası

---

## 9. Anti-Crack Sertleştirme (9 Katmanlı Savunma)

| # | Katman | Saldırı | Önlem |
|---|---|---|---|
| L1 | TLS pinning | DNS hijack ile sahte onox.com.tr | `config/onoxsoft/tls-pinned.json` — cert SHA256 embedded, eşleşmezse abort |
| L2 | Ed25519 imza | Sahte license server response | JWT EdDSA-imzalı, panel sadece embedded public key ile doğrular |
| L3 | HMAC cache | `/etc/onoxsoft/license.jwt` elle edit | Yanında HMAC, eşleşmezse cache invalid |
| L4 | Time warp | Sunucu saatini geri at | Heartbeat response'unda server ts, lokal saat 25h+ geride ise lock |
| L5 | Honeypot | Bypass denemesi | Sahte `/api/license/skip` endpoint'leri, çağrılırsa crack flag |
| L6 | Dual-install | 2 sunucuda paralel | Server tarafı: aynı license farklı IP+machine-id 1h içinde heartbeat → alarm |
| L7 | Code obfuscation | Reverse engineer | ionCube ile `app/Domain/License/*` + middleware encode (production build) |
| L8 | Integrity check | Kod değiştirme | Boot'ta kritik dosyaların SHA256'sı `integrity.json`'a karşı kontrol |
| L9 | Reverse proxy block | MITM ile sahte server | TLS pinning + Ed25519 birleşimi → cracker private key olmadığı için yapamaz |

**Crack tespit edilince:**
1. Panel → onox.com.tr'ye `POST /api/v1/crack-report` (signed event, retry queue)
2. Anında KillSwitch (lokal)
3. License server: `status='suspended'`, customer'a e-posta
4. Admin paneli `crack_reports` tablosunda görür, manuel inceler, refund/ban karar

**ionCube maliyeti:** ~$199 başlangıç + $99/yıl (~₺9K + ₺4.5K). Sadece 8-12 dosya encode edilir, geri kalan AGPL-3.0 community version'da açık.

---

## 10. Phase Roadmap

| Phase | Süre | İçerik | Çıktı |
|---|---|---|---|
| **L0** | 2 hafta | Marka süreci, domain, key pair, brand asset | TPMK başvuru, onox.com.tr aktif, Ed25519 key pair üretilmiş |
| **L1** | 8 hafta | License Server MVP: auth, lisans CRUD, intent flow, Iyzico, /api/v1/* | Test ortamında 1 müşteri end-to-end satın alabiliyor |
| **L2** | 6 hafta | Panel hardening: OnoxsoftLicenseClient, JWT verify, KillSwitch, EnforceLicense, "Lisans Satın Al" sayfası, branding fix | Panel lisans yokken doğru davranıyor, lisansla aktive oluyor |
| **L3** | 4 hafta | Anti-crack: TLS pinning, HMAC, integrity, honeypot, ionCube build pipeline | 9 katman çalışıyor, manuel crack denemesi tespit ediliyor |
| **L4** | 4 hafta | Customer portal: lisanslarım, IP transfer, fatura listesi | Müşteri tek tıkla IP değiştirebiliyor |
| **L5** | 3 hafta | e-Fatura: Paraşüt entegrasyonu | Otomatik fatura kesimi |
| **L6** | 2 hafta | Production launch: Hetzner CX32, SSL, monitoring, beta tester | onox.com.tr canlı, ilk satışa hazır |

**Toplam: ~29 hafta = 7 ay part-time** (Phase 1 GA paralelinde ilerler, GA blocker değil).

---

## 11. Critical Files

| Path | Amaç |
|---|---|
| `C:\xampp\htdocs\ONOXSOFT-LICENSE\` | Yeni Laravel projesi (License Server bütünü) |
| `…\app\Domain\Verify\Services\VerifyService.php` | API endpoint logic — **güvenlik açısından en kritik** |
| `…\app\Domain\License\Services\JwtSigner.php` | Ed25519 imzalama |
| `…\app\Domain\Order\Services\IyzicoGateway.php` | Iyzico 3D-Secure entegrasyonu |
| `…\app\Domain\Security\Services\CrackDetector.php` | Crack signal aggregation |
| `…\config\onoxsoft\license-private.pem` | Ed25519 private key (env'den) |
| `C:\xampp\htdocs\PANELTR\app\Domain\License\Services\OnoxsoftLicenseClient.php` | Panel HTTP istemci |
| `…\app\Domain\License\Services\JwtVerifier.php` | JWT signature verify |
| `…\app\Domain\License\Services\KillSwitch.php` | Failure davranışı uygulama |
| `…\config\onoxsoft\license-pubkey.pem` | Embedded public key |
| `…\config\onoxsoft\tls-pinned.json` | TLS pinning fingerprints |
| `…\resources\js\Pages\License\Buy.vue` | "Lisans Satın Al" sayfası |
| `…\docs\license\anti-crack-runbook.md` | Crack tespit edilince ne yapılır |

---

## 12. Açık Sorular / Sonra Karar Verilecekler

- **Ödeme gateway:** Iyzico vs PayTR vs Param (komisyon ~%2.5-3, integration effort eşit)
- **Hosting maliyeti:** onox.com.tr Hetzner CX32 (~€8/ay), MariaDB+Redis aynı sunucu
- **Backup stratejisi:** License Server DB için saatlik mariabackup snapshot, offsite (B2/S3)
- **Disaster recovery:** License server down → 72 saat grace, sonra otomatik recovery from backup
- **AGPL-3.0 vs ionCube:** ionCube'lu dosyalar commercial tier'a girer; community AGPL'de bu dosyalar açık, crack koruması zayıflar (kabul edilebilir trade-off)
- **Trial lisans politikası:** Gerçekten ücretsiz mi (5 hesap limitli), yoksa 30 gün deneme + kart bilgisi mi?
- **Refund politikası:** 7 gün koşulsuz mu, 14 gün koşullu mu?
- **KVKK aydınlatma metni:** avukat onaylı, license server'a özel

---

## 13. Verification Plan

### L1 — License Server MVP
- Postman ile end-to-end: intent token → buy sayfası → Iyzico sandbox ödeme → license oluşur → JWT döner
- Panel test ortamında activate endpoint çağırır, signed JWT alır, verify eder
- Manuel test: yanlış imzalı JWT panel tarafından reddedilir

### L2 — Panel Hardening
- Lisans olmadan panel açılır → buy sayfası gelir, geri kalan yasak
- Postfix `systemctl is-active` → inactive
- Lisans aktive olunca → Postfix start, login açılır
- 25h JWT exp dolar → grace, 72h sonra KillSwitch

### L3 — Anti-Crack
- Manuel test: `/etc/onoxsoft/license.jwt`'yi elle edit → cache invalid
- Test: TLS cert değiştir (proxy ile) → bağlantı reddedilir
- Test: sahte signature ile heartbeat → reject
- Test: honeypot endpoint çağır → crack report oluşur

### L6 — Production Launch
- Production CX32'de end-to-end satın alma testi
- e-Fatura test (Paraşüt sandbox)
- Beta tester onboarding (5 hosting firması)
- 30 gün sıfır kritik bug
- Pentest (PRODAFT/BTRİSK) — critical/high yok

---

**Plan versiyonu:** v1.0 (2026-05-13)
**Yazan:** Brainstorming session (PANELTR ana plan paralelinde)
**Sonraki adım:** Spec onayı sonrası `writing-plans` skill ile L1 implementation plan yazılacak.
