Compare commits

..
1 Commits
Author SHA1 Message Date
Bruno Eckhardt 4782a2c401 new api with url request 2026-05-13 11:02:42 +02:00
11 changed files with 199 additions and 887 deletions

No files matched your search

-14
View File
@@ -3,17 +3,3 @@ RewriteEngine On
RewriteRule ^(Commands|config_backups|controller|modules)($|/.*) - [F,L,NC]
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
# -----------------------------------
# .php entfernen
# -----------------------------------
# browser requestet datei.php -> redirect zu /datei
RewriteCond %{THE_REQUEST} \s/+(.+?)\.php[\s?] [NC]
RewriteRule ^ /%1 [R=301,L]
# /datei -> datei.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^(.+)$ $1.php [L]
+84
View File
@@ -0,0 +1,84 @@
<?php
include_once(__DIR__ . '/../controller/DatabaseController.php');
include_once(__DIR__ . '/../controller/DataController.php');
include_once(__DIR__ . '/../modules/Mail.php');
header("Content-Type: application/json");
header("Access-Control-Allow-Origin: *");
// 1. Daten aus der URL (GET) statt aus dem Header holen
$token = $_GET['token'] ?? '';
$function = $_GET['action'] ?? ''; // Ich habe es 'action' genannt, passend zur URL
// Prüfen, ob überhaupt etwas übergeben wurde
if (empty($token) || empty($function)) {
http_response_code(400);
echo json_encode(["error" => "Token oder Action fehlt in der URL"]);
exit;
}
// 2. Token-Validierung direkt in der Datenbank (Performanter!)
// Annahme: Deine DatabaseShow kann Filter. Wenn nicht, hier das SQL anpassen.
$checkToken = DatabaseShow(
"API_Credentials",
"TOKEN",
"TOKEN = ?",
$token
);
if (empty($checkToken)) {
http_response_code(401);
// Loggen des Fehlversuchs
DatabaseInsert(
"API_LOGS",
"CLIENT_IP, TOKEN, API, FUNKTION, JSON",
(new getSpecificData())->getClientIP(),
$token,
(new getSpecificData())->getRequestURL(),
$function,
json_encode(["error" => "Unauthorized"])
);
echo json_encode(["error" => "Zugriff verweigert", "hint" => "Token ungültig"]);
exit;
}
// 3. Logik-Teil mit switch (sauberer als viele IFs)
$data = null;
switch ($function) {
case "UeberstundenAbbau":
$data = DatabaseShow("Ueberstunden", "DATUM, MINUTEN", "GRUND = ?", "Abbau");
break;
case "UeberstundenAktuell":
$conn = db_connect();
$sql = "SELECT
(SELECT COALESCE(SUM(OVERTIME), 0) FROM Firmenberichte) AS berichte,
(SELECT COALESCE(SUM(MINUTEN), 0) FROM Ueberstunden WHERE GRUND = 'Abbau') AS abbau,
(SELECT COALESCE(SUM(MINUTEN), 0) FROM Ueberstunden WHERE GRUND = 'Aufbau') AS aufbau";
$res = $conn->query($sql);
$row = $res->fetch_object();
$data = ($row->berichte - $row->abbau + $row->aufbau) / 60;
break;
case "Berichte":
$data = DatabaseShowWithFK("Berufsschulberichte", $Berufsschulberichte);
break;
case "Stundenplan":
$data = DatabaseShowWithFK("Stundenplan", $Stundenplan, "ZEITEN, MO, DI, MI, DO, FR");
break;
default:
http_response_code(404);
echo json_encode(["error" => "Funktion '$function' nicht gefunden"]);
exit;
}
// 4. Erfolgreiche Antwort
echo json_encode([
"success" => true,
"data" => $data
]);
@@ -1,6 +1,6 @@
<?php
include_once( __DIR__ . '/../../controller/DatabaseController.php' );
include_once( __DIR__ . '/../../controller/DataController.php' );
include_once '../controller/DatabaseController.php';
include_once '../controller/DataController.php';
header("Content-Type: application/json");
header("Access-Control-Allow-Origin: *");
@@ -110,4 +110,4 @@ DatabaseInsert(
$json
);
echo $json;
echo $json;
-101
View File
@@ -1,101 +0,0 @@
<?php
include_once( __DIR__ . '/../../controller/DatabaseController.php');
include_once( __DIR__ . '/../../controller/DataController.php');
include_once( __DIR__ . '/../../controller/ApiController.php');
include_once(__DIR__ . '/../../modules/Mail.php');
header("Content-Type: application/json");
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: Authorization, Function, Content-Type");
header("Access-Control-Allow-Methods: POST, GET, OPTIONS");
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
http_response_code(200);
exit();
}
$validTokens = DatabaseShow(
"API_Credentials",
"TOKEN"
);
$validTokens = array_column($validTokens, 'TOKEN');
$headers = getallheaders();
$token = $headers['Authorization'] ?? $headers['authorization'] ?? $_SERVER['HTTP_AUTHORIZATION'] ?? '';
$function = $headers['Function'] ?? $headers['function'] ?? '';
if (!in_array($token, $validTokens)) {
http_response_code(401);
$error = json_encode([
"error" => "Unauthorized",
"debug_received_token" => $token,
"debug_all_headers" => $headers
]);
DatabaseInsert(
"API_LOGS",
"CLIENT_IP, TOKEN, API, FUNKTION, JSON",
(new getSpecificData())->getClientIP(),
$token,
(new getSpecificData())->getRequestURL(),
$function,
$error
);
errorMail(
"API Login failed",
$error,
true,
);
echo json_encode(
[
"error" => "Unauthorized",
"Contact" => "bruno.eckhardt07@gmail.com",
]
);
exit;
}
$data = null;
if (in_array($token, $validTokens)) {
DatabaseInsert(
"API_LOGS",
"CLIENT_IP, TOKEN, API, FUNKTION",
(new getSpecificData())->getClientIP(),
$token,
(new getSpecificData())->getRequestURL(),
$function
);
if ($function === "IPs") {
$data = DatabaseShow(
"logs",
"CLIENT_IP"
);
}
if ($function === "Ueberstunden") {
$data = DatabaseShow(
"Ueberstunden",
"MINUTEN"
);
}
if ($function === "Berichte") {
$data = DatabaseShowWithFK(
"Berufsschulberichte",
$Berufsschulberichte,
);
}
echo json_encode(
[
"success" => true,
"data" => $data,
]
);
exit;
}
-37
View File
@@ -1,37 +0,0 @@
<?php
include_once(__DIR__ . '/../../controller/DatabaseController.php');
include_once(__DIR__ . '/../../controller/DataController.php');
include_once(__DIR__ . '/../../controller/ApiController.php');
header('Content-Type: application/json');
$api = (new ApiController());
if ($api->urlAuth($_GET['token']) == true ) {
if (isset($_GET['day'])) {
$day = $_GET['day'];
$data = DatabaseShowWithFK(
"Stundenplan",
$Stundenplan,
"ZEITEN, $day",
"$day IS NOT NULL AND $day != '' AND $day != '(NULL)' ORDER BY ZEITEN ASC"
);
} else {
$data = DatabaseShowWithFK(
"Stundenplan",
$Stundenplan,
"ZEITEN, MO, DI, MO, DO, FR",
);
}
echo $api->jsonSuccess($data);
$api->requestSave();
}
/**
* http://localhost:9000/api/v2/lessons.php?token=f3a50684d7f0cc2d9b21601798ea48242fab7481a0d0407a2b8683b0b74a79e3
* http://localhost:9000/api/v2/lessons.php?token=f3a50684d7f0cc2d9b21601798ea48242fab7481a0d0407a2b8683b0b74a79e3&day=FR
*/
-37
View File
@@ -1,37 +0,0 @@
<?php
include_once(__DIR__ . '/../../controller/DatabaseController.php');
include_once(__DIR__ . '/../../controller/DataController.php');
include_once(__DIR__ . '/../../controller/ApiController.php');
header('Content-Type: application/json');
$api = (new ApiController());
if ($api->urlAuth($_GET['token']) == true ) {
if (isset($_GET['date'])) {
$date = $_GET['date'];
$data = DatabaseShowWithFK(
"Berufsschulberichte",
$Berufsschulberichte,
"*",
"DATUM = ?",
$date
);
} else {
$data = DatabaseShowWithFK(
"Berufsschulberichte",
$Berufsschulberichte,
);
}
echo $api->jsonSuccess($data);
$api->requestSave();
}
/**
* http://localhost:9000/api/v2/schoolReports.php?token=f3a50684d7f0cc2d9b21601798ea48242fab7481a0d0407a2b8683b0b74a79e3
* http://localhost:9000/api/v2/schoolReports.php?token=f3a50684d7f0cc2d9b21601798ea48242fab7481a0d0407a2b8683b0b74a79e3&date=2025-09-09
*/
-36
View File
@@ -1,36 +0,0 @@
<?php
include_once(__DIR__ . '/../../controller/DatabaseController.php');
include_once(__DIR__ . '/../../controller/DataController.php');
include_once(__DIR__ . '/../../controller/ApiController.php');
header('Content-Type: application/json');
$api = (new ApiController());
if ($api->urlAuth($_GET['token']) == true ) {
if (isset($_GET['date'])) {
$date = $_GET['date'];
$data = DatabaseShow(
"Firmenberichte",
"DATUM, PROZESS_1, PROZESS_2, PROZESS_3, PROZESS_4, BEGINN, ENDE_PUBLIC",
"DATUM = ?",
$date
);
} else {
$data = DatabaseShow(
"Firmenberichte",
"DATUM, PROZESS_1, PROZESS_2, PROZESS_3, PROZESS_4, BEGINN, ENDE_PUBLIC",
);
}
echo $api->jsonSuccess($data);
$api->requestSave();
}
/**
* http://localhost:9000/api/v2/workReports.php?token=f3a50684d7f0cc2d9b21601798ea48242fab7481a0d0407a2b8683b0b74a79e3
* http://localhost:9000/api/v2/workReports.php?token=f3a50684d7f0cc2d9b21601798ea48242fab7481a0d0407a2b8683b0b74a79e3&date=2025-09-09
*/
-131
View File
@@ -1,131 +0,0 @@
<?php
require(__DIR__ . '/DatabaseController.php');
class ApiController {
/**
* method for pretty jsonsuccess output
*
* @param array $data
* @return string
*/
public function jsonSuccess($data) {
return json_encode(
[
'status' => 'success',
'data' => $data,
],
JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE
);
}
/**
* method for pretty jsonerror output
*
* @param array $error
* @return string
*/
public function jsonError ($error) {
echo json_encode(
[
'status' => 'failed',
'data' => 'none',
'error' => $error
],
JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE
);
}
/**
* get authentication key out database
*
* @return array
*/
private function getAuthKey () {
$validTokens = DatabaseShow(
"API_Credentials",
"TOKEN"
);
return array_column($validTokens, 'TOKEN');
}
/**
* url authentication method via token and optional parameter function
*
* @param string $token
* @param string $function
* @return void
*/
public function urlAuth ($token, $function = '') {
$validTokens = $this->getAuthKey();
if (!in_array($token, $validTokens)) {
http_response_code(401);
$error = json_encode([
"error" => "Unauthorized",
"debug_received_token" => $token,
]);
echo $this->jsonError($error);
DatabaseInsert(
"API_LOGS",
"CLIENT_IP, TOKEN, API, FUNKTION, JSON",
(new getSpecificData())->getClientIP(),
$token,
(new getSpecificData())->getRequestURL(),
$function,
$error
);
errorMail(
"API Login failed",
$error,
true,
);
return false;
}
return true;
}
public function requestSave($function = '') {
DatabaseInsert(
"API_LOGS",
"CLIENT_IP, TOKEN, API, FUNKTION, JSON",
(new getSpecificData())->getClientIP(),
$_GET['token'],
(new getSpecificData())->getRequestURL(),
$function,
'{"status": "success"}',
);
}
/**
* create new api token
*
*/
private function createToken() {
return bin2hex(random_bytes(32));
}
/**
* save created api token
*
* @return bool
*/
public function saveToken() {
try {
DatabaseInsert(
"API_Credentials",
"TOKEN, BENUTZER",
$this->createToken(),
"API-User"
);
} catch (Exception $error) {
return false;
}
return true;
}
}
-87
View File
@@ -1,87 +0,0 @@
<?php
require_once(__DIR__ . '/DatabaseController.php');
class RightsController {
/**
* save new site with sitename
*
* @param string $sitename
*/
private function saveSite($sitename) {
DatabaseInsert(
"Backend_Seiten",
"DATEINAME",
$sitename
);
}
/**
* get site id by sitename
*
* @param string $sitename
* @return int
*/
private function getSiteID($sitename) {
$id = DatabaseShow(
"Backend_Seiten",
"ID",
"DATEINAME = ?",
$sitename
);
return $id[0]['ID'];
}
/**
* get user id
*
* @param string $name
* @param string $lastname
* @return int
*/
private function getUserID($name, $lastname) {
$id = DatabaseShow(
"Benutzer",
"ID",
"NAME = ? AND NACHNAME = ?",
$name,
$lastname
);
return $id[0]['ID'];
}
/**
* Rights Handler for saving default user is Bruno
*
* @param string $sitename
* @param string $name
* @param string $lastname
* @return string
*/
public function RightsHandler($sitename, $name = 'Bruno', $lastname = 'Eckhardt') {
try {
$sitename = strtolower($sitename);
$this->saveSite($sitename);
DatabaseInsert(
"Benutzer_Berechtigungen",
"BENUTZER_ID, SEITEN_ID",
$this->getUserID($name, $lastname),
$this->getSiteID($sitename)
);
} catch (Exception $error) {
return json_encode(
[
"status" => "failed",
"error" => $error->getMessage()
], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE
);
}
return json_encode(
[
"status" => "success",
], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE
);
}
}
+112 -437
View File
@@ -1,69 +1,29 @@
<?php
// ======================================================
// API TESTER
// Modul für index.php
// ======================================================
// API Tester Service - Als Modul für index.php
// Dieser Service dient zum manuellen Testen der API-Endpunkte.
// API Basis-Verzeichnis
$apiDir = realpath(__DIR__ . '/../api');
// Alle PHP APIs rekursiv finden
// Basis-Verzeichnisse scannen (Pfad relativ zur index.php)
$apiDir = __DIR__ . '/../api/';
$apiFiles = glob($apiDir . '*.php');
$apiOptions = [];
if ($apiDir !== false) {
$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator(
$apiDir,
RecursiveDirectoryIterator::SKIP_DOTS
)
);
foreach ($iterator as $file) {
if (!$file->isFile()) {
continue;
}
if ($file->getExtension() !== 'php') {
continue;
}
// relativen Pfad erzeugen
$relativePath = str_replace(
$apiDir . DIRECTORY_SEPARATOR,
'',
$file->getPathname()
);
// Windows kompatibel
$relativePath = str_replace('\\', '/', $relativePath);
$apiOptions[] = 'api/' . $relativePath;
}
foreach ($apiFiles as $file) {
$apiOptions[] = 'api/' . basename($file);
}
// sortieren
sort($apiOptions);
// Standard Token
// Token aus deiner get.php entnommen
$defaultToken = "15a437d128c918633e57dc7d18118a073b807644f21731ed5a7ebcf3eca9e242";
?>
<style>
/* ======================================================
API TESTER STYLES
====================================================== */
/* Spezifische Styles für den API Tester innerhalb des Content-Bereichs */
.api-tester-container {
width: 100%;
max-width: 1000px;
max-width: 900px;
margin: 0 auto;
background-color: var(--card-bg);
padding: 25px;
border-radius: 12px;
border-radius: 10px;
border: 1px solid var(--card-border);
box-sizing: border-box;
}
.api-tester-container h2 {
@@ -71,8 +31,83 @@ $defaultToken = "15a437d128c918633e57dc7d18118a073b807644f21731ed5a7ebcf3eca9e24
margin-bottom: 20px;
color: var(--btn-bg);
border-bottom: 1px solid var(--card-border);
padding-bottom: 12px;
padding-bottom: 10px;
display: block;
/* style.css h2 hat flex, wir wollen hier einfaches block */
}
.tester-form-group {
margin-bottom: 15px;
}
.tester-form-group label {
display: block;
margin-bottom: 5px;
font-weight: bold;
font-size: 0.9rem;
}
.tester-input {
width: 100%;
padding: 10px;
background-color: var(--input-bg);
border: 1px solid var(--input-border);
color: var(--input-text);
border-radius: 5px;
box-sizing: border-box;
}
.tester-btn-send {
background-color: var(--btn-bg);
color: white;
padding: 12px 20px;
border: none;
border-radius: 6px;
cursor: pointer;
font-weight: bold;
width: 100%;
margin-top: 10px;
}
.tester-btn-send:hover {
opacity: 0.9;
}
#tester-response-container {
margin-top: 25px;
background-color: var(--input-bg);
padding: 15px;
border-radius: 8px;
border: 1px solid var(--card-border);
min-height: 80px;
overflow-x: auto;
}
#tester-output-content {
white-space: pre-wrap;
font-family: 'Consolas', 'Monaco', monospace;
font-size: 0.85rem;
margin: 0;
color: var(--text);
}
.tester-badge {
display: inline-block;
padding: 3px 8px;
border-radius: 4px;
font-size: 0.8rem;
font-weight: bold;
margin-bottom: 10px;
}
.tester-status-200 {
background-color: var(--status-bg);
color: var(--status-text);
}
.tester-status-error {
background-color: #dc3545;
color: white;
}
.tester-grid {
@@ -81,500 +116,140 @@ $defaultToken = "15a437d128c918633e57dc7d18118a073b807644f21731ed5a7ebcf3eca9e24
gap: 15px;
}
.tester-form-group {
margin-bottom: 16px;
}
.tester-form-group label {
display: block;
margin-bottom: 6px;
font-weight: bold;
font-size: 0.9rem;
}
.tester-input,
.tester-textarea,
select {
width: 100%;
padding: 10px;
background-color: var(--input-bg);
border: 1px solid var(--input-border);
color: var(--input-text);
border-radius: 6px;
box-sizing: border-box;
font-size: 0.9rem;
}
.tester-textarea {
min-height: 120px;
resize: vertical;
font-family: Consolas, monospace;
}
.tester-btn-send {
width: 100%;
background-color: var(--btn-bg);
color: white;
border: none;
border-radius: 8px;
padding: 13px;
font-weight: bold;
cursor: pointer;
transition: 0.2s;
margin-top: 5px;
}
.tester-btn-send:hover {
opacity: 0.9;
transform: translateY(-1px);
}
#tester-response-container {
margin-top: 25px;
background-color: var(--input-bg);
border: 1px solid var(--card-border);
border-radius: 10px;
padding: 15px;
min-height: 100px;
overflow-x: auto;
}
#tester-output-content {
white-space: pre-wrap;
font-family: Consolas, monospace;
font-size: 0.85rem;
margin: 0;
color: var(--text);
}
.tester-badge {
display: inline-block;
padding: 5px 10px;
border-radius: 5px;
font-size: 0.8rem;
font-weight: bold;
margin-bottom: 12px;
}
.tester-status-200 {
background-color: #198754;
color: white;
}
.tester-status-error {
background-color: #dc3545;
color: white;
}
.tester-status-warning {
background-color: #ffc107;
color: black;
@media (max-width: 600px) {
.tester-grid {
grid-template-columns: 1fr;
}
}
.hidden {
display: none !important;
}
.tester-row {
display: flex;
gap: 10px;
align-items: center;
}
.tester-checkbox {
display: flex;
align-items: center;
gap: 6px;
white-space: nowrap;
margin-top: 8px;
}
.tester-small-btn {
background: transparent;
border: 1px solid var(--input-border);
color: var(--text);
padding: 6px 10px;
border-radius: 6px;
cursor: pointer;
}
.tester-small-btn:hover {
background: rgba(255, 255, 255, 0.05);
}
.tester-response-info {
margin-bottom: 12px;
font-size: 0.85rem;
opacity: 0.8;
}
@media (max-width: 700px) {
.tester-grid {
grid-template-columns: 1fr;
}
.tester-row {
flex-direction: column;
align-items: stretch;
}
}
</style>
<div class="api-tester-container">
<h2>🛠️ API Tester</h2>
<!-- API Auswahl -->
<div class="tester-form-group">
<label for="endpoint">API Endpunkt</label>
<select id="endpoint" class="tester-input" onchange="checkEndpoint()">
<?php foreach ($apiOptions as $opt): ?>
<option value="<?= htmlspecialchars($opt) ?>">
<?= htmlspecialchars($opt) ?>
</option>
<option value="<?= $opt ?>"><?= $opt ?></option>
<?php endforeach; ?>
</select>
</div>
<!-- Methode + Function -->
<div class="tester-grid">
<div class="tester-form-group">
<label for="method">HTTP Methode</label>
<select id="method" class="tester-input">
<option value="GET">GET</option>
<option value="POST">POST</option>
<option value="PUT">PUT</option>
<option value="DELETE">DELETE</option>
<option value="PATCH">PATCH</option>
<option value="OPTIONS">OPTIONS</option>
</select>
</div>
<div class="tester-form-group" id="function-group">
<label for="function-header">Function Header</label>
<input type="text" id="function-header" class="tester-input" placeholder="z.B. IPs, Ueberstunden">
</div>
</div>
<!-- Token -->
<div class="tester-form-group">
<label for="token">Authorization Token</label>
<div class="tester-row">
<input type="text" id="token" class="tester-input" value="<?= htmlspecialchars($defaultToken) ?>">
<label class="tester-checkbox">
<input type="checkbox" id="send-token" checked>
Mitsenden
</label>
</div>
<input type="text" id="token" class="tester-input" value="<?= $defaultToken ?>">
</div>
<!-- Eigene Header -->
<div class="tester-form-group">
<label for="custom-headers">
Zusätzliche Header (JSON)
</label>
<textarea id="custom-headers" class="tester-textarea" placeholder='{
"X-Test": "123",
"Client": "Frontend"
}'></textarea>
</div>
<!-- JSON Body -->
<div class="tester-form-group" id="json-body-group">
<label for="json-body">
JSON Body
</label>
<textarea id="json-body" class="tester-textarea" placeholder='{
"test": true
}'></textarea>
</div>
<!-- Datei Upload -->
<div class="tester-form-group hidden" id="file-group">
<label for="files">Dateien Upload</label>
<label for="files">Dateien (files)</label>
<input type="file" id="files" class="tester-input" multiple>
</div>
<!-- Buttons -->
<div class="tester-grid">
<button class="tester-btn-send" onclick="sendApiRequest()">Anfrage senden 🚀</button>
<button class="tester-btn-send" onclick="sendApiRequest()">
Anfrage senden 🚀
</button>
<button class="tester-btn-send" onclick="clearResponse()">
Ausgabe leeren 🧹
</button>
</div>
<!-- Ausgabe -->
<div id="tester-response-container">
<div style="text-align:center; opacity:0.7; padding:15px;">
Bereit für Anfragen.
</div>
<div style="text-align: center; color: #888; padding: 10px;">Bereit für Anfragen.</div>
</div>
</div>
<script>
// ======================================================
// CHECK ENDPOINT
// ======================================================
function checkEndpoint() {
const endpoint = document.getElementById('endpoint').value;
const fileGroup = document.getElementById('file-group');
const functionGroup = document.getElementById('function-group');
const jsonBodyGroup = document.getElementById('json-body-group');
const methodSelect = document.getElementById('method');
// reset
// Standard: alles ausblenden
fileGroup.classList.add('hidden');
functionGroup.classList.remove('hidden');
jsonBodyGroup.classList.remove('hidden');
// upload api
if (endpoint.includes('upload.php')) {
if (endpoint === 'api/upload.php') {
// Nur bei exakt api/upload.php Dateien anzeigen
fileGroup.classList.remove('hidden');
jsonBodyGroup.classList.add('hidden');
functionGroup.classList.add('hidden');
methodSelect.value = 'POST';
}
// get api
if (endpoint.includes('get.php')) {
if (endpoint === 'api/get.php') {
methodSelect.value = 'GET';
}
}
// ======================================================
// CLEAR RESPONSE
// ======================================================
function clearResponse() {
document.getElementById('tester-response-container').innerHTML = `
<div style="text-align:center; opacity:0.7; padding:15px;">
Ausgabe geleert.
</div>
`;
}
// ======================================================
// SEND REQUEST
// ======================================================
async function sendApiRequest() {
const endpoint = document.getElementById('endpoint').value;
const method = document.getElementById('method').value;
const token = document.getElementById('token').value;
const functionHeader = document.getElementById('function-header').value;
const customHeadersInput = document.getElementById('custom-headers').value;
const jsonBodyInput = document.getElementById('json-body').value;
const fileInput = document.getElementById('files');
const sendToken = document.getElementById('send-token').checked;
const responseContainer = document.getElementById('tester-response-container');
responseContainer.innerHTML = `
<div style="text-align:center; padding:15px;">
Anfrage läuft...
</div>
`;
responseContainer.innerHTML = '<div style="text-align: center; padding: 10px;">Lade...</div>';
let headers = {};
let headers = {
'Authorization': token
};
// Token
if (sendToken && token.trim() !== '') {
headers['Authorization'] = token;
}
// Function Header
if (functionHeader.trim() !== '') {
if (endpoint.includes('get.php') && functionHeader) {
headers['Function'] = functionHeader;
}
// Custom Headers
if (customHeadersInput.trim() !== '') {
try {
const customHeaders = JSON.parse(customHeadersInput);
headers = {
...headers,
...customHeaders
};
} catch (e) {
responseContainer.innerHTML = `
<div style="color:#dc3545; padding:15px;">
Fehlerhafte Header JSON Struktur.
</div>
`;
return;
}
}
let options = {
method: method,
headers: headers
};
// Upload
if (endpoint.includes('upload.php') && fileInput.files.length > 0) {
const formData = new FormData();
for (let i = 0; i < fileInput.files.length; i++) {
formData.append('files[]', fileInput.files[i]);
}
options.body = formData;
} else {
// JSON Body
if (
['POST', 'PUT', 'PATCH', 'DELETE']
.includes(method) &&
jsonBodyInput.trim() !== ''
) {
try {
JSON.parse(jsonBodyInput);
headers['Content-Type'] = 'application/json';
options.body = jsonBodyInput;
} catch (e) {
responseContainer.innerHTML = `
<div style="color:#dc3545; padding:15px;">
Fehlerhafte JSON Body Struktur.
</div>
`;
return;
}
}
}
const startedAt = performance.now();
try {
const response = await fetch(endpoint, options);
const duration = (performance.now() - startedAt).toFixed(0);
const status = response.status;
const rawText = await response.text();
let resultText = rawText;
// JSON hübsch formatieren
try {
const json = JSON.parse(rawText);
resultText = JSON.stringify(json, null, 2);
} catch (e) {}
let badgeClass = 'tester-status-error';
if (status >= 200 && status < 300) {
badgeClass = 'tester-status-200';
} else if (status >= 300 && status < 400) {
badgeClass = 'tester-status-warning';
}
const badgeClass = status >= 200 && status < 300 ? 'tester-status-200' : 'tester-status-error';
responseContainer.innerHTML = `
<div class="tester-badge ${badgeClass}">
Status: ${status}
</div>
<div class="tester-response-info">
⏱️ ${duration} ms
</div>
<button
class="tester-small-btn"
onclick="copyResponse()"
>
Antwort kopieren
</button>
<pre id="tester-output-content"></pre>
`;
<div class="tester-badge ${badgeClass}">Status: ${status}</div>
<pre id="tester-output-content"></pre>
`;
document.getElementById('tester-output-content').textContent = resultText;
} catch (error) {
responseContainer.innerHTML = `
<div style="color:#dc3545; padding:15px;">
Fehler: ${error.message}
</div>
`;
responseContainer.innerHTML = `<div style="color:#dc3545; padding: 10px;">Fehler: ${error.message}</div>`;
}
}
// ======================================================
// COPY RESPONSE
// ======================================================
function copyResponse() {
const content = document.getElementById('tester-output-content');
if (!content) {
return;
}
navigator.clipboard.writeText(content.textContent);
alert('Antwort kopiert.');
}
// Initial
// Initial check
checkEndpoint();
</script>
-4
View File
@@ -1,8 +1,5 @@
<?php
include_once(__DIR__ . '/../controller/RightsController.php');
include_once(__DIR__ . '/../config.php');
$configFile = 'config.php';
$backupDir = 'config_backups';
@@ -50,7 +47,6 @@ if (isset($_POST['save']) && ($_SESSION['logged_in'] ?? false)) {
$serviceToGroupMapping[$s['targetGroup']][] = $finalId;
}
}
(new RightsController())->RightsHandler($s['name']);
}
$newServiceGroups = [];