login feature removal

This commit is contained in:
Antti Pilto 2016-08-13 19:48:09 +03:00
parent 613449a82c
commit 101dc0504d
9 changed files with 8 additions and 148 deletions

View file

@ -1,2 +1,3 @@
# Nothing interesting here # Kana Quiz 2
Early alpha of Kana Quiz remade with React.js and Auth0 Kana Quiz remade with React.js.
See live at http://simplemedia.org/kana/

View file

@ -37,10 +37,9 @@
"webpack-dev-server": "^1.14.1" "webpack-dev-server": "^1.14.1"
}, },
"dependencies": { "dependencies": {
"auth0-lock": "^10.0.0",
"jwt-decode": "^2.1.0",
"postcss": "^5.1.0", "postcss": "^5.1.0",
"react": "^15.2.1", "react": "^15.2.1",
"react-addons-css-transition-group": "^15.3.0",
"react-dom": "^15.2.1", "react-dom": "^15.2.1",
"react-toggle-switch": "^2.1.2" "react-toggle-switch": "^2.1.2"
} }

View file

@ -1,38 +1,21 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import AuthService from '../../utils/AuthService'
import './App.scss'; import './App.scss';
import Navbar from '../Navbar/Navbar'; import Navbar from '../Navbar/Navbar';
import GameContainer from '../GameContainer/GameContainer'; import GameContainer from '../GameContainer/GameContainer';
import { removeHash } from '../../data/helperFuncs'; import { removeHash } from '../../data/helperFuncs';
const options = {}; const options = {};
const auth = new AuthService(__AUTH0_CLIENT_ID__, __AUTH0_DOMAIN__, options);
class App extends Component { class App extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
isAuthenticated: this.isAuthenticated(),
gameState: 'chooseCharacters' gameState: 'chooseCharacters'
} }
auth.on('profile_updated', (newProfile) => {
this.setState({isAuthenticated: this.isAuthenticated()});
})
this.logout = this.logout.bind(this);
this.getNickName = this.getNickName.bind(this);
this.startGame = this.startGame.bind(this); this.startGame = this.startGame.bind(this);
this.endGame = this.endGame.bind(this); this.endGame = this.endGame.bind(this);
} }
isAuthenticated() {
removeHash();
return auth.loggedIn() && auth.getProfile() && auth.getProfile().hasOwnProperty('user_id');
}
getNickName() {
return auth.loggedIn() && auth.getProfile() && auth.getProfile().hasOwnProperty('nickname')?auth.getProfile().nickname:'';
}
startGame() { startGame() {
this.setState({gameState: 'game'}); this.setState({gameState: 'game'});
} }
@ -41,34 +24,22 @@ class App extends Component {
this.setState({gameState: 'chooseCharacters'}); this.setState({gameState: 'chooseCharacters'});
} }
logout() {
auth.logout();
this.setState({isAuthenticated: this.isAuthenticated()});
}
render() { render() {
let loginButton = !this.state.isAuthenticated ?
<p className="login-button"><a href="javascript:;" onClick={auth.login.bind(this)}>Log in to save your progress!</a></p> : '';
return ( return (
<div> <div>
<Navbar isAuthenticated={this.state.isAuthenticated} <Navbar
handleLogin={auth.login.bind(this)}
handleLogout={this.logout}
gameState={this.state.gameState} gameState={this.state.gameState}
handleEndGame={this.endGame} handleEndGame={this.endGame}
/> />
<div className="outercontainer"> <div className="outercontainer">
<div className="container game"> <div className="container game">
<GameContainer <GameContainer
isAuthenticated={this.state.isAuthenticated}
nickName={this.getNickName()}
gameState={this.state.gameState} gameState={this.state.gameState}
handleStartGame={this.startGame} handleStartGame={this.startGame}
handleEndGame={this.endGame} handleEndGame={this.endGame}
/> />
</div> </div>
</div> </div>
<div className="row text-center">{loginButton}</div>
</div> </div>
) )
} }

View file

@ -55,7 +55,6 @@ class CharacterGroup extends Component {
<span className={this.props.selected ? <span className={this.props.selected ?
'glyphicon glyphicon-small glyphicon-check' : 'glyphicon glyphicon-small glyphicon-check' :
'glyphicon glyphicon-small glyphicon-unchecked'}></span> {this.state.shownChars} 'glyphicon glyphicon-small glyphicon-unchecked'}></span> {this.state.shownChars}
<span className="pull-right success-percent">0 %</span>
</div> </div>
); );
} }

View file

@ -96,7 +96,7 @@ class ChooseCharacters extends Component {
<div className="col-xs-12"> <div className="col-xs-12">
<div className="panel panel-default"> <div className="panel panel-default">
<div className="panel-body welcome"> <div className="panel-body welcome">
<h4>Welcome to Kana Quiz{this.props.isAuthenticated && this.props.nickName !== '' && typeof this.props.nickName !== 'undefined'?', '+this.props.nickName:''}!</h4> <h4>Welcome to Kana Quiz!</h4>
<p>Please choose the groups of characters that you'd like to be studying.</p> <p>Please choose the groups of characters that you'd like to be studying.</p>
</div> </div>
</div> </div>
@ -105,7 +105,7 @@ class ChooseCharacters extends Component {
<div className="row"> <div className="row">
<div className="col-sm-6"> <div className="col-sm-6">
<div className="panel panel-default"> <div className="panel panel-default">
<div className="panel-heading">Hiragana · ひらがな<span className="pull-right">Progress</span></div> <div className="panel-heading">Hiragana · ひらがな</div>
<div className="panel-body selection-areas"> <div className="panel-body selection-areas">
{this.showGroupRows('hiragana')} {this.showGroupRows('hiragana')}
</div> </div>
@ -116,7 +116,7 @@ class ChooseCharacters extends Component {
</div> </div>
<div className="col-sm-6"> <div className="col-sm-6">
<div className="panel panel-default"> <div className="panel panel-default">
<div className="panel-heading">Katakana · カタカナ<span className="pull-right">Progress</span></div> <div className="panel-heading">Katakana · カタカナ</div>
<div className="panel-body selection-areas"> <div className="panel-body selection-areas">
{this.showGroupRows('katakana')} {this.showGroupRows('katakana')}
</div> </div>

View file

@ -40,8 +40,6 @@ class GameContainer extends Component {
{ this.props.gameState==='chooseCharacters' ? { this.props.gameState==='chooseCharacters' ?
<ChooseCharacters selectedGroups={this.state.decidedGroups} <ChooseCharacters selectedGroups={this.state.decidedGroups}
handleStartGame={this.startGame} handleStartGame={this.startGame}
isAuthenticated={this.props.isAuthenticated}
nickName={this.props.nickName}
stage={this.state.stage} stage={this.state.stage}
isLocked={this.state.isLocked} isLocked={this.state.isLocked}
lockStage={this.lockStage} lockStage={this.lockStage}

View file

@ -12,9 +12,6 @@ class Navbar extends Component {
case 'game': case 'game':
leftLink = <li id="nav-choosecharacters"><a href="javascript:;" onClick={this.props.handleEndGame}><span className="glyphicon glyphicon-small glyphicon-arrow-left"></span> Back to menu</a></li> leftLink = <li id="nav-choosecharacters"><a href="javascript:;" onClick={this.props.handleEndGame}><span className="glyphicon glyphicon-small glyphicon-arrow-left"></span> Back to menu</a></li>
} }
let profileButton = this.props.isAuthenticated ?
<a href="javascript:;" onClick={this.props.handleLogout}><span className="glyphicon glyphicon-small glyphicon-log-out"></span> Log out</a> :
<a href="javascript:;" onClick={this.props.handleLogin}><span className="glyphicon glyphicon-small glyphicon-log-in"></span> Log in</a>;
return ( return (
<nav className="navbar navbar-inverse navbar-fixed-top" role="navigation"> <nav className="navbar navbar-inverse navbar-fixed-top" role="navigation">
<div className="container"> <div className="container">
@ -22,20 +19,11 @@ class Navbar extends Component {
<ul className="nav navbar-nav"> <ul className="nav navbar-nav">
{leftLink} {leftLink}
</ul> </ul>
<ul className="nav navbar-nav navbar-right">
<li id="nav-profile">{profileButton}</li>
</ul>
</div> </div>
</div> </div>
</nav> </nav>
) )
} }
} }
// <li id="nav-settings"><a href="#"><span className="glyphicon glyphicon-small glyphicon-cog"></span><span className="hidden-nano"> Settings</span></a></li>
// <div>{this.props.profile.hasOwnProperty('user_id')?this.props.profile.name+' is logged in':'not logged in'}</div>
// <ul className="nav navbar-nav">
// <li id="nav-about"><a href="#menu">&lt; Back to menu</a></li>
// </ul>
export default Navbar; export default Navbar;

View file

@ -1,75 +0,0 @@
import { EventEmitter } from 'events'
import { isTokenExpired } from './jwtHelper'
import Auth0Lock from 'auth0-lock'
export default class AuthService extends EventEmitter {
constructor(clientId, domain, options) {
super()
// Configure Auth0
this.lock = new Auth0Lock(clientId, domain, options)
// Add callback for lock `authenticated` event
this.lock.on('authenticated', this._doAuthentication.bind(this))
// Add callback for lock `authorization_error` event
this.lock.on('authorization_error', this._authorizationError.bind(this))
// binds login functions to keep this context
this.login = this.login.bind(this)
}
_doAuthentication(authResult){
// Saves the user token
this.setToken(authResult.idToken)
// Async loads the user profile data
this.lock.getProfile(authResult.idToken, (error, profile) => {
if (error) {
console.log('Error loading the Profile', error)
} else {
this.setProfile(profile)
}
})
}
_authorizationError(error){
// Unexpected authentication error
console.log('Authentication Error', error)
}
login() {
// Call the show method to display the widget.
this.lock.show()
}
loggedIn(){
// Checks if there is a saved token and it's still valid
const token = this.getToken()
return !!token && !isTokenExpired(token)
}
setProfile(profile){
// Saves profile data to localStorage
localStorage.setItem('profile', JSON.stringify(profile))
// Triggers profile_updated event to update the UI
this.emit('profile_updated', profile)
}
getProfile(){
// Retrieves the profile data from localStorage
const profile = localStorage.getItem('profile')
return profile ? JSON.parse(localStorage.profile) : {}
}
setToken(idToken){
// Saves user token to localStorage
localStorage.setItem('id_token', idToken)
}
getToken(){
// Retrieves the user token from localStorage
return localStorage.getItem('id_token')
}
logout(){
// Clear user token and profile data from localStorage
localStorage.removeItem('id_token');
localStorage.removeItem('profile');
}
}

View file

@ -1,21 +0,0 @@
import decode from 'jwt-decode';
export function getTokenExpirationDate(token){
const decoded = decode(token)
if(!decoded.exp) {
return null
}
const date = new Date(0) // The 0 here is the key, which sets the date to the epoch
date.setUTCSeconds(decoded.exp)
return date
}
export function isTokenExpired(token){
const date = getTokenExpirationDate(token)
const offsetSeconds = 60*60*24*7
if (date === null) {
return false
}
return !(date.valueOf() > (new Date().valueOf() + (offsetSeconds * 1000)))
}