[DEV-155] add captcha into login (#1090)
* fix apidoc * part 1 * pt2 * add classname and css
This commit is contained in:
parent
e7daf76274
commit
4b9a55b334
|
@ -16,6 +16,9 @@ import Message from 'core-components/message';
|
|||
import Widget from 'core-components/widget';
|
||||
import WidgetTransition from 'core-components/widget-transition';
|
||||
|
||||
import Captcha from 'app/main/captcha';
|
||||
|
||||
const MAX_FREE_LOGIN_ATTEMPTS = 3;
|
||||
class AdminLoginPage extends React.Component {
|
||||
|
||||
state = {
|
||||
|
@ -72,6 +75,7 @@ class AdminLoginPage extends React.Component {
|
|||
className="admin-login-page__login-form-container__login-form__fields__remember"
|
||||
field="checkbox" />
|
||||
</div>
|
||||
{this.props.session.loginAttempts > MAX_FREE_LOGIN_ATTEMPTS ? this.renderLoginCaptcha() : null}
|
||||
<div className="admin-login-page__login-form-container__login-form__submit-button">
|
||||
<SubmitButton>{i18n('LOG_IN')}</SubmitButton>
|
||||
</div>
|
||||
|
@ -87,6 +91,14 @@ class AdminLoginPage extends React.Component {
|
|||
);
|
||||
}
|
||||
|
||||
renderLoginCaptcha() {
|
||||
return(
|
||||
<div className="admin-login-page__captcha">
|
||||
<Captcha ref="captcha" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
renderPasswordRecovery() {
|
||||
return (
|
||||
<div className="admin-login-page__recovery-form-container">
|
||||
|
|
|
@ -31,4 +31,10 @@
|
|||
&__error {
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
&__captcha {
|
||||
margin: 10px auto 20px;
|
||||
height: 78px;
|
||||
width: 304px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,9 +19,12 @@ import WidgetTransition from 'core-components/widget-transition';
|
|||
import Message from 'core-components/message';
|
||||
import Loading from 'core-components/loading';
|
||||
|
||||
import Captcha from 'app/main/captcha';
|
||||
|
||||
const UNVERIFIED_USER_STEP = 0;
|
||||
const LOADING_STEP = 1;
|
||||
const REQUEST_RESULT_STEP = 2;
|
||||
const MAX_FREE_LOGIN_ATTEMPTS = 3;
|
||||
|
||||
class MainHomePageLoginWidget extends React.Component {
|
||||
|
||||
|
@ -61,6 +64,7 @@ class MainHomePageLoginWidget extends React.Component {
|
|||
<FormField placeholder={i18n('PASSWORD_LOWERCASE')} name="password" className="login-widget__input" required fieldProps={{password: true}}/>
|
||||
<FormField name="remember" label={i18n('REMEMBER_ME')} className="login-widget__input" field="checkbox"/>
|
||||
</div>
|
||||
{this.props.session.loginAttempts > MAX_FREE_LOGIN_ATTEMPTS ? this.renderLoginCaptcha() : null}
|
||||
<div className="login-widget__submit-button">
|
||||
<SubmitButton type="primary">{i18n('LOG_IN')}</SubmitButton>
|
||||
</div>
|
||||
|
@ -75,6 +79,14 @@ class MainHomePageLoginWidget extends React.Component {
|
|||
);
|
||||
}
|
||||
|
||||
renderLoginCaptcha() {
|
||||
return(
|
||||
<div className="main-home-page__captcha">
|
||||
<Captcha ref="captcha" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
renderReSendEmailVerificationSection() {
|
||||
if(this.props.session.failMessage === 'UNVERIFIED_USER') {
|
||||
switch (this.state.reSendEmailVerificationStep) {
|
||||
|
@ -148,7 +160,6 @@ class MainHomePageLoginWidget extends React.Component {
|
|||
|
||||
getLoginFormErrors() {
|
||||
let errors = _.extend({}, this.state.loginFormErrors);
|
||||
|
||||
if (this.props.session.failed) {
|
||||
if (this.props.session.failMessage === 'INVALID_CREDENTIALS') {
|
||||
errors.password = i18n('ERROR_PASSWORD');
|
||||
|
|
|
@ -10,4 +10,9 @@
|
|||
margin-left: 20px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
&__captcha {
|
||||
margin: 10px auto 20px;
|
||||
height: 78px;
|
||||
width: 304px;
|
||||
}
|
||||
}
|
|
@ -10,7 +10,8 @@ class SessionReducer extends Reducer {
|
|||
logged: false,
|
||||
pending: false,
|
||||
failed: false,
|
||||
verify: null
|
||||
verify: null,
|
||||
loginAttempts: 0
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -45,7 +46,8 @@ class SessionReducer extends Reducer {
|
|||
pending: false,
|
||||
failed: false,
|
||||
staff: payload.data.staff,
|
||||
userId: payload.data.userId
|
||||
userId: payload.data.userId,
|
||||
loginAttempts: 0
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -54,7 +56,8 @@ class SessionReducer extends Reducer {
|
|||
failMessage: payload.message,
|
||||
logged: false,
|
||||
pending: false,
|
||||
failed: true
|
||||
failed: true,
|
||||
loginAttempts: state.loginAttempts + 1
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
use RedBeanPHP\Facade as RedBean;
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
DataValidator::with('CustomValidations', true);
|
||||
|
||||
/**
|
||||
* @api {post} /user/login Login
|
||||
|
@ -41,10 +43,19 @@ class LoginController extends Controller {
|
|||
private $rememberExpiration;
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
$validations = [
|
||||
'permission' => 'any',
|
||||
'requestData' => []
|
||||
];
|
||||
|
||||
$validations['requestData']['captcha'] = [
|
||||
|
||||
'validation' => DataValidator::oneOf(DataValidator::captcha(),DataValidator::nullType()),
|
||||
'error' => ERRORS::INVALID_CAPTCHA
|
||||
];
|
||||
|
||||
return $validations;
|
||||
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
|
|
Loading…
Reference in New Issue