add security form, begin work on routing
This commit is contained in:
		@@ -31,7 +31,7 @@ class AppRouting extends Component {
 | 
			
		||||
          <AuthenticatedRoute exact path="/ap-configuration" component={APConfiguration} />
 | 
			
		||||
          <AuthenticatedRoute exact path="/ntp-configuration" component={NTPConfiguration} />
 | 
			
		||||
          <AuthenticatedRoute exact path="/ota-configuration" component={OTAConfiguration} />
 | 
			
		||||
          <AuthenticatedRoute exact path="/security" component={Security} />
 | 
			
		||||
          <AuthenticatedRoute exact path="/security/*" component={Security} />
 | 
			
		||||
          <Redirect to="/" />
 | 
			
		||||
        </Switch>
 | 
			
		||||
      </AuthenticationWrapper>
 | 
			
		||||
 
 | 
			
		||||
@@ -137,7 +137,7 @@ class MenuAppBar extends React.Component {
 | 
			
		||||
            </ListItemIcon>
 | 
			
		||||
            <ListItemText primary="OTA Updates" />
 | 
			
		||||
          </ListItem>
 | 
			
		||||
          <ListItem button component={Link} to='/security'>
 | 
			
		||||
          <ListItem button component={Link} to='/security/'>
 | 
			
		||||
            <ListItemIcon>
 | 
			
		||||
              <LockIcon />
 | 
			
		||||
            </ListItemIcon>
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@ import React, { Component } from 'react';
 | 
			
		||||
import { USERS_ENDPOINT } from '../constants/Endpoints';
 | 
			
		||||
import { restComponent } from '../components/RestComponent';
 | 
			
		||||
import ManageUsersForm from '../forms/ManageUsersForm';
 | 
			
		||||
import SectionContent from '../components/SectionContent';
 | 
			
		||||
 | 
			
		||||
class ManageUsers extends Component {
 | 
			
		||||
 | 
			
		||||
@@ -13,15 +14,17 @@ class ManageUsers extends Component {
 | 
			
		||||
  render() {
 | 
			
		||||
    const { data, fetched, errorMessage } = this.props;
 | 
			
		||||
    return (
 | 
			
		||||
      <ManageUsersForm
 | 
			
		||||
        userData={data}
 | 
			
		||||
        userDataFetched={fetched}
 | 
			
		||||
        errorMessage={errorMessage}
 | 
			
		||||
        onSubmit={this.props.saveData}
 | 
			
		||||
        onReset={this.props.loadData}
 | 
			
		||||
        setData={this.props.setData}
 | 
			
		||||
        handleValueChange={this.props.handleValueChange}
 | 
			
		||||
      />
 | 
			
		||||
      <SectionContent title="Manage Users">
 | 
			
		||||
        <ManageUsersForm
 | 
			
		||||
          userData={data}
 | 
			
		||||
          userDataFetched={fetched}
 | 
			
		||||
          errorMessage={errorMessage}
 | 
			
		||||
          onSubmit={this.props.saveData}
 | 
			
		||||
          onReset={this.props.loadData}
 | 
			
		||||
          setData={this.props.setData}
 | 
			
		||||
          handleValueChange={this.props.handleValueChange}
 | 
			
		||||
        />
 | 
			
		||||
      </SectionContent>
 | 
			
		||||
    )
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,15 +1,35 @@
 | 
			
		||||
import React, { Component } from 'react';
 | 
			
		||||
import { Redirect, Switch } from 'react-router-dom'
 | 
			
		||||
 | 
			
		||||
import Tabs from '@material-ui/core/Tabs';
 | 
			
		||||
import Tab from '@material-ui/core/Tab';
 | 
			
		||||
 | 
			
		||||
import AuthenticatedRoute from '../authentication/AuthenticatedRoute';
 | 
			
		||||
import MenuAppBar from '../components/MenuAppBar';
 | 
			
		||||
import ManageUsers from './ManageUsers';
 | 
			
		||||
import SecuritySettings from './SecuritySettings';
 | 
			
		||||
 | 
			
		||||
class Security extends Component {
 | 
			
		||||
 | 
			
		||||
  handleTabChange = (event, path) => {
 | 
			
		||||
    this.props.history.push(path);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  render() {
 | 
			
		||||
    return (
 | 
			
		||||
        <MenuAppBar sectionTitle="Security">
 | 
			
		||||
          <ManageUsers />
 | 
			
		||||
        </MenuAppBar>
 | 
			
		||||
      <MenuAppBar sectionTitle="Security">
 | 
			
		||||
        <Tabs value={this.props.match.url} onChange={this.handleTabChange} indicatorColor="primary" textColor="primary" variant="fullWidth">
 | 
			
		||||
          <Tab value="/security/users" label="Manage Users" />
 | 
			
		||||
          <Tab value="/security/settings" label="Security Settings" />
 | 
			
		||||
        </Tabs>
 | 
			
		||||
        <Switch>
 | 
			
		||||
          <AuthenticatedRoute exact={true} path="/security/users" component={ManageUsers} />
 | 
			
		||||
          <AuthenticatedRoute exact={true} path="/security/settings" component={SecuritySettings} />
 | 
			
		||||
          <Redirect to="/security/users" />
 | 
			
		||||
        </Switch>
 | 
			
		||||
      </MenuAppBar>
 | 
			
		||||
    )
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default Security
 | 
			
		||||
export default Security;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										32
									
								
								interface/src/containers/SecuritySettings.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								interface/src/containers/SecuritySettings.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,32 @@
 | 
			
		||||
import React, { Component } from 'react';
 | 
			
		||||
 | 
			
		||||
import { USERS_ENDPOINT } from '../constants/Endpoints';
 | 
			
		||||
import { restComponent } from '../components/RestComponent';
 | 
			
		||||
import SecuritySettingsForm from '../forms/SecuritySettingsForm';
 | 
			
		||||
import SectionContent from '../components/SectionContent';
 | 
			
		||||
 | 
			
		||||
class SecuritySettings extends Component {
 | 
			
		||||
 | 
			
		||||
  componentDidMount() {
 | 
			
		||||
    this.props.loadData();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  render() {
 | 
			
		||||
    const { data, fetched, errorMessage } = this.props;
 | 
			
		||||
    return (
 | 
			
		||||
      <SectionContent title="Security Settings">
 | 
			
		||||
        <SecuritySettingsForm
 | 
			
		||||
          securitySettings={data}
 | 
			
		||||
          securitySettingsFetched={fetched}
 | 
			
		||||
          errorMessage={errorMessage}
 | 
			
		||||
          onSubmit={this.props.saveData}
 | 
			
		||||
          onReset={this.props.loadData}
 | 
			
		||||
          handleValueChange={this.props.handleValueChange}
 | 
			
		||||
        />
 | 
			
		||||
      </SectionContent>
 | 
			
		||||
    )
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default restComponent(USERS_ENDPOINT, SecuritySettings);
 | 
			
		||||
@@ -21,7 +21,6 @@ import CloseIcon from '@material-ui/icons/Close';
 | 
			
		||||
import CheckIcon from '@material-ui/icons/Check';
 | 
			
		||||
import IconButton from '@material-ui/core/IconButton';
 | 
			
		||||
 | 
			
		||||
import SectionContent from '../components/SectionContent';
 | 
			
		||||
import UserForm from './UserForm';
 | 
			
		||||
import { withAuthenticationContext } from '../authentication/Context';
 | 
			
		||||
 | 
			
		||||
@@ -138,108 +137,101 @@ class ManageUsersForm extends React.Component {
 | 
			
		||||
    const { classes, userData, userDataFetched, errorMessage, onReset } = this.props;
 | 
			
		||||
    const { user, creating } = this.state;
 | 
			
		||||
    return (
 | 
			
		||||
      <SectionContent title="Manage Users">
 | 
			
		||||
        {
 | 
			
		||||
          !userDataFetched ?
 | 
			
		||||
            <div className={classes.loadingSettings}>
 | 
			
		||||
              <LinearProgress className={classes.loadingSettingsDetails} />
 | 
			
		||||
              <Typography variant="h4" className={classes.loadingSettingsDetails}>
 | 
			
		||||
                Loading...
 | 
			
		||||
              </Typography>
 | 
			
		||||
            </div>
 | 
			
		||||
            :
 | 
			
		||||
            userData ?
 | 
			
		||||
              <Fragment>
 | 
			
		||||
                <ValidatorForm onSubmit={this.onSubmit}>
 | 
			
		||||
                  <Table className={classes.table}>
 | 
			
		||||
                    <TableHead>
 | 
			
		||||
                      <TableRow>
 | 
			
		||||
                        <TableCell>Username</TableCell>
 | 
			
		||||
                        <TableCell align="center">Admin?</TableCell>
 | 
			
		||||
                        <TableCell />
 | 
			
		||||
                      </TableRow>
 | 
			
		||||
                    </TableHead>
 | 
			
		||||
                    <TableBody>
 | 
			
		||||
                      {userData.users.sort(compareUsers).map(user => (
 | 
			
		||||
                        <TableRow key={user.username}>
 | 
			
		||||
                          <TableCell component="th" scope="row">
 | 
			
		||||
                            {user.username}
 | 
			
		||||
                          </TableCell>
 | 
			
		||||
                          <TableCell align="center">
 | 
			
		||||
                            {
 | 
			
		||||
                              user.admin ? <CheckIcon /> : <CloseIcon />
 | 
			
		||||
                            }
 | 
			
		||||
                          </TableCell>
 | 
			
		||||
                          <TableCell align="center">
 | 
			
		||||
                            <IconButton aria-label="Delete" onClick={() => this.removeUser(user)}>
 | 
			
		||||
                              <DeleteIcon />
 | 
			
		||||
                            </IconButton>
 | 
			
		||||
                            <IconButton aria-label="Edit" onClick={() => this.startEditingUser(user)}>
 | 
			
		||||
                              <EditIcon />
 | 
			
		||||
                            </IconButton>
 | 
			
		||||
                          </TableCell>
 | 
			
		||||
                        </TableRow>
 | 
			
		||||
                      ))}
 | 
			
		||||
                    </TableBody>
 | 
			
		||||
                    <TableFooter>
 | 
			
		||||
                      <TableRow>
 | 
			
		||||
                        <TableCell colSpan={2} />
 | 
			
		||||
                        <TableCell align="center">
 | 
			
		||||
                          <Button variant="contained" color="secondary" className={classes.button} onClick={this.createUser}>
 | 
			
		||||
                            Add User
 | 
			
		||||
                          </Button>
 | 
			
		||||
                        </TableCell>
 | 
			
		||||
                      </TableRow>
 | 
			
		||||
                    </TableFooter>
 | 
			
		||||
                  </Table>
 | 
			
		||||
                  {
 | 
			
		||||
                    this.noAdminConfigured() &&
 | 
			
		||||
                    <Typography component="div" variant="body1">
 | 
			
		||||
                      <Box bgcolor="error.main" color="error.contrastText" p={2} m={1}>
 | 
			
		||||
                        You must have at least one admin user configured.
 | 
			
		||||
                      </Box>
 | 
			
		||||
                    </Typography>
 | 
			
		||||
                  }
 | 
			
		||||
                  <Button variant="contained" color="primary" className={classes.button} type="submit" disabled={this.noAdminConfigured()}>
 | 
			
		||||
                    Save
 | 
			
		||||
                  </Button>
 | 
			
		||||
                  <Button variant="contained" color="secondary" className={classes.button} onClick={onReset}>
 | 
			
		||||
                    Reset
 | 
			
		||||
      		        </Button>
 | 
			
		||||
                </ValidatorForm>
 | 
			
		||||
                {
 | 
			
		||||
                  user &&
 | 
			
		||||
 | 
			
		||||
                  <UserForm
 | 
			
		||||
                    user={user}
 | 
			
		||||
                    creating={creating}
 | 
			
		||||
                    onDoneEditing={this.doneEditingUser}
 | 
			
		||||
                    onCancelEditing={this.cancelEditingUser}
 | 
			
		||||
                    handleValueChange={this.handleUserValueChange}
 | 
			
		||||
                    handleCheckboxChange={this.handleUserCheckboxChange}
 | 
			
		||||
                    uniqueUsername={this.uniqueUsername}
 | 
			
		||||
                  />
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
              </Fragment>
 | 
			
		||||
              :
 | 
			
		||||
              <SectionContent title="Manage Users">
 | 
			
		||||
                <Typography variant="h4" className={classes.loadingSettingsDetails}>
 | 
			
		||||
                  {errorMessage}
 | 
			
		||||
      !userDataFetched ?
 | 
			
		||||
        <div className={classes.loadingSettings}>
 | 
			
		||||
          <LinearProgress className={classes.loadingSettingsDetails} />
 | 
			
		||||
          <Typography variant="h4" className={classes.loadingSettingsDetails}>
 | 
			
		||||
            Loading...
 | 
			
		||||
          </Typography>
 | 
			
		||||
        </div>
 | 
			
		||||
        :
 | 
			
		||||
        userData ?
 | 
			
		||||
          <Fragment>
 | 
			
		||||
            <ValidatorForm onSubmit={this.onSubmit}>
 | 
			
		||||
              <Table className={classes.table}>
 | 
			
		||||
                <TableHead>
 | 
			
		||||
                  <TableRow>
 | 
			
		||||
                    <TableCell>Username</TableCell>
 | 
			
		||||
                    <TableCell align="center">Admin?</TableCell>
 | 
			
		||||
                    <TableCell />
 | 
			
		||||
                  </TableRow>
 | 
			
		||||
                </TableHead>
 | 
			
		||||
                <TableBody>
 | 
			
		||||
                  {userData.users.sort(compareUsers).map(user => (
 | 
			
		||||
                    <TableRow key={user.username}>
 | 
			
		||||
                      <TableCell component="th" scope="row">
 | 
			
		||||
                        {user.username}
 | 
			
		||||
                      </TableCell>
 | 
			
		||||
                      <TableCell align="center">
 | 
			
		||||
                        {
 | 
			
		||||
                          user.admin ? <CheckIcon /> : <CloseIcon />
 | 
			
		||||
                        }
 | 
			
		||||
                      </TableCell>
 | 
			
		||||
                      <TableCell align="center">
 | 
			
		||||
                        <IconButton aria-label="Delete" onClick={() => this.removeUser(user)}>
 | 
			
		||||
                          <DeleteIcon />
 | 
			
		||||
                        </IconButton>
 | 
			
		||||
                        <IconButton aria-label="Edit" onClick={() => this.startEditingUser(user)}>
 | 
			
		||||
                          <EditIcon />
 | 
			
		||||
                        </IconButton>
 | 
			
		||||
                      </TableCell>
 | 
			
		||||
                    </TableRow>
 | 
			
		||||
                  ))}
 | 
			
		||||
                </TableBody>
 | 
			
		||||
                <TableFooter>
 | 
			
		||||
                  <TableRow>
 | 
			
		||||
                    <TableCell colSpan={2} />
 | 
			
		||||
                    <TableCell align="center">
 | 
			
		||||
                      <Button variant="contained" color="secondary" onClick={this.createUser}>
 | 
			
		||||
                        Add User
 | 
			
		||||
                      </Button>
 | 
			
		||||
                    </TableCell>
 | 
			
		||||
                  </TableRow>
 | 
			
		||||
                </TableFooter>
 | 
			
		||||
              </Table>
 | 
			
		||||
              {
 | 
			
		||||
                this.noAdminConfigured() &&
 | 
			
		||||
                <Typography component="div" variant="body1">
 | 
			
		||||
                  <Box bgcolor="error.main" color="error.contrastText" p={2} m={2}>
 | 
			
		||||
                    You must have at least one admin user configured.
 | 
			
		||||
                  </Box>
 | 
			
		||||
                </Typography>
 | 
			
		||||
                <Button variant="contained" color="secondary" className={classes.button} onClick={onReset}>
 | 
			
		||||
                  Reset
 | 
			
		||||
      		      </Button>
 | 
			
		||||
              </SectionContent>
 | 
			
		||||
        }
 | 
			
		||||
      </SectionContent>
 | 
			
		||||
              }
 | 
			
		||||
              <Button variant="contained" color="primary" className={classes.button} type="submit" disabled={this.noAdminConfigured()}>
 | 
			
		||||
                Save
 | 
			
		||||
              </Button>
 | 
			
		||||
              <Button variant="contained" color="secondary" className={classes.button} onClick={onReset}>
 | 
			
		||||
                Reset
 | 
			
		||||
      		    </Button>
 | 
			
		||||
            </ValidatorForm>
 | 
			
		||||
            {
 | 
			
		||||
              user &&
 | 
			
		||||
              <UserForm
 | 
			
		||||
                user={user}
 | 
			
		||||
                creating={creating}
 | 
			
		||||
                onDoneEditing={this.doneEditingUser}
 | 
			
		||||
                onCancelEditing={this.cancelEditingUser}
 | 
			
		||||
                handleValueChange={this.handleUserValueChange}
 | 
			
		||||
                handleCheckboxChange={this.handleUserCheckboxChange}
 | 
			
		||||
                uniqueUsername={this.uniqueUsername}
 | 
			
		||||
              />
 | 
			
		||||
            }
 | 
			
		||||
          </Fragment>
 | 
			
		||||
          :
 | 
			
		||||
          <div className={classes.loadingSettings}>
 | 
			
		||||
            <Typography variant="h4" className={classes.loadingSettingsDetails}>
 | 
			
		||||
              {errorMessage}
 | 
			
		||||
            </Typography>
 | 
			
		||||
            <Button variant="contained" color="secondary" className={classes.button} onClick={onReset}>
 | 
			
		||||
              Reset
 | 
			
		||||
      		  </Button>
 | 
			
		||||
          </div>
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ManageUsersForm.propTypes = {
 | 
			
		||||
  authenticationContext: PropTypes.object.isRequired,
 | 
			
		||||
  classes: PropTypes.object.isRequired,
 | 
			
		||||
  userData: PropTypes.object,
 | 
			
		||||
  userDataFetched: PropTypes.bool.isRequired,
 | 
			
		||||
@@ -247,7 +239,8 @@ ManageUsersForm.propTypes = {
 | 
			
		||||
  onSubmit: PropTypes.func.isRequired,
 | 
			
		||||
  onReset: PropTypes.func.isRequired,
 | 
			
		||||
  setData: PropTypes.func.isRequired,
 | 
			
		||||
  handleValueChange: PropTypes.func.isRequired
 | 
			
		||||
  handleValueChange: PropTypes.func.isRequired,
 | 
			
		||||
  authenticationContext: PropTypes.object.isRequired,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default withAuthenticationContext(withStyles(styles)(ManageUsersForm));
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										97
									
								
								interface/src/forms/SecuritySettingsForm.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								interface/src/forms/SecuritySettingsForm.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,97 @@
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import PropTypes from 'prop-types';
 | 
			
		||||
import { ValidatorForm } from 'react-material-ui-form-validator';
 | 
			
		||||
 | 
			
		||||
import { withStyles } from '@material-ui/core/styles';
 | 
			
		||||
import Button from '@material-ui/core/Button';
 | 
			
		||||
import LinearProgress from '@material-ui/core/LinearProgress';
 | 
			
		||||
import Typography from '@material-ui/core/Typography';
 | 
			
		||||
import Box from '@material-ui/core/Box';
 | 
			
		||||
 | 
			
		||||
import PasswordValidator from '../components/PasswordValidator';
 | 
			
		||||
import { withAuthenticationContext } from '../authentication/Context';
 | 
			
		||||
 | 
			
		||||
const styles = theme => ({
 | 
			
		||||
  loadingSettings: {
 | 
			
		||||
    margin: theme.spacing.unit,
 | 
			
		||||
  },
 | 
			
		||||
  loadingSettingsDetails: {
 | 
			
		||||
    margin: theme.spacing.unit * 4,
 | 
			
		||||
    textAlign: "center"
 | 
			
		||||
  },
 | 
			
		||||
  textField: {
 | 
			
		||||
    width: "100%"
 | 
			
		||||
  },
 | 
			
		||||
  button: {
 | 
			
		||||
    marginRight: theme.spacing.unit * 2,
 | 
			
		||||
    marginTop: theme.spacing.unit * 2,
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
class SecuritySettingsForm extends React.Component {
 | 
			
		||||
 | 
			
		||||
  onSubmit = () => {
 | 
			
		||||
    this.props.onSubmit();
 | 
			
		||||
    this.props.authenticationContext.refresh();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  render() {
 | 
			
		||||
    const { classes, securitySettingsFetched, securitySettings, errorMessage, handleValueChange, onReset } = this.props;
 | 
			
		||||
    return (
 | 
			
		||||
      !securitySettingsFetched ?
 | 
			
		||||
        <div className={classes.loadingSettings}>
 | 
			
		||||
          <LinearProgress className={classes.loadingSettingsDetails} />
 | 
			
		||||
          <Typography variant="h4" className={classes.loadingSettingsDetails}>
 | 
			
		||||
            Loading...
 | 
			
		||||
          </Typography>
 | 
			
		||||
        </div>
 | 
			
		||||
        :
 | 
			
		||||
        securitySettings ?
 | 
			
		||||
          <ValidatorForm onSubmit={this.onSubmit} ref="SecuritySettingsForm">
 | 
			
		||||
            <PasswordValidator
 | 
			
		||||
              validators={['required', 'matchRegexp:^.{0,64}$']}
 | 
			
		||||
              errorMessages={['JWT Secret Required', 'JWT Secret must be 64 characters or less']}
 | 
			
		||||
              name="jwt_secret"
 | 
			
		||||
              label="JWT Secret"
 | 
			
		||||
              className={classes.textField}
 | 
			
		||||
              value={securitySettings.jwt_secret}
 | 
			
		||||
              onChange={handleValueChange('jwt_secret')}
 | 
			
		||||
              margin="normal"
 | 
			
		||||
            />
 | 
			
		||||
            <Typography component="div" variant="body1">
 | 
			
		||||
              <Box bgcolor="primary.main" color="primary.contrastText" p={2} m={2}>
 | 
			
		||||
                If you modify the JWT Secret, all users will be logged out.
 | 
			
		||||
              </Box>
 | 
			
		||||
            </Typography>
 | 
			
		||||
            <Button variant="contained" color="primary" className={classes.button} type="submit">
 | 
			
		||||
              Save
 | 
			
		||||
            </Button>
 | 
			
		||||
            <Button variant="contained" color="secondary" className={classes.button} onClick={onReset}>
 | 
			
		||||
              Reset
 | 
			
		||||
      		  </Button>
 | 
			
		||||
          </ValidatorForm>
 | 
			
		||||
          :
 | 
			
		||||
          <div className={classes.loadingSettings}>
 | 
			
		||||
            <Typography variant="h4" className={classes.loadingSettingsDetails}>
 | 
			
		||||
              {errorMessage}
 | 
			
		||||
            </Typography>
 | 
			
		||||
            <Button variant="contained" color="secondary" className={classes.button} onClick={onReset}>
 | 
			
		||||
              Reset
 | 
			
		||||
      		  </Button>
 | 
			
		||||
          </div>
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SecuritySettingsForm.propTypes = {
 | 
			
		||||
  classes: PropTypes.object.isRequired,
 | 
			
		||||
  securitySettingsFetched: PropTypes.bool.isRequired,
 | 
			
		||||
  securitySettings: PropTypes.object,
 | 
			
		||||
  errorMessage: PropTypes.string,
 | 
			
		||||
  onSubmit: PropTypes.func.isRequired,
 | 
			
		||||
  onReset: PropTypes.func.isRequired,
 | 
			
		||||
  handleValueChange: PropTypes.func.isRequired,
 | 
			
		||||
  authenticationContext: PropTypes.object.isRequired,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default withAuthenticationContext(withStyles(styles)(SecuritySettingsForm));
 | 
			
		||||
@@ -44,7 +44,7 @@ class UserForm extends React.Component {
 | 
			
		||||
    return (
 | 
			
		||||
      <ValidatorForm onSubmit={onDoneEditing} ref={this.formRef}>
 | 
			
		||||
        <Dialog onClose={onCancelEditing} aria-labelledby="user-form-dialog-title" open={true} scroll="paper">
 | 
			
		||||
          <DialogTitle id="user-form-dialog-title">{creating ? 'Create' : 'Modify'} User</DialogTitle>
 | 
			
		||||
          <DialogTitle id="user-form-dialog-title">{creating ? 'Add' : 'Modify'} User</DialogTitle>
 | 
			
		||||
          <DialogContent dividers={true}>
 | 
			
		||||
            <TextValidator
 | 
			
		||||
              validators={creating ? ['required', 'uniqueUsername', 'matchRegexp:^[a-zA-Z0-9_\\.]{1,24}$'] : []}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user