fix 4
This commit is contained in:
@@ -6,7 +6,10 @@ async function api(path, options = {}) {
|
||||
})
|
||||
const data = await response.json().catch(() => ({}))
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error || `Fehler ${response.status}`)
|
||||
const err = new Error(data.error || `Fehler ${response.status}`)
|
||||
err.status = response.status
|
||||
if (data.retryAfterSeconds) err.retryAfterSeconds = data.retryAfterSeconds
|
||||
throw err
|
||||
}
|
||||
return data
|
||||
}
|
||||
@@ -64,9 +67,41 @@ async function initLoginPage() {
|
||||
const errorEl = document.getElementById('login-error')
|
||||
const btn = document.getElementById('login-btn')
|
||||
|
||||
async function applyCooldown(seconds) {
|
||||
if (seconds <= 0) return
|
||||
showError(
|
||||
errorEl,
|
||||
`Zu viele Anmeldeversuche. Bitte warte noch ${seconds} Sekunden (ca. ${Math.ceil(seconds / 60)} Min.).`
|
||||
)
|
||||
btn.disabled = true
|
||||
const tick = setInterval(async () => {
|
||||
const status = await fetch('/api/auth/login-status').then((r) => r.json()).catch(() => ({}))
|
||||
const left = status.retryAfterSeconds || 0
|
||||
if (left <= 0) {
|
||||
clearInterval(tick)
|
||||
hideError(errorEl)
|
||||
btn.disabled = false
|
||||
return
|
||||
}
|
||||
showError(
|
||||
errorEl,
|
||||
`Zu viele Anmeldeversuche. Bitte warte noch ${left} Sekunden (ca. ${Math.ceil(left / 60)} Min.).`
|
||||
)
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
try {
|
||||
const status = await fetch('/api/auth/login-status').then((r) => r.json())
|
||||
if (status.blocked) {
|
||||
await applyCooldown(status.retryAfterSeconds)
|
||||
}
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
|
||||
try {
|
||||
const me = await api('/api/auth/me')
|
||||
if (me.customer) {
|
||||
if (me.authenticated && me.customer) {
|
||||
window.location.href = '/dashboard.html'
|
||||
return
|
||||
}
|
||||
@@ -76,8 +111,10 @@ async function initLoginPage() {
|
||||
|
||||
form?.addEventListener('submit', async (e) => {
|
||||
e.preventDefault()
|
||||
if (btn.disabled) return
|
||||
errorEl.classList.add('hidden')
|
||||
btn.disabled = true
|
||||
let cooldownActive = false
|
||||
try {
|
||||
await api('/api/auth/login', {
|
||||
method: 'POST',
|
||||
@@ -87,10 +124,15 @@ async function initLoginPage() {
|
||||
}),
|
||||
})
|
||||
window.location.href = '/dashboard.html'
|
||||
return
|
||||
} catch (err) {
|
||||
showError(errorEl, err.message)
|
||||
if (err.status === 429) {
|
||||
cooldownActive = true
|
||||
await applyCooldown(err.retryAfterSeconds || 900)
|
||||
}
|
||||
} finally {
|
||||
btn.disabled = false
|
||||
if (!cooldownActive) btn.disabled = false
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -109,12 +151,17 @@ async function initDashboardPage() {
|
||||
})
|
||||
|
||||
try {
|
||||
const [{ customer }, { projects }, { features }] = await Promise.all([
|
||||
const [{ authenticated, customer }, { projects }, { features }] = await Promise.all([
|
||||
api('/api/auth/me'),
|
||||
api('/api/projects'),
|
||||
api('/api/features'),
|
||||
])
|
||||
|
||||
if (!authenticated || !customer) {
|
||||
window.location.href = '/login.html'
|
||||
return
|
||||
}
|
||||
|
||||
meta.textContent = customer.name ? `${customer.name} (${customer.email})` : customer.email
|
||||
loading.classList.add('hidden')
|
||||
|
||||
|
||||
Reference in New Issue
Block a user