enable/disable license

This commit is contained in:
Flatlogic Bot 2026-02-19 18:46:30 +00:00
parent cc2f923ac2
commit 7c8899df47
4 changed files with 218 additions and 8 deletions

View File

@ -0,0 +1,3 @@
-- SQL for the License Manager Database (u128023052_meezan_license)
ALTER TABLE licenses ADD COLUMN owner VARCHAR(255) DEFAULT NULL;
ALTER TABLE licenses ADD COLUMN address TEXT DEFAULT NULL;

150
index.php
View File

@ -1088,6 +1088,37 @@ if (isset($_POST['add_hr_department'])) {
}
}
}
if (isset($_POST['update_license'])) {
$id = (int)$_POST['id'];
$status = $_POST['status'] ?? null;
$owner = $_POST['owner'] ?? null;
$address = $_POST['address'] ?? null;
$updateData = [];
if ($status !== null) $updateData['status'] = $status;
if ($owner !== null) $updateData['owner'] = $owner;
if ($address !== null) $updateData['address'] = $address;
$res = LicenseService::updateLicense($id, $updateData);
if ($res['success']) {
$message = "License updated successfully!";
} else {
$message = "Error: " . ($res['error'] ?? 'Unknown error');
}
}
if (isset($_POST['issue_license'])) {
$max = (int)($_POST['max_activations'] ?? 1);
$owner = $_POST['owner'] ?? null;
$address = $_POST['address'] ?? null;
$res = LicenseService::issueLicense($max, 'FLAT', $owner, $address);
if ($res['success']) {
$message = "New License Issued: " . $res['license_key'];
} else {
$message = "Error: " . ($res['error'] ?? 'Unknown error');
}
}
if (isset($_POST['pay_payroll'])) {
$id = (int)$_POST['id'];
if ($id) {
@ -7168,6 +7199,9 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
<p class="text-muted small mb-0" data-en="View and search license keys activated on your system" data-ar="عرض والبحث في مفاتيح التراخيص المفعلة في نظامك">View and search license keys activated on your system</p>
</div>
<div class="d-flex gap-2">
<button class="btn btn-primary btn-sm rounded-pill px-3" data-bs-toggle="modal" data-bs-target="#issueLicenseModal">
<i class="bi bi-plus-circle"></i> <span data-en="Issue License" data-ar="إصدار ترخيص">Issue License</span>
</button>
<button onclick="location.reload()" class="btn btn-light btn-sm rounded-pill px-3">
<i class="bi bi-arrow-clockwise"></i> <span data-en="Refresh" data-ar="تحديث">Refresh</span>
</button>
@ -7187,16 +7221,17 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
<tr>
<th data-en="ID" data-ar="المعرف">ID</th>
<th data-en="License Key" data-ar="مفتاح الترخيص">License Key</th>
<th data-en="Max Activations" data-ar="أقصى تفعيل">Max</th>
<th data-en="Current Activations" data-ar="التفعيلات الحالية">Used</th>
<th data-en="Owner" data-ar="المالك">Owner</th>
<th data-en="Max/Used" data-ar="الأقصى/المستخدم">Max/Used</th>
<th data-en="Status" data-ar="الحالة">Status</th>
<th data-en="Created At" data-ar="تاريخ الإنشاء">Created At</th>
<th data-en="Actions" data-ar="الإجراءات" class="text-end pe-4">Actions</th>
</tr>
</thead>
<tbody>
<?php if (empty($data['licenses'])): ?>
<tr>
<td colspan="6" class="text-center py-5 text-muted">
<td colspan="7" class="text-center py-5 text-muted">
<i class="bi bi-key fs-1 d-block mb-3 opacity-25"></i>
<span data-en="No license data found on the server." data-ar="لم يتم العثور على بيانات ترخيص على السيرفر.">No license data found on the server.</span>
</td>
@ -7206,8 +7241,15 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
<tr>
<td><span class="badge bg-light text-dark border">#<?= $l['id'] ?></span></td>
<td><code class="fw-bold text-primary"><?= htmlspecialchars($l['license_key']) ?></code></td>
<td><span class="badge bg-secondary"><?= (int)$l['max_activations'] ?></span></td>
<td><span class="badge bg-<?= $l['activations_count'] >= $l['max_activations'] ? 'danger' : 'info' ?>"><?= (int)$l['activations_count'] ?></span></td>
<td>
<div class="fw-bold"><?= htmlspecialchars($l['owner'] ?? 'N/A') ?></div>
<div class="small text-muted"><?= htmlspecialchars($l['address'] ?? '') ?></div>
</td>
<td>
<span class="badge bg-secondary"><?= (int)$l['max_activations'] ?></span>
/
<span class="badge bg-<?= $l['activations_count'] >= $l['max_activations'] ? 'danger' : 'info' ?>"><?= (int)$l['activations_count'] ?></span>
</td>
<td>
<?php if ($l['is_active']): ?>
<span class="badge bg-success-subtle text-success border border-success-subtle rounded-pill">Active</span>
@ -7216,6 +7258,21 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
<?php endif; ?>
</td>
<td class="small text-muted"><?= htmlspecialchars($l['created_at']) ?></td>
<td class="text-end pe-4">
<div class="btn-group">
<button class="btn btn-sm btn-outline-primary"
onclick='editLicense(<?= json_encode($l) ?>)'
title="Edit"><i class="bi bi-pencil"></i></button>
<form method="POST" class="d-inline ms-1">
<input type="hidden" name="id" value="<?= $l['id'] ?>">
<input type="hidden" name="status" value="<?= $l['is_active'] ? 'suspended' : 'active' ?>">
<button type="submit" name="update_license" class="btn btn-sm btn-outline-<?= $l['is_active'] ? 'warning' : 'success' ?>"
title="<?= $l['is_active'] ? 'Disable' : 'Enable' ?>">
<i class="bi bi-power"></i>
</button>
</form>
</div>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
@ -7225,6 +7282,89 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
</div>
</div>
<!-- Issue License Modal -->
<div class="modal fade" id="issueLicenseModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content border-0 shadow">
<div class="modal-header">
<h5 class="modal-title">Issue New License</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<form method="POST">
<div class="modal-body">
<div class="mb-3">
<label class="form-label">Owner Name</label>
<input type="text" name="owner" class="form-control" placeholder="e.g. Acme Corp" required>
</div>
<div class="mb-3">
<label class="form-label">Address / Contact</label>
<textarea name="address" class="form-control" rows="2"></textarea>
</div>
<div class="mb-3">
<label class="form-label">Max Activations</label>
<input type="number" name="max_activations" class="form-control" value="1" min="1" max="100">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-light" data-bs-dismiss="modal">Cancel</button>
<button type="submit" name="issue_license" class="btn btn-primary">Generate Key</button>
</div>
</form>
</div>
</div>
</div>
<!-- Edit License Modal -->
<div class="modal fade" id="editLicenseModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content border-0 shadow">
<div class="modal-header">
<h5 class="modal-title">Edit License</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<form method="POST">
<input type="hidden" name="id" id="edit_license_id">
<div class="modal-body">
<div class="mb-3">
<label class="form-label">Owner Name</label>
<input type="text" name="owner" id="edit_license_owner" class="form-control">
</div>
<div class="mb-3">
<label class="form-label">Address / Contact</label>
<textarea name="address" id="edit_license_address" class="form-control" rows="2"></textarea>
</div>
<div class="mb-3">
<label class="form-label">Status</label>
<select name="status" id="edit_license_status" class="form-select">
<option value="active">Active</option>
<option value="suspended">Suspended</option>
<option value="expired">Expired</option>
</select>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-light" data-bs-dismiss="modal">Cancel</button>
<button type="submit" name="update_license" class="btn btn-primary">Save Changes</button>
</div>
</form>
</div>
</div>
</div>
<script>
function editLicense(license) {
document.getElementById('edit_license_id').value = license.id;
document.getElementById('edit_license_owner').value = license.owner || '';
document.getElementById('edit_license_address').value = license.address || '';
document.getElementById('edit_license_status').value = license.status;
var editModal = new bootstrap.Modal(document.getElementById('editLicenseModal'));
editModal.show();
}
</script>
<style>
#licensesTable td { padding: 1rem 0.75rem; }
</style>
<?php elseif ($page === 'users'): ?>
<div class="card border-0 shadow-sm rounded-4 overflow-hidden">
<div class="card-header bg-white py-3 d-flex justify-content-between align-items-center border-0">

View File

@ -144,6 +144,27 @@ class LicenseService {
return self::callRemoteApi('/list', []);
}
/**
* Updates an existing license.
*/
public static function updateLicense($id, $data) {
$params = array_merge(['id' => $id, 'secret' => '1485-5215-2578'], $data);
return self::callRemoteApi('/update', $params);
}
/**
* Issues a new license.
*/
public static function issueLicense($max_activations, $prefix = 'FLAT', $owner = null, $address = null) {
return self::callRemoteApi('/issue', [
'secret' => '1485-5215-2578',
'max_activations' => $max_activations,
'prefix' => $prefix,
'owner' => $owner,
'address' => $address
]);
}
/**
* Remote API Caller
*/

View File

@ -18,6 +18,7 @@ if (strpos($request_uri, '/verify') !== false) $endpoint = 'verify';
if (strpos($request_uri, '/deactivate') !== false) $endpoint = 'deactivate';
if (strpos($request_uri, '/issue') !== false) $endpoint = 'issue';
if (strpos($request_uri, '/list') !== false) $endpoint = 'list';
if (strpos($request_uri, '/update') !== false) $endpoint = 'update';
$input = json_decode(file_get_contents('php://input'), true);
@ -154,19 +155,23 @@ if ($endpoint === 'issue') {
$max_activations = (int)($input['max_activations'] ?? 1);
$prefix = strtoupper(trim($input['prefix'] ?? 'FLAT'));
$owner = $input['owner'] ?? null;
$address = $input['address'] ?? null;
// Generate a formatted key: PREFIX-XXXX-XXXX
$key = $prefix . '-' . bin2hex(random_bytes(2)) . '-' . bin2hex(random_bytes(2));
$key = strtoupper($key);
try {
$stmt = $pdo->prepare("INSERT INTO licenses (license_key, max_activations) VALUES (?, ?)");
$stmt->execute([$key, $max_activations]);
$stmt = $pdo->prepare("INSERT INTO licenses (license_key, max_activations, owner, address) VALUES (?, ?, ?, ?)");
$stmt->execute([$key, $max_activations, $owner, $address]);
echo json_encode([
'success' => true,
'license_key' => $key,
'max_activations' => $max_activations
'max_activations' => $max_activations,
'owner' => $owner,
'address' => $address
]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'error' => 'Failed to generate license.']);
@ -198,4 +203,45 @@ if ($endpoint === 'list') {
exit;
}
if ($endpoint === 'update') {
$secret = $input['secret'] ?? '';
if ($secret !== SERVER_SECRET) {
echo json_encode(['success' => false, 'error' => 'Unauthorized.']);
exit;
}
$id = (int)($input['id'] ?? 0);
$status = $input['status'] ?? null;
$owner = $input['owner'] ?? null;
$address = $input['address'] ?? null;
if (!$id) {
echo json_encode(['success' => false, 'error' => 'ID is required.']);
exit;
}
try {
$fields = [];
$params = [];
if ($status !== null) { $fields[] = "status = ?"; $params[] = $status; }
if ($owner !== null) { $fields[] = "owner = ?"; $params[] = $owner; }
if ($address !== null) { $fields[] = "address = ?"; $params[] = $address; }
if (empty($fields)) {
echo json_encode(['success' => false, 'error' => 'No fields to update.']);
exit;
}
$params[] = $id;
$sql = "UPDATE licenses SET " . implode(', ', $fields) . " WHERE id = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
echo json_encode(['success' => true]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'error' => 'Update failed: ' . $e->getMessage()]);
}
exit;
}
echo json_encode(['success' => false, 'error' => 'Invalid endpoint.']);