Compare commits

..
4 Commits
Author SHA1 Message Date
adminandClaude Opus 5 488bc698de Instanzname in die Config, Setup-Luecke geschlossen
Instanz:
- $instanz in der externen Config bestimmt INSTANZ, UPLOADS_PATH und
  SESSION_NAME. Der Verzeichnisname waehlt nur noch die Config-Datei aus
  und ist Fallback, solange $instanz fehlt.
- savePDF() schreibt nicht mehr fest nach DOCUMENT_ROOT."kunden", sondern
  in das Verzeichnis, das es auch aufraeumt. .gitkeep wird nicht mehr
  mitgeloescht.

Sicherheit:
- index.php?action=setup war ohne Login auch bei gueltiger Config
  erreichbar. rebuild-settings.php schrieb $_POST ungeprueft als PHP-Code
  in die Config (Codeausfuehrung, sofern die Datei schreibbar war).
- Setup nur noch ohne gueltige Config, firststart.php und
  rebuild-settings.php pruefen das zusaetzlich selbst.
- Config-Werte werden per var_export() maskiert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 08:44:33 +02:00
adminandClaude Opus 5 81d3042216 Tote Code-Pfade entfernt
Entfernt, weil kein Code mehr darauf verwies:

- smarty3/ (Smarty 3.1.6; alle Aufrufer nutzen smarty/ mit 4.5.6)
- incs/tcpdf_old/
- incs/fpdf.php samt FPDF-Schriftmetriken in incs/font/*.php
  und incs/font/makefont/ (nur von sites/makepdf_OLD.php genutzt,
  parste ab PHP 8.0 ohnehin nicht mehr)
- sites/makepdf_OLD.php
- incs/users_old.php
- oldindex.php (nirgends verlinkter Alt-Einstiegspunkt)

Behalten: incs/PHPMailer_v5.1 (wird von sites/projectadd.php genutzt)
und die TTFs in incs/font (werden von stats.php fuer pChart geladen).

CLAUDE.md entsprechend nachgezogen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 17:02:30 +02:00
adminandClaude Opus 5 dbbc932115 CLAUDE.md mit Architektur-Ueberblick ergaenzt
Dokumentiert die Punkte, die sich nur aus dem Zusammenspiel mehrerer
Dateien erschliessen: Instanz-Ableitung aus dem Arbeitsverzeichnis,
externe Konfiguration, Request-Ablauf ueber checkRightsNInclude(),
das positionsbasierte Rechte-Schema, die bei jedem Request laufenden
Schema-Migrationen sowie tote Pfade und Stolperfallen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 16:58:14 +02:00
adminandClaude Opus 5 e6eb55bc4b Initialer Commit: Kundenverwaltung (PHP/Smarty)
Bestehende Codebasis als Ausgangsstand aufgenommen.

- .gitignore: Kundendaten (uploads_*), Smarty-Compile-Cache
  (templates_c), Laufzeit-Temp und Datenbank-Dumps ausgeschlossen;
  Verzeichnisstruktur ueber .gitkeep erhalten
- .gitattributes: Zeilenenden normalisiert (LF im Repo),
  Binaerformate markiert
- db-backup.php: MySQL-Zugangsdaten kommen jetzt wie im Rest der
  Anwendung aus der externen Konfiguration statt hartkodiert aus der
  Datei; Passwort wird ueber eine temporaere Optionsdatei statt per
  Kommandozeile uebergeben, Fehler von mysqldump/gzip werden gemeldet,
  Aufraeumen aelterer Backups berechnet Jahr und Monat konsistent

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 16:41:18 +02:00
4 changed files with 24 additions and 44 deletions
+1 -1
View File
@@ -45,7 +45,7 @@ cd /home/intranet/kunden && php db-backup.php
`CONFIG_PATH` zeigt auf `/volume1/homes/wagner/kundenconfig/` (Linux) bzw. `c:/kundenverwaltung/config/` (Windows). Geschrieben wird die Datei von `update/rebuild-settings.php` beim Ersteinrichten. `CONFIG_PATH` zeigt auf `/volume1/homes/wagner/kundenconfig/` (Linux) bzw. `c:/kundenverwaltung/config/` (Windows). Geschrieben wird die Datei von `update/rebuild-settings.php` beim Ersteinrichten.
Neben den DB-Zugangsdaten stehen dort auch `$instanz` (siehe oben), die SMTP-Zugänge je Firma (`$smtp_konten`, Schlüssel `"*"` als Rückfall, genutzt von `mail_attachment()`), der Zugang zur Statistik-Datenbank für `stats.php` (`$stats_mysql_*`) und die Wetter-API-Schlüssel (`$openweathermap_appid`, `$aeris_client_*`). Die Datei deklariert `$mysql_user`, `$mysql_pw`, `$mysql_server`, `$mysql_db`, `$firma` und weitere ausdrücklich als `global` und weist sie erst danach zu. Nur deshalb funktioniert `readsettings()` in `incs/settings.php`: Das `include` passiert im Funktionsrumpf, ohne die `global`-Zeilen blieben die Variablen dort lokal. Wer die Config-Struktur ändert, muss diese Eigenheit erhalten. Neben den Zugangsdaten steht dort auch `$instanz` (siehe oben). Die Datei deklariert `$mysql_user`, `$mysql_pw`, `$mysql_server`, `$mysql_db`, `$firma` und weitere ausdrücklich als `global` und weist sie erst danach zu. Nur deshalb funktioniert `readsettings()` in `incs/settings.php`: Das `include` passiert im Funktionsrumpf, ohne die `global`-Zeilen blieben die Variablen dort lokal. Wer die Config-Struktur ändert, muss diese Eigenheit erhalten.
Zugangsdaten gehören **nie** in den Code — `db-backup.php` zeigt das Muster für Skripte außerhalb des Request-Zyklus (Config einlesen, Passwort über eine temporäre Optionsdatei an `mysqldump`, nicht per Kommandozeile). Zugangsdaten gehören **nie** in den Code — `db-backup.php` zeigt das Muster für Skripte außerhalb des Request-Zyklus (Config einlesen, Passwort über eine temporäre Optionsdatei an `mysqldump`, nicht per Kommandozeile).
+18 -15
View File
@@ -85,16 +85,7 @@ function PopulateSessionVars()
use PHPMailer\PHPMailer\PHPMailer; use PHPMailer\PHPMailer\PHPMailer;
function mail_attachment($filename, $path, $mailto, $from_mail, $from_name, $replyto, $subject, $message) { function mail_attachment($filename, $path, $mailto, $from_mail, $from_name, $replyto, $subject, $message) {
// SMTP-Zugänge stehen in der externen Config, je Firma ein Eintrag,
// "*" gilt für alle übrigen: array("user" => "...", "pw" => "...")
global $smtp_konten;
if(isset($smtp_konten[$_SESSION["firma"]]))
$konto = $smtp_konten[$_SESSION["firma"]];
elseif(isset($smtp_konten["*"]))
$konto = $smtp_konten["*"];
else
return error("Kein SMTP-Zugang für \"".htmlspecialchars($_SESSION["firma"])."\" in der Konfiguration (\$smtp_konten).");
$mail = new PHPMailer(); $mail = new PHPMailer();
@@ -106,8 +97,21 @@ function mail_attachment($filename, $path, $mailto, $from_mail, $from_name, $rep
$mail->SMTPAuth = true; // turn on SMTP authentication $mail->SMTPAuth = true; // turn on SMTP authentication
$mail->SMTPSecure = "ssl"; $mail->SMTPSecure = "ssl";
$mail->Port = 465; $mail->Port = 465;
$mail->Username = $konto["user"]; if($_SESSION["firma"] == "Wagner Markisen")
$mail->Password = $konto["pw"]; {
$mail->Username = "info@wagner-markisen.de"; // SMTP username
$mail->Password = "m0w1337@RootServer"; // SMTP password
}
elseif($_SESSION["firma"] == "Ingenieurbüro Wagner")
{
$mail->Username = "m0w1337@gmail.com"; // SMTP username
$mail->Password = "Gmail@RootServer"; // SMTP password
}
else
{
$mail->Username = "wagnermarkisen12@googlemail.com"; // SMTP username
$mail->Password = "m0w1337@RootServer"; // SMTP password
}
$mail->From = $from_mail; $mail->From = $from_mail;
$mail->FromName = $from_name; $mail->FromName = $from_name;
@@ -566,10 +570,9 @@ function GetWeather($plz='87509', $land='germany', $icons_src="./pics/icons/weat
{ {
$station = $plz."-".$land; $station = $plz."-".$land;
} }
// API-Schlüssel stehen in der externen Config //$url[0] = "http://api.aerisapi.com/observations/immenstadt,germany?client_id=8JYXl86uUEeoPl40ncnBs&client_secret=RvVVj0K9yFgmp7U8CmgCH57YwGYeyuHjHtrSPxGV";
global $openweathermap_appid, $aeris_client_id, $aeris_client_secret; $url[0] = "http://api.openweathermap.org/data/2.5/weather?zip=87509,de&APPID=a7be2029b8584f5eeff40ca9789f6435";
$url[0] = "http://api.openweathermap.org/data/2.5/weather?zip=87509,de&APPID=".urlencode($openweathermap_appid); $url[1] = "http://api.aerisapi.com/forecasts/immenstadt,germany?client_id=8JYXl86uUEeoPl40ncnBs&client_secret=RvVVj0K9yFgmp7U8CmgCH57YwGYeyuHjHtrSPxGV&from=today&to=+6days";
$url[1] = "http://api.aerisapi.com/forecasts/immenstadt,germany?client_id=".urlencode($aeris_client_id)."&client_secret=".urlencode($aeris_client_secret)."&from=today&to=+6days";
$response = file_get_contents($url[1]); $response = file_get_contents($url[1]);
+2 -5
View File
@@ -6,11 +6,8 @@
include("incs/pChart/pChart.class"); include("incs/pChart/pChart.class");
// Zugang zur Statistik-Datenbank steht in der externen Config $dbconn = mysqli_connect("localhost","m0","m0sSqL");
require_once("incs/settings.php"); mysqli_select_db($dbconn,"systemstats");
readsettings();
$dbconn = mysqli_connect($stats_mysql_server, $stats_mysql_user, $stats_mysql_pw) or die("Keine Verbindung zur Statistik-Datenbank.");
mysqli_select_db($dbconn, $stats_mysql_db);
$qry = mysqli_query($dbconn, "SELECT DATE_FORMAT(datetime, '%d.%m.%y') AS datetime, MAX(percent) AS value FROM hdd WHERE datetime > DATE_SUB(NOW(), INTERVAL 31 DAY) GROUP BY DATE_FORMAT(datetime, '%d.%m.%y') ORDER BY DATE_FORMAT(datetime, '%y%m%d') ASC") or die(mysqli_error($dbconn)); $qry = mysqli_query($dbconn, "SELECT DATE_FORMAT(datetime, '%d.%m.%y') AS datetime, MAX(percent) AS value FROM hdd WHERE datetime > DATE_SUB(NOW(), INTERVAL 31 DAY) GROUP BY DATE_FORMAT(datetime, '%d.%m.%y') ORDER BY DATE_FORMAT(datetime, '%y%m%d') ASC") or die(mysqli_error($dbconn));
// Dataset definition // Dataset definition
-20
View File
@@ -30,14 +30,6 @@ if(!file_put_contents (CONFIG_PATH.CONFIG_FILE,
global $firma; global $firma;
global $dbconn; global $dbconn;
global $geodbconn; global $geodbconn;
global $smtp_konten;
global $stats_mysql_server;
global $stats_mysql_user;
global $stats_mysql_pw;
global $stats_mysql_db;
global $openweathermap_appid;
global $aeris_client_id;
global $aeris_client_secret;
$instanz = '.var_export(INSTANZ, true).'; $instanz = '.var_export(INSTANZ, true).';
$dbconn = 0; $dbconn = 0;
@@ -48,18 +40,6 @@ if(!file_put_contents (CONFIG_PATH.CONFIG_FILE,
$mysql_server = '.configWert("mysqlserver").'; $mysql_server = '.configWert("mysqlserver").';
$mysql_opengeodb = '.configWert("opengeodb").'; $mysql_opengeodb = '.configWert("opengeodb").';
$firma = '.configWert("firma", true).'; $firma = '.configWert("firma", true).';
// Von Hand zu pflegen: SMTP-Zugänge je Firma, "*" für alle übrigen
$smtp_konten = array(
"*" => array("user" => "", "pw" => ""),
);
$stats_mysql_server = "localhost";
$stats_mysql_user = "";
$stats_mysql_pw = "";
$stats_mysql_db = "systemstats";
$openweathermap_appid = "";
$aeris_client_id = "";
$aeris_client_secret = "";
?>')) ?>'))
{ {
$err= error("Konfiguration konnte nicht geschrieben werden!"); $err= error("Konfiguration konnte nicht geschrieben werden!");