Fix API correctness: external API stub/collision, recurring dates, CSV, audit
- create_ticket_api.php: remove the wrong CREATE TABLE stub that broke a fresh DB; generate collision-safe ticket_ids so a genuine id collision isn't misreported as a duplicate and a hw alert dropped; stop leaking raw DB errors; correct a reopen comment that falsely claimed refreshed sensor data - manage_recurring.php: fix next-run so create/edit no longer skips the current period (monthly day-of-month this month, daily today if time not passed, correct ISO weekday, month-length clamp); only recompute on schedule changes to avoid double-fire - export_tickets.php, audit_log.php: neutralize CSV formula injection - revoke_api_key.php, generate_api_key.php: correct HTTP status codes and stop the catch clobbering specific 4xx codes - health.php: stop leaking PHP version / extension names / paths to unauthenticated callers - watch_ticket.php: define $data before use - manage_templates/recurring/custom_fields: add audit logging for CRUD; add recurring_ticket + custom_field to the audit entity whitelist Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+28
-6
@@ -24,11 +24,13 @@ try {
|
||||
session_start();
|
||||
}
|
||||
if (!isset($_SESSION['user']) || !isset($_SESSION['user']['user_id'])) {
|
||||
http_response_code(401);
|
||||
throw new Exception("Authentication required");
|
||||
}
|
||||
|
||||
// Check admin privileges
|
||||
if (!isset($_SESSION['user']['is_admin']) || !$_SESSION['user']['is_admin']) {
|
||||
http_response_code(403);
|
||||
throw new Exception("Admin privileges required");
|
||||
}
|
||||
|
||||
@@ -51,12 +53,14 @@ try {
|
||||
// Get request data
|
||||
$input = json_decode(file_get_contents('php://input'), true);
|
||||
if (!$input) {
|
||||
http_response_code(400);
|
||||
throw new Exception("Invalid request data");
|
||||
}
|
||||
|
||||
$keyId = (int)($input['key_id'] ?? 0);
|
||||
|
||||
if ($keyId <= 0) {
|
||||
http_response_code(400);
|
||||
throw new Exception("Valid key ID is required");
|
||||
}
|
||||
|
||||
@@ -68,10 +72,12 @@ try {
|
||||
$keyInfo = $apiKeyModel->getKeyById($keyId);
|
||||
|
||||
if (!$keyInfo) {
|
||||
http_response_code(404);
|
||||
throw new Exception("API key not found");
|
||||
}
|
||||
|
||||
if (!$keyInfo['is_active']) {
|
||||
http_response_code(409);
|
||||
throw new Exception("API key is already revoked");
|
||||
}
|
||||
|
||||
@@ -79,6 +85,7 @@ try {
|
||||
$success = $apiKeyModel->revokeKey($keyId);
|
||||
|
||||
if (!$success) {
|
||||
http_response_code(500);
|
||||
throw new Exception("Failed to revoke API key");
|
||||
}
|
||||
|
||||
@@ -103,11 +110,26 @@ try {
|
||||
]);
|
||||
} catch (Exception $e) {
|
||||
ob_end_clean();
|
||||
error_log("Revoke API key error: " . $e->getMessage());
|
||||
header('Content-Type: application/json');
|
||||
http_response_code(isset($conn) ? 400 : 500);
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'error' => 'An internal error occurred'
|
||||
]);
|
||||
|
||||
// Preserve any specific status set before the throw (401/403/404/409/...);
|
||||
// only fall back to 500 when nothing more specific was set.
|
||||
$code = http_response_code();
|
||||
if (!is_int($code) || $code < 400) {
|
||||
$code = 500;
|
||||
}
|
||||
http_response_code($code);
|
||||
|
||||
if ($code >= 500) {
|
||||
error_log("Revoke API key error: " . $e->getMessage());
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'error' => 'An internal error occurred'
|
||||
]);
|
||||
} else {
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user