@micha.bigler/ui-core-micha 1.4.8 → 1.4.10

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.
@@ -18,6 +18,6 @@ disabled = false, }) => {
18
18
  const supportsPasskey = !!onPasskeyLogin &&
19
19
  typeof window !== 'undefined' &&
20
20
  !!window.PublicKeyCredential;
21
- return (_jsxs(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 3 }, children: [error && (_jsx(Typography, { color: "error", gutterBottom: true, children: error })), supportsPasskey && (_jsxs(_Fragment, { children: [_jsx(Button, { variant: "contained", fullWidth: true, type: "button", onClick: onPasskeyLogin, disabled: disabled, children: t('Auth.LOGIN_USE_PASSKEY_BUTTON') }), _jsx(Divider, { sx: { my: 2 }, children: t('Auth.LOGIN_OR') })] })), _jsxs(Box, { component: "form", onSubmit: handleSubmit, sx: { display: 'flex', flexDirection: 'column', gap: 2 }, children: [_jsx(TextField, { label: t('Auth.EMAIL_LABEL'), type: "email", required: true, fullWidth: true, value: identifier, onChange: (e) => setIdentifier(e.target.value), disabled: disabled }), _jsx(TextField, { label: t('Auth.LOGIN_PASSWORD_LABEL'), type: "password", required: true, fullWidth: true, value: password, onChange: (e) => setPassword(e.target.value), disabled: disabled }), _jsx(Button, { type: "submit", variant: "contained", fullWidth: true, disabled: disabled, children: t('Auth.LOGIN_SUBMIT') })] }), _jsxs(Box, { children: [_jsx(Divider, { sx: { my: 2 }, children: t('Auth.LOGIN_OR') }), _jsx(SocialLoginButtons, { onProviderClick: onSocialLogin })] }), _jsxs(Box, { children: [_jsx(Typography, { variant: "subtitle2", sx: { mb: 1 }, children: t('Auth.LOGIN_ACCOUNT_RECOVERY_TITLE') }), _jsxs(Box, { sx: { display: 'flex', gap: 1, flexWrap: 'wrap' }, children: [onSignUp && (_jsx(Button, { type: "button", variant: "outlined", onClick: onSignUp, disabled: disabled, children: t('Auth.LOGIN_SIGNUP_BUTTON') })), _jsx(Button, { type: "button", variant: "outlined", onClick: onForgotPassword, disabled: disabled, children: t('Auth.LOGIN_FORGOT_PASSWORD_BUTTON') })] })] })] }));
21
+ return (_jsxs(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 3 }, children: [error && (_jsx(Typography, { color: "error", gutterBottom: true, children: error })), supportsPasskey && (_jsxs(_Fragment, { children: [_jsx(Button, { variant: "contained", fullWidth: true, type: "button", onClick: onPasskeyLogin, disabled: disabled, children: t('Auth.LOGIN_USE_PASSKEY_BUTTON') }), _jsx(Divider, { sx: { my: 2 }, children: t('Auth.LOGIN_OR') })] })), _jsxs(Box, { component: "form", onSubmit: handleSubmit, sx: { display: 'flex', flexDirection: 'column', gap: 2 }, children: [_jsx(TextField, { label: t('Auth.EMAIL_LABEL'), type: "email", required: true, fullWidth: true, value: identifier, onChange: (e) => setIdentifier(e.target.value), disabled: disabled }), _jsx(TextField, { label: t('Auth.LOGIN_PASSWORD_LABEL'), type: "password", required: true, fullWidth: true, value: password, onChange: (e) => setPassword(e.target.value), disabled: disabled }), _jsx(Button, { type: "submit", variant: "contained", fullWidth: true, disabled: disabled, children: t('Auth.LOGIN_SUBMIT') })] }), _jsxs(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 3 }, children: [_jsx(Divider, { children: t('Auth.LOGIN_OR') }), _jsx(SocialLoginButtons, { onProviderClick: onSocialLogin })] }), _jsxs(Box, { children: [_jsx(Typography, { variant: "subtitle2", sx: { mb: 1 }, children: t('Auth.LOGIN_ACCOUNT_RECOVERY_TITLE') }), _jsxs(Box, { sx: { display: 'flex', gap: 1, flexWrap: 'wrap' }, children: [onSignUp && (_jsx(Button, { type: "button", variant: "outlined", onClick: onSignUp, disabled: disabled, children: t('Auth.LOGIN_SIGNUP_BUTTON') })), _jsx(Button, { type: "button", variant: "outlined", onClick: onForgotPassword, disabled: disabled, children: t('Auth.LOGIN_FORGOT_PASSWORD_BUTTON') })] })] })] }));
22
22
  };
23
23
  export default LoginForm;
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  // src/auth/components/MfaLoginComponent.jsx
3
3
  import React, { useState } from 'react';
4
- import { Box, Typography, TextField, Button, Stack, Alert, } from '@mui/material';
4
+ import { Box, Typography, TextField, Button, Stack, Alert, Divider, } from '@mui/material';
5
5
  import { useTranslation } from 'react-i18next';
6
6
  import { authApi } from '../auth/authApi';
7
7
  const MfaLoginComponent = ({ availableTypes, identifier, onSuccess, onCancel }) => {
@@ -67,6 +67,6 @@ const MfaLoginComponent = ({ availableTypes, identifier, onSuccess, onCancel })
67
67
  setSubmitting(false);
68
68
  }
69
69
  };
70
- return (_jsxs(Box, { children: [_jsx(Typography, { variant: "body2", sx: { mb: 2 }, children: t('Auth.MFA_SUBTITLE', 'Please confirm your login using one of the available methods.') }), errorKey && (_jsx(Alert, { severity: "error", sx: { mb: 2 }, children: t(errorKey) })), infoKey && (_jsx(Alert, { severity: "info", sx: { mb: 2 }, children: t(infoKey) })), _jsxs(Stack, { spacing: 2, children: [supportsWebauthn && (_jsx(Button, { variant: "contained", fullWidth: true, onClick: handlePasskey, disabled: submitting || helpRequested, children: t('Auth.MFA_USE_PASSKEY', 'Use passkey / security key') })), supportsTotpOrRecovery && (_jsxs(Box, { component: "form", onSubmit: handleSubmitCode, children: [_jsx(TextField, { label: t('Auth.MFA_CODE_LABEL', 'Authenticator code (or recovery code)'), value: code, onChange: (e) => setCode(e.target.value), fullWidth: true, disabled: submitting || helpRequested, autoComplete: "one-time-code", sx: { mb: 2 } }), _jsx(Button, { type: "submit", variant: "contained", fullWidth: true, disabled: submitting || !code.trim() || helpRequested, children: t('Auth.MFA_VERIFY', 'Verify') })] })), _jsxs(Stack, { direction: "row", spacing: 1, sx: { mt: 1 }, children: [_jsx(Button, { fullWidth: true, size: "small", variant: "outlined", onClick: onCancel, disabled: submitting, children: t('Auth.MFA_BACK_TO_LOGIN', 'Back to login') }), _jsx(Button, { fullWidth: true, size: "small", variant: "outlined", color: "secondary", onClick: handleNeedHelp, disabled: submitting || helpRequested, children: t('Auth.MFA_NEED_HELP', "I can't use any of these methods") })] })] })] }));
70
+ return (_jsxs(Box, { children: [_jsx(Typography, { variant: "body2", sx: { mb: 2 }, children: t('Auth.MFA_SUBTITLE', 'Please confirm your login using one of the available methods.') }), errorKey && (_jsx(Alert, { severity: "error", sx: { mb: 2 }, children: t(errorKey) })), infoKey && (_jsx(Alert, { severity: "info", sx: { mb: 2 }, children: t(infoKey) })), _jsxs(Stack, { spacing: 2, children: [supportsWebauthn && (_jsx(Button, { variant: "contained", fullWidth: true, onClick: handlePasskey, disabled: submitting || helpRequested, children: t('Auth.LOGIN_USE_PASSKEY_BUTTON', 'Use passkey / security key') })), _jsx(Divider, { sx: { my: 2 }, children: t('Auth.LOGIN_OR') }), supportsTotpOrRecovery && (_jsxs(Box, { component: "form", onSubmit: handleSubmitCode, children: [_jsx(TextField, { label: t('Auth.MFA_CODE_LABEL', 'Authenticator code (or recovery code)'), value: code, onChange: (e) => setCode(e.target.value), fullWidth: true, disabled: submitting || helpRequested, autoComplete: "one-time-code", sx: { mb: 2 } }), _jsx(Button, { type: "submit", variant: "contained", fullWidth: true, disabled: submitting || !code.trim() || helpRequested, children: t('Auth.MFA_VERIFY', 'Verify') })] })), _jsx(Divider, { sx: { my: 2 }, children: t('Auth.LOGIN_OR') }), _jsxs(Stack, { direction: "row", spacing: 1, sx: { mt: 1 }, children: [_jsx(Button, { fullWidth: true, size: "small", variant: "outlined", onClick: onCancel, disabled: submitting, children: t('Auth.MFA_BACK_TO_LOGIN', 'Back to login') }), _jsx(Button, { fullWidth: true, size: "small", variant: "outlined", color: "secondary", onClick: handleNeedHelp, disabled: submitting || helpRequested, children: t('Auth.MFA_NEED_HELP', "I can't use any of these methods") })] })] })] }));
71
71
  };
72
72
  export default MfaLoginComponent;
@@ -15,7 +15,7 @@ const SocialLoginButtons = ({ onProviderClick }) => {
15
15
  onProviderClick(provider);
16
16
  }
17
17
  };
18
- return (_jsxs(Stack, { spacing: 1.5, sx: { mt: 1 }, children: [_jsx(Button, { variant: "outlined", fullWidth: true, onClick: () => handleClick(SOCIAL_PROVIDERS.google), startIcon: _jsx(Box, { sx: {
18
+ return (_jsxs(Stack, { spacing: 1.5, children: [_jsx(Button, { variant: "outlined", fullWidth: true, onClick: () => handleClick(SOCIAL_PROVIDERS.google), startIcon: _jsx(Box, { sx: {
19
19
  width: 24,
20
20
  height: 24,
21
21
  borderRadius: '50%',
@@ -54,6 +54,6 @@ const SupportRecoveryRequestsTab = () => {
54
54
  }
55
55
  return (_jsxs(Box, { children: [_jsx(Typography, { variant: "h6", gutterBottom: true, children: t('Support.RECOVERY_REQUESTS_TITLE', 'Account recovery requests') }), _jsx(Typography, { variant: "body2", sx: { mb: 2 }, children: t('Support.RECOVERY_REQUESTS_DESCRIPTION', 'Users who cannot complete MFA can request support. You can send them a recovery link or reject the request after verification.') }), errorKey && (_jsx(Alert, { severity: "error", sx: { mb: 2 }, children: t(errorKey) })), _jsxs(Stack, { direction: "row", spacing: 2, sx: { mb: 2 }, children: [_jsx(Button, { variant: statusFilter === 'pending' ? 'contained' : 'outlined', size: "small", onClick: () => setStatusFilter('pending'), children: t('Support.RECOVERY_FILTER_PENDING', 'Open') }), _jsx(Button, { variant: statusFilter === 'approved' ? 'contained' : 'outlined', size: "small", onClick: () => setStatusFilter('approved'), children: t('Support.RECOVERY_FILTER_APPROVED', 'Approved') }), _jsx(Button, { variant: statusFilter === 'rejected' ? 'contained' : 'outlined', size: "small", onClick: () => setStatusFilter('rejected'), children: t('Support.RECOVERY_FILTER_REJECTED', 'Rejected') })] }), requests.length === 0 ? (_jsx(Typography, { variant: "body2", children: t('Support.RECOVERY_REQUESTS_EMPTY', 'No recovery requests for this filter.') })) : (_jsx(TableContainer, { component: Paper, children: _jsxs(Table, { size: "small", children: [_jsx(TableHead, { children: _jsxs(TableRow, { children: [_jsx(TableCell, { children: t('Support.RECOVERY_COL_CREATED', 'Created') }), _jsx(TableCell, { children: t('Support.RECOVERY_COL_USER', 'User') }), _jsx(TableCell, { children: t('Support.RECOVERY_COL_SUPPORT', 'Assigned support') }), _jsx(TableCell, { children: t('Support.RECOVERY_COL_STATUS', 'Status') }), _jsx(TableCell, { children: t('Support.RECOVERY_COL_ACTIONS', 'Actions') })] }) }), _jsx(TableBody, { children: requests.map((req) => (_jsxs(TableRow, { children: [_jsx(TableCell, { children: req.created_at
56
56
  ? new Date(req.created_at).toLocaleString()
57
- : '-' }), _jsx(TableCell, { children: req.user_email || req.user }), _jsx(TableCell, { children: req.support_email || '–' }), _jsx(TableCell, { children: req.status }), _jsx(TableCell, { children: _jsxs(Stack, { direction: "row", spacing: 1, children: [_jsx(Button, { variant: "contained", size: "small", onClick: () => handleSendRecoveryLink(req.id), disabled: req.status !== 'pending', children: t('Support.RECOVERY_ACTION_SEND_LINK', 'Send recovery link') }), _jsx(Button, { variant: "outlined", size: "small", color: "error", onClick: () => handleReject(req.id), disabled: req.status !== 'pending', children: t('Support.RECOVERY_ACTION_REJECT', 'Reject') })] }) })] }, req.id))) })] }) }))] }));
57
+ : '-' }), _jsx(TableCell, { children: req.user_email || req.user }), _jsx(TableCell, { children: req.status }), _jsx(TableCell, { children: _jsxs(Stack, { direction: "row", spacing: 1, children: [_jsx(Button, { variant: "contained", size: "small", onClick: () => handleSendRecoveryLink(req.id), disabled: req.status !== 'pending', children: t('Support.RECOVERY_ACTION_SEND_LINK', 'Send recovery link') }), _jsx(Button, { variant: "outlined", size: "small", color: "error", onClick: () => handleReject(req.id), disabled: req.status !== 'pending', children: t('Support.RECOVERY_ACTION_REJECT', 'Reject') })] }) })] }, req.id))) })] }) }))] }));
58
58
  };
59
59
  export default SupportRecoveryRequestsTab;
@@ -806,11 +806,6 @@ export const authTranslations = {
806
806
  "fr": "Votre connexion actuelle ne satisfait pas aux exigences de sécurité recommandées. Veuillez configurer un facteur de sécurité supplémentaire (clé d’accès ou application d’authentification) et générer des codes de récupération.",
807
807
  "en": "Your current sign-in does not meet the recommended security requirements. Please set up an additional security factor (passkey or authenticator app) and generate recovery codes."
808
808
  },
809
- "Auth.MFA_HELP_REQUESTED": {
810
- "de": "Wir haben deinen Support-Kontakt informiert. Du erhältst eine Rückmeldung, sobald deine Identität geprüft wurde.",
811
- "fr": "Nous avons informé votre contact de support. Vous recevrez une réponse dès que votre identité aura été vérifiée.",
812
- "en": "We have informed your support contact. You will hear back as soon as your identity has been verified."
813
- },
814
809
  "Auth.MFA_HELP_REQUEST_FAILED": {
815
810
  "de": "Die Support-Anfrage konnte nicht gesendet werden. Bitte versuche es später erneut oder kontaktiere den Support direkt.",
816
811
  "fr": "La demande d'assistance n'a pas pu être envoyée. Veuillez réessayer plus tard ou contacter le support directement.",
@@ -826,5 +821,15 @@ export const authTranslations = {
826
821
  "fr": "Récupération de compte",
827
822
  "en": "Account recovery"
828
823
  },
824
+ "Auth.MFA_IDENTIFIER_REQUIRED": {
825
+ "de": "E-Mail-Adresse oder Kennung ist erforderlich.",
826
+ "fr": "L’adresse e-mail ou l’identifiant est requis.",
827
+ "en": "Email address or identifier is required."
828
+ },
829
+ "Auth.MFA_HELP_REQUESTED": {
830
+ "de": "Falls dieses Konto existiert, wurde Ihre Anfrage dem Support weitergeleitet. Bitte kontaktiere den Support für weitere Hilfe.",
831
+ "fr": "Si ce compte existe, votre demande a été transmise au support. Veuillez contacter le support pour obtenir de l’aide supplémentaire.",
832
+ "en": "If this account exists, your request has been forwarded to support. Please contact support for further assistance."
833
+ },
829
834
  // ...
830
835
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@micha.bigler/ui-core-micha",
3
- "version": "1.4.8",
3
+ "version": "1.4.10",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.js",
6
6
  "private": false,
@@ -101,8 +101,8 @@ const LoginForm = ({
101
101
  </Box>
102
102
 
103
103
  {/* Other ways to sign in */}
104
- <Box>
105
- <Divider sx={{ my: 2 }}>
104
+ <Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
105
+ <Divider>
106
106
  {t('Auth.LOGIN_OR')}
107
107
  </Divider>
108
108
  <SocialLoginButtons onProviderClick={onSocialLogin} />
@@ -7,6 +7,7 @@ import {
7
7
  Button,
8
8
  Stack,
9
9
  Alert,
10
+ Divider,
10
11
  } from '@mui/material';
11
12
  import { useTranslation } from 'react-i18next';
12
13
  import { authApi } from '../auth/authApi';
@@ -106,10 +107,14 @@ const MfaLoginComponent = ({ availableTypes, identifier, onSuccess, onCancel })
106
107
  onClick={handlePasskey}
107
108
  disabled={submitting || helpRequested}
108
109
  >
109
- {t('Auth.MFA_USE_PASSKEY', 'Use passkey / security key')}
110
+ {t('Auth.LOGIN_USE_PASSKEY_BUTTON', 'Use passkey / security key')}
110
111
  </Button>
111
112
  )}
112
113
 
114
+ <Divider sx={{ my: 2 }}>
115
+ {t('Auth.LOGIN_OR')}
116
+ </Divider>
117
+
113
118
  {supportsTotpOrRecovery && (
114
119
  <Box component="form" onSubmit={handleSubmitCode}>
115
120
  <TextField
@@ -135,6 +140,10 @@ const MfaLoginComponent = ({ availableTypes, identifier, onSuccess, onCancel })
135
140
  </Box>
136
141
  )}
137
142
 
143
+ <Divider sx={{ my: 2 }}>
144
+ {t('Auth.LOGIN_OR')}
145
+ </Divider>
146
+
138
147
 
139
148
 
140
149
  <Stack direction="row" spacing={1} sx={{ mt: 1 }}>
@@ -18,7 +18,7 @@ const SocialLoginButtons = ({ onProviderClick }) => {
18
18
  };
19
19
 
20
20
  return (
21
- <Stack spacing={1.5} sx={{ mt: 1 }}>
21
+ <Stack spacing={1.5}>
22
22
  <Button
23
23
  variant="outlined"
24
24
  fullWidth
@@ -141,7 +141,6 @@ const SupportRecoveryRequestsTab = () => {
141
141
  : '-'}
142
142
  </TableCell>
143
143
  <TableCell>{req.user_email || req.user}</TableCell>
144
- <TableCell>{req.support_email || '–'}</TableCell>
145
144
  <TableCell>{req.status}</TableCell>
146
145
  <TableCell>
147
146
  <Stack direction="row" spacing={1}>
@@ -853,11 +853,6 @@ export const authTranslations = {
853
853
  "fr": "Votre connexion actuelle ne satisfait pas aux exigences de sécurité recommandées. Veuillez configurer un facteur de sécurité supplémentaire (clé d’accès ou application d’authentification) et générer des codes de récupération.",
854
854
  "en": "Your current sign-in does not meet the recommended security requirements. Please set up an additional security factor (passkey or authenticator app) and generate recovery codes."
855
855
  },
856
- "Auth.MFA_HELP_REQUESTED": {
857
- "de": "Wir haben deinen Support-Kontakt informiert. Du erhältst eine Rückmeldung, sobald deine Identität geprüft wurde.",
858
- "fr": "Nous avons informé votre contact de support. Vous recevrez une réponse dès que votre identité aura été vérifiée.",
859
- "en": "We have informed your support contact. You will hear back as soon as your identity has been verified."
860
- },
861
856
  "Auth.MFA_HELP_REQUEST_FAILED": {
862
857
  "de": "Die Support-Anfrage konnte nicht gesendet werden. Bitte versuche es später erneut oder kontaktiere den Support direkt.",
863
858
  "fr": "La demande d'assistance n'a pas pu être envoyée. Veuillez réessayer plus tard ou contacter le support directement.",
@@ -873,6 +868,16 @@ export const authTranslations = {
873
868
  "fr": "Récupération de compte",
874
869
  "en": "Account recovery"
875
870
  },
871
+ "Auth.MFA_IDENTIFIER_REQUIRED": {
872
+ "de": "E-Mail-Adresse oder Kennung ist erforderlich.",
873
+ "fr": "L’adresse e-mail ou l’identifiant est requis.",
874
+ "en": "Email address or identifier is required."
875
+ },
876
+ "Auth.MFA_HELP_REQUESTED": {
877
+ "de": "Falls dieses Konto existiert, wurde Ihre Anfrage dem Support weitergeleitet. Bitte kontaktiere den Support für weitere Hilfe.",
878
+ "fr": "Si ce compte existe, votre demande a été transmise au support. Veuillez contacter le support pour obtenir de l’aide supplémentaire.",
879
+ "en": "If this account exists, your request has been forwarded to support. Please contact support for further assistance."
880
+ },
876
881
 
877
882
 
878
883