dolibarr.stundenzettel/ajax/pwa_auth.php
data 292db5d40c Version 2.0.0: PWA Mobile App + Produktliste-Verbesserungen
PWA (neue Dateien):
- Vollständige Progressive Web App mit Token-basierter Auth
- 4 Swipe-Panels: Alle STZ, Stundenzettel, Produktliste, Lieferauflistung
- Kundensuche, Leistungen-Accordion, Mehraufwand-Sektion
- Produkt-Übernahme aus Auftrag + Mehraufwand in STZ
- Service Worker, Manifest, App-Icons für Installation

Desktop-Änderungen:
- Produktliste: Checkboxen immer sichtbar (außer bereits auf STZ)
- Lieferauflistung: Vereinfachte Ansicht (nur Verbaut-Spalte)
- Admin: PWA-Link in Einstellungen
- Sprachdatei: PWA-Übersetzungen

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 21:21:14 +01:00

144 lines
4 KiB
PHP

<?php
/* Copyright (C) 2026 Eduard Wisch <data@data-it-solution.de>
*
* Stundenzettel PWA - Token-basierte Authentifizierung
*/
if (!defined('NOLOGIN')) {
define('NOLOGIN', '1');
}
if (!defined('NOREQUIREMENU')) {
define('NOREQUIREMENU', '1');
}
if (!defined('NOREQUIREHTML')) {
define('NOREQUIREHTML', '1');
}
if (!defined('NOREQUIREAJAX')) {
define('NOREQUIREAJAX', '1');
}
// Dolibarr-Umgebung laden
$res = 0;
if (!$res && file_exists("../../main.inc.php")) $res = @include "../../main.inc.php";
if (!$res && file_exists("../../../main.inc.php")) $res = @include "../../../main.inc.php";
if (!$res && file_exists("../../../../main.inc.php")) $res = @include "../../../../main.inc.php";
if (!$res) die(json_encode(array('success' => false, 'error' => 'Dolibarr nicht geladen')));
header('Content-Type: application/json; charset=UTF-8');
$action = GETPOST('action', 'aZ09');
$response = array('success' => false);
switch ($action) {
case 'login':
$username = GETPOST('username', 'alphanohtml');
$password = GETPOST('password', 'none');
if (empty($username) || empty($password)) {
$response['error'] = 'Benutzername und Passwort erforderlich';
break;
}
// Brute-Force-Schutz
usleep(100000); // 100ms Verzoegerung
require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
$userLogin = new User($db);
// Benutzer per Login suchen
$sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."user WHERE login = '".$db->escape($username)."' AND statut = 1";
$result = $db->query($sql);
if ($result && $db->num_rows($result) > 0) {
$obj = $db->fetch_object($result);
$userLogin->fetch($obj->rowid);
$userLogin->getrights();
// Passwort pruefen
require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
$passOk = false;
if (!empty($userLogin->pass_indatabase_crypted)) {
$passOk = dol_verifyHash($password, $userLogin->pass_indatabase_crypted);
}
if ($passOk) {
// Stundenzettel-Berechtigung pruefen
if ($userLogin->hasRight('stundenzettel', 'read')) {
// Token generieren (15 Tage gueltig)
$tokenData = array(
'user_id' => $userLogin->id,
'login' => $userLogin->login,
'created' => time(),
'expires' => time() + (15 * 24 * 60 * 60),
'hash' => md5($userLogin->id . $userLogin->login . getDolGlobalString('MAIN_SECURITY_SALT', 'defaultsalt'))
);
$token = base64_encode(json_encode($tokenData));
$response['success'] = true;
$response['token'] = $token;
$response['user'] = array(
'id' => $userLogin->id,
'login' => $userLogin->login,
'name' => $userLogin->getFullName($langs)
);
} else {
$response['error'] = 'Keine Berechtigung fuer Stundenzettel';
}
} else {
$response['error'] = 'Falsches Passwort';
}
} else {
$response['error'] = 'Benutzer nicht gefunden';
}
break;
case 'verify':
$token = GETPOST('token', 'none');
if (empty($token)) {
$response['error'] = 'Kein Token';
break;
}
$tokenData = json_decode(base64_decode($token), true);
if (!$tokenData || empty($tokenData['user_id']) || empty($tokenData['expires'])) {
$response['error'] = 'Ungueltiges Token';
break;
}
// Ablaufdatum pruefen
if ($tokenData['expires'] < time()) {
$response['error'] = 'Token abgelaufen';
break;
}
// Hash verifizieren
$expectedHash = md5($tokenData['user_id'] . $tokenData['login'] . getDolGlobalString('MAIN_SECURITY_SALT', 'defaultsalt'));
if ($tokenData['hash'] !== $expectedHash) {
$response['error'] = 'Token manipuliert';
break;
}
// Benutzer noch aktiv?
require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
$userCheck = new User($db);
if ($userCheck->fetch($tokenData['user_id']) > 0 && $userCheck->statut == 1) {
$response['success'] = true;
$response['user'] = array(
'id' => $userCheck->id,
'login' => $userCheck->login,
'name' => $userCheck->getFullName($langs)
);
} else {
$response['error'] = 'Benutzer nicht mehr aktiv';
}
break;
default:
$response['error'] = 'Unbekannte Aktion';
}
echo json_encode($response);
$db->close();