TW Reporter Registration Package
Host Project Environment
Installation
npm i --save twreporter-registration
Work Flow
Sign Up Account
- User sign up
- API obtain data and inform database to add new account.
- API send activation email to registered account.
- email link contain authorized token and user's email address.
- User click customized link and activate account.
- API return authorized info and the app store(action) info in localStorage.
Sig In with TWReporter(TWR) Account
- User Sign in.
- API obtain data, send request to database.
- API return auth info. The app store(action) info in localStroage.
Sign In with oAuth(Facebook, Google)
- User Sign in.
- Data from front-end App -> API -> Database
- API return auth info and redirect page to home page.
- medium of auth info is cookie.
- order of medium
- cookie
- redux state
- local storage
Usage js
- If user can't pass AuthScreen, the app will be rediected automatically according to the provided redirectPath.
import SignIn from '../containers/SignIn'
import SignUp from '../containers/SignUp'
import Activation from '../containers/Activation'
import Features from '../containers/features'
import AuthenticationScreen from 'twreporter-registration'
export default function (history = browserHistory) {
return (
<Router history={history} onUpdate={scrollAndFireTracking} >
<Route path="/topics/:slug" component={TopicLandingPage} />
<Route path="/" component={Home} />
<Route path="/" component={App}>
<Route path="signup" component={SignUp} />
<Route path="signin" component={SignIn} />
<Route path="activate" component={Activation} />
<Route path="features" component={AuthenticationScreen(Features)} redirectPath={'/signin'} />
</Route>
</Router>
)
}
Sign Up
import React from 'react'
import { connect } from 'react-redux'
import { SignUpForm } from 'twreporter-registration'
const SignUp = (props) => (
<SignUpForm
title='title'
signUpMessage='signUpMessage'
{...props}
/>
)
export default connect()(SignUp)
Sign In
import React from 'react'
import { connect } from 'react-redux'
import { SignInForm, FacebookButton, GoogleButton } from 'twreporter-registration'
const SignIn = (props) => (
<SignInForm
title={'title'}
signInRedirectPath = {'/'}
defaultStyle={true}
{...props}
>
<FacebookButton />
<GoogleButton />
</SignInForm>
)
export default connect()(SignIn)
Sign Out
- Sign out action will remove localStorage auth info and change redux state
import { Link } from 'react-router'
import { signOutAction } from 'twreporter-registration'
<Link to={`/${memberConfigs.path}`} onClick={() => {signOutAction()}}>
<div>Click here to sign out</div>
</Link>
Activation
import React from 'react'
import { ActivePage } from 'twreporter-registration'
import { browserHistory } from 'react-router'
import { connect } from 'react-redux'
const Activation = (props) => (
<div>
<ActivePage
activateRedirectPath={'/'}
browserHistory={browserHistory}
{...props}
/>
</div>
)
React Reducer
import { authReducer, configureReducer } from 'twreporter-registration'
const registrationInitialState = {
apiUrl: '',
signUp: '',
signIn: '',
activate: '',
oAuthProviders: {
google: '',
facebook: ''
},
location: '',
domain: '',
}
const ConfigureReducer = configureReducer(registrationInitialState)
const rootReducer = combineReducers({
authConfigure: ConfigureReducer,
auth: authReducer,
})
export default rootReducer
Server Side
- obtain oAuth data from cookie and pass it to redux state.
- setup authentication api server url, path(endpoints).
import cookieParser from 'cookie-parser'
import { configureAction, authUserAction, authInfoStringToObj } from 'twreporter-registration'
server.use(cookieParser())
if (req.query.login) {
const authType = req.query.login
const cookies = req.cookies
const authInfoString = cookies.auth_info
const authInfoObj = authInfoStringToObj(authInfoString)
store.dispatch(authUserAction(authType, authInfoObj))
}
const registrationConfigure = {
apiUrl: 'http://localhost:8080',
signUp: '/v1/signup',
signIn: '/v1/login',
activate: '/v1/activate',
oAuthProviders: {
google: '/v1/auth/google',
facebook: '/v1/auth/facebook'
},
location: 'http://testtest.twreporter.org:3000',
domain: 'twreporter.org'
}
store.dispatch(configureAction(registrationConfigure))
Enter Point of the Project
import { setupTokenInLocalStorage, deletAuthInfoAction, authUserByTokenAction } from 'twreporter-registration'
const { auth } = store.getState()
if(auth.authenticated && auth.authInfo && (auth.authType=== 'facebook' || auth.authType==='google')) {
setupTokenInLocalStorage(auth.authInfo)
store.dispatch(deletAuthInfoAction())
}
store.dispatch(authUserByTokenAction(7, auth.authType))
.then(() => {})
.catch(() => {})
Next.js Example
class SignIn extends React.Component {
static getInitialProps ({ store }) {
const registrationConfigure = {
apiUrl: 'http://testtest.twreporter.org:8080',
signUp: '/v1/signup',
signIn: '/v1/login',
activate: '/v1/activate',
oAuthProviders: {
google: '/v1/auth/google',
facebook: '/v1/auth/facebook'
},
location: 'http://testtest.twreporter.org:3000',
domain: 'twreporter.org'
}
store.dispatch(configureAction(registrationConfigure))
}
render() {
return (
<SignInForm
title={'Sign In to Newsletter'}
browserHistory={Router}
AssignedLink={Link}
signInRedirectPath={'/features'}
location={'http://testtest.twreporter.org:3000/features'}
domain={'twreporter.org'}
account={false}
facebook={true}
google={true}
defaultStyle={false}
/>
)
}
}
Development
npm run dev //development mode
npm run build //production mode
//Hard reload development without npm link
CUSTOMER_FOLDER=/Users/hanReporter/Documents/twReporter_frontEnd/twreporter-react npm run dev
-
advice for developer/programmer:
You can program in es2015 + es2017 and only need to edit files in src directory.
All files will be transpiled through babel-preset-es2017 and transferred to lib directory.
-
TO DO
create next version of active page