import styles from './login.module.scss' import "./third_party_identity_providers.scss"; import React from 'react'; import ReCAPTCHA from "react-google-recaptcha"; import ReactDOM from 'react-dom'; import Avatar from '@material-ui/core/Avatar'; import Button from '@material-ui/core/Button'; import CssBaseline from '@material-ui/core/CssBaseline'; import TextField from '@material-ui/core/TextField'; import Link from '@material-ui/core/Link'; import Typography from '@material-ui/core/Typography'; import Paper from '@material-ui/core/Paper'; import Container from '@material-ui/core/Container'; import Chip from '@material-ui/core/Chip'; import FormControlLabel from '@material-ui/core/FormControlLabel'; import Checkbox from '@material-ui/core/Checkbox'; import {verifyAccount, emitOTP} from './actions'; import {MuiThemeProvider, createMuiTheme} from '@material-ui/core/styles'; import DividerWithText from '../components/divider_with_text'; import Visibility from '@material-ui/icons/Visibility'; import VisibilityOff from '@material-ui/icons/VisibilityOff'; import InputAdornment from '@material-ui/core/InputAdornment'; import IconButton from '@material-ui/core/IconButton'; import {emailValidator} from '../validator'; import Grid from '@material-ui/core/Grid'; import Swal from 'sweetalert2' const EmailInputForm = ({onValidateEmail, onHandleUserNameChange, disableInput, emailError}) => { return ( {emailError == "" && } ); } const PasswordInputForm = ({ formAction, onAuthenticate, disableInput, showPassword, passwordValue, passwordError, onUserPasswordChange, handleClickShowPassword, handleMouseDownPassword, userNameValue, csrfToken, shouldShowCaptcha, captchaPublicKey, onChangeRecaptcha }) => { return(
{showPassword ? : } ) }} /> } label="Remember me" /> {shouldShowCaptcha() && } ); } const OTPInputForm = ({ formAction, onAuthenticate, disableInput, showPassword, passwordValue, passwordError, onUserPasswordChange, handleClickShowPassword, handleMouseDownPassword, userNameValue, csrfToken, shouldShowCaptcha, captchaPublicKey, onChangeRecaptcha }) => { return(
{showPassword ? : } ) }} />

A Verification Code was just sent to your Email.

} label="Remember me" /> {shouldShowCaptcha() && } ); } const HelpLinks = ({forgotPasswordAction, verifyEmailAction, helpAction, appName, emitOtpAction}) => { return ( <>
Get A Login Code emailed to you Forgot password? Verify {appName} Having trouble? ); } const OTPHelpLinks = ({emitOtpAction}) => { return ( <>

Didn't receive it ?

Check your spam folder or resend email.

); } const EmailErrorActions = ({createAccountAction, onValidateEmail, disableInput}) => { return( Create Account ); } const ThirdPartyIdentityProviders = ({thirdPartyProviders, formAction, disableInput}) => { return( <> Or { thirdPartyProviders.map((provider) => { return ( ); }) } ); } class LoginPage extends React.Component { constructor(props) { super(props); this.state = { user_name: props.userName, user_password: '', user_pic: props.hasOwnProperty('user_pic') ? props.user_pic : null, user_fullname: props.hasOwnProperty('user_fullname') ? props.user_fullname : null, user_verified: props.hasOwnProperty('user_verified') ? props.user_verified : false, errors: { email: "", password: props.authError != "" ? props.authError : "", }, captcha_value: '', showPassword: false, disableInput: false, authFlow: props.flow, } this.onHandleUserNameChange = this.onHandleUserNameChange.bind(this); this.onValidateEmail = this.onValidateEmail.bind(this); this.handleDelete = this.handleDelete.bind(this); this.onAuthenticate = this.onAuthenticate.bind(this); this.onChangeRecaptcha = this.onChangeRecaptcha.bind(this); this.onUserPasswordChange = this.onUserPasswordChange.bind(this); this.shouldShowCaptcha = this.shouldShowCaptcha.bind(this); this.handleClickShowPassword = this.handleClickShowPassword.bind(this); this.handleMouseDownPassword = this.handleMouseDownPassword.bind(this); this.handleEmitOtpAction = this.handleEmitOtpAction.bind(this); } handleEmitOtpAction(ev){ ev.preventDefault(); let user_fullname = this.state.user_fullname ? this.state.user_fullname : this.state.user_name; emitOTP(this.state.user_name, this.props.token).then((payload) => { let {response} = payload; this.setState({...this.state, authFlow:"otp", errors: { email: "", password:"", }, user_verified: true, user_fullname:user_fullname, }); }, (error) => { let {response, status, message} = error; Swal('Oops...', 'Something went wrong!', 'error') }); return false; } shouldShowCaptcha() { return ( this.props.hasOwnProperty('maxLoginAttempts2ShowCaptcha') && this.props.hasOwnProperty('loginAttempts') && this.props.loginAttempts >= this.props.maxLoginAttempts2ShowCaptcha ) } onAuthenticate(ev) { if (this.state.user_password == '') { let error = 'Password is empty'; if(this.state.authFlow == 'OTP'){ error = 'Verification Code is empty'; } this.setState({...this.state, errors: {...this.state.errors, password: error}}); ev.preventDefault(); return false; } if (this.state.captcha_value == '' && this.shouldShowCaptcha()) { this.setState({...this.state, errors: {...this.state.errors, password: 'you must check CAPTCHA'}}); ev.preventDefault(); return false; } return true; } onChangeRecaptcha(value) { this.setState({...this.state, captcha_value: value}); } onHandleUserNameChange(ev) { let {value, id} = ev.target; this.setState({...this.state, user_name: value}); } onUserPasswordChange(ev) { let {errors} = this.state; let {value, id} = ev.target; if(value == "") // clean error errors[id] = ''; this.setState({...this.state, user_password: value, errors: {...errors}}); } onValidateEmail(ev) { ev.preventDefault(); if (this.state.user_name == '') { return false; } if (!emailValidator(this.state.user_name)) { return false; } this.setState({...this.state, disableInput: true}); verifyAccount(this.state.user_name).then((payload) => { let {response} = payload; this.setState({ ...this.state, user_pic: response.pic, user_fullname: response.full_name, user_verified: true, errors: { email: '', password: '' }, disableInput: false }) }, (error) => { let {response, status, message} = error; let newErrors = {}; newErrors['password'] = ''; newErrors['email'] = "We could not find an Account with that email Address"; if(status == 429){ newErrors['email'] = "Too many requests. Try it later."; } this.setState({ ...this.state, user_pic: null, user_fullname: null, user_verified: false, errors: newErrors, disableInput: false }); }); return true; } handleDelete() { this.setState({...this.state, user_name: null, user_pic: null, user_fullname: null, user_verified: false, authFlow:"password", errors: { email: "", password:"", },}); } handleClickShowPassword(ev) { this.setState({...this.state, showPassword: !this.state.showPassword}) } handleMouseDownPassword(ev) { ev.preventDefault(); } render() { return (
appLogo Sign in {this.state.user_fullname && } variant="outlined" className={styles.valid_user_name_chip} label={this.state.user_fullname} onDelete={this.handleDelete}/>} {!this.state.user_verified && <> { this.state.errors.email == '' && this.props.thirdPartyProviders.length > 0 && } { // we already had an interaction and got an user error... this.state.errors.email != '' && <> } } {this.state.user_verified && this.state.authFlow == 'password' && // proceed to ask for password ( 2nd step ) <> } {this.state.user_verified && this.state.authFlow == 'otp' && // proceed to ask for password ( 2nd step ) <> }
); } } // Or Create your Own theme: const theme = createMuiTheme({ palette: { primary: { main: '#3fa2f7' }, }, overrides: { MuiButton: { containedPrimary: { color: 'white' } } } }); ReactDOM.render( , document.querySelector('#root') );