login feature removal
This commit is contained in:
parent
613449a82c
commit
101dc0504d
|
@ -1,2 +1,3 @@
|
|||
# Nothing interesting here
|
||||
Early alpha of Kana Quiz remade with React.js and Auth0
|
||||
# Kana Quiz 2
|
||||
Kana Quiz remade with React.js.
|
||||
See live at http://simplemedia.org/kana/
|
||||
|
|
|
@ -37,10 +37,9 @@
|
|||
"webpack-dev-server": "^1.14.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"auth0-lock": "^10.0.0",
|
||||
"jwt-decode": "^2.1.0",
|
||||
"postcss": "^5.1.0",
|
||||
"react": "^15.2.1",
|
||||
"react-addons-css-transition-group": "^15.3.0",
|
||||
"react-dom": "^15.2.1",
|
||||
"react-toggle-switch": "^2.1.2"
|
||||
}
|
||||
|
|
|
@ -1,38 +1,21 @@
|
|||
import React, { Component } from 'react';
|
||||
import AuthService from '../../utils/AuthService'
|
||||
import './App.scss';
|
||||
import Navbar from '../Navbar/Navbar';
|
||||
import GameContainer from '../GameContainer/GameContainer';
|
||||
import { removeHash } from '../../data/helperFuncs';
|
||||
|
||||
const options = {};
|
||||
const auth = new AuthService(__AUTH0_CLIENT_ID__, __AUTH0_DOMAIN__, options);
|
||||
|
||||
class App extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
isAuthenticated: this.isAuthenticated(),
|
||||
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.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() {
|
||||
this.setState({gameState: 'game'});
|
||||
}
|
||||
|
@ -41,34 +24,22 @@ class App extends Component {
|
|||
this.setState({gameState: 'chooseCharacters'});
|
||||
}
|
||||
|
||||
logout() {
|
||||
auth.logout();
|
||||
this.setState({isAuthenticated: this.isAuthenticated()});
|
||||
}
|
||||
|
||||
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 (
|
||||
<div>
|
||||
<Navbar isAuthenticated={this.state.isAuthenticated}
|
||||
handleLogin={auth.login.bind(this)}
|
||||
handleLogout={this.logout}
|
||||
<Navbar
|
||||
gameState={this.state.gameState}
|
||||
handleEndGame={this.endGame}
|
||||
/>
|
||||
<div className="outercontainer">
|
||||
<div className="container game">
|
||||
<GameContainer
|
||||
isAuthenticated={this.state.isAuthenticated}
|
||||
nickName={this.getNickName()}
|
||||
gameState={this.state.gameState}
|
||||
handleStartGame={this.startGame}
|
||||
handleEndGame={this.endGame}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row text-center">{loginButton}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -55,7 +55,6 @@ class CharacterGroup extends Component {
|
|||
<span className={this.props.selected ?
|
||||
'glyphicon glyphicon-small glyphicon-check' :
|
||||
'glyphicon glyphicon-small glyphicon-unchecked'}></span> {this.state.shownChars}
|
||||
<span className="pull-right success-percent">0 %</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -96,7 +96,7 @@ class ChooseCharacters extends Component {
|
|||
<div className="col-xs-12">
|
||||
<div className="panel panel-default">
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -105,7 +105,7 @@ class ChooseCharacters extends Component {
|
|||
<div className="row">
|
||||
<div className="col-sm-6">
|
||||
<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">
|
||||
{this.showGroupRows('hiragana')}
|
||||
</div>
|
||||
|
@ -116,7 +116,7 @@ class ChooseCharacters extends Component {
|
|||
</div>
|
||||
<div className="col-sm-6">
|
||||
<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">
|
||||
{this.showGroupRows('katakana')}
|
||||
</div>
|
||||
|
|
|
@ -40,8 +40,6 @@ class GameContainer extends Component {
|
|||
{ this.props.gameState==='chooseCharacters' ?
|
||||
<ChooseCharacters selectedGroups={this.state.decidedGroups}
|
||||
handleStartGame={this.startGame}
|
||||
isAuthenticated={this.props.isAuthenticated}
|
||||
nickName={this.props.nickName}
|
||||
stage={this.state.stage}
|
||||
isLocked={this.state.isLocked}
|
||||
lockStage={this.lockStage}
|
||||
|
|
|
@ -12,9 +12,6 @@ class Navbar extends Component {
|
|||
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>
|
||||
}
|
||||
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 (
|
||||
<nav className="navbar navbar-inverse navbar-fixed-top" role="navigation">
|
||||
<div className="container">
|
||||
|
@ -22,20 +19,11 @@ class Navbar extends Component {
|
|||
<ul className="nav navbar-nav">
|
||||
{leftLink}
|
||||
</ul>
|
||||
<ul className="nav navbar-nav navbar-right">
|
||||
<li id="nav-profile">{profileButton}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</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">< Back to menu</a></li>
|
||||
// </ul>
|
||||
|
||||
export default Navbar;
|
|
@ -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');
|
||||
}
|
||||
}
|
|
@ -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)))
|
||||
}
|
Loading…
Reference in a new issue