mirror of
https://github.com/mattermost/mattermost.git
synced 2025-02-25 18:55:24 -06:00
[MM-51521] Prevent adjusting password stength fields when set in environment (#24151)
Co-authored-by: Nathan Geist <ngeist@spiria.com>
This commit is contained in:
parent
7d43712daa
commit
5985a0c531
@ -0,0 +1,33 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`components/admin_console/CheckboxSetting should match snapshot 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="form-group"
|
||||
data-testid="string.id"
|
||||
>
|
||||
<div
|
||||
class="col-sm-12"
|
||||
>
|
||||
<a
|
||||
id="string.id"
|
||||
/>
|
||||
<label
|
||||
class="checkbox-inline"
|
||||
>
|
||||
<input
|
||||
data-testid="string.id"
|
||||
id="string.id"
|
||||
name="string.id"
|
||||
type="checkbox"
|
||||
/>
|
||||
some label
|
||||
</label>
|
||||
<div
|
||||
class="help-text"
|
||||
data-testid="string.idhelp-text"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
@ -0,0 +1,50 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import {renderWithContext, screen, fireEvent} from 'tests/react_testing_utils';
|
||||
|
||||
import CheckboxSetting from './checkbox_setting';
|
||||
|
||||
describe('components/admin_console/CheckboxSetting', () => {
|
||||
test('should match snapshot', () => {
|
||||
const onChange = jest.fn();
|
||||
const {container} = renderWithContext(
|
||||
<CheckboxSetting
|
||||
id='string.id'
|
||||
label='some label'
|
||||
defaultChecked={false}
|
||||
onChange={onChange}
|
||||
setByEnv={false}
|
||||
disabled={false}
|
||||
/>,
|
||||
);
|
||||
const checkbox: HTMLInputElement = screen.getByRole('checkbox');
|
||||
expect(checkbox).toBeVisible();
|
||||
expect(checkbox).toHaveProperty('type', 'checkbox');
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('onChange', () => {
|
||||
const onChange = jest.fn();
|
||||
renderWithContext(
|
||||
<CheckboxSetting
|
||||
id='string.id'
|
||||
label='some label'
|
||||
defaultChecked={false}
|
||||
onChange={onChange}
|
||||
setByEnv={false}
|
||||
disabled={false}
|
||||
/>,
|
||||
);
|
||||
const checkbox: HTMLInputElement = screen.getByRole('checkbox');
|
||||
expect(checkbox).not.toBeChecked();
|
||||
|
||||
fireEvent.click(checkbox);
|
||||
|
||||
expect(onChange).toHaveBeenCalledTimes(1);
|
||||
expect(onChange).toHaveBeenCalledWith('string.id', true);
|
||||
expect(checkbox).toBeChecked();
|
||||
});
|
||||
});
|
@ -0,0 +1,67 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import Setting from './setting';
|
||||
|
||||
type Props = {
|
||||
id: string;
|
||||
label: React.ReactNode;
|
||||
defaultChecked?: boolean;
|
||||
onChange: (id: string, foo: boolean) => void;
|
||||
disabled: boolean;
|
||||
setByEnv: boolean;
|
||||
disabledText?: React.ReactNode;
|
||||
helpText?: React.ReactNode;
|
||||
}
|
||||
|
||||
export default class CheckboxSetting extends React.PureComponent<Props> {
|
||||
public static defaultProps = {
|
||||
disabled: false,
|
||||
};
|
||||
|
||||
private handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
this.props.onChange(this.props.id, e.target.checked);
|
||||
};
|
||||
|
||||
public render() {
|
||||
let helpText;
|
||||
if (this.props.disabled && this.props.disabledText) {
|
||||
helpText = (
|
||||
<div>
|
||||
<span className='admin-console__disabled-text'>
|
||||
{this.props.disabledText}
|
||||
</span>
|
||||
{this.props.helpText}
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
helpText = this.props.helpText;
|
||||
}
|
||||
|
||||
return (
|
||||
<Setting
|
||||
inputId={this.props.id}
|
||||
label={this.props.label}
|
||||
helpText={helpText}
|
||||
setByEnv={this.props.setByEnv}
|
||||
nested={true}
|
||||
>
|
||||
<a id={this.props.id}/>
|
||||
<label className='checkbox-inline'>
|
||||
<input
|
||||
data-testid={this.props.id}
|
||||
type='checkbox'
|
||||
id={this.props.id}
|
||||
name={this.props.id}
|
||||
defaultChecked={this.props.defaultChecked}
|
||||
onChange={this.handleChange}
|
||||
disabled={this.props.disabled || this.props.setByEnv}
|
||||
/>
|
||||
{this.props.label}
|
||||
</label>
|
||||
</Setting>
|
||||
);
|
||||
}
|
||||
}
|
@ -14,6 +14,7 @@ import AdminSettings from './admin_settings';
|
||||
import type {BaseProps, BaseState} from './admin_settings';
|
||||
import BlockableLink from './blockable_link';
|
||||
import BooleanSetting from './boolean_setting';
|
||||
import CheckboxSetting from './checkbox_setting';
|
||||
import Setting from './setting';
|
||||
import SettingsGroup from './settings_group';
|
||||
import TextSetting from './text_setting';
|
||||
@ -182,9 +183,9 @@ export default class PasswordSettings extends AdminSettings<Props, State> {
|
||||
);
|
||||
};
|
||||
|
||||
handleCheckboxChange = (id: string) => {
|
||||
return (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
this.handleChange(id, event.target.checked);
|
||||
handleBooleanChange = (id: string) => {
|
||||
return (_: string, value: boolean) => {
|
||||
this.handleChange(id, value);
|
||||
};
|
||||
};
|
||||
|
||||
@ -220,52 +221,52 @@ export default class PasswordSettings extends AdminSettings<Props, State> {
|
||||
label={<FormattedMessage {...messages.passwordRequirements}/>}
|
||||
>
|
||||
<div>
|
||||
<label className='checkbox-inline'>
|
||||
<input
|
||||
type='checkbox'
|
||||
defaultChecked={this.state.passwordLowercase}
|
||||
name='admin.password.lowercase'
|
||||
disabled={this.props.isDisabled}
|
||||
onChange={this.handleCheckboxChange('passwordLowercase')}
|
||||
/>
|
||||
<FormattedMessage {...messages.lowercase}/>
|
||||
</label>
|
||||
<CheckboxSetting
|
||||
id='admin.password.lowercase'
|
||||
label={
|
||||
<FormattedMessage {...messages.lowercase}/>
|
||||
}
|
||||
defaultChecked={this.state.passwordLowercase}
|
||||
onChange={this.handleBooleanChange('passwordLowercase')}
|
||||
setByEnv={this.isSetByEnv('PasswordSettings.Lowercase')}
|
||||
disabled={this.props.isDisabled}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className='checkbox-inline'>
|
||||
<input
|
||||
type='checkbox'
|
||||
defaultChecked={this.state.passwordUppercase}
|
||||
name='admin.password.uppercase'
|
||||
disabled={this.props.isDisabled}
|
||||
onChange={this.handleCheckboxChange('passwordUppercase')}
|
||||
/>
|
||||
<FormattedMessage {...messages.uppercase}/>
|
||||
</label>
|
||||
<CheckboxSetting
|
||||
id='admin.password.uppercase'
|
||||
label={
|
||||
<FormattedMessage {...messages.uppercase}/>
|
||||
}
|
||||
defaultChecked={this.state.passwordUppercase}
|
||||
onChange={this.handleBooleanChange('passwordUppercase')}
|
||||
setByEnv={this.isSetByEnv('PasswordSettings.Uppercase')}
|
||||
disabled={this.props.isDisabled}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className='checkbox-inline'>
|
||||
<input
|
||||
type='checkbox'
|
||||
defaultChecked={this.state.passwordNumber}
|
||||
name='admin.password.number'
|
||||
disabled={this.props.isDisabled}
|
||||
onChange={this.handleCheckboxChange('passwordNumber')}
|
||||
/>
|
||||
<FormattedMessage {...messages.number}/>
|
||||
</label>
|
||||
<CheckboxSetting
|
||||
id='admin.password.number'
|
||||
label={
|
||||
<FormattedMessage {...messages.number}/>
|
||||
}
|
||||
defaultChecked={this.state.passwordNumber}
|
||||
onChange={this.handleBooleanChange('passwordNumber')}
|
||||
setByEnv={this.isSetByEnv('PasswordSettings.Number')}
|
||||
disabled={this.props.isDisabled}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className='checkbox-inline'>
|
||||
<input
|
||||
type='checkbox'
|
||||
defaultChecked={this.state.passwordSymbol}
|
||||
name='admin.password.symbol'
|
||||
disabled={this.props.isDisabled}
|
||||
onChange={this.handleCheckboxChange('passwordSymbol')}
|
||||
/>
|
||||
<FormattedMessage {...messages.symbol}/>
|
||||
</label>
|
||||
<CheckboxSetting
|
||||
id='admin.password.symbol'
|
||||
label={
|
||||
<FormattedMessage {...messages.symbol}/>
|
||||
}
|
||||
defaultChecked={this.state.passwordSymbol}
|
||||
onChange={this.handleBooleanChange('passwordSymbol')}
|
||||
setByEnv={this.isSetByEnv('PasswordSettings.Symbol')}
|
||||
disabled={this.props.isDisabled}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<br/>
|
||||
|
@ -1,6 +1,7 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import classNames from 'classnames';
|
||||
import React from 'react';
|
||||
|
||||
import SetByEnv from './set_by_env';
|
||||
@ -11,21 +12,29 @@ export type Props = {
|
||||
children?: React.ReactNode;
|
||||
helpText?: React.ReactNode;
|
||||
setByEnv?: boolean;
|
||||
nested?: boolean;
|
||||
}
|
||||
|
||||
const Settings = ({children, setByEnv, helpText, inputId, label}: Props) => {
|
||||
const Settings = ({children, setByEnv, helpText, inputId, label, nested = false}: Props) => {
|
||||
return (
|
||||
<div
|
||||
data-testid={inputId}
|
||||
className='form-group'
|
||||
>
|
||||
<label
|
||||
className='control-label col-sm-4'
|
||||
htmlFor={inputId}
|
||||
{!nested && (
|
||||
<label
|
||||
className='control-label col-sm-4'
|
||||
htmlFor={inputId}
|
||||
>
|
||||
{label}
|
||||
</label>
|
||||
)}
|
||||
<div
|
||||
className={classNames({
|
||||
'col-sm-8': nested === false,
|
||||
'col-sm-12': nested === true,
|
||||
})}
|
||||
>
|
||||
{label}
|
||||
</label>
|
||||
<div className='col-sm-8'>
|
||||
{children}
|
||||
<div
|
||||
data-testid={inputId + 'help-text'}
|
||||
|
Loading…
Reference in New Issue
Block a user