Zaloguj się
{ const data = await res.json(); if (!res.ok) { window.dispatchEvent(new CustomEvent('toast', { detail: { message: data?.error || data?.detail || 'Błąd zmiany hasła', type: 'error' } })); return; } window.dispatchEvent(new CustomEvent('toast', { detail: 'Hasło zmienione pomyślnie', type: 'success' })); window.location.href = '/internal/dashboard/'; }) .catch(() => { window.dispatchEvent(new CustomEvent('toast', { detail: { message: 'Błąd sieci przy zmianie hasła', type: 'error' } })); }); ">
Stare hasło
Nowe hasło
Powtórz nowe hasło
Zmień hasło
{ if (!res.ok) { await showErrorToastFromResponse(res, 'Błąd logowania'); return; } const data = await res.json(); if (data.mfa_required) { mfaRequired = true; methods = data.mfa_methods; if (!hasLocalPasskey) { methods = methods.filter(m => m !== 'fido'); } method = methods.includes('fido') ? 'fido' : data.default_method || methods[0]; otpSent = false; totpQR = data.totp_qr || ''; totpConfigured = !!data.totp_configured; window.dispatchEvent(new CustomEvent('toast', { detail: 'Wymagana weryfikacja MFA', type: 'info' })); } else { window.dispatchEvent(new CustomEvent('toast', { detail: 'Zalogowano!', type: 'success' })); showPasskeyPrompt = false; } }) .catch(() => { window.dispatchEvent(new CustomEvent('toast', { detail: { message: 'Błąd sieci lub nieznany wyjątek', type: 'error' } })); }); ">
Email
Hasło
Zaloguj się
Resetuj hasło
📲 Zeskanuj kod QR w aplikacji TOTP:
{ otpSent = true; window.dispatchEvent(new CustomEvent('toast', { detail: 'Kod OTP wysłany', type: 'info' })); }).catch(() => { window.dispatchEvent(new CustomEvent('toast', { detail: 'Błąd przy wysyłce OTP', type: 'error' })); }); "> Wyślij kod na
{ const data = await res.json(); if (!res.ok) { window.dispatchEvent(new CustomEvent('toast', { detail: { message: data?.error || 'Nieprawidłowy kod', type: 'error' } })); return; } if (data.token) { localStorage.setItem('token', data.token); if (data.password_expired) { changePasswordRequired = true; return; } changePasswordRequired = false; const hasFidoInMethods = methods.includes('fido'); if (hasLocalPasskey || !hasFidoInMethods) { showPasskeyPrompt = true; } else { window.location.href = '/internal/dashboard/'; } } }) .catch(() => { window.dispatchEvent(new CustomEvent('toast', { detail: { message: 'Błąd połączenia przy walidacji OTP', type: 'error' } })); }); ">
Kod OTP
Potwierdź
{ const data = await res.json(); if (!res.ok) { window.dispatchEvent(new CustomEvent('toast', { detail: { message: data?.error || 'Nieprawidłowy kod', type: 'error' } })); return; } if (data.token) { localStorage.setItem('token', data.token); if (data.password_expired) { changePasswordRequired = true; return; } const hasFidoInMethods = methods.includes('fido'); if (hasLocalPasskey || !hasFidoInMethods) { showPasskeyPrompt = true; } else { window.location.href = '/internal/dashboard/'; } } }) .catch(() => { window.dispatchEvent(new CustomEvent('toast', { detail: { message: 'Błąd połączenia z serwerem przy weryfikacji kodu', type: 'error' } })); }); ">
Kod z aplikacji
Zatwierdź kod
res.json()) .then(async options => { const publicKey = { ...options, challenge: base64urlToBuffer(options.challenge), allowCredentials: options.allowCredentials?.map(cred => ({ ...cred, id: base64urlToBuffer(cred.id) })) }; const cred = await navigator.credentials.get({ publicKey }); const credential = { id: cred.id, rawId: bufferToBase64Url(cred.rawId), type: cred.type, response: { authenticatorData: bufferToBase64Url(cred.response.authenticatorData), clientDataJSON: bufferToBase64Url(cred.response.clientDataJSON), signature: bufferToBase64Url(cred.response.signature), userHandle: cred.response.userHandle ? bufferToBase64Url(cred.response.userHandle) : null } }; return fetch('/internal/auth/api/mfa/passkey/login/verify/', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRFToken': getCookie('csrftoken') }, body: JSON.stringify(credential) }); }) .then(async res => { const data = await res.json(); if (res.status === 403 && data?.error?.includes('Hasło')) { localStorage.setItem('token', data.token); changePasswordRequired = true; return; } if (!res.ok) throw new Error(data.detail || data.error || 'Błąd logowania'); localStorage.setItem('token', data.token); window.location.href = '/internal/dashboard/'; }) .catch(err => { window.dispatchEvent(new CustomEvent('toast', { detail: { message: err.message || 'Błąd WebAuthn', type: 'error' } })); }); ">🔐 Zaloguj przez Passkey
🔐 Chcesz dodać
Passkey
(klucz bezpieczeństwa)?
res.json()) .then(async options => { const publicKey = { ...options, challenge: base64urlToBuffer(options.challenge), user: { ...options.user, id: base64urlToBuffer(options.user.id) } }; const cred = await navigator.credentials.create({ publicKey }); const credential = { id: cred.id, rawId: btoa(String.fromCharCode(...new Uint8Array(cred.rawId))), type: cred.type, response: { attestationObject: btoa(String.fromCharCode(...new Uint8Array(cred.response.attestationObject))), clientDataJSON: btoa(String.fromCharCode(...new Uint8Array(cred.response.clientDataJSON))) } }; return fetch('/internal/auth/api/mfa/passkey/register/verify/', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRFToken': getCookie('csrftoken') }, body: JSON.stringify(credential) }); }) .then(() => { window.dispatchEvent(new CustomEvent('toast', { detail: 'Passkey dodany!', type: 'success' })); window.location.href = '/internal/dashboard/'; }) .catch(err => { window.dispatchEvent(new CustomEvent('toast', { detail: { message: err.message || 'Błąd rejestracji Passkey', type: 'error' } })); window.location.href = '/internal/dashboard/'; }); ">Tak, dodaj
Pomiń
✅
❌
⚠️
ℹ️
Potwierdź wylogowanie
Czy na pewno chcesz się wylogować?