67 lines
1.8 KiB
PHP
67 lines
1.8 KiB
PHP
<?php
|
|
/**
|
|
* generate_door_token.php
|
|
* AJAX endpoint: generates a new encrypted door access token
|
|
* Called by scanning.php when the custom code is recognized
|
|
*/
|
|
header('Content-Type: application/json');
|
|
header('Access-Control-Allow-Origin: *');
|
|
|
|
// Only accept POST
|
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
|
http_response_code(405);
|
|
echo json_encode(['status' => 'error', 'message' => 'Method not allowed']);
|
|
exit;
|
|
}
|
|
|
|
$ENCRYPTION_KEY = 'FiberID_DoorAccess_SecretKey_2026!';
|
|
$TOKEN_LIFETIME = 30; // seconds
|
|
$MANIFEST_PATH = __DIR__ . '/custom_code_tokens.json';
|
|
|
|
// --- Clean expired tokens ---
|
|
$tokens = [];
|
|
if (file_exists($MANIFEST_PATH)) {
|
|
$tokens = json_decode(file_get_contents($MANIFEST_PATH), true) ?: [];
|
|
}
|
|
$now = time();
|
|
foreach ($tokens as $k => $v) {
|
|
if ($now > $v['expires_at']) {
|
|
unset($tokens[$k]);
|
|
}
|
|
}
|
|
|
|
// --- Rate limiting: max 1 token per 10 seconds per IP ---
|
|
$clientIP = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
|
|
foreach ($tokens as $k => $v) {
|
|
if (isset($v['ip']) && $v['ip'] === $clientIP && ($now - $v['created_at']) < 10) {
|
|
echo json_encode(['status' => 'error', 'message' => 'Please wait before scanning again']);
|
|
exit;
|
|
}
|
|
}
|
|
|
|
// --- Generate new token ---
|
|
$randomBytes = bin2hex(random_bytes(16));
|
|
$payload = json_encode([
|
|
'ts' => $now,
|
|
'rand' => $randomBytes,
|
|
'src' => 'door_access'
|
|
]);
|
|
|
|
$iv = random_bytes(16);
|
|
$cipher = openssl_encrypt($payload, 'AES-256-CBC', $ENCRYPTION_KEY, 0, $iv);
|
|
$token = rtrim(strtr(base64_encode($iv . '::' . $cipher), '+/', '-_'), '=');
|
|
|
|
// Store token
|
|
$tokens[$token] = [
|
|
'created_at' => $now,
|
|
'expires_at' => $now + $TOKEN_LIFETIME,
|
|
'ip' => $clientIP
|
|
];
|
|
|
|
file_put_contents($MANIFEST_PATH, json_encode($tokens, JSON_PRETTY_PRINT));
|
|
|
|
echo json_encode([
|
|
'status' => 'success',
|
|
'token' => $token
|
|
]);
|