diff options
Diffstat (limited to 'animism-align/frontend/app/views/auth')
5 files changed, 100 insertions, 26 deletions
diff --git a/animism-align/frontend/app/views/auth/auth.actions.js b/animism-align/frontend/app/views/auth/auth.actions.js index d7663b7..936e062 100644 --- a/animism-align/frontend/app/views/auth/auth.actions.js +++ b/animism-align/frontend/app/views/auth/auth.actions.js @@ -1,12 +1,14 @@ import fetch from 'node-fetch' +import jsonwebtoken from 'jsonwebtoken' +import * as types from 'app/types' import { session } from 'app/session' const urls = { login: "/api/v1/auth/login", } -export const login = (data) => dispatch => ( +export const login = data => dispatch => ( fetch(urls.login, { method: 'POST', body: JSON.stringify(data), @@ -18,16 +20,26 @@ export const login = (data) => dispatch => ( }) .then(req => req.json()) .then(res => { - if (res.access_token) { - session.set('access_token', res.access_token) + if (!res.access_token) { + throw new Error(res.description) } - return res - }) - .catch(error => { - console.error(error) + session.set('access_token', res.access_token) + load_access_token()(dispatch) }) ) +export const load_access_token = () => dispatch => { + const access_token = session.get('access_token') || null + if (access_token) { + const creds = jsonwebtoken.decode(access_token) + const user_id = creds.identity + return dispatch({ type: types.auth.logged_in, user_id }) + } else { + return dispatch({ type: types.auth.logged_out }) + } +} + export const logout = () => dispatch => { session.set('access_token', '') + return dispatch({ type: types.auth.logged_out }) } diff --git a/animism-align/frontend/app/views/auth/auth.css b/animism-align/frontend/app/views/auth/auth.css index e9ceb85..2bf5053 100644 --- a/animism-align/frontend/app/views/auth/auth.css +++ b/animism-align/frontend/app/views/auth/auth.css @@ -2,13 +2,13 @@ position: fixed; top: 0; left: 0; width: 100%; height: 100%; - background: linear-gradient(#190051, #1c0406); + background: linear-gradient(#190051, #020800); display: flex; justify-content: center; align-items: center; } .login { - background: #333; + background: #282828; padding: 1rem; box-shadow: 0 5px 10px #000; } diff --git a/animism-align/frontend/app/views/auth/auth.gate.js b/animism-align/frontend/app/views/auth/auth.gate.js index 498d32a..ba69256 100644 --- a/animism-align/frontend/app/views/auth/auth.gate.js +++ b/animism-align/frontend/app/views/auth/auth.gate.js @@ -1,4 +1,5 @@ import React, { Component } from 'react' +import { connect } from 'react-redux' import './auth.css' @@ -6,24 +7,49 @@ import actions from 'app/actions' import AuthLogin from './auth.login' -export default class AuthGate extends Component { +class AuthGate extends Component { constructor(props) { super(props) + actions.auth.load_access_token() } - componentDidMount() { - // actions.site.loadProject() + componentDidUpdate(prevProps) { + if (this.props.user_id !== prevProps.user_id) { + this.load() + } } - componentDidUpdate() { - + load() { + if (!this.props.user_id) return + actions.user.show(this.props.user_id) + .then(() => { + actions.site.loadProject() + }).catch(error => { + if (error.status_code === 401) { + actions.auth.logout() + } else { + console.error(error) + } + }) } render() { + if (this.props.user) { + return this.props.children + } return ( <div className='auth'> - <AuthLogin /> + {this.props.logged_in + ? <div className="login">Logging in...</div> + : <AuthLogin onAuthenticate={this.load} /> + } </div> ) } -}
\ No newline at end of file +} + +const mapStateToProps = state => ({ + ...state.auth, +}) + +export default connect(mapStateToProps)(AuthGate) diff --git a/animism-align/frontend/app/views/auth/auth.login.js b/animism-align/frontend/app/views/auth/auth.login.js index 9ba4c0b..6697901 100644 --- a/animism-align/frontend/app/views/auth/auth.login.js +++ b/animism-align/frontend/app/views/auth/auth.login.js @@ -22,7 +22,6 @@ export default class AuthLogin extends Component { handleChange(e) { e && e.preventDefault() - console.log(e.target.name, e.target.value) this.setState({ data: { ...this.state.data, @@ -34,14 +33,11 @@ export default class AuthLogin extends Component { handleSubmit(e) { e && e.preventDefault() this.setState({ error: null }) - actions.auth.login(this.state) - .then(res => { - console.log(res) - if (res.error) { - this.props.onAuthenticate() - } else { - this.setState({ error }) - } + actions.auth.login(this.state.data) + .then(this.props.onAuthenticate) + .catch(error => { + console.error(error) + this.setState({ error: error.description || error.message }) }) } @@ -49,7 +45,7 @@ export default class AuthLogin extends Component { return ( <form className='login' onSubmit={this.handleSubmit}> <h6> - Welcome to the Animism Editor + {'Welcome to Animism '}{'🐍'} </h6> <TextInput title="Username" diff --git a/animism-align/frontend/app/views/auth/auth.reducer.js b/animism-align/frontend/app/views/auth/auth.reducer.js new file mode 100644 index 0000000..05741f3 --- /dev/null +++ b/animism-align/frontend/app/views/auth/auth.reducer.js @@ -0,0 +1,40 @@ +import * as types from 'app/types' +import { getDefault } from 'app/session' + +const initialState = { + logged_in: !!getDefault('access_token', false), + user_id: null, + user: null, +} + +export default function authReducer(state = initialState, action) { + // console.log(action.type, action) + switch (action.type) { + case types.auth.logged_in: + return { + ...state, + logged_in: true, + user_id: action.user_id, + user: null, + } + case types.auth.logged_out: + return { + ...state, + logged_in: false, + user_id: null, + user: null, + } + case types.user.show: + if (action.data.res.id !== state.user_id) { + return state + } + return { + ...state, + user: { + ...action.data.res, + } + } + default: + return state + } +} |
