Fix the password length limit when not setting a new password
Relates #1446
This commit is contained in:
parent
eadfbc9f6d
commit
43ec14e741
|
@ -1915,7 +1915,7 @@
|
|||
"message": "Failed to set password"
|
||||
},
|
||||
"passwordLengthError": {
|
||||
"message": "Password must be between 6 and 50 characters long",
|
||||
"message": "Password must be between 6 and 64 characters long",
|
||||
"description": "Error string shown to the user when password doesn't meet length criteria"
|
||||
},
|
||||
"passwordTypeError": {
|
||||
|
|
|
@ -1698,7 +1698,7 @@
|
|||
"message": "Échec de la définition du mot de passe"
|
||||
},
|
||||
"passwordLengthError": {
|
||||
"message": "Le mot de passe doit avoir une longueur comprise entre 6 et 50 caractères",
|
||||
"message": "Le mot de passe doit avoir une longueur comprise entre 6 et 64 caractères",
|
||||
"description": "Error string shown to the user when password doesn't meet length criteria"
|
||||
},
|
||||
"passwordTypeError": {
|
||||
|
|
|
@ -1698,7 +1698,7 @@
|
|||
"message": "Failed to set password"
|
||||
},
|
||||
"passwordLengthError": {
|
||||
"message": "Password must be between 6 and 50 characters long",
|
||||
"message": "Password must be between 6 and 64 characters long",
|
||||
"description": "Error string shown to the user when password doesn't meet length criteria"
|
||||
},
|
||||
"passwordTypeError": {
|
||||
|
|
|
@ -40,7 +40,6 @@ window.CONSTANTS = {
|
|||
MAX_USERNAME_LENGTH: 20,
|
||||
};
|
||||
|
||||
window.passwordUtil = require('./ts/util/passwordUtils');
|
||||
window.Signal.Logs = require('./js/modules/logs');
|
||||
|
||||
window.resetDatabase = () => {
|
||||
|
|
|
@ -173,7 +173,6 @@ window.setPassword = (passPhrase, oldPhrase) =>
|
|||
ipc.send('set-password', passPhrase, oldPhrase);
|
||||
});
|
||||
|
||||
window.passwordUtil = require('./ts/util/passwordUtils');
|
||||
window.libsession = require('./ts/session');
|
||||
|
||||
window.getMessageController =
|
||||
|
|
|
@ -237,8 +237,7 @@ export class Lightbox extends React.Component<Props> {
|
|||
}
|
||||
|
||||
if (current.paused) {
|
||||
// tslint:disable-next-line no-floating-promises
|
||||
current.play();
|
||||
void current.play();
|
||||
} else {
|
||||
current.pause();
|
||||
}
|
||||
|
@ -272,7 +271,7 @@ export class Lightbox extends React.Component<Props> {
|
|||
</div>
|
||||
</div>
|
||||
<div style={styles.controls}>
|
||||
<Flex flexGrow={1}>
|
||||
<Flex flex="1 1 auto">
|
||||
<IconButton
|
||||
type="close"
|
||||
onClick={this.onClose}
|
||||
|
|
|
@ -14,6 +14,7 @@ import { SessionSpinner } from './SessionSpinner';
|
|||
import { StringUtils, ToastUtils } from '../../session/utils';
|
||||
import { lightTheme } from '../../state/ducks/SessionTheme';
|
||||
import { ConversationController } from '../../session/conversations';
|
||||
import { PasswordUtil } from '../../util';
|
||||
|
||||
enum SignInMode {
|
||||
Default,
|
||||
|
@ -454,7 +455,6 @@ export class RegistrationTabs extends React.Component<any, State> {
|
|||
error={this.state.passwordErrorString}
|
||||
type="password"
|
||||
placeholder={window.i18n('enterOptionalPassword')}
|
||||
maxLength={window.CONSTANTS.MAX_PASSWORD_LENGTH}
|
||||
onValueChanged={(val: string) => {
|
||||
this.onPasswordChanged(val);
|
||||
}}
|
||||
|
@ -470,7 +470,6 @@ export class RegistrationTabs extends React.Component<any, State> {
|
|||
error={passwordsDoNotMatch}
|
||||
type="password"
|
||||
placeholder={window.i18n('confirmPassword')}
|
||||
maxLength={window.CONSTANTS.MAX_PASSWORD_LENGTH}
|
||||
onValueChanged={(val: string) => {
|
||||
this.onPasswordVerifyChanged(val);
|
||||
}}
|
||||
|
@ -592,7 +591,7 @@ export class RegistrationTabs extends React.Component<any, State> {
|
|||
return;
|
||||
}
|
||||
|
||||
const error = window.passwordUtil.validatePassword(input, window.i18n);
|
||||
const error = PasswordUtil.validatePassword(input, window.i18n);
|
||||
if (error) {
|
||||
this.setState({
|
||||
passwordErrorString: error,
|
||||
|
|
|
@ -2,7 +2,7 @@ import React from 'react';
|
|||
|
||||
import { SessionModal } from './SessionModal';
|
||||
import { SessionButton, SessionButtonColor } from './SessionButton';
|
||||
import { PasswordUtil } from '../../util/';
|
||||
import { missingCaseError, PasswordUtil } from '../../util/';
|
||||
import { ToastUtils } from '../../session/utils';
|
||||
import { toast } from 'react-toastify';
|
||||
import { SessionToast, SessionToastType } from './SessionToast';
|
||||
|
@ -46,8 +46,6 @@ class SessionPasswordModalInner extends React.Component<Props, State> {
|
|||
|
||||
this.onPasswordInput = this.onPasswordInput.bind(this);
|
||||
this.onPasswordConfirmInput = this.onPasswordConfirmInput.bind(this);
|
||||
|
||||
this.onPaste = this.onPaste.bind(this);
|
||||
}
|
||||
|
||||
public componentDidMount() {
|
||||
|
@ -86,8 +84,6 @@ class SessionPasswordModalInner extends React.Component<Props, State> {
|
|||
}}
|
||||
placeholder={placeholders[0]}
|
||||
onKeyUp={this.onPasswordInput}
|
||||
maxLength={window.CONSTANTS.MAX_PASSWORD_LENGTH}
|
||||
onPaste={this.onPaste}
|
||||
/>
|
||||
{action !== PasswordAction.Remove && (
|
||||
<input
|
||||
|
@ -95,8 +91,6 @@ class SessionPasswordModalInner extends React.Component<Props, State> {
|
|||
id="password-modal-input-confirm"
|
||||
placeholder={placeholders[1]}
|
||||
onKeyUp={this.onPasswordConfirmInput}
|
||||
maxLength={window.CONSTANTS.MAX_PASSWORD_LENGTH}
|
||||
onPaste={this.onPaste}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
@ -108,7 +102,7 @@ class SessionPasswordModalInner extends React.Component<Props, State> {
|
|||
<SessionButton
|
||||
text={window.i18n('ok')}
|
||||
buttonColor={confirmButtonColor}
|
||||
onClick={async () => this.setPassword(onOk)}
|
||||
onClick={this.setPassword}
|
||||
/>
|
||||
|
||||
<SessionButton
|
||||
|
@ -145,8 +139,106 @@ class SessionPasswordModalInner extends React.Component<Props, State> {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns false and set the state error field in the input is not a valid password
|
||||
* or returns true
|
||||
*/
|
||||
private validatePassword(firstPassword: string) {
|
||||
// if user did not fill the first password field, we can't do anything
|
||||
const errorFirstInput = PasswordUtil.validatePassword(
|
||||
firstPassword,
|
||||
window.i18n
|
||||
);
|
||||
if (errorFirstInput !== null) {
|
||||
this.setState({
|
||||
error: errorFirstInput,
|
||||
});
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private async handleActionSet(
|
||||
enteredPassword: string,
|
||||
enteredPasswordConfirm: string
|
||||
) {
|
||||
// be sure both password are valid
|
||||
if (!this.validatePassword(enteredPassword)) {
|
||||
return;
|
||||
}
|
||||
// no need to validate second password. we just need to check that enteredPassword is valid, and that both password matches
|
||||
|
||||
if (enteredPassword !== enteredPasswordConfirm) {
|
||||
this.setState({
|
||||
error: window.i18n('setPasswordInvalid'),
|
||||
});
|
||||
return;
|
||||
}
|
||||
await window.setPassword(enteredPassword, null);
|
||||
ToastUtils.pushToastSuccess(
|
||||
'setPasswordSuccessToast',
|
||||
window.i18n('setPasswordTitle'),
|
||||
window.i18n('setPasswordToastDescription'),
|
||||
SessionIconType.Lock
|
||||
);
|
||||
|
||||
this.props.onOk(this.props.action);
|
||||
this.closeDialog();
|
||||
}
|
||||
|
||||
private async handleActionChange(oldPassword: string, newPassword: string) {
|
||||
// We don't validate oldPassword on change: this is validate on the validatePasswordHash below
|
||||
// we only validate the newPassword here
|
||||
if (!this.validatePassword(newPassword)) {
|
||||
return;
|
||||
}
|
||||
const isValidWithStoredInDB = Boolean(
|
||||
await this.validatePasswordHash(oldPassword)
|
||||
);
|
||||
if (!isValidWithStoredInDB) {
|
||||
this.setState({
|
||||
error: window.i18n('changePasswordInvalid'),
|
||||
});
|
||||
return;
|
||||
}
|
||||
await window.setPassword(newPassword, oldPassword);
|
||||
|
||||
ToastUtils.pushToastSuccess(
|
||||
'setPasswordSuccessToast',
|
||||
window.i18n('changePasswordTitle'),
|
||||
window.i18n('changePasswordToastDescription'),
|
||||
SessionIconType.Lock
|
||||
);
|
||||
|
||||
this.props.onOk(this.props.action);
|
||||
this.closeDialog();
|
||||
}
|
||||
|
||||
private async handleActionRemove(oldPassword: string) {
|
||||
// We don't validate oldPassword on change: this is validate on the validatePasswordHash below
|
||||
const isValidWithStoredInDB = Boolean(
|
||||
await this.validatePasswordHash(oldPassword)
|
||||
);
|
||||
if (!isValidWithStoredInDB) {
|
||||
this.setState({
|
||||
error: window.i18n('removePasswordInvalid'),
|
||||
});
|
||||
return;
|
||||
}
|
||||
await window.setPassword(null, oldPassword);
|
||||
|
||||
ToastUtils.pushToastWarning(
|
||||
'setPasswordSuccessToast',
|
||||
window.i18n('removePasswordTitle'),
|
||||
window.i18n('removePasswordToastDescription')
|
||||
);
|
||||
|
||||
this.props.onOk(this.props.action);
|
||||
this.closeDialog();
|
||||
}
|
||||
|
||||
// tslint:disable-next-line: cyclomatic-complexity
|
||||
private async setPassword(onSuccess?: any) {
|
||||
private async setPassword() {
|
||||
const { action } = this.props;
|
||||
const {
|
||||
currentPasswordEntered,
|
||||
|
@ -155,106 +247,28 @@ class SessionPasswordModalInner extends React.Component<Props, State> {
|
|||
const { Set, Remove, Change } = PasswordAction;
|
||||
|
||||
// Trim leading / trailing whitespace for UX
|
||||
const enteredPassword = (currentPasswordEntered || '').trim();
|
||||
const enteredPasswordConfirm = (currentPasswordConfirmEntered || '').trim();
|
||||
const firstPasswordEntered = (currentPasswordEntered || '').trim();
|
||||
const secondPasswordEntered = (currentPasswordConfirmEntered || '').trim();
|
||||
|
||||
// if user did not fill the first password field, we can't do anything
|
||||
const errorFirstInput = PasswordUtil.validatePassword(
|
||||
enteredPassword,
|
||||
window.i18n
|
||||
);
|
||||
if (errorFirstInput !== null) {
|
||||
this.setState({
|
||||
error: errorFirstInput,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// if action is Set or Change, we need a valid ConfirmPassword
|
||||
if (action === Set || action === Change) {
|
||||
const errorSecondInput = PasswordUtil.validatePassword(
|
||||
enteredPasswordConfirm,
|
||||
window.i18n
|
||||
);
|
||||
if (errorSecondInput !== null) {
|
||||
this.setState({
|
||||
error: errorSecondInput,
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Passwords match or remove password successful
|
||||
const newPassword = action === Remove ? null : enteredPasswordConfirm;
|
||||
const oldPassword = action === Set ? null : enteredPassword;
|
||||
|
||||
// Check if password match, when setting, changing or removing
|
||||
let valid;
|
||||
if (action === Set) {
|
||||
valid = enteredPassword === enteredPasswordConfirm;
|
||||
} else {
|
||||
valid = Boolean(await this.validatePasswordHash(oldPassword));
|
||||
}
|
||||
|
||||
if (!valid) {
|
||||
let str;
|
||||
switch (action) {
|
||||
case Set:
|
||||
str = window.i18n('setPasswordInvalid');
|
||||
break;
|
||||
case Change:
|
||||
str = window.i18n('changePasswordInvalid');
|
||||
break;
|
||||
case Remove:
|
||||
str = window.i18n('removePasswordInvalid');
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Invalid action ${action}`);
|
||||
}
|
||||
this.setState({
|
||||
error: str,
|
||||
});
|
||||
|
||||
case Set: {
|
||||
await this.handleActionSet(firstPasswordEntered, secondPasswordEntered);
|
||||
return;
|
||||
}
|
||||
case Change: {
|
||||
await this.handleActionChange(
|
||||
firstPasswordEntered,
|
||||
secondPasswordEntered
|
||||
);
|
||||
return;
|
||||
}
|
||||
case Remove: {
|
||||
await this.handleActionRemove(firstPasswordEntered);
|
||||
return;
|
||||
}
|
||||
|
||||
await window.setPassword(newPassword, oldPassword);
|
||||
let title;
|
||||
let description;
|
||||
switch (action) {
|
||||
case Set:
|
||||
title = window.i18n('setPasswordTitle');
|
||||
description = window.i18n('setPasswordToastDescription');
|
||||
break;
|
||||
case Change:
|
||||
title = window.i18n('changePasswordTitle');
|
||||
description = window.i18n('changePasswordToastDescription');
|
||||
break;
|
||||
case Remove:
|
||||
title = window.i18n('removePasswordTitle');
|
||||
description = window.i18n('removePasswordToastDescription');
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Invalid action ${action}`);
|
||||
throw missingCaseError(action);
|
||||
}
|
||||
|
||||
if (action !== Remove) {
|
||||
ToastUtils.pushToastSuccess(
|
||||
'setPasswordSuccessToast',
|
||||
title,
|
||||
description,
|
||||
SessionIconType.Lock
|
||||
);
|
||||
} else {
|
||||
ToastUtils.pushToastWarning(
|
||||
'setPasswordSuccessToast',
|
||||
title,
|
||||
description
|
||||
);
|
||||
}
|
||||
|
||||
onSuccess(this.props.action);
|
||||
this.closeDialog();
|
||||
}
|
||||
|
||||
private closeDialog() {
|
||||
|
@ -263,26 +277,9 @@ class SessionPasswordModalInner extends React.Component<Props, State> {
|
|||
}
|
||||
}
|
||||
|
||||
private onPaste(event: any) {
|
||||
const clipboard = event.clipboardData.getData('text');
|
||||
|
||||
if (clipboard.length > window.CONSTANTS.MAX_PASSWORD_LENGTH) {
|
||||
const title = String(
|
||||
window.i18n(
|
||||
'pasteLongPasswordToastTitle',
|
||||
window.CONSTANTS.MAX_PASSWORD_LENGTH
|
||||
)
|
||||
);
|
||||
ToastUtils.pushToastWarning('passwordModal', title);
|
||||
}
|
||||
|
||||
// Prevent pating into input
|
||||
return false;
|
||||
}
|
||||
|
||||
private async onPasswordInput(event: any) {
|
||||
if (event.key === 'Enter') {
|
||||
return this.setPassword(this.props.onOk);
|
||||
return this.setPassword();
|
||||
}
|
||||
const currentPasswordEntered = event.target.value;
|
||||
|
||||
|
@ -291,7 +288,7 @@ class SessionPasswordModalInner extends React.Component<Props, State> {
|
|||
|
||||
private async onPasswordConfirmInput(event: any) {
|
||||
if (event.key === 'Enter') {
|
||||
return this.setPassword(this.props.onOk);
|
||||
return this.setPassword();
|
||||
}
|
||||
const currentPasswordConfirmEntered = event.target.value;
|
||||
|
||||
|
|
|
@ -32,7 +32,6 @@ class SessionPasswordPromptInner extends React.PureComponent<
|
|||
};
|
||||
|
||||
this.onKeyUp = this.onKeyUp.bind(this);
|
||||
this.onPaste = this.onPaste.bind(this);
|
||||
|
||||
this.initLogin = this.initLogin.bind(this);
|
||||
this.initClearDataView = this.initClearDataView.bind(this);
|
||||
|
@ -72,8 +71,6 @@ class SessionPasswordPromptInner extends React.PureComponent<
|
|||
defaultValue=""
|
||||
placeholder={' '}
|
||||
onKeyUp={this.onKeyUp}
|
||||
maxLength={window.CONSTANTS.MAX_PASSWORD_LENGTH}
|
||||
onPaste={this.onPaste}
|
||||
ref={this.inputRef}
|
||||
/>
|
||||
);
|
||||
|
@ -135,24 +132,6 @@ class SessionPasswordPromptInner extends React.PureComponent<
|
|||
event.preventDefault();
|
||||
}
|
||||
|
||||
public onPaste(event: any) {
|
||||
const clipboard = event.clipboardData.getData('text');
|
||||
|
||||
if (clipboard.length > window.CONSTANTS.MAX_PASSWORD_LENGTH) {
|
||||
this.setState({
|
||||
error: String(
|
||||
window.i18n(
|
||||
'pasteLongPasswordToastTitle',
|
||||
window.CONSTANTS.MAX_PASSWORD_LENGTH
|
||||
)
|
||||
),
|
||||
});
|
||||
}
|
||||
|
||||
// Prevent pasting into input
|
||||
return false;
|
||||
}
|
||||
|
||||
public async onLogin(passPhrase: string) {
|
||||
const passPhraseTrimmed = passPhrase.trim();
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import { SessionModal } from './SessionModal';
|
|||
import { SessionButton } from './SessionButton';
|
||||
import { ToastUtils } from '../../session/utils';
|
||||
import { DefaultTheme, withTheme } from 'styled-components';
|
||||
import { PasswordUtil } from '../../util';
|
||||
|
||||
interface Props {
|
||||
onClose: any;
|
||||
|
@ -77,7 +78,6 @@ class SessionSeedModalInner extends React.Component<Props, State> {
|
|||
}
|
||||
|
||||
private renderPasswordView() {
|
||||
const maxPasswordLen = 64;
|
||||
const error = this.state.error;
|
||||
const i18n = window.i18n;
|
||||
const { onClose } = this.props;
|
||||
|
@ -90,7 +90,6 @@ class SessionSeedModalInner extends React.Component<Props, State> {
|
|||
id="seed-input-password"
|
||||
placeholder={i18n('password')}
|
||||
onKeyUp={this.onEnter}
|
||||
maxLength={maxPasswordLen}
|
||||
/>
|
||||
|
||||
{error && (
|
||||
|
@ -143,8 +142,8 @@ class SessionSeedModalInner extends React.Component<Props, State> {
|
|||
private confirmPassword() {
|
||||
const passwordHash = this.state.passwordHash;
|
||||
const passwordValue = jQuery('#seed-input-password').val();
|
||||
const isPasswordValid = window.passwordUtil.matchesHash(
|
||||
passwordValue,
|
||||
const isPasswordValid = PasswordUtil.matchesHash(
|
||||
passwordValue as string,
|
||||
passwordHash
|
||||
);
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import {
|
|||
SessionButtonColor,
|
||||
SessionButtonType,
|
||||
} from '../SessionButton';
|
||||
import { BlockedNumberController } from '../../../util';
|
||||
import { BlockedNumberController, PasswordUtil } from '../../../util';
|
||||
import { ToastUtils } from '../../../session/utils';
|
||||
import { ConversationLookupType } from '../../../state/ducks/conversations';
|
||||
import { StateType } from '../../../state/reducer';
|
||||
|
@ -172,8 +172,7 @@ class SettingsViewInner extends React.Component<SettingsViewProps, State> {
|
|||
type="password"
|
||||
id="password-lock-input"
|
||||
defaultValue=""
|
||||
placeholder={' '}
|
||||
maxLength={window.CONSTANTS.MAX_PASSWORD_LENGTH}
|
||||
placeholder="Password"
|
||||
/>
|
||||
|
||||
<div className="spacer-xs" />
|
||||
|
@ -211,7 +210,7 @@ class SettingsViewInner extends React.Component<SettingsViewProps, State> {
|
|||
|
||||
// Check if the password matches the hash we have stored
|
||||
const hash = await window.Signal.Data.getPasswordHash();
|
||||
if (hash && !window.passwordUtil.matchesHash(enteredPassword, hash)) {
|
||||
if (hash && !PasswordUtil.matchesHash(enteredPassword, hash)) {
|
||||
this.setState({
|
||||
pwdLockError: window.i18n('invalidPassword'),
|
||||
});
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
const { assert } = require('chai');
|
||||
|
||||
const passwordUtil = require('../../ts/util/passwordUtils');
|
||||
import { assert } from 'chai';
|
||||
import { PasswordUtil } from '../../../../util';
|
||||
|
||||
describe('Password Util', () => {
|
||||
describe('hash generation', () => {
|
||||
it('generates the same hash for the same phrase', () => {
|
||||
const first = passwordUtil.generateHash('phrase');
|
||||
const second = passwordUtil.generateHash('phrase');
|
||||
const first = PasswordUtil.generateHash('phrase');
|
||||
const second = PasswordUtil.generateHash('phrase');
|
||||
assert.strictEqual(first, second);
|
||||
});
|
||||
it('generates different hashes for different phrases', () => {
|
||||
const first = passwordUtil.generateHash('0');
|
||||
const second = passwordUtil.generateHash('1');
|
||||
const first = PasswordUtil.generateHash('0');
|
||||
const second = PasswordUtil.generateHash('1');
|
||||
assert.notStrictEqual(first, second);
|
||||
});
|
||||
});
|
||||
|
@ -19,12 +18,12 @@ describe('Password Util', () => {
|
|||
describe('hash matching', () => {
|
||||
it('returns true for the same hash', () => {
|
||||
const phrase = 'phrase';
|
||||
const hash = passwordUtil.generateHash(phrase);
|
||||
assert.isTrue(passwordUtil.matchesHash(phrase, hash));
|
||||
const hash = PasswordUtil.generateHash(phrase);
|
||||
assert.isTrue(PasswordUtil.matchesHash(phrase, hash));
|
||||
});
|
||||
it('returns false for different hashes', () => {
|
||||
const hash = passwordUtil.generateHash('phrase');
|
||||
assert.isFalse(passwordUtil.matchesHash('phrase2', hash));
|
||||
const hash = PasswordUtil.generateHash('phrase');
|
||||
assert.isFalse(PasswordUtil.matchesHash('phrase2', hash));
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -44,26 +43,26 @@ describe('Password Util', () => {
|
|||
'#'.repeat(50),
|
||||
];
|
||||
valid.forEach(pass => {
|
||||
assert.isNull(passwordUtil.validatePassword(pass));
|
||||
assert.isNull(PasswordUtil.validatePassword(pass));
|
||||
});
|
||||
});
|
||||
|
||||
it('should return an error if password is not a string', () => {
|
||||
const invalid = [0, 123456, [], {}, null, undefined];
|
||||
invalid.forEach(pass => {
|
||||
const invalid = [0, 123456, [], {}, null, undefined] as any;
|
||||
invalid.forEach((pass: any) => {
|
||||
assert.strictEqual(
|
||||
passwordUtil.validatePassword(pass),
|
||||
PasswordUtil.validatePassword(pass),
|
||||
'Password must be a string'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('should return an error if password is not between 6 and 50 characters', () => {
|
||||
it('should return an error if password is not between 6 and 64 characters', () => {
|
||||
const invalid = ['a', 'abcde', '#'.repeat(51), '#'.repeat(100)];
|
||||
invalid.forEach(pass => {
|
||||
assert.strictEqual(
|
||||
passwordUtil.validatePassword(pass),
|
||||
'Password must be between 6 and 50 characters long'
|
||||
PasswordUtil.validatePassword(pass),
|
||||
'Password must be between 6 and 64 characters long'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@ -82,7 +81,7 @@ describe('Password Util', () => {
|
|||
];
|
||||
invalid.forEach(pass => {
|
||||
assert.strictEqual(
|
||||
passwordUtil.validatePassword(pass),
|
||||
PasswordUtil.validatePassword(pass),
|
||||
'Password must only contain letters, numbers and symbols'
|
||||
);
|
||||
});
|
|
@ -3,7 +3,7 @@ import { LocalizerType } from '../types/Util';
|
|||
|
||||
const ERRORS = {
|
||||
TYPE: 'Password must be a string',
|
||||
LENGTH: 'Password must be between 6 and 50 characters long',
|
||||
LENGTH: 'Password must be between 6 and 64 characters long',
|
||||
CHARACTER: 'Password must only contain letters, numbers and symbols',
|
||||
};
|
||||
|
||||
|
@ -17,7 +17,7 @@ export const generateHash = (phrase: string) => phrase && sha512(phrase.trim());
|
|||
export const matchesHash = (phrase: string | null, hash: string) =>
|
||||
phrase && sha512(phrase.trim()) === hash.trim();
|
||||
|
||||
export const validatePassword = (phrase: string, i18n: LocalizerType) => {
|
||||
export const validatePassword = (phrase: string, i18n?: LocalizerType) => {
|
||||
if (typeof phrase !== 'string') {
|
||||
return i18n ? i18n('passwordTypeError') : ERRORS.TYPE;
|
||||
}
|
||||
|
@ -27,7 +27,10 @@ export const validatePassword = (phrase: string, i18n: LocalizerType) => {
|
|||
return i18n ? i18n('noGivenPassword') : ERRORS.LENGTH;
|
||||
}
|
||||
|
||||
if (trimmed.length < 6 || trimmed.length > 50) {
|
||||
if (
|
||||
trimmed.length < 6 ||
|
||||
trimmed.length > window.CONSTANTS.MAX_PASSWORD_LENGTH
|
||||
) {
|
||||
return i18n ? i18n('passwordLengthError') : ERRORS.LENGTH;
|
||||
}
|
||||
|
||||
|
|
|
@ -72,7 +72,6 @@ declare global {
|
|||
lokiSnodeAPI: LokiSnodeAPI;
|
||||
mnemonic: RecoveryPhraseUtil;
|
||||
onLogin: any;
|
||||
passwordUtil: any;
|
||||
resetDatabase: any;
|
||||
restart: any;
|
||||
seedNodeList: any;
|
||||
|
|
Loading…
Reference in New Issue