Files
WKVS/html/intern/wk-leitung/logindata.php
T

1131 lines
43 KiB
PHP

<?php
use Dotenv\Dotenv;
date_default_timezone_set('Europe/Zurich');
if (!isset($baseDir)) {
$baseDir = $_SERVER['DOCUMENT_ROOT'];
}
require_once $baseDir . '/../scripts/session_functions.php';
ini_wkvs_session(true);
$csrf_token = $_SESSION['csrf_token'] ?? '';
$access_granted_wkl = check_user_permission('wk_leitung', true) ?? false;
if (!$access_granted_wkl):
$logintype = 'wk_leitung';
require $baseDir . '/../scripts/login/login.php';
$logintype = '';
else:
echo '<link rel="icon" type="png" href="/intern/img/icon.png">';
require $baseDir . '/../scripts/db/db-functions.php';
require $baseDir . '/../scripts/db/db-tables.php';
$type = 'wkl';
$dbconnection = require $baseDir . '/../scripts/db/db-verbindung-script.php';
if ($dbconnection['success'] !== true) {
echo 'Critical DB Error.';
exit;
}
require $baseDir . '/../composer/vendor/autoload.php';
$envFile = realpath($baseDir . '/../config/.env.pw-encryption-key');
if ($envFile === false) {
http_response_code(500);
echo json_encode([
'success' => false,
'message' => "Environment file not found"
]);
exit;
}
try {
$envDir = dirname($envFile);
$dotenv = Dotenv::createImmutable($envDir, '.env.pw-encryption-key');
$dotenv->load();
} catch (Throwable $e) {
http_response_code(500);
echo json_encode([
'success' => false,
'message' => "Dotenv error"
]);
}
?>
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="png" href="/intern/img/icon.png">
<title>WK-Leitung - Logindata</title>
<link rel="stylesheet" href="/files/fonts/fonts.css">
<link rel="stylesheet" href="/intern/css/logindata.css">
<link rel="stylesheet" href="/intern/css/sidebar.css">
<script src="/intern/js/jquery/jquery-3.7.1.min.js"></script>
<script src="/intern/js/qr-code/qrcode.min.js"></script>
<script src="/intern/js/custom-msg-display.js"></script>
<link rel="stylesheet" href="/intern/css/custom-msg-display.css">
<link rel="stylesheet" href="/intern/css/user.css">
<link rel="stylesheet" href="/intern/css/flatpickr/flatpickr.min.css">
<script src="/intern/js/flatpickr/flatpickr.min.js"></script>
<script src="/intern/js/flatpickr/de.min.js"></script>
<script src="/intern/js/flatpickr/fr.min.js"></script>
<script src="/intern/js/flatpickr/it.min.js"></script>
</head>
<body class="logindata">
<?php
$currentPage = 'logindata';
require $baseDir . '/../scripts/sidebar/sidebar.php';
?>
<!-- Loading Overlay -->
<div id="loading-overlay">
<div>Aktualisiere...</div>
</div>
<div id="oturldiv" class="ot-modal hidden">
<div class="ot-modal-content">
<div class="ot-modal-top-content">
<div class="ot-title">One-Time Login URL:</div>
<button id="otCloseOTL" class="ot-close-btn">✕</button>
</div>
<a id="aOturl" class="ot-url" target="_blank" href="/"></a>
<p id="oturlGb"></p>
<button id="otCopy" class="ot-copy-btn">URL Kopieren</button>
<div class="qrcodeWrapper">
<div id="qrcode"></div>
</div>
<button id="btnDownloadQRCode" class="ot-copy-btn">QR-Code herunterladen</button>
</div>
</div>
<script>
const otModal = document.getElementById("oturldiv");
const otUrl = document.getElementById("aOturl");
const otCopy = document.getElementById("otCopy");
const otClose = document.getElementById("otCloseOTL");
function showOneTimeUrl(fullUrl) {
otUrl.innerHTML = fullUrl;
otUrl.href = fullUrl;
otModal.style.display = "flex";
}
otCopy.addEventListener("click", () => {
navigator.clipboard.writeText(otUrl.href)
.then(() => {
otCopy.innerText = "Copied!";
setTimeout(() => otCopy.innerText = "Copy URL", 1500);
});
});
otClose.addEventListener("click", () => {
otModal.style.display = "none";
});
otModal.addEventListener("click", (e) => {
if (e.target === otModal) otModal.style.display = "none";
});
</script>
<!-- Loading Overlay -->
<div id="new-overlay">
<div>Füge Benutzer hinzu...</div>
</div>
<!-- Reload Overlay -->
<div id="new-reload">
<div>Seite wird neu geladen...</div>
</div>
<!-- Success Overlay -->
<div id="success-overlay" class="divSucsess">
<span class="textSucsess">Success!</span>
</div>
<!-- Error Overlay -->
<div id="error-overlay" class="divError">
<span class="textError">Error!</span>
</div>
<div class="headerDivTrainer">
<div class="headingPanelDiv">
<h2 class="headingPanel">Benutzerverwaltung</h2>
</div>
<div class="menuWrapper">
<?php sidebarRender('button'); ?>
</div>
</div>
<?php sidebarRender('modal'); ?>
<section class="bgSection">
<h3 class="normalTitle">Neuer Account</h3>
<div class="bg-erfassen">
<button id="newUser" class="blackBtn">Neuen Account erstellen</button>
<button id="newUserLink" class="blackBtn">Neuen Account erstellen (mit Link zur Konfiguration)</button>
</div>
<h3 class="normalTitle">Bestehnde Accouts</h3>
<section class="benutzerGrid" id="section-benutzer">
<?php
$stmt = $mysqli->prepare("SELECT `name`, `id` FROM $db_tabelle_disziplinen ORDER BY start_index ASC");
if (!$stmt->execute()) {
http_response_code(500);
exit;
}
$result = $stmt->get_result();
$dbArrayGeraete = $result->fetch_all(MYSQLI_ASSOC);
$indexedArrayGereate = array_column($dbArrayGeraete, 'name', 'id');
$arrayGereateIds = array_keys($indexedArrayGereate);
$stmt->close();
$vereine = db_select($mysqli, $db_tabelle_vereine, "id, verein, email", '', [], 'verein ASC');
$entrys = db_select($mysqli, $db_tabelle_intern_benutzende, "id, username, name_person, password_cipher, freigabe, login_active", '', [], 'username ASC');
$vereineNamesArray = array_column($vereine, "verein");
foreach ($entrys as $entry) {
$freigabe_values = json_decode($entry['freigabe'], true) ?: [];
$freigaben_types = $freigabe_values['types'] ?? [];
$freigabenTrainer = (in_array('trainer', $freigaben_types)) ? $freigabe_values['freigabenTrainer'] : [];
$freigabenKampfrichter = (in_array('kampfrichter', $freigaben_types)) ? $freigabe_values['freigabenKampfrichter'] : [];
$decrypted_password = '';
if ($entry && $entry['password_cipher']) {
$data = base64_decode($entry['password_cipher']);
$iv_length = openssl_cipher_iv_length('aes-256-cbc');
$iv = substr($data, 0, $iv_length);
$encrypted = substr($data, $iv_length);
$decrypted_password = openssl_decrypt($encrypted, 'aes-256-cbc', $_ENV['PW_ENCRYPTION_KEY'], 0, $iv);
}
// Count active permissions per section
$role_keys = ['wk_leitung', 'trainer', 'kampfrichter'];
$active_roles = array_intersect($role_keys, $freigaben_types);
$active_disciplines = array_intersect(array_merge($arrayGereateIds, ['A']), $freigabenKampfrichter);
$active_vereine_list = array_intersect(array_merge(array_column($vereine, 'verein'), ['admin']), $freigabenTrainer);
$user_is_active = (bool) $entry['login_active'];
$hidden_buttons = !$user_is_active ? 'hidden' : '';
$hidden_buttons_div = !$user_is_active ? 'mty' : '';
?>
<div class="single_pwedit" id="div-single_pwedit-<?= (int) $entry['id'] ?>">
<form id="secure-password-form-<?= (int) $entry['id'] ?>" class="userForm" data-id="<?= (int) $entry['id'] ?>">
<?php if (!$user_is_active): ?>
<span class="userNotActive">Dieser Account wurde noch nicht durch die benutzende Person konfiguriert</span>
<?php endif; ?>
<div class="field-group">
<label for="username-<?= (int) $entry['id'] ?>">Accountname</label>
<input type="text" class="inputUsernameUser" id="username-<?= (int) $entry['id'] ?>" name="username"
value="<?= htmlspecialchars($entry['username']) ?>" required>
</div>
<div class="field-group">
<label for="name_person-<?= (int) $entry['id'] ?>">Name der benutzenden Person</label>
<input type="text" class="inputNameUser" id="name_person-<?= (int) $entry['id'] ?>" name="name_person"
value="<?= htmlspecialchars($entry['name_person']) ?>" required>
</div>
<div class="field-group">
<label for="password-<?php echo $entry['id']; ?>">Passwort</label>
<?php
$password_set_by_user = (bool) ($decrypted_password === 'SET_BY_OTL');
$value = ($password_set_by_user) ? '' : htmlspecialchars($decrypted_password);
$placeholder = ($password_set_by_user) ? 'Passwort durch Benutzer gesetzt' : '';
$class = ($password_set_by_user) ? 'setByUser' : '';
?>
<input class="inputPasswordUser <?= $class ?>" type="text" id="password-<?= (int) $entry['id'] ?>"
name="password" value="<?= htmlspecialchars($value) ?>"
placeholder="<?= htmlspecialchars($placeholder) ?>">
</div>
<div class="perm-section perm-section-types open" id="perm-zugang-<?= (int) $entry['id'] ?>">
<div class="perm-section-header" onclick="this.parentElement.classList.toggle('open')">
<span class="perm-section-title">
Zugang
<span class="perm-badge" id="badge-zugang-<?= (int) $entry['id'] ?>"><span
class="permBadgeCount"><?= count($active_roles); ?></span> <span
class="permBadgeText"></span></span>
</span>
<svg class="perm-section-chevron" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
stroke-linecap="round" stroke-linejoin="round">
<path d="M6 9l6 6 6-6" />
</svg>
</div>
<div class="perm-section-body">
<label>
<input type="checkbox" class="freigabeCheckbox" data-type="type" value="wk_leitung"
<?= in_array('wk_leitung', $freigaben_types) ? 'checked' : '' ?>>
WK-Leitung
</label>
<label>
<input type="checkbox" class="freigabeCheckbox" data-type="type" value="trainer" <?= in_array('trainer', $freigaben_types) ? 'checked' : '' ?>>
Trainer
</label>
<label>
<input type="checkbox" class="freigabeCheckbox" data-type="type" value="kampfrichter"
<?= in_array('kampfrichter', $freigaben_types) ? 'checked' : '' ?>>
Kampfrichter
</label>
</div>
</div>
<div class="containerTrainerKampfrichterPermissions">
<div class="perm-section perm-section-trainer" id="perm-tr-<?= (int) $entry['id'] ?>">
<div class="perm-section-header" onclick="this.parentElement.classList.toggle('open')">
<span class="perm-section-title">
Trainer Vereine
<span class="perm-badge" id="badge-tr-<?= (int) $entry['id'] ?>"><span
class="permBadgeCount"><?= count($active_vereine_list) ?></span> <span
class="permBadgeText"></span></span>
</span>
<svg class="perm-section-chevron" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
stroke-linecap="round" stroke-linejoin="round">
<path d="M6 9l6 6 6-6" />
</svg>
</div>
<div class="perm-section-body">
<label>
<input type="checkbox" class="freigabeCheckbox" data-type="trainer" value="admin" <?= in_array('admin', $freigabenTrainer) ? 'checked' : '' ?>>
Admin (Für WK-Leitung)
</label>
<?php foreach ($vereine as $verein): ?>
<label>
<input type="checkbox" class="freigabeCheckbox" data-type="trainer"
value="<?= htmlspecialchars($verein['verein']) ?>" <?= in_array($verein['verein'], $freigabenTrainer) ? 'checked' : '' ?>>
<?= htmlspecialchars($verein['verein']) ?>
</label>
<?php endforeach; ?>
</div>
</div>
<div class="perm-section perm-section-kampfrichter" id="perm-kr-<?= (int) $entry['id'] ?>">
<div class="perm-section-header" onclick="this.parentElement.classList.toggle('open')">
<span class="perm-section-title">
Kampfrichter Geräte
<span class="perm-badge" id="badge-kr-<?= (int) $entry['id'] ?>"><span
class="permBadgeCount"><?= count($active_disciplines) ?></span> <span
class="permBadgeText"></span></span>
</span>
<svg class="perm-section-chevron" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
stroke-linecap="round" stroke-linejoin="round">
<path d="M6 9l6 6 6-6" />
</svg>
</div>
<div class="perm-section-body">
<label>
<input type="checkbox" class="freigabeCheckbox" data-type="kampfrichter" value="A" <?= in_array('A', $freigabenKampfrichter) ? 'checked' : ''; ?>>
Admin (Für WK-Leitung)
</label>
<?php foreach ($indexedArrayGereate as $sgID => $sgName): ?>
<label>
<input type="checkbox" class="freigabeCheckbox" data-type="kampfrichter" value="<?= $sgID ?>"
<?= in_array($sgID, $freigabenKampfrichter) ? 'checked' : '' ?>>
<?= htmlspecialchars($sgName) ?>
</label>
<?php endforeach; ?>
</div>
</div>
</div>
<div class="userActionsDivEdit">
<button type="submit" class="blackBtn">Benutzer aktualisieren</button>
<button id="delete-user-<?= (int) $entry['id'] ?>" class="delete-user-btn"
data-id="<?= (int) $entry['id'] ?>" type="button">
Benutzer löschen
</button>
</div>
<input type="hidden" id="field_id-<?= (int) $entry['id'] ?>" name="field_id"
value="<?= (int) $entry['id'] ?>">
</form>
<div class="userActionsDivLink <?= $hidden_buttons_div ?>">
<button class="createOturl <?= $hidden_buttons ?>" data-username="<?= htmlspecialchars($entry['username']) ?>"
data-type="login" data-id="<?= (int) $entry['id'] ?>" type="button">
Einmallogin-Link erstellen
</button>
<button class="createOturl <?= $hidden_buttons ?>" data-username="<?= htmlspecialchars($entry['username']) ?>"
data-type="pwreset" data-id="<?= (int) $entry['id'] ?>" type="button">
Passwortreset-Link erstellen
</button>
</div>
</div>
<?php
}
?>
</section>
<section class="containerSection">
<div>
<h3 class="normalTitle">Vereine</h3>
<table class="wkvsTabelle trainer">
<thead>
<tr>
<th>Verein</th>
<th>Speichern</th>
<th>Löschen</th>
</tr>
</thead>
<tbody>
<?php foreach ($vereine as $entryvaer): ?>
<tr class="rowVerein" id="div_verein-<?= (int) $entryvaer['id'] ?>">
<form id="<?= (int) $entryvaer['id'] ?>-verein">
<td>
<input type="text" id="verein-<?= (int) $entryvaer['id'] ?>" name="verein"
value="<?= htmlspecialchars($entryvaer['verein']) ?>" required
style="padding: 6px 10px; border: 1px dashed #999; border-radius: 4px; font-size: 0.9rem; width: 100%;">
</td>
<td>
<button type="submit"
style="padding: 6px 14px; border: 1px solid #7777778e; background: #7777778e; color: #fff; border-radius: 4px; font-size: 0.85rem; cursor: pointer; transition: all 0.2s;">Speichern</button>
<input type="hidden" id="field_idverein-<?= (int) $entryvaer['id'] ?>" name="field_id"
value="<?= (int) $entryvaer['id'] ?>">
</td>
</form>
<td>
<button id="delete-verein-<?= (int) $entryvaer['id']; ?>" class="delete-verein-btn"
data-id="<?= (int) $entryvaer['id']; ?>" type="button"
style="border:none; background:none; cursor:pointer;">
<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"
style="color: #b91c1c;">
<polyline points="3 6 5 6 21 6"></polyline>
<path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path>
<line x1="10" y1="11" x2="10" y2="17"></line>
<line x1="14" y1="11" x2="14" y2="17"></line>
</svg>
</button>
</td>
</tr>
<?php endforeach; ?>
<!-- Row for creating a new Verein -->
<tr id="div_verein-new" class="addRow">
<form id="new-verein">
<td>
<input type="text" id="verein-new" name="verein" placeholder="Neuer Verein..." required>
</td>
<td>
<button type="submit">Hinzufügen</button>
<input type="hidden" id="field_idverein-new" name="field_id" value="0">
</td>
</form>
<td></td> <!-- No delete button for the new row -->
</tr>
</tbody>
</table>
</div>
</section>
</section>
<div class="bgNewUserLink hidden">
<div class="newUserLinkDiv">
<div class="ot-modal-top-content">
<div class="ot-title">Daten & Freigaben:</div>
<button id="otCloseNBL" class="ot-close-btn">✕</button>
</div>
<form class="newUserLinkForm">
<div class="field-group">
<label for="username-linkUser">Accountname (optional)</label>
<input type="text" id="username-linkUser" name="username" value="">
</div>
<div class="field-group">
<label for="name_person-linkUser">Name der benutzenden Person (optional)</label>
<input type="text" id="name_person-linkUser" name="name_person" value="">
</div>
<div class="field-group">
<label for="password-linkUser">Passwort (optional)</label>
<input type="text" id="password-linkUser" name="password" value="">
</div>
<p>Alle obrigen Daten, welche nicht gesetzt werden, werden durch die benutzende Peron beim ersten Login selbst
gesetzt.</p>
<div class="perm-section perm-section-types open" id="perm-zugang-linkUser">
<div class="perm-section-header" onclick="this.parentElement.classList.toggle('open')">
<span class="perm-section-title">
Zugang
<span class="perm-badge" id="badge-zugang-linkUser">erforderlich</span>
</span>
<svg class="perm-section-chevron" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
stroke-linecap="round" stroke-linejoin="round">
<path d="M6 9l6 6 6-6" />
</svg>
</div>
<div class="perm-section-body">
<label>
<input type="checkbox" class="freigabeCheckbox" data-type="type" value="wk_leitung">
WK-Leitung
</label>
<label>
<input type="checkbox" class="freigabeCheckbox" data-type="type" value="trainer">
Trainer
</label>
<label>
<input type="checkbox" class="freigabeCheckbox" data-type="type" value="kampfrichter">
Kampfrichter
</label>
</div>
</div>
<!-- Permission dropdown: Trainer Vereine -->
<div class="perm-section perm-section-trainer" id="perm-tr-linkUser">
<div class="perm-section-header" onclick="this.parentElement.classList.toggle('open')">
<span class="perm-section-title">
Trainer Vereine
<span class="perm-badge" id="badge-tr-linkUser">erforderlich</span>
</span>
<svg class="perm-section-chevron" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
stroke-linecap="round" stroke-linejoin="round">
<path d="M6 9l6 6 6-6" />
</svg>
</div>
<div class="perm-section-body">
<label>
<input type="checkbox" class="freigabeCheckbox" data-type="trainer" value="admin">
Admin (alle Vereine)
</label>
<?php foreach ($vereine as $verein): ?>
<label>
<input type="checkbox" class="freigabeCheckbox" data-type="trainer"
value="<?= htmlspecialchars($verein['verein']) ?>">
<?= htmlspecialchars($verein['verein']) ?>
</label>
<?php endforeach; ?>
</div>
</div>
<!-- Permission dropdown: Kampfrichter Geräte -->
<div class="perm-section perm-section-kampfrichter" id="perm-kr-linkUser">
<div class="perm-section-header" onclick="this.parentElement.classList.toggle('open')">
<span class="perm-section-title">
Kampfrichter Geräte
<span class="perm-badge" id="badge-kr-linkUser">erforderlich</span>
</span>
<svg class="perm-section-chevron" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
stroke-linecap="round" stroke-linejoin="round">
<path d="M6 9l6 6 6-6" />
</svg>
</div>
<div class="perm-section-body">
<label>
<input type="checkbox" class="freigabeCheckbox" data-type="kampfrichter" value="admin">
Admin (alle Geräte)
</label>
<?php foreach ($indexedArrayGereate as $sgID => $sgName): ?>
<label>
<input type="checkbox" class="freigabeCheckbox" data-type="kampfrichter" value="<?= (int) $sgID ?>">
<?= htmlspecialchars($sgName) ?>
</label>
<?php endforeach; ?>
</div>
</div>
<div class="divAblaufdatumLink">
<label for="ablaufdatumRegistrationslink">Ablaufdatum des Links (Maximum 7 Tage)</label>
<input id="ablaufdatumRegistrationslink" type="datetime-local"
value="<?= date('Y-m-d H:i:s', strtotime('+1 days')) ?>">
</div>
<button type="submit" class="blackBtn">Link erstellen</button>
<input type="hidden" id="field_id-linkUser" name="field_id" value="linkUser">
</form>
</div>
</div>
<script>
const csrf_token = "<?= htmlspecialchars($csrf_token) ?>";
function tooglePermBadgeText($el) {
const $textSpan = $el.siblings('.permBadgeText');
if ($textSpan.length !== 1) return;
const label = (parseInt($el.text()) !== 1) ? 'Freigaben' : 'Freigabe';
$textSpan.text(label);
}
function toogleAllPermBadgeText() {
const $valueSpans = $('.permBadgeCount');
$valueSpans.each((ind, el) => {
tooglePermBadgeText($(el));
})
}
toogleAllPermBadgeText();
function toggleFreigabenDropdowns(el) {
const $input = $(el);
const type = $input.val();
if (type !== 'kampfrichter' && type !== 'trainer') {
return;
}
const dropdown = $input.closest('form').find('.perm-section-' + type);
if ($input.is(':checked')) {
dropdown.show();
} else {
dropdown.hide();
}
}
const targetCheckboxes = '.freigabeCheckbox';
$(targetCheckboxes).each(function () {
toggleFreigabenDropdowns(this);
});
$(document).on('change', '.freigabeCheckbox', function () {
toggleFreigabenDropdowns(this);
const $el = $(this);
const $container = $el.closest('.perm-section');
if ($container.length !== 1) return;
const checkedCheckboxes = $container.find('.freigabeCheckbox:checked').length;
const $permBadge = $container.find('.permBadgeCount');
if ($permBadge.length !== 1) return;
$permBadge.text(checkedCheckboxes);
tooglePermBadgeText($permBadge);
})
const allowedFreigabenTypes = <?= json_encode(["wk_leitung", "trainer", "kampfrichter"], JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT) ?>;
const allowedFreigabenTrainer = <?= json_encode(array_merge($vereineNamesArray, ['admin']), JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT) ?>;
const allowedFreigabenKampfrichter = <?= json_encode(array_merge(array_map("strval", $arrayGereateIds), ['A']), JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT) ?>;
$(document).on('submit', '.userForm', async function (e) {
e.preventDefault();
const $form = $(this);
$form.find('.incorrectInput').removeClass('incorrectInput');
const personId = parseInt($form.data('id') || 0);
if (personId < 1) {
displayMsg(0, "Fehler in der HTML des Formulares");
}
const username = ($form.find('.inputUsernameUser').val() || '').trim();
const namePerson = ($form.find('.inputNameUser').val() || '').trim();
let password = ($form.find('.inputPasswordUser').val() || '').trim();
let returnWf = false;
let updateType = 'all';
// Validate Fields
if (username === '') {
$form.find('.inputUsernameUser').addClass('incorrectInput');
returnWf = true;
}
if (namePerson === '') {
$form.find('.inputNameUser').addClass('incorrectInput');
returnWf = true;
}
const $passwordIsUserSet = $form.find('.inputPasswordUser').hasClass('setByUser');
if (password === '' && !$passwordIsUserSet) {
$form.find('.inputPasswordUser').addClass('incorrectInput');
returnWf = true;
}
if (returnWf) {
displayMsg(2, "Manche Felder sind leer");
return;
}
if (password !== '' && $passwordIsUserSet && !await displayConfirm('Das Passwort dieses Benutzers wurde durch den Benutzer gesetzt und wird hiermit überschrieben.')) {
return;
}
if (password === '' && $passwordIsUserSet) {
if (!await displayConfirm('Das Passwort dieses Benutzers wurde durch den Benutzer gesetzt und wird nicht aktualisiert.')) {
return;
}
password = null;
updateType = 'no_password';
}
if (updateType !== 'no_password' && password.length < 6) {
displayMsg(1, "Das Passwort muss mindestens 6 Zeichen enthalten");
return;
}
const freigabenTypes = $form.find('.freigabeCheckbox[data-type="type"]:checked').map((_, el) => $(el).val()).get()
.filter(val => allowedFreigabenTypes.includes(val));
if (freigabenTypes.length < 1 && !await displayConfirm('Dieser Benutzer hat keine Freigaben. Trotzdem aktualisieren?')) {
return;
}
let freigabenTrainer = [];
if (freigabenTypes.includes('trainer')) {
const $inputsTrainer = $form.find('.freigabeCheckbox[data-type="trainer"]:checked');
if ($inputsTrainer.length < 1 && !await displayConfirm('Dieser Benutzer hat die Freigabe Trainer aber keine Vereine zugewiesen. Trotzdem aktualisieren?')) {
return;
}
freigabenTrainer = $inputsTrainer.map((_, el) => $(el).val()).get()
.filter(val => allowedFreigabenTrainer.includes(val));
}
let freigabenKampfrichter = [];
if (freigabenTypes.includes('kampfrichter')) {
const $inputsKampfrichter = $form.find('.freigabeCheckbox[data-type="kampfrichter"]:checked');
if ($inputsKampfrichter.length < 1 && !await displayConfirm('Dieser Benutzer hat die Freigabe Kampfrichter aber keine Geräte zugewiesen. Trotzdem aktualisieren?')) {
return;
}
freigabenKampfrichter = $inputsKampfrichter.map((_, el) => $(el).val()).get()
.filter(val => allowedFreigabenKampfrichter.includes(val));
}
$.ajax({
url: "/intern/scripts/logindata/ajax-update-user-information.php",
type: 'POST',
data: {
csrf_token,
username,
namePerson,
password,
freigaben: freigabenTypes,
freigabenTrainer,
freigabenKampfrichter,
updateType,
personId
},
success: function (response) {
if (!response.success) {
displayMsg(0, response.message);
return;
}
displayMsg(0, response.message);
},
error: function (xhr, status, error) {
displayMsg(0, 'Fehler beim Aktualisieren: ' + error);
}
});
});
$('#newUser').on('click', function () {
$.ajax({
url: "/intern/scripts/logindata/ajax-update-user-information.php",
type: 'POST',
data: {
csrf_token,
updateType: 'new_user'
},
success: function (response) {
if (!response.success) {
displayMsg(0, response.message);
return;
}
location.reload();
},
error: function (xhr, status, error) {
displayMsg(0, 'Fehler beim Einfügrn: ' + error);
}
});
})
document.querySelectorAll('[id$="-verein"], #new-verein').forEach(form => {
form.addEventListener('submit', e => {
e.preventDefault();
const id = form.id === 'new-verein' ? 'new' : form.id.split('-')[0];
const verein = document.getElementById('verein-' + id)?.value || document.getElementById('verein-new').value;
const field_id = document.getElementById('field_idverein-' + id)?.value || document.getElementById('field_idverein-new').value;
const params = new URLSearchParams();
params.append('action', 'set_verein');
params.append('verein', verein);
params.append('field_id', field_id);
params.append('csrf_token', csrf_token);
// Show loading overlay
if (id === 'new') {
document.getElementById('new-overlay').style.display = 'block';
} else {
document.getElementById('loading-overlay').style.display = 'block';
}
fetch('/intern/scripts/logindata/ajax-vereine-handler.php', {
method: 'POST',
body: params
})
.then(res => res.json())
.then(data => {
if (id === 'new') {
document.getElementById('new-overlay').style.display = 'none';
} else {
document.getElementById('loading-overlay').style.display = 'none';
}
if (data.success) {
if (id === 'new') {
// Show success and reload
document.getElementById('new-reload').style.display = 'block';
setTimeout(() => { window.location.reload(); }, 1000);
return;
}
}
})
.catch(err => {
console.error(err);
document.getElementById('loading-overlay').style.display = 'none';
displayMsg(0, 'Fehler, siehe Konsole.');
});
});
});
document.querySelectorAll('.delete-user-btn').forEach(btn => {
btn.addEventListener('click', e => {
e.preventDefault();
const id = btn.dataset.id;
if (!await displayConfirm("Benutzer wirklich löschen?")) {
return;
}
// Show loading overlay
document.getElementById('loading-overlay').style.display = 'block';
const params = new URLSearchParams();
params.append('action', 'delete_secure_user');
params.append('field_id', id);
params.append('csrf_token', csrf_token);
fetch('/intern/scripts/logindata/ajax-delete-user.php', {
method: 'POST',
body: params
})
.then(res => res.json())
.then(data => {
document.getElementById('loading-overlay').style.display = 'none';
if (data.success) {
const div = document.getElementById('div-single_pwedit-' + id);
if (div) div.remove();
displayMsg(1, data.message || 'Benutzer gelöscht!');
} else {
displayMsg(0, data.data || 'Fehler beim Löschen');
}
})
.catch(err => {
console.error(err);
document.getElementById('loading-overlay').style.display = 'none';
displayMsg(0, 'Fehler, siehe Konsole.');
});
});
});
function germanDate(date) {
return date.toLocaleString("de-DE", {
weekday: "long",
day: "numeric",
month: "long",
hour: "2-digit",
minute: "2-digit"
}) + " Uhr";
}
$(document).on('click', '.createOturl', function (e) {
e.preventDefault();
const $btn = $(this);
const id = $btn.data('id');
const type = $btn.data('type');
const username = $btn.data('username');
$.ajax({
url: "/intern/scripts/logindata/ajax-create-otl.php",
type: 'POST',
data: {
csrf_token,
user_id: id,
type
},
success: function (response) {
if (!response.success) {
displayMsg(0, response.message || 'Fehler beim Erstellen des Links');
return;
}
const fullUrl = window.location.origin + '/intern/otlogin?otl=' + response.url;
if (!updateOTLLinkDiv(fullUrl, response.expiresAt, username)) {
displayMsg(0, "Fehler beim Anzeigen des Links");
return
}
},
error: function (xhr, status, error) {
displayMsg(0, 'Fehler beim Aktualisieren: ' + error);
}
});
});
$(document).on('click', '.delete-verein-btn', async function (e) {
e.preventDefault();
const $btn = $(this);
const id = $btn.data('id');
if (!await displayConfirm("Verein wirklich löschen?")) return;
const params = new URLSearchParams();
params.append('field_id', id);
params.append('csrf_token', csrf_token);
$.ajax({
url: '/intern/scripts/logindata/ajax-delete-verein.php',
type: "DELETE",
data: {
csrf_token,
id
},
success: function (response) {
if (!response.success) {
displayMsg(0, response.message || 'Fehler beim Löschen');
return;
}
const $row = $btn.closest('.rowVerein');
if ($row.length !== 1) return;
$row.remove();
displayMsg(1, 'Verein gelöscht');
},
error: function (xhr, status, error) {
displayMsg(0, 'Fehler beim Löschen: ' + error);
}
});
});
const $bgNewUserLink = $('.bgNewUserLink');
const $closeXNUL = $('#otCloseNBL');
$('#newUserLink').on('click', function () {
$bgNewUserLink.removeClass("hidden");
});
$closeXNUL.on('click', function (e) {
$bgNewUserLink.addClass("hidden");
});
$bgNewUserLink.on('click', function (e) {
if (e.target === e.currentTarget) {
$(this).addClass("hidden");
}
});
const dateTimeNow = "<?= date('Y-m-d H:i:s') ?>";
const normalDateTimeExpire = "<?= date('Y-m-d H:i:s', strtotime('+1 days')) ?>";
const maxDateTimeExpire = "<?= date('Y-m-d H:i:s', strtotime('+7 days')) ?>";
const nowDate = new Date(dateTimeNow);
const maxDate = new Date(maxDateTimeExpire);
$(document).on('submit', '.newUserLinkForm', async function (e) {
e.preventDefault();
const $form = $(this);
$form.find('.incorrectInput').removeClass('incorrectInput');
const username = ($form.find('.inputUsernameUser').val() || '').trim() || null;
const namePerson = ($form.find('.inputNameUser').val() || '').trim() || null;
let password = ($form.find('.inputPasswordUser').val() || '').trim() || null;
const expirationDateTime = ($form.find('#ablaufdatumRegistrationslink').val() || '').trim() || normalDateTimeExpire;
const checkDate = new Date(expirationDateTime);
if (checkDate <= nowDate) {
displayMsg(0, "Das Ablaufdatum muss in der Zukunft liegen.");
$form.find('#ablaufdatumRegistrationslink').addClass('incorrectInput');
return;
}
if (checkDate > maxDate) {
displayMsg(0, "Der Link darf aus Sicherheitsgründen maximal 7 Tage lang gültig sein.");
$form.find('#ablaufdatumRegistrationslink').addClass('incorrectInput');
return;
}
if (password !== null && password.length < 6) {
displayMsg(1, "Das Passwort muss mindestens 6 Zeichen enthalten");
return;
}
const freigabenTypes = $form.find('.freigabeCheckbox[data-type="type"]:checked').map((_, el) => $(el).val()).get()
.filter(val => allowedFreigabenTypes.includes(val));
if (freigabenTypes.length < 1 && !await displayConfirm('Dieser Benutzer hat keine Freigaben. Trotzdem erstellen?')) {
return;
}
let freigabenTrainer = [];
if (freigabenTypes.includes('trainer')) {
const $inputsTrainer = $form.find('.freigabeCheckbox[data-type="trainer"]:checked');
if ($inputsTrainer.length < 1 && !await displayConfirm('Dieser Benutzer hat die Freigabe Trainer aber keine Vereine zugewiesen. Trotzdem erstellen?')) {
return;
}
freigabenTrainer = $inputsTrainer.map((_, el) => $(el).val()).get()
.filter(val => allowedFreigabenTrainer.includes(val));
}
let freigabenKampfrichter = [];
if (freigabenTypes.includes('kampfrichter')) {
const $inputsKampfrichter = $form.find('.freigabeCheckbox[data-type="kampfrichter"]:checked');
if ($inputsKampfrichter.length < 1 && !await displayConfirm('Dieser Benutzer hat die Freigabe Kampfrichter aber keine Geräte zugewiesen. Trotzdem erstellen?')) {
return;
}
freigabenKampfrichter = $inputsKampfrichter.map((_, el) => $(el).val()).get()
.filter(val => allowedFreigabenKampfrichter.includes(val));
}
$.ajax({
url: "/intern/scripts/logindata/ajax-create-link-user.php",
type: 'POST',
data: {
csrf_token,
username,
namePerson,
password,
freigaben: freigabenTypes,
freigabenTrainer,
freigabenKampfrichter,
linkExpiresAt: expirationDateTime
},
success: function (response) {
if (!response.success) {
displayMsg(0, response.message);
return;
}
const fullUrl = window.location.origin + '/intern/otlogin?otl=' + response.url;
if (!updateOTLLinkDiv(fullUrl, response.expiresAt, username)) {
displayMsg(0, "Fehler beim Anzeigen des Links");
return
}
},
error: function (xhr, status, error) {
displayMsg(0, 'Fehler beim Aktualisieren: ' + error);
}
});
});
function updateOTLLinkDiv(url, expiresAt, username) {
const $urlDiv = $('#oturldiv');
if ($urlDiv.length !== 1) return false;
$urlDiv.removeClass('hidden');
const aOturl = $('#aOturl');
if (aOturl.length !== 1) return false;
aOturl.text(url).attr('href', url);
let oturlGb = $('#oturlGb');
if (oturlGb.length !== 1) return false;
const expDate = new Date(expiresAt);
oturlGb.html('Link gültig bis: ' + germanDate(expDate));
const $qrcodeContainer = $("#qrcode");
$qrcodeContainer.html('');
$urlDiv.data('username', username || 'BLANK_BENUTZER')
const qr = new QRCode(document.getElementById("qrcode"), {
text: url,
width: 256,
height: 256
});
return true;
}
$("#btnDownloadQRCode").off("click").on("click", function () {
const $canvas = $('#oturldiv canvas');
if ($canvas.length === 1) {
const image = $canvas[0].toDataURL("image/png");
const displayedUsername = $('#oturldiv').data('username');
const $link = $("<a></a>");
$link.attr('href', image);
$link.attr('download', `QR_Code_User_Setup_${displayedUsername}.png`);
$link[0].click();
} else {
alert("QR Code not ready yet!");
}
});
flatpickr("#ablaufdatumRegistrationslink", {
locale: "de",
dateFormat: "Y-m-d H:i:s",
altInput: true,
altFormat: "j. F Y H:i",
allowInput: true,
disableMobile: true,
enableTime: true,
time_24hr: true,
minDate: "today",
maxDate: "<?= date('Y-m-d H:i:s', strtotime('+7 days')) ?>"
});
</script>
</body>
</html>
<?php endif; ?>