Resolve recommended-profile Critical and High findings, update vulnerable dependencies, restore invoice queue E2E authentication setup, and clear the remaining frontend Qodana findings.
461 lines
16 KiB
HTML
461 lines
16 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="" class="theme-light tw-bootstrap-loading" data-theme="light">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<script>
|
|
(function () {
|
|
window.__TW_LOADER_STARTED_AT__ = window.performance && typeof window.performance.now === 'function'
|
|
? window.performance.now()
|
|
: Date.now();
|
|
var match = window.location.pathname.match(/^\/[^/]+\/frontend(?:\/|$)/);
|
|
var href = match ? match[0].replace(/\/+$/, '') + '/' : '/';
|
|
var base = document.createElement('base');
|
|
base.href = href;
|
|
document.currentScript.after(base);
|
|
})();
|
|
</script>
|
|
<link rel="icon" type="image/png" href="%BASE_URL%assets/favicons/favicon-96x96.png" sizes="96x96" />
|
|
<link rel="icon" type="image/svg+xml" href="%BASE_URL%assets/favicons/favicon.svg" />
|
|
<link rel="shortcut icon" href="%BASE_URL%assets/favicons/favicon.ico" />
|
|
<link rel="apple-touch-icon" sizes="180x180" href="%BASE_URL%assets/favicons/apple-touch-icon.png" />
|
|
<meta name="apple-mobile-web-app-title" content="Truck Wash Kundeportal" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
|
<meta name="mobile-web-app-capable" content="yes">
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.1/css/all.min.css" integrity="sha512-5Hs3dF2AEPkpNAR7UiOHba+lRSJNeM2ECkwxUIxC1Q/FLycGTbNapWXB4tP889k5T5Ju8fs4b1P5z/iB4nMfSQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />
|
|
<title>Truck Wash Kundeportal</title>
|
|
<style>
|
|
html,
|
|
body,
|
|
#app {
|
|
min-height: 100%;
|
|
}
|
|
|
|
html.tw-bootstrap-loading {
|
|
font-size: 16px !important;
|
|
}
|
|
|
|
body {
|
|
margin: 0;
|
|
background: #fff;
|
|
}
|
|
|
|
body.tw-bootstrap-loading {
|
|
background: #041f32;
|
|
}
|
|
|
|
html.tw-bootstrap-loading,
|
|
html.tw-loader-scroll-lock,
|
|
body.tw-bootstrap-loading,
|
|
body.tw-loader-scroll-lock {
|
|
overflow: hidden;
|
|
scrollbar-width: none;
|
|
}
|
|
|
|
html.tw-bootstrap-loading::-webkit-scrollbar,
|
|
html.tw-loader-scroll-lock::-webkit-scrollbar,
|
|
body.tw-bootstrap-loading::-webkit-scrollbar,
|
|
body.tw-loader-scroll-lock::-webkit-scrollbar {
|
|
display: none;
|
|
width: 0;
|
|
height: 0;
|
|
}
|
|
|
|
.tw-bootstrap-loader {
|
|
--tw-loader-navy: #063651;
|
|
--tw-loader-blue: #0787bb;
|
|
--tw-loader-cyan: #69d7f5;
|
|
--tw-loader-foam: #f8fbff;
|
|
--tw-loader-warm: #f4c15d;
|
|
|
|
position: fixed;
|
|
inset: 0;
|
|
z-index: 100000;
|
|
display: grid;
|
|
min-height: 100vh;
|
|
place-items: center;
|
|
overflow: hidden;
|
|
padding: 2rem;
|
|
box-sizing: border-box;
|
|
background:
|
|
radial-gradient(circle at 20% 20%, rgba(105, 215, 245, 0.18), transparent 28rem),
|
|
radial-gradient(circle at 82% 74%, rgba(244, 193, 93, 0.12), transparent 24rem),
|
|
linear-gradient(145deg, #041f32 0%, var(--tw-loader-navy) 52%, #04263d 100%);
|
|
color: var(--tw-loader-foam);
|
|
font-family: Avenir, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
}
|
|
|
|
.tw-bootstrap-loader__ambient {
|
|
position: absolute;
|
|
inset: 0;
|
|
pointer-events: none;
|
|
}
|
|
|
|
.tw-bootstrap-loader__ambient::before {
|
|
position: absolute;
|
|
inset: 14% 9%;
|
|
content: "";
|
|
border: 1px solid rgba(248, 251, 255, 0.08);
|
|
border-radius: 8px;
|
|
}
|
|
|
|
.tw-bootstrap-loader__wash {
|
|
position: absolute;
|
|
left: 50%;
|
|
display: block;
|
|
width: 72rem;
|
|
height: 8rem;
|
|
border-radius: 999px;
|
|
background: linear-gradient(90deg, transparent, rgba(105, 215, 245, 0.2), rgba(248, 251, 255, 0.18), transparent);
|
|
filter: blur(8px);
|
|
transform: translateX(-50%) rotate(-9deg);
|
|
}
|
|
|
|
.tw-bootstrap-loader__wash--wide {
|
|
top: 26%;
|
|
animation: tw-bootstrap-loader-wash 5.8s ease-in-out var(--tw-loader-wash-wide-delay, 0ms) infinite;
|
|
}
|
|
|
|
.tw-bootstrap-loader__wash--tight {
|
|
bottom: 22%;
|
|
width: 48rem;
|
|
height: 5rem;
|
|
animation: tw-bootstrap-loader-wash 6.8s ease-in-out var(--tw-loader-wash-tight-delay, 0ms) infinite reverse;
|
|
}
|
|
|
|
.tw-bootstrap-loader__panel {
|
|
position: relative;
|
|
display: grid;
|
|
width: min(100%, 25rem);
|
|
min-height: 27rem;
|
|
align-content: center;
|
|
justify-items: center;
|
|
padding: 2.5rem 2rem 2.25rem;
|
|
box-sizing: border-box;
|
|
border: 1px solid rgba(248, 251, 255, 0.16);
|
|
border-radius: 8px;
|
|
background: rgba(4, 31, 50, 0.74);
|
|
box-shadow: 0 24px 80px rgba(0, 0, 0, 0.32);
|
|
text-align: center;
|
|
backdrop-filter: blur(18px);
|
|
}
|
|
|
|
.tw-bootstrap-loader__panel::after {
|
|
position: absolute;
|
|
inset: 0;
|
|
content: "";
|
|
border-radius: inherit;
|
|
background: linear-gradient(180deg, rgba(248, 251, 255, 0.08), transparent 38%);
|
|
pointer-events: none;
|
|
}
|
|
|
|
.tw-bootstrap-loader__brand,
|
|
.tw-bootstrap-loader__motion,
|
|
.tw-bootstrap-loader__status,
|
|
.tw-bootstrap-loader__hint,
|
|
.tw-bootstrap-loader__dots {
|
|
position: relative;
|
|
z-index: 1;
|
|
}
|
|
|
|
.tw-bootstrap-loader__brand {
|
|
display: grid;
|
|
width: 13rem;
|
|
min-height: 4rem;
|
|
place-items: center;
|
|
margin-bottom: 2.25rem;
|
|
}
|
|
|
|
.tw-bootstrap-loader__logo {
|
|
display: block;
|
|
width: 100%;
|
|
max-height: 4rem;
|
|
object-fit: contain;
|
|
}
|
|
|
|
.tw-bootstrap-loader__motion {
|
|
display: grid;
|
|
width: 8.5rem;
|
|
height: 8.5rem;
|
|
place-items: center;
|
|
margin-bottom: 2rem;
|
|
}
|
|
|
|
.tw-bootstrap-loader__ring {
|
|
position: absolute;
|
|
inset: 0;
|
|
border: 2px solid rgba(248, 251, 255, 0.12);
|
|
border-top-color: var(--tw-loader-cyan);
|
|
border-right-color: rgba(7, 135, 187, 0.78);
|
|
border-radius: 50%;
|
|
animation: tw-bootstrap-loader-spin 1.8s linear var(--tw-loader-spin-delay, 0ms) infinite;
|
|
}
|
|
|
|
.tw-bootstrap-loader__ring::before,
|
|
.tw-bootstrap-loader__ring::after {
|
|
position: absolute;
|
|
content: "";
|
|
border-radius: 50%;
|
|
}
|
|
|
|
.tw-bootstrap-loader__ring::before {
|
|
inset: 1rem;
|
|
border: 1px solid rgba(248, 251, 255, 0.18);
|
|
}
|
|
|
|
.tw-bootstrap-loader__ring::after {
|
|
inset: 2.3rem;
|
|
background: radial-gradient(circle, rgba(105, 215, 245, 0.38), rgba(7, 135, 187, 0.18) 45%, transparent 70%);
|
|
animation: tw-bootstrap-loader-pulse 2.4s ease-in-out var(--tw-loader-pulse-delay, 0ms) infinite;
|
|
}
|
|
|
|
.tw-bootstrap-loader__sweep {
|
|
width: 6rem;
|
|
height: 1.15rem;
|
|
border-radius: 999px;
|
|
background: linear-gradient(90deg, transparent 0%, rgba(248, 251, 255, 0.92) 45%, var(--tw-loader-cyan) 100%);
|
|
box-shadow: 0 0 24px rgba(105, 215, 245, 0.48);
|
|
transform: rotate(-12deg);
|
|
animation: tw-bootstrap-loader-sweep 1.8s ease-in-out var(--tw-loader-sweep-delay, 0ms) infinite;
|
|
}
|
|
|
|
.tw-bootstrap-loader__spark {
|
|
position: absolute;
|
|
width: 0.55rem;
|
|
height: 0.55rem;
|
|
border-radius: 50%;
|
|
background: var(--tw-loader-warm);
|
|
box-shadow: 0 0 18px rgba(244, 193, 93, 0.76);
|
|
opacity: 0.9;
|
|
}
|
|
|
|
.tw-bootstrap-loader__spark--one {
|
|
top: 1rem;
|
|
right: 1.3rem;
|
|
animation: tw-bootstrap-loader-spark 2.6s ease-in-out var(--tw-loader-spark-one-delay, 0ms) infinite;
|
|
}
|
|
|
|
.tw-bootstrap-loader__spark--two {
|
|
bottom: 1.4rem;
|
|
left: 1rem;
|
|
animation: tw-bootstrap-loader-spark 2.6s ease-in-out var(--tw-loader-spark-two-delay, 0.65s) infinite;
|
|
}
|
|
|
|
.tw-bootstrap-loader__status {
|
|
margin: 0;
|
|
color: var(--tw-loader-foam);
|
|
font-size: 1.2rem;
|
|
font-weight: 800;
|
|
letter-spacing: 0;
|
|
line-height: 1.25;
|
|
}
|
|
|
|
.tw-bootstrap-loader__hint {
|
|
max-width: 18rem;
|
|
margin: 0.55rem 0 0;
|
|
color: rgba(248, 251, 255, 0.72);
|
|
font-size: 0.9rem;
|
|
line-height: 1.45;
|
|
}
|
|
|
|
.tw-bootstrap-loader__dots {
|
|
display: inline-flex;
|
|
gap: 0.45rem;
|
|
height: 0.6rem;
|
|
margin-top: 1.35rem;
|
|
align-items: center;
|
|
}
|
|
|
|
.tw-bootstrap-loader__dots span {
|
|
display: block;
|
|
width: 0.42rem;
|
|
height: 0.42rem;
|
|
border-radius: 50%;
|
|
background: var(--tw-loader-cyan);
|
|
animation: tw-bootstrap-loader-dot 1.35s ease-in-out var(--tw-loader-dot-one-delay, 0ms) infinite;
|
|
}
|
|
|
|
.tw-bootstrap-loader__dots span:nth-child(2) {
|
|
animation-delay: var(--tw-loader-dot-two-delay, 0.18s);
|
|
}
|
|
|
|
.tw-bootstrap-loader__dots span:nth-child(3) {
|
|
animation-delay: var(--tw-loader-dot-three-delay, 0.36s);
|
|
}
|
|
|
|
@keyframes tw-bootstrap-loader-spin {
|
|
to {
|
|
transform: rotate(360deg);
|
|
}
|
|
}
|
|
|
|
@keyframes tw-bootstrap-loader-sweep {
|
|
0%,
|
|
100% {
|
|
opacity: 0.6;
|
|
transform: translateX(-0.65rem) rotate(-12deg);
|
|
}
|
|
50% {
|
|
opacity: 1;
|
|
transform: translateX(0.65rem) rotate(-12deg);
|
|
}
|
|
}
|
|
|
|
@keyframes tw-bootstrap-loader-pulse {
|
|
0%,
|
|
100% {
|
|
opacity: 0.7;
|
|
transform: scale(0.94);
|
|
}
|
|
50% {
|
|
opacity: 1;
|
|
transform: scale(1);
|
|
}
|
|
}
|
|
|
|
@keyframes tw-bootstrap-loader-spark {
|
|
0%,
|
|
100% {
|
|
opacity: 0.35;
|
|
transform: scale(0.7);
|
|
}
|
|
45% {
|
|
opacity: 1;
|
|
transform: scale(1);
|
|
}
|
|
}
|
|
|
|
@keyframes tw-bootstrap-loader-dot {
|
|
0%,
|
|
100% {
|
|
opacity: 0.35;
|
|
transform: translateY(0);
|
|
}
|
|
45% {
|
|
opacity: 1;
|
|
transform: translateY(-0.25rem);
|
|
}
|
|
}
|
|
|
|
@keyframes tw-bootstrap-loader-wash {
|
|
0%,
|
|
100% {
|
|
opacity: 0.42;
|
|
transform: translateX(-54%) rotate(-9deg);
|
|
}
|
|
50% {
|
|
opacity: 0.72;
|
|
transform: translateX(-46%) rotate(-9deg);
|
|
}
|
|
}
|
|
|
|
@media screen and (max-width: 480px) {
|
|
.tw-bootstrap-loader {
|
|
padding: 1rem;
|
|
}
|
|
|
|
.tw-bootstrap-loader__panel {
|
|
min-height: 25rem;
|
|
padding: 2rem 1.4rem;
|
|
}
|
|
|
|
.tw-bootstrap-loader__brand {
|
|
width: 11.5rem;
|
|
margin-bottom: 1.8rem;
|
|
}
|
|
|
|
.tw-bootstrap-loader__motion {
|
|
width: 7.25rem;
|
|
height: 7.25rem;
|
|
margin-bottom: 1.75rem;
|
|
}
|
|
|
|
.tw-bootstrap-loader__status {
|
|
font-size: 1.1rem;
|
|
}
|
|
}
|
|
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.tw-bootstrap-loader *,
|
|
.tw-bootstrap-loader *::before,
|
|
.tw-bootstrap-loader *::after {
|
|
animation-duration: 0.001ms !important;
|
|
animation-iteration-count: 1 !important;
|
|
transition-duration: 0.001ms !important;
|
|
}
|
|
|
|
.tw-bootstrap-loader__sweep {
|
|
opacity: 0.95;
|
|
transform: rotate(-12deg);
|
|
}
|
|
|
|
.tw-bootstrap-loader__dots span {
|
|
opacity: 0.75;
|
|
transform: none;
|
|
}
|
|
}
|
|
</style>
|
|
</head>
|
|
<body class="tw-bootstrap-loading">
|
|
<div id="app">
|
|
<div
|
|
class="tw-bootstrap-loader"
|
|
data-testid="app-bootstrap-loading"
|
|
role="status"
|
|
aria-live="polite"
|
|
aria-label="Indlæser Truck Wash kundeportal"
|
|
>
|
|
<div class="tw-bootstrap-loader__ambient" aria-hidden="true">
|
|
<span class="tw-bootstrap-loader__wash tw-bootstrap-loader__wash--wide"></span>
|
|
<span class="tw-bootstrap-loader__wash tw-bootstrap-loader__wash--tight"></span>
|
|
</div>
|
|
<div class="tw-bootstrap-loader__panel">
|
|
<div class="tw-bootstrap-loader__brand">
|
|
<img
|
|
src="%BASE_URL%assets/branding/truckwash-banner-white-compressed.png"
|
|
alt="Truck Wash"
|
|
class="tw-bootstrap-loader__logo"
|
|
/>
|
|
</div>
|
|
<div class="tw-bootstrap-loader__motion" aria-hidden="true">
|
|
<span class="tw-bootstrap-loader__ring"></span>
|
|
<span class="tw-bootstrap-loader__sweep"></span>
|
|
<span class="tw-bootstrap-loader__spark tw-bootstrap-loader__spark--one"></span>
|
|
<span class="tw-bootstrap-loader__spark tw-bootstrap-loader__spark--two"></span>
|
|
</div>
|
|
<p class="tw-bootstrap-loader__status" data-testid="app-bootstrap-loading-status">Indlæser...</p>
|
|
<p class="tw-bootstrap-loader__hint">Vi gør kundeportalen klar</p>
|
|
<div class="tw-bootstrap-loader__dots" aria-hidden="true">
|
|
<span></span>
|
|
<span></span>
|
|
<span></span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<script>
|
|
(function () {
|
|
var appPath = window.location.pathname.replace(/^\/[^/]+\/frontend(?=\/|$)/, '') || '/';
|
|
var hasStoredSession;
|
|
try {
|
|
hasStoredSession = Boolean(window.localStorage && window.localStorage.getItem('token'));
|
|
} catch (error) {
|
|
hasStoredSession = false;
|
|
}
|
|
var usesProtectedSessionLoader = /^\/(?:user|admin|superuser|backoffice)(?:\/|$)/.test(appPath);
|
|
var usesGuestSessionLoader = /^\/(?:$|login(?:\/driver|\/qr)?$|admin\/login$|register$|auth\/password-reset(?:\/|$)|qr\/new-(?:customer|driver)$)/.test(appPath);
|
|
var usesSessionLoader = usesProtectedSessionLoader || (hasStoredSession && usesGuestSessionLoader);
|
|
if (!usesSessionLoader) return;
|
|
|
|
var loader = document.querySelector('[data-testid="app-bootstrap-loading"]');
|
|
var status = document.querySelector('[data-testid="app-bootstrap-loading-status"]');
|
|
var hint = loader ? loader.querySelector('.tw-bootstrap-loader__hint') : null;
|
|
if (loader) loader.setAttribute('aria-label', 'Bekræfter bruger');
|
|
if (status) status.textContent = 'Bekræfter bruger...';
|
|
if (hint) hint.textContent = 'Vi indlæser din session';
|
|
})();
|
|
</script>
|
|
<script type="module" src="/src/releaseBootstrap.js"></script>
|
|
</body>
|
|
</html>
|