UNPKG

acklen-keystone

Version:

Web Application Framework and Admin GUI / Content Management System built on Express.js and Mongoose

219 lines (217 loc) 7.57 kB
/** * The actual Sign In view, with the login form */ import assign from 'object-assign'; import classnames from 'classnames'; import React from 'react'; import Auth0Lock from 'auth0-lock'; import Auth0 from 'auth0-js'; import xhr from 'xhr'; import { Button } from '../App/elemental'; import Alert from './components/Alert'; import Brand from './components/Brand'; import { isTokenExpired } from '../utils/jwtHelper'; const clientID = Keystone.auth0ClientId; const domain = Keystone.auth0DomainUrl; var webAuth = new Auth0.WebAuth({ domain, clientID, responseType: 'token id_token', scope: 'openid', }); var lock = new Auth0Lock(clientID, domain, { configurationBaseUrl: 'https://cdn.auth0.com', auth: { responseType: 'token', redirectUrl: window.location.origin, params: { state: window.location.pathname, }, }, allowSignUp: false, theme: { logo: `${Keystone.adminPath}/images/aga_full_logo.png`, primaryColor: '#008fd4', }, version: 'v2', socialButtonStyle: 'small', additionalSignUpFields: [ { name: 'first_name', placeholder: 'your first name', icon: `${Keystone.adminPath}/images/user.png`, }, { name: 'last_name', placeholder: 'your last name', icon: `${Keystone.adminPath}/images/user.png`, }, ], }); var SigninView = React.createClass({ getInitialState () { lock.on('authenticated', this.doAuthentication); lock.on('authorization_error', this.authorizationError); return { email: '', password: '', isAnimating: false, isInvalid: false, invalidMessage: '', signedOut: window.location.search === '?signedout', }; }, componentDidMount () { webAuth.checkSession({ redirectUri: window.location.origin, }, (errRenew, authResult) => { if (authResult && authResult.accessToken) { this.doAuthentication(authResult); } else { this.clearToken(); } }); }, clearToken () { localStorage.removeItem('id_token'); }, login () { lock.show(); }, doAuthentication (authResult) { lock.getProfile(authResult.accessToken, (error, profile) => { if (error) { this.setState({ invalidMessage: 'We\'re sorry, something went wrong when attempting to log in.', }); } else { var firstName = profile.first; var lastName = profile.last; var email = profile.email ? profile.email : profile.screen_name; var pwd = profile.pwd || profile.user_id; var netForumUserId = profile.user_metadata.netForumUserId; this.authenticateKeystoneUser(email, firstName, lastName, pwd, netForumUserId, authResult.accessToken); } }); }, authorizationError (error) { if (error && error.error_description) { this.displayError(error.error_description); } else { this.displayError('Sorry, we are unable to login you in with this account.'); } }, validToken () { const token = this.getToken(); return !!token && !isTokenExpired(token); }, getToken () { return localStorage.getItem('id_token'); }, setToken (idToken) { localStorage.setItem('id_token', idToken); }, handleInputChange (e) { // Set the new state when the input changes const newState = {}; newState[e.target.name] = e.target.value; this.setState(newState); }, logout () { localStorage.removeItem('id_token'); new Auth0Lock(clientID, domain).logout({ returnTo: window.location.origin + `${Keystone.adminPath}/signout`, }); }, authenticateKeystoneUser (email, firstName, lastName, pwd, netForumUserId, token) { if (!email) { return this.displayError('Invalid credentials to sign in.'); } xhr({ url: `${Keystone.adminPath}/api/session/signin`, method: 'post', json: { email, firstName, lastName, pwd, netForumUserId, }, headers: assign({}, Keystone.csrf.header), }, (err, resp, body) => { if (err || body && body.error) { return body.error === 'invalid csrf' ? this.displayError('Something went wrong; please refresh your browser and try again.') : this.displayError('The email and password you entered are not valid.'); } else { if (body.user.isAdmin) { this.setToken(token); // Redirect to where we came from or to the default admin path if (Keystone.redirect) { top.location.href = Keystone.redirect; } else { top.location.href = this.props.from ? this.props.from : Keystone.adminPath; } } else { this.displayError('You are not authorized to view this content'); } } }); }, /** * Display an error message * * @param {String} message The message you want to show */ displayError (message) { this.setState({ isAnimating: true, isInvalid: true, invalidMessage: message, }); setTimeout(this.finishAnimation, 750); }, // Finish the animation and select the email field finishAnimation () { // TODO isMounted was deprecated, find out if we need this guard if (!this.isMounted()) return; if (this.refs.email) { this.refs.email.select(); } this.setState({ isAnimating: false, }); }, render () { const boxClassname = classnames('auth-box', { 'auth-box--has-errors': this.state.isAnimating, }); return ( <div className="auth-wrapper"> <Alert isInvalid={this.state.isInvalid} signedOut={this.state.signedOut} invalidMessage={this.state.invalidMessage} /> <div className={boxClassname}> <h1 className="u-hidden-visually">{this.props.brand ? this.props.brand : 'Keystone'} Sign In </h1> <div className="auth-box__inner"> <Brand logo={this.props.logo} brand={this.props.brand} /> <div className="auth-box__col"> <div className="auth-box__brand" style={{ borderRight: 'inherit' }}> <Button color="primary" type="button" onClick={this.login}> Sign In </Button> </div> </div> </div> </div> <div className="auth-footer"> <span>Powered by </span> <a href="http://keystonejs.com" target="_blank" title="The Node.js CMS and web application platform (new window)">KeystoneJS</a> </div> </div> ); }, }); module.exports = SigninView;