Skip to content

Commit

Permalink
Merge pull request #163 from openware/fix/wiprex/otp
Browse files Browse the repository at this point in the history
Fix/wiprex/otp
  • Loading branch information
josadcha committed Feb 3, 2020
2 parents 4d6f667 + fd21763 commit 94d7f27
Show file tree
Hide file tree
Showing 10 changed files with 67 additions and 24 deletions.
7 changes: 2 additions & 5 deletions src/custom/components/SignUp/index.tsx
Expand Up @@ -232,8 +232,9 @@ export class SignUpForm extends React.Component<SignUpFormProps> {
id="agreeWithTerms"
checked={hasConfirmed}
onChange={this.props.clickCheckBox}
label={this.checkboxLabel()}
label={this.props.termsMessage}
/>
&nbsp;(<span className="highlight">{this.props.termsMessageHighlight}</span>)
</Form>
<Form className="cr-sign-up-form__group">
<Form.Check
Expand Down Expand Up @@ -276,10 +277,6 @@ export class SignUpForm extends React.Component<SignUpFormProps> {
);
}

private checkboxLabel = () => (
<span>{this.props.termsMessage} (<span className="highlight">{this.props.termsMessageHighlight}</span>)</span>
);

private disableButton = (): boolean => {
const {
hasConfirmed,
Expand Down
3 changes: 2 additions & 1 deletion src/custom/components/TwoFactorAuth/index.tsx
Expand Up @@ -3,6 +3,7 @@ import * as React from 'react';
import { Button } from 'react-bootstrap';
import { CustomInput } from '../../../components';
import { IconBack } from '../../assets/images/IconBack';
import { otpCodeCheck } from '../../helpers/passwordChecks';

export interface TwoFactorAuthProps {
error?: React.ReactNode;
Expand Down Expand Up @@ -69,7 +70,7 @@ class TwoFactorAuthComponent extends React.Component<TwoFactorAuthProps> {
</div>
<div className={buttonWrapperClass}>
<Button
disabled={isLoading || !otpCode.match(/.{6}/g)}
disabled={isLoading || !otpCodeCheck(otpCode)}
onClick={this.handleSubmit}
size="lg"
variant="primary"
Expand Down
2 changes: 2 additions & 0 deletions src/custom/helpers/passwordChecks.ts
Expand Up @@ -2,3 +2,5 @@ export const passwordCheckForUpperCase = (value: string) => value.match(/[a-zA-Z
export const passwordCheckForLowerCase = (value: string) => value.match(/[a-z]/g);
export const passwordCheckForNumber = (value: string) => value.match(/[a-zA-Z0-9]*[0-9]+[a-zA-Z0-9]*/g);
export const passwordCheckFor10Chars = (value: string) => value.match(/.{10,}/g);

export const otpCodeCheck = (value: string) => value.match(/\b\d{6}\b/g);
4 changes: 4 additions & 0 deletions src/custom/screens/SignInScreen/index.tsx
Expand Up @@ -14,6 +14,7 @@ import {
selectUserFetching,
selectUserLoggedIn,
signIn,
signInRequire2FA,
signInError,
signUpRequireVerification,
} from '../../../modules';
Expand All @@ -29,6 +30,7 @@ interface DispatchProps {
signIn: typeof signIn;
signInError: typeof signInError;
signUpRequireVerification: typeof signUpRequireVerification;
signInRequire2FA: typeof signInRequire2FA;
}

interface SignInState {
Expand Down Expand Up @@ -56,6 +58,7 @@ class SignIn extends React.Component<Props, SignInState> {
setDocumentTitle('Sign In');
this.props.signInError({ code: undefined, message: undefined });
this.props.signUpRequireVerification({requireVerification: false});
this.props.signInRequire2FA({ require2fa: false });
}

public componentWillReceiveProps(props: Props) {
Expand Down Expand Up @@ -211,6 +214,7 @@ const mapDispatchProps: MapDispatchToPropsFunction<DispatchProps, {}> = dispatch
signIn: data => dispatch(signIn(data)),
signInError: error => dispatch(signInError(error)),
signUpRequireVerification: data => dispatch(signUpRequireVerification(data)),
signInRequire2FA: payload => dispatch(signInRequire2FA(payload)),
});

// tslint:disable no-any
Expand Down
44 changes: 32 additions & 12 deletions src/custom/screens/TwoFactorAuthScreen/index.tsx
Expand Up @@ -18,13 +18,17 @@ import {
signInError,
signInRequire2FA,
signUpRequireVerification,
selectSignInError,
} from '../../../modules';
import { otpCodeCheck } from '../../helpers/passwordChecks';
import { CommonError } from '../../../modules/types';

interface ReduxProps {
isLoggedIn: boolean;
loading?: boolean;
require2FA?: boolean;
requireEmailVerification?: boolean;
otpError?: CommonError;
}

interface DispatchProps {
Expand Down Expand Up @@ -61,13 +65,23 @@ class TwoFactorAuthComponent extends React.Component<Props, SignInState> {

public componentDidMount() {
setDocumentTitle('Login Verification');
const { email, password } = this.props.history.location.state;
this.props.signInError({ code: undefined, message: undefined });

if (!email || !password || !this.props.require2FA) {
this.props.history.push('/signin');
}
}

public componentWillReceiveProps(props: Props) {
const { otpCode } = this.state;
if (props.isLoggedIn) {
this.props.history.push('/wallets');
}

if (props.otpError && otpCodeCheck(otpCode)) {
this.setState({ error2fa: <this.errorMessage /> });
}
}

public render() {
Expand Down Expand Up @@ -107,8 +121,19 @@ class TwoFactorAuthComponent extends React.Component<Props, SignInState> {
}

private handleChangeOtpCode = (value: string) => {
const { error2fa } = this.state;

if (otpCodeCheck(value) && error2fa) {
this.setState({
error2fa: undefined,
});
} else if (!otpCodeCheck(value) && !error2fa && value.length >= 6) {
this.setState({
error2fa: <this.errorMessage />,
});
}

this.setState({
error2fa: '',
otpCode: value,
});
};
Expand All @@ -117,17 +142,11 @@ class TwoFactorAuthComponent extends React.Component<Props, SignInState> {
const { otpCode } = this.state;
const { email, password } = this.props.history.location.state;

if (!otpCode) {
this.setState({
error2fa: <this.errorMessage />,
});
} else {
this.props.signIn({
email,
password,
otp_code: otpCode,
});
}
this.props.signIn({
email,
password,
otp_code: otpCode,
});
};

private errorMessage = () => (
Expand All @@ -150,6 +169,7 @@ const mapStateToProps: MapStateToProps<ReduxProps, {}, RootState> = state => ({
loading: selectUserFetching(state),
require2FA: selectSignInRequire2FA(state),
requireEmailVerification: selectSignUpRequireVerification(state),
otpError: selectSignInError(state),
});

const mapDispatchProps: MapDispatchToPropsFunction<DispatchProps, {}> = dispatch => ({
Expand Down
2 changes: 1 addition & 1 deletion src/custom/styles/components/SignUp.pcss
Expand Up @@ -49,7 +49,7 @@

.custom-control {
&-label {
width: 83%;
width: 100%;
font-size: 14px;
display: flex;
flex-direction: row;
Expand Down
13 changes: 12 additions & 1 deletion src/custom/styles/screens/SignUpScreen.pcss
Expand Up @@ -77,7 +77,18 @@

&:nth-child(2), &:nth-child(4) {
margin-bottom: 4px;
}
}

&:nth-child(7) {
display: flex;
align-items: center;
}

.highlight {
color: var(--primary-cta-color);
font-size: 14px;
cursor: pointer;
}
}

&__option {
Expand Down
11 changes: 8 additions & 3 deletions src/custom/styles/screens/TwoFactorAuthScreen.pcss
Expand Up @@ -9,9 +9,14 @@
margin-top: calc(var(--gap) * 3.33);
width: calc(var(--gap) * 70.66);

.pg-2fa___form .cr-email-form__cros-icon {
top: -2px;
}
.pg-2fa___form .cr-email-form {
&__cros-icon {
top: -2px;
}
&__button-wrapper {
min-height: calc(var(--gap) * 4);
}
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/modules/user/auth/sagas/signInSaga.ts
Expand Up @@ -27,7 +27,7 @@ export function* signInSaga(action: SignInFetch) {
break;
case 403:
if (error.message.indexOf('identity.session.invalid_otp') > -1) {
yield put(alertPush({message: error.message, code: error.code, type: 'error'}));
yield put(signInError(error));
}
yield put(signInRequire2FA({ require2fa: true }));
break;
Expand Down
3 changes: 3 additions & 0 deletions src/modules/user/auth/selectors.ts
Expand Up @@ -13,3 +13,6 @@ export const selectSignUpError = (state: RootState): CommonError | undefined =>

export const selectEmailVerified = (state: RootState): AuthState['emailVerified'] =>
state.user.auth.emailVerified;

export const selectSignInError = (state: RootState): CommonError | undefined =>
state.user.auth.authError;

0 comments on commit 94d7f27

Please sign in to comment.