Skip to content

Instantly share code, notes, and snippets.

@jermsam
Last active May 14, 2018 08:17
Show Gist options
  • Save jermsam/a693a54d4ba86cfb4f0a31fa15f78c93 to your computer and use it in GitHub Desktop.
Save jermsam/a693a54d4ba86cfb4f0a31fa15f78c93 to your computer and use it in GitHub Desktop.
AUthUser Stays when I logout.
import React,{Component} from 'react'
import PropTypes from 'prop-types'
import { compose } from 'recompose'
import {connect} from 'react-redux'
import {
withRouter,
} from 'react-router-dom';
import {
Divider, Message,Container,Header
} from 'semantic-ui-react';
import {session,getUserFromJwtTocken} from '../services';
import PublicLayout from "./frames/PublicLayout";
import NearBottom from "./navs/NearBottom";
import Next2Footer from "./navs/Next2Footer";
import './css/nav.css'
import SigninForm from './forms/SigninForm'
/* eslint-disable no-console */
class SigninPageUI extends Component{
onSubmit= (user) => {
const {history:{push},onLogin,retrieveAuthUserFromJWT} = this.props;
return onLogin(user).then(res=>res.value.accessToken)
.then(t=>retrieveAuthUserFromJWT(t))
.then(u=>u.value.id)
.then(id=>push(`/users/${id}`))
.catch(() => {
console.log("PPPPPP: ",this.props.errors);
});
}
render(){
const {history,loading,errors,isVerified,verifiedUser} = this.props
const errs =(errors)? errors.message.split(","):'';
return(
<PublicLayout
className="register"
url1="/" link1="Home"
url2="/signup" link2="Sign up"
url3="/htw" link3="How It Works"
>
<Divider section hidden/>
{errors &&
<Container text textAlign='justified'>
<Message
error
header='There are some errors with your submission'
list={errs.map(e=>e)}
/>
</Container>
}{
isVerified?
<Container text>
<Divider section hidden />
<Message>
<Header as ='h1'> Greetings {verifiedUser.firstname} {verifiedUser.lastname}</Header>
<Header>
Your Account Has Been Verified
</Header>
</Message>
<Divider section hidden/>
<SigninForm
user={verifiedUser}
onSubmit={this.onSubmit}
errors={errors}
loading={loading}
history={history}
/>
</Container>
:
<Container text>
<Divider section hidden />
<SigninForm
user={verifiedUser}
onSubmit={this.onSubmit}
errors={errors}
loading={loading}
history={history}
/>
</Container>
}
<NearBottom/>
<Next2Footer/>
</PublicLayout>
);
}
}
SigninPageUI.propTypes={
verifiedUser:PropTypes.shape({}),
isVerified:PropTypes.bool,
loading:PropTypes.bool,
errors:PropTypes.shape({}),
history:PropTypes.shape({
push:PropTypes.func.isRequired
}).isRequired,
onLogin:PropTypes.func.isRequired,
retrieveAuthUserFromJWT:PropTypes.func.isRequired,
}
SigninPageUI.defaultProps={
isVerified:false,
verifiedUser:null,
errors:{},
loading:false
}
/**
* To use connect(), you need to define a special function called mapStateToProps
* that tells how to transform the current Redux store state into the props you want
* to pass to a presentational component you are wrapping.
*/
const mapStateToProps =(state) =>({
authUser:state.sessionState.user,
errors: state.sessionState.isError ,
loading:state.sessionState.isLoading,
user:state.userState.data||{
email:'',password:'',id:null
},
isVerified:state.authManagementState.isFinished,
verifiedUser:state.authManagementState.data||{
email:'',password:'',id:null
}
})
/**
* In addition to reading the state, container components can dispatch actions.
* In a similar fashion, you can define a function called mapDispatchToProps() that receives the dispatch() method
* and returns callback props that you want to inject into the presentational component.
*/
// SERVICES_MESSAGES_FIND
const mapDispatchToProps = (dispatch) => ({
// Sign in with credentials
onLogin: (user) =>dispatch(session.authenticate({ strategy: 'local', ...user})),
retrieveAuthUserFromJWT : jwt=> dispatch({
type: 'RETRIEVE_AUTH_USER_FROMJWT',
// payload:authUser
payload: getUserFromJwtTocken(jwt)
}),
});
const SigninPage=compose(
withRouter,
connect(
mapStateToProps,
mapDispatchToProps
),
)(SigninPageUI)
export default SigninPage;
import { combineReducers } from 'redux';
import {reducer as formReducer} from 'redux-form'
import {session,services} from './services';
const INITIAL_STATE = {
authUser: null,
isLoading:false,
isSet:false
};
const authUserReducer =(state = INITIAL_STATE, action) =>{
switch(action.type) {
case 'RETRIEVE_AUTH_USER_FROMJWT_PENDING':{
/* eslint-disable no-console */
console.log("Retrieve Auth User From Token: Pending...")
return {
...state,
authUser:null,
loading: true,
isSet:false
}
}
case 'RETRIEVE_AUTH_USER_FROMJWT_FULFILLED':{
/* eslint-disable no-console */
console.log("Retreive Auth User From Token Fulfilled: ",action.payload)
return {
...state,
authUser:action.payload,
loading: false,
isSet:true
}
}
case 'CLEAR_AUTH_USER_FROM_STORE_FULFILLED':{
/* eslint-disable no-console */
console.log(" Cleared Auth User From Store Fullflled: ")
return {
...state,
authUser:null
}
}
default : return state;
}
}
// Configure reducers
const reducers ={
sessionState: session.reducer,
userState:services.users.reducer,
authManagementState: services.authManagement.reducer,
authUserState:authUserReducer,
// postState:services.users.reducer,
// commentState:services.users.reducer,
form:formReducer
}
// combine reducers
const rootReducer = combineReducers(reducers)
export default rootReducer;
import reduxifyServices ,{ getServicesStatus as getStatus } from 'feathers-redux';
import reduxifyAuthentication from 'feathers-reduxify-authentication';
/* eslint-disable no-console */
// well Configured and authenticated feathers-client
import app from './app'
const checkEmtpyAuthUser = authUser =>Object.keys(authUser).length === 0 && authUser.constructor === Object
async function getUserFromJwtTocken(token) {
try {
// Get our initialized service so that we can register hooks and filters
const service = app.service('users');
console.log('token: ',token)
const payload = await app.passport.verifyJWT(token);
console.log('payload: ',payload)
const user = await service.get(payload.userId);
console.log('we got: ',user)
return checkEmtpyAuthUser(user)? null:user;
} catch (err) {
return {};
}
}
async function checkIfUserIsVerified() {
try {
const token = localStorage.getItem('feathers-jwt');
// Get our initialized service so that we can register hooks and filters
const user = await getUserFromJwtTocken(token);
return user&&user.isVerified ;
} catch (err) {
return {};
}
}
// store jwt to localStorage
async function setJwtTocken(token) {
try {
// remove cause it was for testing purposes
// localStorage.removeItem('feathers-jwt');
return await window.localStorage.setItem('feathers-jwt', token);
} catch (err) {
return {};
}
}
// Reduxify feathers-client.authentication
const session = reduxifyAuthentication(app,
checkIfUserIsVerified().then(t=> ({isUserAuthorized: t}) ) // WE INSIST USER IS 'verified' TO AUTHENTICATE
);
/**
// Sign in with the JWT currently in localStorage
if (localStorage['feathers-jwt']) {
store.dispatch(signin.authenticate()).catch(err => { ... });
}
// Sign in with credentials
store.dispatch(signin.authenticate({ type: 'local', email, password }))
.then(() => { ... )
.catch(err => { ... });
*/
const services = reduxifyServices(app, ['users','authManagement']);
/**
* // email addr verification with long token
// Feathers is now 100% compatible with Redux. Use just like [Feathers method calls.](#methods)
store.dispatch(services.authManagement.create({ action: 'verifySignupLong',
value: verifyToken,
}, {})
);
*/
export{
app,
setJwtTocken,
getUserFromJwtTocken,
session,
services,
getStatus
}
// With Login button
//.......
justLogout=()=>{
const {onLogout,history:{push},clearAuthUserFromJWT} = this.props;
clearAuthUserFromJWT().then(()=>onLogout()).then(()=>push('/'))
}
//.......
<Menu.Menu position = "right">
{(!isLoggedin||(isLoggedin && url1!=='/signin' && url1!=='/signup')) && <Menu.Item as={Link} to={url1} > {link1}</Menu.Item>}
{(!isLoggedin||(isLoggedin && url2!=='/signin' && url2!=='/signup')) && <Menu.Item as={Link} to={url2} > {link2} </Menu.Item>}
{(!isLoggedin||(isLoggedin && url3!=='/signin' && url3!=='/signup')) && <Menu.Item as={Link} to={url3} > {link3} </Menu.Item>}
{isLoggedin && <Menu.Item > <Form onSubmit={this.justLogout}><Button type='submit' >Logout</Button></Form> </Menu.Item> }
</Menu.Menu>
//.....
const mapStateToProps = (state) => ({
isLoggedin: state.sessionState.isSignedIn,
});
const mapDispatchToProps = (dispatch) => ({
// Sign in with credentials
onLogout: async () =>dispatch(session.logout()),
clearAuthUserFromJWT: async () => {
try{
await localStorage.removeItem('feathers-jwt')
return dispatch({
type: 'CLEAR_AUTH_USER_FROM_STORE',
// payload:contacts
authUser: null
})
}catch(err){
console.log(err)
return null
}
}
});
export default compose(withRouter,connect(mapStateToProps,mapDispatchToProps))(TopNavigation);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment