diff --git a/admin/admin.php b/admin/admin.php
deleted file mode 100644
index 2ca8b0e..0000000
--- a/admin/admin.php
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
-
-
diff --git a/admin/anrufbeantworter.php b/admin/anrufbeantworter.php
index 071eb13..aeafc3b 100644
--- a/admin/anrufbeantworter.php
+++ b/admin/anrufbeantworter.php
@@ -9,6 +9,15 @@ $user = check_admin_user();
include("templates/header.inc.php");
+// check_admin_user() liefert bei fehlender Anmeldung nur null zurueck und
+// bricht nicht ab. Ohne diese Pruefung lief die Seite fuer anonyme
+// Besucher weiter (und $user['vorname'] warf eine Warnung).
+if (!$user) {
+ echo "
diff --git a/admin/kalender.php b/admin/kalender.php
index a90cd41..d9c164a 100644
--- a/admin/kalender.php
+++ b/admin/kalender.php
@@ -9,6 +9,15 @@ $user = check_admin_user();
include("templates/header.inc.php");
+// check_admin_user() liefert bei fehlender Anmeldung nur null zurueck und
+// bricht nicht ab. Ohne diese Pruefung lief die Seite fuer anonyme
+// Besucher weiter (und $user['vorname'] warf eine Warnung).
+if (!$user) {
+ echo "
";
+ include("templates/footer.inc.php");
+ exit;
+}
+
echo '
';
function build_calendar($month, $year) {
diff --git a/admin/login.php b/admin/login.php
index 1110237..efa9bd2 100644
--- a/admin/login.php
+++ b/admin/login.php
@@ -34,10 +34,20 @@ if (!empty($_POST['email']) && !empty($_POST['passwort'])) {
$hash = hash('sha256', $securitytoken);
- $insert = $pdo->prepare("
- INSERT INTO securitytokens (user_id, identifier, securitytoken, user_type)
- VALUES (:user_id, :identifier, :securitytoken, 'admin')
- ");
+ // Ablaufdatum nur setzen, wenn die Spalte existiert - der Code laeuft
+ // damit vor und nach der Migration. Ablauf per NOW() in SQL, weil
+ // Webserver und DB-Server in verschiedenen Zeitzonen laufen.
+ if (securitytokensHatAblaufspalte($pdo)) {
+ $insert = $pdo->prepare("
+ INSERT INTO securitytokens (user_id, identifier, securitytoken, user_type, expires_at)
+ VALUES (:user_id, :identifier, :securitytoken, 'admin', DATE_ADD(NOW(), INTERVAL 30 DAY))
+ ");
+ } else {
+ $insert = $pdo->prepare("
+ INSERT INTO securitytokens (user_id, identifier, securitytoken, user_type)
+ VALUES (:user_id, :identifier, :securitytoken, 'admin')
+ ");
+ }
$insert->execute([
'user_id' => (int)$user['id'],
'identifier' => $identifier,
@@ -45,7 +55,7 @@ if (!empty($_POST['email']) && !empty($_POST['passwort'])) {
]);
$cookieOpts = [
- 'expires' => time() + 365*24*3600,
+ 'expires' => time() + 30*24*3600, // deckungsgleich mit dem Token-Ablauf
'path' => '/',
'secure' => true, // nur wenn HTTPS
'httponly' => true,
diff --git a/admin/mailtemplate.php b/admin/mailtemplate.php
index f95bb8c..ab5012d 100644
--- a/admin/mailtemplate.php
+++ b/admin/mailtemplate.php
@@ -4,6 +4,15 @@ require_once __DIR__ . '/../inc/functions.inc.php';
header('Content-Type: application/json');
+// Dieser Endpunkt liefert gerenderte Mailvorlagen aus und damit Name,
+// Geburtstag, Adresse, Medikamente und den Anfragetext des Patienten.
+// Ohne diese Pruefung war er fuer jeden ohne Anmeldung abrufbar.
+if (!check_admin_user()) {
+ http_response_code(401);
+ echo json_encode(['error' => 'Nicht angemeldet']);
+ exit;
+}
+
try {
$templetid = $_POST['templetid'] ?? '';
$anfrageid = (int)($_POST['anfrageid'] ?? 0);
@@ -38,8 +47,11 @@ try {
]);
} catch (Throwable $e) {
+ // Interne Meldungen nur ins Log - sie verraten sonst Tabellen-,
+ // Spalten- und Datensatznamen an den Aufrufer.
+ error_log('mailtemplate.php: ' . $e->getMessage());
http_response_code(500);
echo json_encode([
- 'error' => $e->getMessage()
+ 'error' => 'Die Vorlage konnte nicht geladen werden.'
]);
}
\ No newline at end of file
diff --git a/admin/mailtemplatebetreff.php b/admin/mailtemplatebetreff.php
deleted file mode 100644
index 9383ae9..0000000
--- a/admin/mailtemplatebetreff.php
+++ /dev/null
@@ -1,19 +0,0 @@
-
\ No newline at end of file
diff --git a/admin/mailtemplatebody.php b/admin/mailtemplatebody.php
deleted file mode 100644
index 634b767..0000000
--- a/admin/mailtemplatebody.php
+++ /dev/null
@@ -1,60 +0,0 @@
-
\ No newline at end of file
diff --git a/admin/passwortzuruecksetzen.php b/admin/passwortzuruecksetzen.php
index 7d30420..7f76531 100644
--- a/admin/passwortzuruecksetzen.php
+++ b/admin/passwortzuruecksetzen.php
@@ -13,16 +13,21 @@ $userid = $_GET['userid'];
$code = $_GET['code'];
//Abfrage des Nutzers
-$statement = $pdo->prepare("SELECT * FROM users WHERE id = :userid");
+$statement = $pdo->prepare("SELECT *, (passwortcode_time IS NOT NULL AND passwortcode_time > DATE_SUB(NOW(), INTERVAL 24 HOUR)) AS code_noch_gueltig FROM users WHERE id = :userid");
$result = $statement->execute(array('userid' => $userid));
$user = $statement->fetch();
//Überprüfe dass ein Nutzer gefunden wurde und dieser auch ein Passwortcode hat
-if($user === null || $user['passwortcode'] === null) {
+// fetch() liefert false und nicht null, wenn kein Benutzer gefunden wird -
+// die alte Bedingung griff daher nie und lief mit false in den Array-Zugriff.
+if(!$user || $user['passwortcode'] === null) {
error("Der Benutzer wurde nicht gefunden oder hat kein neues Passwort angefordert.");
}
-if($user['passwortcode_time'] === null || strtotime($user['passwortcode_time']) < (time()-24*3600) ) {
+// Ablauf in SQL pruefen: passwortcode_time wird mit NOW() gesetzt (Uhr des
+// DB-Servers), waehrend PHP auf dem Webserver in einer anderen Zeitzone
+// laeuft. strtotime()/time() lag hier um genau diese Differenz daneben.
+if(!$user['code_noch_gueltig']) {
error("Dein Code ist leider abgelaufen. Bitte benutze die Passwort vergessen Funktion erneut.");
}
diff --git a/admin/phpinfo.php b/admin/phpinfo.php
deleted file mode 100644
index c9121e7..0000000
--- a/admin/phpinfo.php
+++ /dev/null
@@ -1,6 +0,0 @@
-
\ No newline at end of file
diff --git a/admin/sql b/admin/sql
deleted file mode 100644
index e69de29..0000000
diff --git a/admin/sql/2026-09-02_securitytokens_expires_at.sql b/admin/sql/2026-09-02_securitytokens_expires_at.sql
new file mode 100644
index 0000000..80ca5b7
--- /dev/null
+++ b/admin/sql/2026-09-02_securitytokens_expires_at.sql
@@ -0,0 +1,20 @@
+-- Ablaufdatum fuer "Angemeldet bleiben"-Tokens des Admin- und
+-- Zeiterfassungsbereichs. Bisher hatte die Tabelle keine Ablaufspalte: ein
+-- einmal erbeutetes Cookie war unbegrenzt gueltig. Der interne
+-- Patientenbereich setzt 30 Tage (Tabelle intern_securitytokens).
+--
+-- Der Code laeuft vor und nach dieser Migration: securitytokensHatAblaufspalte()
+-- in inc/functions.inc.php prueft die Spalte zur Laufzeit. Nach dem Einspielen
+-- greift der Ablauf automatisch, ohne weiteres Deployment.
+--
+-- Bestehende Tokens bekommen 30 Tage ab jetzt; NULL bliebe unbegrenzt gueltig.
+
+ALTER TABLE securitytokens
+ ADD COLUMN expires_at DATETIME NULL DEFAULT NULL AFTER user_type;
+
+UPDATE securitytokens
+ SET expires_at = DATE_ADD(NOW(), INTERVAL 30 DAY)
+ WHERE expires_at IS NULL;
+
+-- Gelegentlich aufraeumen:
+-- DELETE FROM securitytokens WHERE expires_at IS NOT NULL AND expires_at < NOW();
diff --git a/admin/togoadmin.php b/admin/togoadmin.php
index 5b11a97..c2832ac 100644
--- a/admin/togoadmin.php
+++ b/admin/togoadmin.php
@@ -125,7 +125,7 @@ if(!check_worker()){
?>
| Nummer | Person | IP-Adresse | Anlegungsdatum | Aktion |
";
@@ -171,7 +171,7 @@ if(!check_worker()){
## EDIT EinzelTermin
}elseif($_GET["a"] == "togoedittermin" ){
- $queryinsert = mysqli_query($con, "SELECT * FROM togo_termin WHERE terminid = ". $_GET["id"] . "");
+ $queryinsert = mysqli_query($con, "SELECT * FROM togo_termin WHERE terminid = " . (int)$_GET["id"]);
while ($row = $queryinsert->fetch_assoc()) {
$date = $row["date"];
$start = $row["start"];
@@ -223,7 +223,7 @@ if(!check_worker()){
### Allen im Termin eine E-Mail senden
}else if($_GET["a"] == "togosendmail" ){
- $queryinsert = mysqli_query($con, "SELECT * FROM togo_termin WHERE terminid = ". $_GET["id"] . "");
+ $queryinsert = mysqli_query($con, "SELECT * FROM togo_termin WHERE terminid = " . (int)$_GET["id"]);
while ($row = $queryinsert->fetch_assoc()) {
$date = $row["date"];
$start = $row["start"];
@@ -276,7 +276,7 @@ if(!check_worker()){
### EDIT Serientermin
}else if($_GET["a"] == "togoeditserientermin" ){
- $queryinsert = mysqli_query($con, "SELECT * FROM togo_termin WHERE terminid = ". $_GET["id"] . "");
+ $queryinsert = mysqli_query($con, "SELECT * FROM togo_termin WHERE terminid = " . (int)$_GET["id"]);
while ($row = $queryinsert->fetch_assoc()) {
$date = $row["date"];
$start = $row["start"];
@@ -437,7 +437,7 @@ if(!check_worker()){
if($_GET["a"] == "removeserie" ){
- $sqlstring = "DELETE FROM togo_terminvorgaben WHERE vorgabenid = ". $_GET["id"] . "";
+ $sqlstring = "DELETE FROM togo_terminvorgaben WHERE vorgabenid = " . (int)$_GET["id"];
$query = mysqli_query($con,$sqlstring);
if($query){
@@ -477,7 +477,7 @@ if(!check_worker()){
}
if($_GET["a"] == "deletetogotermin" ){
- $sqlstring = "DELETE FROM togo_termin WHERE terminid = ". $_GET["id"] . "";
+ $sqlstring = "DELETE FROM togo_termin WHERE terminid = " . (int)$_GET["id"];
$query = mysqli_query($con,$sqlstring);
if($query){
@@ -496,7 +496,18 @@ if(!check_worker()){
$standort = $_POST["standort"];
$error = $_POST["error"];
$warning = $_POST["warning"];
- $queryinsert = mysqli_query($con, "INSERT INTO togo_terminvorgaben (date, start, ende,standort,error,warning) VALUES ('".$date."', '".$start."', '".$end."', '".$standort."', '".$error."', '".$warning."')");
+ $stmt = $pdo->prepare("
+ INSERT INTO togo_terminvorgaben (date, start, ende, standort, error, warning)
+ VALUES (:date, :start, :ende, :standort, :error, :warning)
+");
+$queryinsert = $stmt->execute([
+ 'date' => $date,
+ 'start' => $start,
+ 'ende' => $end,
+ 'standort' => $standort,
+ 'error' => $error,
+ 'warning' => $warning
+]);
// Termin wird gespeichert
if($queryinsert){
@@ -518,7 +529,7 @@ if(!check_worker()){
WHERE standort IS NULL OR COUNT = '-1'");
}else{
- $queryinsert = mysqli_query($con, "SELECT * FROM togo_termin_teilnehmer WHERE terminid = ". $_POST["id"] . "");
+ $queryinsert = mysqli_query($con, "SELECT * FROM togo_termin_teilnehmer WHERE terminid = " . (int)$_POST["id"]);
}
while ($row = $queryinsert->fetch_assoc()) {
@@ -534,7 +545,7 @@ if(!check_worker()){
}
if($_POST["abgesagten"] == "1"){
$id = $row["terminteilnehmerid"];
- $sqldeletestring = "DELETE FROM togo_termin_teilnehmer WHERE terminteilnehmerid = ". $id . "";
+ $sqldeletestring = "DELETE FROM togo_termin_teilnehmer WHERE terminteilnehmerid = " . (int)$id;
$querydelete = mysqli_query($con,$sqldeletestring);
echo "Benutzer $id gelöscht
";
@@ -560,7 +571,20 @@ if(!check_worker()){
$count = $_POST["count"];
// Termin Änderung speichern
- $queryinsert = mysqli_query($con, "UPDATE togo_termin SET date='".$date."', start='".$start."', count='".$count."', end='".$end."', standort='".$standort."', error= '".$error."', warning='".$warning."' WHERE terminid='".$terminid."'");
+ $stmt = $pdo->prepare("
+ UPDATE togo_termin SET date = :date, start = :start, count = :count, end = :end,
+ standort = :standort, error = :error, warning = :warning WHERE terminid = :terminid
+");
+$queryinsert = $stmt->execute([
+ 'date' => $date,
+ 'start' => $start,
+ 'count' => $count,
+ 'end' => $end,
+ 'standort' => $standort,
+ 'error' => $error,
+ 'warning' => $warning,
+ 'terminid' => $terminid
+]);
if($queryinsert){
@@ -585,7 +609,18 @@ if(!check_worker()){
// Termin Änderung speichern
$endTime = strtotime($start) + ($folgelaenge*60);
$ende = date('H:i:s', $endTime);
- $queryinsert = mysqli_query($con, "INSERT INTO togo_termin (date, start, end,standort,error,warning) VALUES ('".$date."', '".$start."', '".$ende."', '".$standort."', '".$error."', '".$warning."')");
+ $stmt = $pdo->prepare("
+ INSERT INTO togo_termin (date, start, end, standort, error, warning)
+ VALUES (:date, :start, :ende, :standort, :error, :warning)
+");
+$queryinsert = $stmt->execute([
+ 'date' => $date,
+ 'start' => $start,
+ 'ende' => $ende,
+ 'standort' => $standort,
+ 'error' => $error,
+ 'warning' => $warning
+]);
$start = $ende;
@@ -610,7 +645,20 @@ if(!check_worker()){
$warning = $_POST["warning"];
$terminid = $_POST["terminid"];
$count = $_POST["count"];
- $queryinsert = mysqli_query($con, "UPDATE togo_termin SET date='".$date."', start='".$start."', ende='".$end."',count='".$count."', standort='".$standort."', error= '".$error."', warning='".$warning."' WHERE terminid='".$terminid."'");
+ $stmt = $pdo->prepare("
+ UPDATE togo_termin SET date = :date, start = :start, ende = :ende, count = :count,
+ standort = :standort, error = :error, warning = :warning WHERE terminid = :terminid
+");
+$queryinsert = $stmt->execute([
+ 'date' => $date,
+ 'start' => $start,
+ 'ende' => $end,
+ 'count' => $count,
+ 'standort' => $standort,
+ 'error' => $error,
+ 'warning' => $warning,
+ 'terminid' => $terminid
+]);
// Termin wird angelegt
@@ -631,7 +679,18 @@ if(!check_worker()){
$standort = $_POST["standort"];
$error = $_POST["error"];
$warning = $_POST["warning"];
- $queryinsert = mysqli_query($con, "INSERT INTO togo_termin (date, start, end,standort,error,warning) VALUES ('".$date."', '".$start."', '".$end."', '".$standort."', '".$error."', '".$warning."')");
+ $stmt = $pdo->prepare("
+ INSERT INTO togo_termin (date, start, end, standort, error, warning)
+ VALUES (:date, :start, :ende, :standort, :error, :warning)
+");
+$queryinsert = $stmt->execute([
+ 'date' => $date,
+ 'start' => $start,
+ 'ende' => $end,
+ 'standort' => $standort,
+ 'error' => $error,
+ 'warning' => $warning
+]);
// Termin wird angelegt
if($queryinsert){
@@ -647,8 +706,19 @@ if(!check_worker()){
$mail = $_POST["mail"];
$name = $_POST["name"];
##Doppelte Anemldung blocken zum gleichen Termin
- $queryinsert = mysqli_query($con, "Select * FROM togo_termin_teilnehmer WHERE terminid = '".$terminid."' AND mail = '".$mail."' AND name = '".$name."' AND ip = '".$ip."'");
- $rows = mysqli_num_rows($queryinsert);
+ // Prepared Statement: $terminid, $mail, $name und $ip kommen direkt
+ // aus $_POST und wurden vorher ungeprueft in das SQL verkettet.
+ $stmtDup = $pdo->prepare("
+ SELECT COUNT(*) FROM togo_termin_teilnehmer
+ WHERE terminid = :terminid AND mail = :mail AND name = :name AND ip = :ip
+ ");
+ $stmtDup->execute([
+ 'terminid' => $terminid,
+ 'mail' => $mail,
+ 'name' => $name,
+ 'ip' => $ip
+ ]);
+ $rows = (int)$stmtDup->fetchColumn();
//echo $rows;
//echo $rowsvierzehen;
@@ -662,8 +732,21 @@ if(!check_worker()){
}else{
- $queryinsert = mysqli_query($con, "UPDATE togo_termin SET count = count + 1 WHERE terminid = '".$terminid."'");
- $queryinserttwo = mysqli_query($con, "INSERT INTO togo_termin_teilnehmer (terminid, ip, mail, create_time,name) VALUES ('".$terminid."', '".$ip."', '".$mail."', '". date("Y-m-d H:i:s") ."', '".$name."')");
+ $stmtCount = $pdo->prepare("UPDATE togo_termin SET count = count + 1 WHERE terminid = :terminid");
+ $queryinsert = $stmtCount->execute(['terminid' => $terminid]);
+
+ // create_time per NOW() statt per PHP-date(): Webserver und DB-Server
+ // laufen in unterschiedlichen Zeitzonen.
+ $stmtTeiln = $pdo->prepare("
+ INSERT INTO togo_termin_teilnehmer (terminid, ip, mail, create_time, name)
+ VALUES (:terminid, :ip, :mail, NOW(), :name)
+ ");
+ $queryinserttwo = $stmtTeiln->execute([
+ 'terminid' => $terminid,
+ 'ip' => $ip,
+ 'mail' => $mail,
+ 'name' => $name
+ ]);
// Termin wird angelegt
if($queryinsert){
diff --git a/inc/functions.inc.php b/inc/functions.inc.php
index 52dd015..c37031a 100644
--- a/inc/functions.inc.php
+++ b/inc/functions.inc.php
@@ -1995,6 +1995,35 @@ function redirectToLogin(): void
+/**
+ * Prueft einmal je Request, ob securitytokens eine Spalte expires_at hat.
+ *
+ * Die Spalte wird per Migration nachgeruestet (admin/sql/2026-09-02_securitytokens_expires_at.sql).
+ * Solange sie fehlt, verhaelt sich check_admin_user() wie bisher; sobald sie da
+ * ist, greift der Ablauf - ohne dass der Code noch einmal angefasst werden muss.
+ */
+function securitytokensHatAblaufspalte(PDO $pdo): bool
+{
+ static $vorhanden = null;
+ if ($vorhanden !== null) {
+ return $vorhanden;
+ }
+ try {
+ $stmt = $pdo->prepare("
+ SELECT COUNT(*)
+ FROM information_schema.COLUMNS
+ WHERE TABLE_SCHEMA = DATABASE()
+ AND TABLE_NAME = 'securitytokens'
+ AND COLUMN_NAME = 'expires_at'
+ ");
+ $stmt->execute();
+ $vorhanden = ((int)$stmt->fetchColumn() > 0);
+ } catch (Throwable $e) {
+ error_log('securitytokensHatAblaufspalte: ' . $e->getMessage());
+ $vorhanden = false;
+ }
+ return $vorhanden;
+}
function check_admin_user() {
global $pdo;
@@ -2014,7 +2043,12 @@ function check_admin_user() {
$identifier = (string)$_COOKIE['identifier'];
$securitytoken = (string)$_COOKIE['securitytoken'];
- $st = $pdo->prepare("SELECT user_id, securitytoken FROM securitytokens WHERE identifier = ? AND user_type = 'admin' LIMIT 1");
+ // Abgelaufene Tokens gar nicht erst laden. Ohne die Spalte gilt das
+ // alte Verhalten - siehe securitytokensHatAblaufspalte().
+ $ablauf = securitytokensHatAblaufspalte($pdo)
+ ? " AND (expires_at IS NULL OR expires_at > NOW())"
+ : "";
+ $st = $pdo->prepare("SELECT user_id, securitytoken FROM securitytokens WHERE identifier = ? AND user_type = 'admin'" . $ablauf . " LIMIT 1");
$st->execute([$identifier]);
$row = $st->fetch(PDO::FETCH_ASSOC);
diff --git a/intern/admin.php b/intern/admin.php
deleted file mode 100644
index cc7f83f..0000000
--- a/intern/admin.php
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
-
-
diff --git a/intern/authentifizierung.php b/intern/authentifizierung.php
index e73fc68..534922e 100644
--- a/intern/authentifizierung.php
+++ b/intern/authentifizierung.php
@@ -15,17 +15,22 @@ $userid = $_GET['userid'];
$code = $_GET['code'];
//Abfrage des Nutzers
-$statement = $pdo->prepare("SELECT * FROM intern_users WHERE id = :userid");
+$statement = $pdo->prepare("SELECT *, (passwortcode_time IS NOT NULL AND passwortcode_time > DATE_SUB(NOW(), INTERVAL 24 HOUR)) AS code_noch_gueltig FROM intern_users WHERE id = :userid");
$result = $statement->execute(array('userid' => $userid));
$user = $statement->fetch();
//Überprüfe dass ein Nutzer gefunden wurde und dieser auch ein Authentifizierungscode angefordert hat
-if($user === null || $user['passwortcode'] === null) {
+// fetch() liefert false und nicht null, wenn kein Benutzer gefunden wird -
+// die alte Bedingung griff daher nie und lief mit false in den Array-Zugriff.
+if(!$user || $user['passwortcode'] === null) {
error("Der Benutzer wurde nicht gefunden oder hat kein ein Authentifizierungscode angefordert.");
$showForm = false;
}
-if($user['passwortcode_time'] === null || strtotime($user['passwortcode_time']) < (time()-24*3600) ) {
+// Ablauf in SQL pruefen: passwortcode_time wird mit NOW() gesetzt (Uhr des
+// DB-Servers), waehrend PHP auf dem Webserver in einer anderen Zeitzone
+// laeuft. strtotime()/time() lag hier um genau diese Differenz daneben.
+if(!$user['code_noch_gueltig']) {
error("Dein Code ist leider abgelaufen. Bitte benutze die Authentifizierungsfunktion erneut.");
$showForm = false;
}
@@ -51,7 +56,8 @@ if(check_mailreg()){
}elseif($showForm){
- $passworthash = password_hash($passwort, PASSWORD_DEFAULT);
+ // (hier stand ein password_hash() auf einer nie gesetzten Variablen, dessen
+ // Ergebnis niemand benutzt hat - es warf nur eine Deprecation-Warnung)
$statement = $pdo->prepare("UPDATE intern_users SET mailreg='1', passwortcode = NULL, passwortcode_time = NULL WHERE id = :userid");
$result = $statement->execute(array('userid'=> $userid ));
diff --git a/intern/mailtemplatebetreff.php b/intern/mailtemplatebetreff.php
deleted file mode 100644
index aaa44d8..0000000
--- a/intern/mailtemplatebetreff.php
+++ /dev/null
@@ -1,19 +0,0 @@
-
\ No newline at end of file
diff --git a/intern/mailtemplatebody.php b/intern/mailtemplatebody.php
deleted file mode 100644
index d9d4aab..0000000
--- a/intern/mailtemplatebody.php
+++ /dev/null
@@ -1,60 +0,0 @@
-
\ No newline at end of file
diff --git a/intern/meineanfragen.php b/intern/meineanfragen.php
index 9f50bb7..4b04cac 100644
--- a/intern/meineanfragen.php
+++ b/intern/meineanfragen.php
@@ -54,10 +54,25 @@ include("templates/header.inc.php");
if(check_mailreg() && check_userdatenvorhanden() ){
if($_POST["aktion"] == "11"){
- $sqlstring = "SELECT * FROM anfragen INNER JOIN persons ON anfragen.requester_person_id = persons.person_id INNER JOIN anfrageart ON anfragen.anforderungart = anfrageart.artid WHERE anfrageid='" . $_POST["anfrageid"] . "'";
- $query = mysqli_query($con,$sqlstring);
+ // Zwei Fehler auf einmal: die anfrageid kam ungeprueft aus $_POST in das
+ // SQL, und gefiltert wurde ausschliesslich danach - jeder angemeldete
+ // Patient konnte so fremde Anfragen mitsamt Name, Geburtstag, Adresse
+ // und Telefonnummer abrufen. Jetzt Prepared Statement und zusaetzlich
+ // an die E-Mail des angemeldeten Benutzers gebunden, wie in der
+ // Listenansicht weiter unten.
+ $statementAnfrage = $pdo->prepare("
+ SELECT * FROM anfragen
+ INNER JOIN persons ON anfragen.requester_person_id = persons.person_id
+ INNER JOIN anfrageart ON anfragen.anforderungart = anfrageart.artid
+ WHERE anfragen.anfrageid = :anfrageid
+ AND persons.email = :email
+ ");
+ $statementAnfrage->execute([
+ 'anfrageid' => (int)($_POST["anfrageid"] ?? 0),
+ 'email' => $user["email"]
+ ]);
// Ticket und Antwort ansehen.
- while ($row = $query->fetch_assoc()) {
+ while ($row = $statementAnfrage->fetch(PDO::FETCH_ASSOC)) {
$anfrageid = $row["anfrageid"];