Add shared auth login flow
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
(function initHelpIconOverlayModule() {
|
||||
const CLOSE_HANDLERS = {
|
||||
'.sg-pulldown-demo': (root) => {
|
||||
root.querySelectorAll('.sg-pulldown-demo').forEach((demo) => {
|
||||
const trigger = demo.querySelector('.sg-pulldown-demo__trigger');
|
||||
demo.dataset.open = 'false';
|
||||
if (trigger) {
|
||||
trigger.setAttribute('aria-expanded', 'false');
|
||||
}
|
||||
});
|
||||
},
|
||||
'.sg-sandwich-menu-wrap': (root) => {
|
||||
root.querySelectorAll('.sg-sandwich-menu-wrap').forEach((wrap) => {
|
||||
const button = wrap.querySelector('.sg-sandwich-button');
|
||||
wrap.dataset.open = 'false';
|
||||
if (button) {
|
||||
button.setAttribute('aria-expanded', 'false');
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
const getViewportWidth = () => {
|
||||
if (window.visualViewport && typeof window.visualViewport.width === 'number') {
|
||||
return window.visualViewport.width;
|
||||
}
|
||||
return window.innerWidth;
|
||||
};
|
||||
|
||||
const getSafeInsetPx = () => {
|
||||
const rootStyles = getComputedStyle(document.documentElement);
|
||||
const spacingSmallRaw = rootStyles.getPropertyValue('--spacing-small').trim();
|
||||
const rootFontSize = parseFloat(rootStyles.fontSize) || 16;
|
||||
const spacingSmallValue = parseFloat(spacingSmallRaw);
|
||||
if (Number.isNaN(spacingSmallValue)) {
|
||||
return 0;
|
||||
}
|
||||
if (spacingSmallRaw.endsWith('rem')) {
|
||||
return spacingSmallValue * rootFontSize;
|
||||
}
|
||||
return spacingSmallValue;
|
||||
};
|
||||
|
||||
const closeAllHelpIcons = (root) => {
|
||||
root.querySelectorAll('.sg-help-icon-wrap').forEach((wrap) => {
|
||||
const button = wrap.querySelector('.sg-help-icon');
|
||||
const panel = wrap.querySelector('.sg-help-icon-panel');
|
||||
wrap.dataset.open = 'false';
|
||||
if (panel) {
|
||||
panel.style.removeProperty('transform');
|
||||
}
|
||||
if (button) {
|
||||
button.setAttribute('aria-expanded', 'false');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
window.sgInitHelpIconOverlays = (options = {}) => {
|
||||
const root = options.root || document;
|
||||
const closeOnOpenSelectors = options.closeOnOpenSelectors || [];
|
||||
const outsideClickIgnoreSelectors = options.outsideClickIgnoreSelectors || [];
|
||||
|
||||
root.querySelectorAll('.sg-help-icon-wrap').forEach((wrap) => {
|
||||
if (wrap.dataset.helpIconInit === 'true') {
|
||||
return;
|
||||
}
|
||||
wrap.dataset.helpIconInit = 'true';
|
||||
|
||||
const button = wrap.querySelector('.sg-help-icon');
|
||||
const panel = wrap.querySelector('.sg-help-icon-panel');
|
||||
if (!button || !panel) {
|
||||
return;
|
||||
}
|
||||
|
||||
button.addEventListener('click', (event) => {
|
||||
event.stopPropagation();
|
||||
const nextState = wrap.dataset.open !== 'true';
|
||||
|
||||
closeAllHelpIcons(root);
|
||||
closeOnOpenSelectors.forEach((selector) => {
|
||||
const handler = CLOSE_HANDLERS[selector];
|
||||
if (handler) {
|
||||
handler(root);
|
||||
}
|
||||
});
|
||||
|
||||
if (!nextState) {
|
||||
return;
|
||||
}
|
||||
|
||||
wrap.dataset.align = 'left';
|
||||
wrap.dataset.open = 'true';
|
||||
button.setAttribute('aria-expanded', 'true');
|
||||
|
||||
const viewportWidth = getViewportWidth();
|
||||
const panelRect = panel.getBoundingClientRect();
|
||||
if (panelRect.right > viewportWidth) {
|
||||
wrap.dataset.align = 'right';
|
||||
}
|
||||
const alignedPanelRect = panel.getBoundingClientRect();
|
||||
if (alignedPanelRect.left < 0) {
|
||||
wrap.dataset.align = 'left';
|
||||
}
|
||||
|
||||
const clampedRect = panel.getBoundingClientRect();
|
||||
const safeInset = getSafeInsetPx();
|
||||
let shiftX = 0;
|
||||
if (clampedRect.right > (viewportWidth - safeInset)) {
|
||||
shiftX -= clampedRect.right - (viewportWidth - safeInset);
|
||||
}
|
||||
if ((clampedRect.left + shiftX) < safeInset) {
|
||||
shiftX += safeInset - (clampedRect.left + shiftX);
|
||||
}
|
||||
if (shiftX !== 0) {
|
||||
panel.style.transform = `translateX(${shiftX}px)`;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
document.addEventListener('click', (event) => {
|
||||
const isInsideIgnoredZone = ['.sg-help-icon-wrap', ...outsideClickIgnoreSelectors]
|
||||
.some((selector) => event.target.closest(selector));
|
||||
if (isInsideIgnoredZone) {
|
||||
return;
|
||||
}
|
||||
closeAllHelpIcons(root);
|
||||
});
|
||||
};
|
||||
})();
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
require_once __DIR__ . '/../modules/shared/auth/service.php';
|
||||
require_once __DIR__ . '/../modules/shared/auth/ui/login.php';
|
||||
require_once __DIR__ . '/../modules/shared/auth/ui/home.php';
|
||||
|
||||
$env = expand_env_values(parse_env_file(__DIR__ . '/../.env'));
|
||||
$pdo = connect_database($env);
|
||||
auth_bootstrap_session();
|
||||
auth_ensure_schema($pdo);
|
||||
|
||||
if (($_SERVER['REQUEST_METHOD'] ?? 'GET') === 'POST') {
|
||||
$csrfToken = (string) ($_POST['csrf_token'] ?? '');
|
||||
if (!auth_validate_csrf_token($csrfToken)) {
|
||||
render_auth_login_page([
|
||||
'identifier_value' => (string) ($_POST['identifier'] ?? ''),
|
||||
'errors' => [
|
||||
'identifier' => 'Ungültiges Sicherheits-Token. Bitte Seite neu laden.',
|
||||
'password' => null,
|
||||
],
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$loginResult = auth_login(
|
||||
$pdo,
|
||||
(string) ($_POST['identifier'] ?? ''),
|
||||
(string) ($_POST['password'] ?? '')
|
||||
);
|
||||
|
||||
if (($loginResult['ok'] ?? false) === true) {
|
||||
header('Location: ' . auth_take_return_to());
|
||||
exit;
|
||||
}
|
||||
|
||||
render_auth_login_page([
|
||||
'identifier_value' => (string) ($_POST['identifier'] ?? ''),
|
||||
'errors' => $loginResult['errors'] ?? [],
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$currentUser = auth_current_user($pdo);
|
||||
if ($currentUser !== null) {
|
||||
render_auth_home_page($currentUser);
|
||||
exit;
|
||||
}
|
||||
|
||||
render_auth_login_page([
|
||||
'identifier_value' => '',
|
||||
'errors' => [
|
||||
'identifier' => null,
|
||||
'password' => null,
|
||||
],
|
||||
]);
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
require_once __DIR__ . '/../modules/shared/auth/service.php';
|
||||
|
||||
auth_bootstrap_session();
|
||||
auth_logout();
|
||||
header('Location: /');
|
||||
exit;
|
||||
@@ -1,4 +1,12 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
require_once __DIR__ . '/../../modules/shared/auth/service.php';
|
||||
|
||||
$env = expand_env_values(parse_env_file(__DIR__ . '/../../.env'));
|
||||
$pdo = connect_database($env);
|
||||
auth_bootstrap_session();
|
||||
auth_ensure_schema($pdo);
|
||||
auth_require_user($pdo);
|
||||
|
||||
require_once __DIR__ . '/../../modules/erp/direktverkauf/ui/index.php';
|
||||
|
||||
Reference in New Issue
Block a user