License System — ডকুমেন্টেশন

v2.0 Updated {{ date('d M Y') }}

সিস্টেম পরিচিতি

License System কী এবং কোন কোন component আছে

License System কী করে?

এটি একটি সম্পূর্ণ Software License Management System। Admin বা User যখন কারো জন্য License Key তৈরি করে, সেটি সেই client এর website এর .env ফাইলে স্বয়ংক্রিয়ভাবে সেভ হয়। Client এর script সেই key দিয়ে এই server-এ verify করে নিজেকে সক্রিয় রাখে।

🔑
License Key

Format: LIC-XXXX-XXXX-XXXX
প্রতিটি License unique।

✍️
Signature Key

64-char HMAC-SHA256।
Domain + License Key থেকে তৈরি।

⚡
Auto .env Save

Client এর server নিজেই লেখে।
কোনো manual কাজ নেই।

♾️
Lifetime License

Expiry date ছাড়া license।
Admin ও User দিতে পারে।

সম্পূর্ণ কার্যপ্রবাহ

License তৈরি থেকে .env save পর্যন্ত

── তৈরির উৎস ────────────────────────────────────────────── Admin Panel │ User Panel (Free/Paid) │ Public Buy Page /license └─────────────────────────┴──────────────────────────────┘ ↓ LicenseService::generateLicenseKey() LicenseService::generateSignature() ↓ Database: licenses table তে save ↓ ── .env auto-save (দুটো পদ্ধতি একসাথে) ────────────── ① HTTP Push ② Auto-Sync (প্রতি request) POST → /license-receiver.php Client script check করে: Client নিজেই .env এ লেখে "LICENSE_KEY আছে?" না থাকলে → /api/fetch-license Server key দেয় → .env এ লেখে ↓ Client .env ফাইল আপডেট হয়: LICENSE_KEY=LIC-XXXX-XXXX-XXXX LICENSE_SIGNATURE=abc123...64chars LICENSE_EXPIRY=2027-05-15 ↓ Client script verify করে → Active ✅

Admin থেকে License তৈরি

/admin/licenses → Generate License

Form Fields
Fieldবিবরণপ্রয়োজনীয়?
user_idকোন client-এর জন্যRequired
domain_nameClient এর domain (যেমন: example.com)Required
validity0=Lifetime, 1=১ বছর, 2=২ বছর, 3=৩ বছরRequired
site_pathSame-server হলে folder path (ঐচ্ছিক)Optional
License Generate হলে স্বয়ংক্রিয়ভাবে কী হয়
১
Database-এ সেভ হয়

licenses table-এ: license_key, signature_key, site_path, expiry_date

২
HTTP Push (Automatic)

Server সাথে সাথে https://clientdomain.com/license-receiver.php এ POST করে

৩
Table-এ 🟢 Push বাটন

যেকোনো সময় manually push করা যায়। HTTP Push ব্যর্থ হলে এটা ব্যবহার করুন।

Signature Key দেখা: Admin table-এ Signature Key column এ ক্লিক করলে clipboard-এ copy হয়। Edit modal-এ পুরো key দেখা ও copy করা যায়।

User থেকে License তৈরি

/license/generate

🎁 Free License

Admin যদি কোনো user-এর free_license_generation = 1 করে দেয়, সে বিনামূল্যে generate করতে পারে। সাথে সাথে license তৈরি হয়।

💳 Paid License

UddoktaPay payment gateway দিয়ে payment করলে তারপর license তৈরি হয়। Pending payment-এ admin manually activate করতে পারে।

Validity Options
Valueমেয়াদমূল্য
1১ বছরlicense_generation_price × 1
2২ বছরlicense_generation_price × 2
3৩ বছরlicense_generation_price × 3
0♾ Lifetimelicense_lifetime_price (default: price × 10)
User form-এ Site Root Path field আছে (optional)। দিলে same-server হলে সরাসরি .env-এ লেখে। না দিলেও HTTP Push বা Auto-Sync কাজ করবে।

Public Purchase Page

/license?domain=example.com

Client site যখন license error দেয়

Client এর script license error পেলে এই page-এ redirect করবে domain সহ। সেখানে client সরাসরি payment করে license নিতে পারবে।

Client script এ redirect URL আপডেট
// ❌ পুরনো (domain ছাড়া redirect) header('Location: {{ $serverUrl }}/license'); // ✅ নতুন (domain সহ redirect) $domain = $_SERVER['HTTP_HOST'] ?? ''; header('Location: {{ $serverUrl }}/license?domain=' . urlencode($domain));
🆕
Domain আছে, License নেই

Payment form দেখায়। Client নাম + email দিয়ে UddoktaPay-তে pay করে।

✅
License Active আছে

License Key দেখায়। Expiry date দেখায়। কোনো payment option নেই।

❌
Domain নেই (Legacy)

Generic error দেখায়। Support contact বাটন দেখায়।

Routes
MethodURLকাজ
GET/license?domain=xxxPurchase page দেখায়
POST/license/buyUddoktaPay-তে redirect
GET/license/buy/successPayment success callback
POST/license/buy/webhookUddoktaPay webhook
GET/license/buy/cancelPayment cancel

Auto-Sync — Client Script থেকে

SystemGuard.php → autoSyncLicense()

এটাই সবচেয়ে সহজ পদ্ধতি। Client এর existing script-এই এই code আছে। কোনো আলাদা setup লাগে না।
কীভাবে কাজ করে
১
Client এর প্রতিটি request-এ

EnforceRemoteLicenseKillSwitch middleware চলে

২
LICENSE_KEY চেক করে

.env এ LICENSE_KEY এবং LICENSE_SIGNATURE আছে কিনা দেখে

৩
না থাকলে server-এ call করে

GET /api/fetch-license?domain=xxx&token=yyy → Server license key + signature দেয়

৪
নিজের .env এ লেখে

base_path('.env') এ LICENSE_KEY, LICENSE_SIGNATURE, LICENSE_EXPIRY save করে

Client .env এ যা লাগে
# License Server এর URL (একবার manually দিতে হবে) LICENSE_REMOTE_BASE_URL={{ $serverUrl }} # Domain (optional, না দিলে HTTP_HOST থেকে নেয়) LICENSE_GUARD_DOMAIN=example.com # নিচের গুলো Auto-Sync এ automatically set হবে: # LICENSE_KEY=LIC-XXXX-XXXX-XXXX # LICENSE_SIGNATURE=abc123... # LICENSE_EXPIRY=2027-05-15

HTTP Push — Server থেকে Client এ

license-receiver.php এর মাধ্যমে

এটি সেকেন্ডারি পদ্ধতি। Auto-Sync কাজ না করলে বা instant save করতে চাইলে এটা ব্যবহার হয়। License generate হলে server automatically try করে।
Push payload (Server থেকে Client এ যায়)
{ "license_key": "LIC-XXXX-XXXX-XXXX", "signature_key": "abc123...64chars...", "expiry_date": "2027-05-15", "push_token": "HMAC(domain|license_key, salt)" }
Client এর license-receiver.php এর কাজ

১. push_token verify করে (security check)
২. .env ফাইলে LICENSE_KEY, LICENSE_SIGNATURE লেখে
৩. {"status":"ok"} response দেয়

Client Setup

নতুন client কে কী করতে হবে

Auto-Sync ব্যবহারকারীদের জন্য কোনো extra setup লাগে না। শুধু LICENSE_REMOTE_BASE_URL={{ $serverUrl }} .env এ দিলেই হবে।
HTTP Push এর জন্য (one-time setup)
১
Script ডাউনলোড করুন

Admin → Licenses → Download license-receiver.php

২
Website root এ আপলোড করুন

.env ফাইলের পাশে রাখুন। cPanel-এ public_html/ ফোল্ডারে।

৩
.env permission ঠিক করুন

chmod 664 .env বা cPanel থেকে permission 664 দিন।

৪
Test করুন

Browser-এ https://clientdomain.com/license-receiver.php visit করুন। {"status":"error","message":"Method not allowed."} দেখালে সফল।

API: verify-license

Client script লাইসেন্স যাচাই করতে call করে

MethodURLAuth
POST{{ $serverUrl }}/api/verify-licenseHMAC signature
Request Parameters
ParameterTypeবিবরণ
domainstringClient এর domain (www ছাড়া)
license_keystringLIC-XXXX-XXXX-XXXX format
signaturestringhash_hmac('sha256', domain, HMAC_SALT)
Success Response
{ "status": "valid", "blocked": false, "domain_name": "example.com", "license_key": "LIC-XXXX-XXXX-XXXX", "expiry_date": "2027-05-15", // বা "lifetime" "secure_token": "md5 token", "cache_signal": "random string", "action": "none" // বা "wipe_out" }
PHP Example (Client Script)
$domain = strtolower(preg_replace('#^www\.#i', '', $_SERVER['HTTP_HOST'])); $licenseKey = env('LICENSE_KEY'); $signature = hash_hmac('sha256', $domain, '{{ $hmacSalt }}'); $response = Http::post('{{ $serverUrl }}/api/verify-license', [ 'domain' => $domain, 'license_key' => $licenseKey, 'signature' => $signature, ]); // Response check করুন $data = $response->json(); if (($data['status'] ?? '') !== 'valid') { header('Location: {{ $serverUrl }}/license?domain='.urlencode($domain)); exit; }

API: fetch-license

Client script নিজের license key fetch করতে call করে (Auto-Sync)

MethodURLRate Limit
GET{{ $serverUrl }}/api/fetch-license20 req/min
Parameters
Parameterবিবরণ
domainClient এর domain
tokenhash_hmac('sha256', domain + '|' + YYYYmmddHH, HMAC_SALT) — প্রতি ঘন্টায় বদলায়
Success Response
{ "status": "ok", "license_key": "LIC-XXXX-XXXX-XXXX", "signature_key": "abc123...64chars...", "expiry_date": "2027-05-15" }
Token প্রতি ঘন্টায় বদলায়। Current hour এবং previous hour দুটোই accept করা হয় (clock drift এর জন্য)। Replay attack সম্ভব নয়।

API: cache-signal

Kill-switch signal — admin চাইলে client script destroy করতে পারে

MethodURL
GET{{ $serverUrl }}/api/cache-signal?domain=xxx
Response (action = wipe_out)
{ "action": "wipe_out" // সব DB table ও file delete হবে } // Normal: { "action": "none" }

Security Architecture

HMAC + Token সিস্টেম

🔐 HMAC_SALT

সব signature calculation এ একই salt ব্যবহার হয়। Server ও Client script এ মিলিয়ে রাখতে হবে।

// Server: LicenseController.php private const HMAC_SALT = '{{ $hmacSalt }}'; // Client: license-receiver.php define('HMAC_SALT', '{{ $hmacSalt }}');
✍️ Signature Formula

প্রতিটি সিস্টেমে ভিন্ন formula:

// verify-license (client verify এ): hash_hmac('sha256', $domain, SALT) // License Signature Key: hash_hmac('sha256', $key.'|'.$domain, SALT) // fetch-license token: hash_hmac('sha256', $domain.'|'.$hour, SALT) // push token: hash_hmac('sha256', $domain.'|'.$key, SALT)

Lifetime License

মেয়াদহীন লাইসেন্স

Lifetime কীভাবে কাজ করে

Validity = 0 দিলে expiry_date = NULL database-এ। Verify করার সময় NULL expiry মানে কখনো expire হবে না। API response-এ "expiry_date": "lifetime" আসে।

Table-এ Lifetime badge

Admin table-এ Expiry column-এ ♾ Lifetime badge দেখায়।

Lifetime license-এর মূল্য: generalsettings.license_lifetime_price (default = license_generation_price × 10)

License System Documentation — {{ $gs->title ?? 'Creative Design' }} © {{ date('Y') }}

License Panel Setup Guide Download Receiver

{{-- /doc-wrap --}}
{{-- /main --}}