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:
@@ -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,6 +53,7 @@ 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");
|
||||
}
|
||||
|
||||
@@ -58,10 +61,12 @@ try {
|
||||
$expiresInDays = $input['expires_in_days'] ?? null;
|
||||
|
||||
if (empty($keyName)) {
|
||||
http_response_code(400);
|
||||
throw new Exception("Key name is required");
|
||||
}
|
||||
|
||||
if (strlen($keyName) > 100) {
|
||||
http_response_code(400);
|
||||
throw new Exception("Key name must be 100 characters or less");
|
||||
}
|
||||
|
||||
@@ -69,6 +74,7 @@ try {
|
||||
if ($expiresInDays !== null && $expiresInDays !== '') {
|
||||
$expiresInDays = (int)$expiresInDays;
|
||||
if ($expiresInDays < 1 || $expiresInDays > 3650) {
|
||||
http_response_code(400);
|
||||
throw new Exception("Expiration must be between 1 and 3650 days");
|
||||
}
|
||||
} else {
|
||||
@@ -110,11 +116,26 @@ try {
|
||||
]);
|
||||
} catch (Exception $e) {
|
||||
ob_end_clean();
|
||||
error_log("Generate 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/400/...);
|
||||
// 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("Generate 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