Portal: Mitarbeiter-Login gesperrt (Hinweis aufs Ticketsystem), alte Mitarbeiter-Sitzungen enden
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
d0ca3c41cd
commit
3a4fa581c0
13 files changed
+145
-559
No files matched your search
+14
-75
@@ -17,6 +17,8 @@ async function api(path, options = {}) {
|
||||
err.status = response.status
|
||||
if (data.code) err.code = data.code
|
||||
if (data.retryAfterSeconds) err.retryAfterSeconds = data.retryAfterSeconds
|
||||
// Mitarbeiter-Login gesperrt: Adresse des Ticketsystems fuer den Link unter dem Hinweis
|
||||
if (data.ticketUrl) err.ticketUrl = data.ticketUrl
|
||||
// Passwort auf einem anderen Gerät geändert: diese Sitzung gilt nicht mehr
|
||||
if (data.code === 'session_revoked' && document.body.classList.contains('dashboard-page') && !sessionEndRedirected) {
|
||||
sessionEndRedirected = true
|
||||
@@ -473,17 +475,12 @@ async function postLoginRedirect() {
|
||||
window.location.href = await resolvePostLoginTarget()
|
||||
}
|
||||
|
||||
// Links aus Admin-Mails (z. B. /admin.html?gutschrift=<id>) nach dem Login wieder aufnehmen
|
||||
function adminLoginTarget() {
|
||||
const next = getQueryParam('next')
|
||||
return /^\/admin\.html(\?[A-Za-z0-9=&_-]*)?$/.test(next) ? next : '/admin.html'
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------- Login-Page --- */
|
||||
async function initLoginPage() {
|
||||
const form = document.getElementById('login-form')
|
||||
const errorEl = document.getElementById('login-error')
|
||||
const btn = document.getElementById('login-btn')
|
||||
const staffLink = document.getElementById('login-staff-link')
|
||||
|
||||
const errorFromQuery = getQueryParam('error')
|
||||
if (errorFromQuery) {
|
||||
@@ -523,11 +520,8 @@ async function initLoginPage() {
|
||||
}
|
||||
|
||||
try {
|
||||
// Alte Mitarbeiter-Sitzung beendet /me selbst (reason staff): dann bleibt die Anmeldeseite stehen
|
||||
const me = await api('/api/auth/me')
|
||||
if (me.authenticated && me.role === 'admin' && !me.viewAs) {
|
||||
window.location.href = adminLoginTarget()
|
||||
return
|
||||
}
|
||||
if (me.authenticated && me.customer) {
|
||||
await postLoginRedirect()
|
||||
return
|
||||
@@ -540,6 +534,7 @@ async function initLoginPage() {
|
||||
e.preventDefault()
|
||||
if (btn.disabled) return
|
||||
errorEl.classList.add('hidden')
|
||||
staffLink?.classList.add('hidden')
|
||||
btn.disabled = true
|
||||
btn.classList.add('is-loading')
|
||||
btn.setAttribute('aria-busy', 'true')
|
||||
@@ -552,18 +547,14 @@ async function initLoginPage() {
|
||||
password: document.getElementById('password').value,
|
||||
}),
|
||||
})
|
||||
if (result.mfaRequired) {
|
||||
showMfaStep(result.email)
|
||||
return
|
||||
}
|
||||
if (result.role === 'admin') {
|
||||
window.location.href = adminLoginTarget()
|
||||
return
|
||||
}
|
||||
await postLoginRedirect()
|
||||
return
|
||||
} catch (err) {
|
||||
showError(errorEl, err.message)
|
||||
if (err.ticketUrl && staffLink) {
|
||||
staffLink.href = err.ticketUrl
|
||||
staffLink.classList.remove('hidden')
|
||||
}
|
||||
if (err.status === 429) {
|
||||
cooldownActive = true
|
||||
await applyCooldown(err.retryAfterSeconds || 900)
|
||||
@@ -576,59 +567,6 @@ async function initLoginPage() {
|
||||
})
|
||||
}
|
||||
|
||||
/* Mitarbeiter-2FA: Code aus der E-Mail (POST /api/auth/login/mfa) */
|
||||
function showMfaStep(maskedEmail) {
|
||||
const loginForm = document.getElementById('login-form')
|
||||
const form = document.getElementById('mfa-form')
|
||||
const input = document.getElementById('mfa-code')
|
||||
const errorEl = document.getElementById('mfa-error')
|
||||
const btn = document.getElementById('mfa-btn')
|
||||
const resend = document.getElementById('mfa-resend')
|
||||
loginForm?.classList.add('hidden')
|
||||
form?.classList.remove('hidden')
|
||||
document.getElementById('mfa-hint').textContent = `Wir haben dir einen Code an ${maskedEmail} geschickt.`
|
||||
input?.focus()
|
||||
|
||||
form?.addEventListener('submit', async (e) => {
|
||||
e.preventDefault()
|
||||
if (btn.disabled) return
|
||||
hideError(errorEl)
|
||||
btn.disabled = true
|
||||
btn.classList.add('is-loading')
|
||||
try {
|
||||
await api('/api/auth/login/mfa', { method: 'POST', body: JSON.stringify({ otp: input.value.trim() }) })
|
||||
window.location.href = adminLoginTarget()
|
||||
} catch (err) {
|
||||
if (err.status === 410) {
|
||||
window.location.href = `/login.html?error=${encodeURIComponent(err.message)}`
|
||||
return
|
||||
}
|
||||
showError(errorEl, err.message)
|
||||
input.select()
|
||||
} finally {
|
||||
btn.disabled = false
|
||||
btn.classList.remove('is-loading')
|
||||
}
|
||||
})
|
||||
|
||||
resend?.addEventListener('click', async () => {
|
||||
hideError(errorEl)
|
||||
resend.disabled = true
|
||||
try {
|
||||
await api('/api/auth/login/mfa/resend', { method: 'POST' })
|
||||
document.getElementById('mfa-hint').textContent = `Neuer Code ist unterwegs an ${maskedEmail}.`
|
||||
} catch (err) {
|
||||
if (err.status === 410) {
|
||||
window.location.href = `/login.html?error=${encodeURIComponent(err.message)}`
|
||||
return
|
||||
}
|
||||
showError(errorEl, err.message)
|
||||
} finally {
|
||||
resend.disabled = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------- View-as --- */
|
||||
function renderViewAsBanner(me) {
|
||||
const banner = document.getElementById('viewas-banner')
|
||||
@@ -2088,16 +2026,17 @@ async function initDashboardPage() {
|
||||
const me = await api('/api/auth/me')
|
||||
|
||||
if (!me.authenticated) {
|
||||
// Alte Mitarbeiter-Sitzung (Mitarbeiter arbeiten im Ticketsystem): dorthin weiter
|
||||
if (me.reason === 'staff' && me.redirect) {
|
||||
window.location.href = me.redirect
|
||||
return
|
||||
}
|
||||
const target = new URL(loginUrl, window.location.origin)
|
||||
// Passwort auf einem anderen Gerät geändert oder Kundenansicht abgelaufen: Hinweis auf der Anmeldeseite
|
||||
if ((me.reason === 'password_changed' || me.reason === 'view_expired') && me.message) target.searchParams.set('error', me.message)
|
||||
window.location.href = target.pathname + target.search
|
||||
return
|
||||
}
|
||||
if (me.role === 'admin' && !me.customer) {
|
||||
window.location.href = '/admin.html'
|
||||
return
|
||||
}
|
||||
if (!me.customer) {
|
||||
window.location.href = loginUrl
|
||||
return
|
||||
|
||||
Reference in new issue
Block a user