@micha.bigler/ui-core-micha 1.3.2 → 1.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -373,30 +373,32 @@ export async function authenticateWithMFA({ code, credential }) {
373
373
  // Authentication: password (MODIFIZIERT)
374
374
  // -----------------------------
375
375
  export async function loginWithPassword(email, password) {
376
- var _a;
376
+ var _a, _b;
377
377
  try {
378
378
  await axios.post(`${HEADLESS_BASE}/auth/login`, { email, password }, { withCredentials: true });
379
379
  }
380
380
  catch (error) {
381
- // SKEPTISCHER CHECK: Ist es der MFA-Flow?
382
- if (error.response &&
383
- error.response.status === 401 &&
384
- ((_a = error.response.data) === null || _a === void 0 ? void 0 : _a.flow) === 'mfa_authenticate') {
385
- // KEIN FEHLER! Wir geben zurück, dass MFA nötig ist.
381
+ const status = (_a = error.response) === null || _a === void 0 ? void 0 : _a.status;
382
+ const data = (_b = error.response) === null || _b === void 0 ? void 0 : _b.data;
383
+ // --- SKEPTISCHER CHECK: MFA NÖTIG? ---
384
+ // Wenn Allauth 401 mit flow="mfa_authenticate" sendet, ist das KEIN Fehler,
385
+ // sondern die Aufforderung für Schritt 2.
386
+ if (status === 401 && (data === null || data === void 0 ? void 0 : data.flow) === 'mfa_authenticate') {
386
387
  return {
387
388
  needsMfa: true,
388
- availableTypes: error.response.data.types || [], // z.B. ["webauthn", "totp"]
389
+ availableTypes: data.types || [], // z.B. ["webauthn", "totp"]
389
390
  };
390
391
  }
391
- // Bestehende Logik für "Already logged in"
392
- if (error.response && error.response.status === 409) {
393
- // continue to fetch user
392
+ // --- "Already Logged In" Handling ---
393
+ if (status === 409) {
394
+ // User ist schon eingeloggt, wir machen einfach weiter
394
395
  }
395
396
  else {
397
+ // Echter Fehler (z.B. falsches Passwort oder Serverfehler)
396
398
  throw new Error(extractErrorMessage(error));
397
399
  }
398
400
  }
399
- // Wenn wir hier landen, war kein MFA nötig oder wir waren schon eingeloggt
401
+ // Wenn wir hier landen, war der Login direkt erfolgreich (kein MFA)
400
402
  const user = await fetchCurrentUser();
401
403
  return { user, needsMfa: false };
402
404
  }
@@ -76,7 +76,25 @@ export function LoginPage() {
76
76
  };
77
77
  // ... (Social & Sign Up Handler bleiben gleich) ...
78
78
  const handleSocialLogin = (provider) => authApi.startSocialLogin(provider);
79
- const handlePasskeyLoginInitial = async () => { };
79
+ const handlePasskeyLoginInitial = async () => {
80
+ var _a, _b;
81
+ setError('');
82
+ setSubmitting(true);
83
+ try {
84
+ // Wir rufen die existierende Passkey-Login Funktion auf
85
+ const { user } = await authApi.loginWithPasskey();
86
+ login(user);
87
+ navigate('/');
88
+ }
89
+ catch (err) {
90
+ setError(((_b = (_a = err === null || err === void 0 ? void 0 : err.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.detail) ||
91
+ (err === null || err === void 0 ? void 0 : err.message) ||
92
+ 'Passkey login failed.');
93
+ }
94
+ finally {
95
+ setSubmitting(false);
96
+ }
97
+ };
80
98
  const handleSignUp = () => navigate('/signup');
81
99
  const handleForgotPassword = () => navigate('/reset-request-password');
82
100
  return (_jsxs(NarrowPage, { title: "Login", children: [_jsx(Helmet, { children: _jsx("title", { children: "Login" }) }), error && _jsx(Alert, { severity: "error", sx: { mb: 2 }, children: error }), step === 'credentials' && (_jsx(LoginForm, { onSubmit: handleSubmitCredentials, onForgotPassword: handleForgotPassword, onSocialLogin: handleSocialLogin, onPasskeyLogin: handlePasskeyLoginInitial, onSignUp: handleSignUp, disabled: submitting })), step === 'mfa' && (_jsxs(Box, { children: [_jsx(Typography, { variant: "body1", gutterBottom: true, children: "Two-Factor Authentication required." }), _jsxs(Stack, { spacing: 2, sx: { mt: 2 }, children: [mfaTypes.includes('webauthn') && (_jsx(Button, { variant: "outlined", onClick: handleMfaPasskey, fullWidth: true, children: "Use Passkey / Security Key" })), (mfaTypes.includes('totp') || mfaTypes.includes('recovery_codes')) && (_jsxs("form", { onSubmit: handleMfaTotpSubmit, children: [_jsx(TextField, { label: "Authenticator Code (or Recovery Code)", value: totpCode, onChange: (e) => setTotpCode(e.target.value), fullWidth: true, autoFocus: true, disabled: submitting, sx: { mb: 2 } }), _jsx(Button, { type: "submit", variant: "contained", fullWidth: true, disabled: submitting, children: "Verify" })] })), _jsx(Button, { size: "small", onClick: () => setStep('credentials'), children: "Back to Login" })] })] }))] }));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@micha.bigler/ui-core-micha",
3
- "version": "1.3.2",
3
+ "version": "1.3.4",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.js",
6
6
  "private": false,
@@ -489,31 +489,32 @@ export async function loginWithPassword(email, password) {
489
489
  await axios.post(
490
490
  `${HEADLESS_BASE}/auth/login`,
491
491
  { email, password },
492
- { withCredentials: true }
492
+ { withCredentials: true },
493
493
  );
494
494
  } catch (error) {
495
- // SKEPTISCHER CHECK: Ist es der MFA-Flow?
496
- if (
497
- error.response &&
498
- error.response.status === 401 &&
499
- error.response.data?.flow === 'mfa_authenticate'
500
- ) {
501
- // KEIN FEHLER! Wir geben zurück, dass MFA nötig ist.
495
+ const status = error.response?.status;
496
+ const data = error.response?.data;
497
+
498
+ // --- SKEPTISCHER CHECK: MFA NÖTIG? ---
499
+ // Wenn Allauth 401 mit flow="mfa_authenticate" sendet, ist das KEIN Fehler,
500
+ // sondern die Aufforderung für Schritt 2.
501
+ if (status === 401 && data?.flow === 'mfa_authenticate') {
502
502
  return {
503
503
  needsMfa: true,
504
- availableTypes: error.response.data.types || [], // z.B. ["webauthn", "totp"]
504
+ availableTypes: data.types || [], // z.B. ["webauthn", "totp"]
505
505
  };
506
506
  }
507
-
508
- // Bestehende Logik für "Already logged in"
509
- if (error.response && error.response.status === 409) {
510
- // continue to fetch user
507
+
508
+ // --- "Already Logged In" Handling ---
509
+ if (status === 409) {
510
+ // User ist schon eingeloggt, wir machen einfach weiter
511
511
  } else {
512
- throw new Error(extractErrorMessage(error));
512
+ // Echter Fehler (z.B. falsches Passwort oder Serverfehler)
513
+ throw new Error(extractErrorMessage(error));
513
514
  }
514
515
  }
515
516
 
516
- // Wenn wir hier landen, war kein MFA nötig oder wir waren schon eingeloggt
517
+ // Wenn wir hier landen, war der Login direkt erfolgreich (kein MFA)
517
518
  const user = await fetchCurrentUser();
518
519
  return { user, needsMfa: false };
519
520
  }
@@ -77,7 +77,24 @@ export function LoginPage() {
77
77
 
78
78
  // ... (Social & Sign Up Handler bleiben gleich) ...
79
79
  const handleSocialLogin = (provider) => authApi.startSocialLogin(provider);
80
- const handlePasskeyLoginInitial = async () => { /* wie gehabt für Step 1 */ };
80
+ const handlePasskeyLoginInitial = async () => {
81
+ setError('');
82
+ setSubmitting(true);
83
+ try {
84
+ // Wir rufen die existierende Passkey-Login Funktion auf
85
+ const { user } = await authApi.loginWithPasskey();
86
+ login(user);
87
+ navigate('/');
88
+ } catch (err) {
89
+ setError(
90
+ err?.response?.data?.detail ||
91
+ err?.message ||
92
+ 'Passkey login failed.',
93
+ );
94
+ } finally {
95
+ setSubmitting(false);
96
+ }
97
+ };
81
98
  const handleSignUp = () => navigate('/signup');
82
99
  const handleForgotPassword = () => navigate('/reset-request-password');
83
100