mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-10 17:59:53 +03:00
translate NTP, AP, MQTT and User
This commit is contained in:
@@ -19,6 +19,8 @@ import { MessageBox } from '../../components';
|
||||
import * as SecurityApi from '../../api/security';
|
||||
import { Token } from '../../types';
|
||||
|
||||
import { useI18nContext } from '../../i18n/i18n-react';
|
||||
|
||||
interface GenerateTokenProps {
|
||||
username?: string;
|
||||
onClose: () => void;
|
||||
@@ -28,15 +30,17 @@ const GenerateToken: FC<GenerateTokenProps> = ({ username, onClose }) => {
|
||||
const [token, setToken] = useState<Token>();
|
||||
const open = !!username;
|
||||
|
||||
const { LL } = useI18nContext();
|
||||
|
||||
const { enqueueSnackbar } = useSnackbar();
|
||||
|
||||
const getToken = useCallback(async () => {
|
||||
try {
|
||||
setToken((await SecurityApi.generateToken(username)).data);
|
||||
} catch (error: unknown) {
|
||||
enqueueSnackbar(extractErrorMessage(error, 'Problem generating token'), { variant: 'error' });
|
||||
enqueueSnackbar(extractErrorMessage(error, LL.PROBLEM_UPDATING()), { variant: 'error' });
|
||||
}
|
||||
}, [username, enqueueSnackbar]);
|
||||
}, [username, enqueueSnackbar, LL]);
|
||||
|
||||
useEffect(() => {
|
||||
if (open) {
|
||||
@@ -46,16 +50,11 @@ const GenerateToken: FC<GenerateTokenProps> = ({ username, onClose }) => {
|
||||
|
||||
return (
|
||||
<Dialog onClose={onClose} aria-labelledby="generate-token-dialog-title" open={!!username} fullWidth maxWidth="sm">
|
||||
<DialogTitle id="generate-token-dialog-title">Access Token for {username}</DialogTitle>
|
||||
<DialogTitle id="generate-token-dialog-title">{LL.ACCESS_TOKEN_FOR() + ' ' + username}</DialogTitle>
|
||||
<DialogContent dividers>
|
||||
{token ? (
|
||||
<>
|
||||
<MessageBox
|
||||
message="The token below is used with REST API calls that require authorization. It can be passed either as a Bearer token in the
|
||||
'Authorization' header or in the 'access_token' URL query parameter."
|
||||
level="info"
|
||||
my={2}
|
||||
/>
|
||||
<MessageBox message={LL.ACCESS_TOKEN_TEXT()} level="info" my={2} />
|
||||
<Box mt={2} mb={2}>
|
||||
<TextField label="Token" multiline value={token.token} fullWidth contentEditable={false} />
|
||||
</Box>
|
||||
@@ -63,13 +62,13 @@ const GenerateToken: FC<GenerateTokenProps> = ({ username, onClose }) => {
|
||||
) : (
|
||||
<Box m={4} textAlign="center">
|
||||
<LinearProgress />
|
||||
<Typography variant="h6">Generating token…</Typography>
|
||||
<Typography variant="h6">{LL.GENERATING_TOKEN()}…</Typography>
|
||||
</Box>
|
||||
)}
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button startIcon={<CloseIcon />} variant="outlined" onClick={onClose} color="secondary">
|
||||
Close
|
||||
{LL.CLOSE()}
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
|
||||
@@ -20,6 +20,8 @@ import { createUserValidator } from '../../validators';
|
||||
import { useRest } from '../../utils';
|
||||
import { AuthenticatedContext } from '../../contexts/authentication';
|
||||
|
||||
import { useI18nContext } from '../../i18n/i18n-react';
|
||||
|
||||
import GenerateToken from './GenerateToken';
|
||||
import UserForm from './UserForm';
|
||||
|
||||
@@ -34,9 +36,11 @@ const ManageUsersForm: FC = () => {
|
||||
const [generatingToken, setGeneratingToken] = useState<string>();
|
||||
const authenticatedContext = useContext(AuthenticatedContext);
|
||||
|
||||
const { LL } = useI18nContext();
|
||||
|
||||
const table_theme = useTheme({
|
||||
Table: `
|
||||
--data-table-library_grid-template-columns: repeat(1, minmax(0, 1fr)) 90px 120px;
|
||||
--data-table-library_grid-template-columns: repeat(1, minmax(0, 1fr)) 120px 120px;
|
||||
`,
|
||||
BaseRow: `
|
||||
font-size: 14px;
|
||||
@@ -136,8 +140,8 @@ const ManageUsersForm: FC = () => {
|
||||
<>
|
||||
<Header>
|
||||
<HeaderRow>
|
||||
<HeaderCell resize>USERNAME</HeaderCell>
|
||||
<HeaderCell stiff>IS ADMIN</HeaderCell>
|
||||
<HeaderCell resize>{LL.USERNAME()}</HeaderCell>
|
||||
<HeaderCell stiff>{LL.IS_ADMIN()}</HeaderCell>
|
||||
<HeaderCell stiff />
|
||||
</HeaderRow>
|
||||
</Header>
|
||||
@@ -169,9 +173,7 @@ const ManageUsersForm: FC = () => {
|
||||
)}
|
||||
</Table>
|
||||
|
||||
{noAdminConfigured() && (
|
||||
<MessageBox level="warning" message="You must have at least one admin user configured" my={2} />
|
||||
)}
|
||||
{noAdminConfigured() && <MessageBox level="warning" message={LL.USER_WARNING()} my={2} />}
|
||||
|
||||
<Box display="flex" flexWrap="wrap">
|
||||
<Box flexGrow={1} sx={{ '& button': { mt: 2 } }}>
|
||||
@@ -183,14 +185,14 @@ const ManageUsersForm: FC = () => {
|
||||
type="submit"
|
||||
onClick={onSubmit}
|
||||
>
|
||||
Save
|
||||
{LL.SAVE()}
|
||||
</Button>
|
||||
</Box>
|
||||
|
||||
<Box flexWrap="nowrap" whiteSpace="nowrap">
|
||||
<ButtonRow>
|
||||
<Button startIcon={<PersonAddIcon />} variant="outlined" color="secondary" onClick={createUser}>
|
||||
Add
|
||||
{LL.ADD()}
|
||||
</Button>
|
||||
</ButtonRow>
|
||||
</Box>
|
||||
@@ -210,7 +212,7 @@ const ManageUsersForm: FC = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<SectionContent title="Manage Users" titleGutter>
|
||||
<SectionContent title={LL.MANAGE_USERS()} titleGutter>
|
||||
{content()}
|
||||
</SectionContent>
|
||||
);
|
||||
|
||||
@@ -19,8 +19,8 @@ const Security: FC = () => {
|
||||
return (
|
||||
<>
|
||||
<RouterTabs value={routerTab}>
|
||||
<Tab value="users" label="Manage Users" />
|
||||
<Tab value="settings" label="Security Settings" />
|
||||
<Tab value="users" label={LL.MANAGE_USERS()} />
|
||||
<Tab value="settings" label={LL.SECURITY() + ' ' + LL.SETTINGS()} />
|
||||
</RouterTabs>
|
||||
<Routes>
|
||||
<Route path="users" element={<ManageUsersForm />} />
|
||||
|
||||
@@ -11,7 +11,11 @@ import { SECURITY_SETTINGS_VALIDATOR, validate } from '../../validators';
|
||||
import { updateValue, useRest } from '../../utils';
|
||||
import { AuthenticatedContext } from '../../contexts/authentication';
|
||||
|
||||
import { useI18nContext } from '../../i18n/i18n-react';
|
||||
|
||||
const SecuritySettingsForm: FC = () => {
|
||||
const { LL } = useI18nContext();
|
||||
|
||||
const [fieldErrors, setFieldErrors] = useState<ValidateFieldsError>();
|
||||
const { loadData, saving, data, setData, saveData, errorMessage } = useRest<SecuritySettings>({
|
||||
read: SecurityApi.readSecuritySettings,
|
||||
@@ -42,7 +46,7 @@ const SecuritySettingsForm: FC = () => {
|
||||
<ValidatedPasswordField
|
||||
fieldErrors={fieldErrors}
|
||||
name="jwt_secret"
|
||||
label="su Password"
|
||||
label={"su " + LL.PASSWORD()}
|
||||
fullWidth
|
||||
variant="outlined"
|
||||
value={data.jwt_secret}
|
||||
@@ -51,7 +55,7 @@ const SecuritySettingsForm: FC = () => {
|
||||
/>
|
||||
<MessageBox
|
||||
level="info"
|
||||
message="The su (super user) password is used to sign authentication tokens and also enable admin privileges within the Console."
|
||||
message={LL.SU_TEXT()}
|
||||
mt={1}
|
||||
/>
|
||||
<ButtonRow>
|
||||
@@ -63,7 +67,7 @@ const SecuritySettingsForm: FC = () => {
|
||||
type="submit"
|
||||
onClick={validateAndSubmit}
|
||||
>
|
||||
Save
|
||||
{LL.SAVE()}
|
||||
</Button>
|
||||
</ButtonRow>
|
||||
</>
|
||||
@@ -71,7 +75,7 @@ const SecuritySettingsForm: FC = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<SectionContent title="Security Settings" titleGutter>
|
||||
<SectionContent title={LL.SECURITY() + " " + LL.SETTINGS()} titleGutter>
|
||||
{content()}
|
||||
</SectionContent>
|
||||
);
|
||||
|
||||
@@ -11,6 +11,8 @@ import { User } from '../../types';
|
||||
import { updateValue } from '../../utils';
|
||||
import { validate } from '../../validators';
|
||||
|
||||
import { useI18nContext } from '../../i18n/i18n-react';
|
||||
|
||||
interface UserFormProps {
|
||||
creating: boolean;
|
||||
validator: Schema;
|
||||
@@ -23,6 +25,8 @@ interface UserFormProps {
|
||||
}
|
||||
|
||||
const UserForm: FC<UserFormProps> = ({ creating, validator, user, setUser, onDoneEditing, onCancelEditing }) => {
|
||||
const { LL } = useI18nContext();
|
||||
|
||||
const updateFormValue = updateValue(setUser);
|
||||
const [fieldErrors, setFieldErrors] = useState<ValidateFieldsError>();
|
||||
const open = !!user;
|
||||
@@ -49,12 +53,14 @@ const UserForm: FC<UserFormProps> = ({ creating, validator, user, setUser, onDon
|
||||
<Dialog onClose={onCancelEditing} open={!!user} fullWidth maxWidth="sm">
|
||||
{user && (
|
||||
<>
|
||||
<DialogTitle id="user-form-dialog-title">{creating ? 'Add' : 'Modify'} User</DialogTitle>
|
||||
<DialogTitle id="user-form-dialog-title">
|
||||
{creating ? LL.ADD() : LL.MODIFY()} {LL.USER()}
|
||||
</DialogTitle>
|
||||
<DialogContent dividers>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
name="username"
|
||||
label="Username"
|
||||
label={LL.USERNAME()}
|
||||
fullWidth
|
||||
variant="outlined"
|
||||
value={user.username}
|
||||
@@ -65,7 +71,7 @@ const UserForm: FC<UserFormProps> = ({ creating, validator, user, setUser, onDon
|
||||
<ValidatedPasswordField
|
||||
fieldErrors={fieldErrors}
|
||||
name="password"
|
||||
label="Password"
|
||||
label={LL.PASSWORD()}
|
||||
fullWidth
|
||||
variant="outlined"
|
||||
value={user.password}
|
||||
@@ -74,12 +80,12 @@ const UserForm: FC<UserFormProps> = ({ creating, validator, user, setUser, onDon
|
||||
/>
|
||||
<BlockFormControlLabel
|
||||
control={<Checkbox name="admin" checked={user.admin} onChange={updateFormValue} />}
|
||||
label="is Admin?"
|
||||
label={LL.IS_ADMIN()}
|
||||
/>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button startIcon={<CancelIcon />} variant="outlined" onClick={onCancelEditing} color="secondary">
|
||||
Cancel
|
||||
{LL.CANCEL()}
|
||||
</Button>
|
||||
<Button
|
||||
startIcon={<PersonAddIcon />}
|
||||
@@ -88,7 +94,7 @@ const UserForm: FC<UserFormProps> = ({ creating, validator, user, setUser, onDon
|
||||
color="primary"
|
||||
autoFocus
|
||||
>
|
||||
Add
|
||||
{LL.ADD()}
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</>
|
||||
|
||||
Reference in New Issue
Block a user