From 4883bb17b9d249fb5b7f67798f9ac262c7798c17 Mon Sep 17 00:00:00 2001 From: Chi Vinh Le Date: Fri, 9 Feb 2018 00:08:31 +0100 Subject: [PATCH] Finish refactor embed stream auth --- client/coral-embed-stream/src/AppRouter.js | 25 ------ .../coral-embed-stream/src/actions/login.js | 86 +++---------------- .../src/components/Embed.js | 8 +- .../src/containers/Embed.js | 9 +- client/coral-embed-stream/src/index.js | 4 +- .../coral-embed-stream/src/reducers/login.js | 17 +++- .../src/tabs/stream/containers/Stream.js | 5 +- client/coral-framework/actions/auth.js | 10 +++ client/coral-framework/constants/auth.js | 3 + client/coral-framework/reducers/auth.js | 19 ++++ client/coral-login/src/containers/Main.js | 9 ++ client/coral-login/src/index.js | 23 +++++ client/coral-login/src/reducers/index.js | 1 + .../client/components/UserBox.js | 7 +- routes/index.js | 4 + views/login.ejs | 20 +++++ webpack.config.js | 1 + 17 files changed, 132 insertions(+), 119 deletions(-) delete mode 100644 client/coral-embed-stream/src/AppRouter.js create mode 100644 client/coral-login/src/containers/Main.js create mode 100644 client/coral-login/src/index.js create mode 100644 client/coral-login/src/reducers/index.js create mode 100644 views/login.ejs diff --git a/client/coral-embed-stream/src/AppRouter.js b/client/coral-embed-stream/src/AppRouter.js deleted file mode 100644 index ec7b6300a..000000000 --- a/client/coral-embed-stream/src/AppRouter.js +++ /dev/null @@ -1,25 +0,0 @@ -import React from 'react'; -import { Router, Route } from 'react-router'; -import PropTypes from 'prop-types'; - -import Embed from './containers/Embed'; -import { LoginContainer } from './containers/LoginContainer'; - -const routes = ( -
- - -
-); - -class AppRouter extends React.Component { - static contextTypes = { - history: PropTypes.object, - }; - - render() { - return ; - } -} - -export default AppRouter; diff --git a/client/coral-embed-stream/src/actions/login.js b/client/coral-embed-stream/src/actions/login.js index 3a110c1b9..84c98ea78 100644 --- a/client/coral-embed-stream/src/actions/login.js +++ b/client/coral-embed-stream/src/actions/login.js @@ -3,12 +3,7 @@ import bowser from 'bowser'; import * as actions from '../constants/login'; import { notify } from 'coral-framework/actions/notification'; import t from 'coral-framework/services/i18n'; -import get from 'lodash/get'; - -export const updateStatus = status => ({ - type: actions.UPDATE_STATUS, - status, -}); +import { checkLogin } from 'coral-framework/actions/auth'; export const showSignInDialog = () => ({ type: actions.SHOW_SIGNIN_DIALOG, @@ -27,10 +22,6 @@ export const hideSignInDialog = () => dispatch => { dispatch({ type: actions.HIDE_SIGNIN_DIALOG }); }; -export const resetSignInDialog = () => dispatch => { - dispatch({ type: actions.HIDE_SIGNIN_DIALOG }); -}; - export const focusSignInDialog = () => ({ type: actions.FOCUS_SIGNIN_DIALOG, }); @@ -39,6 +30,17 @@ export const blurSignInDialog = () => ({ type: actions.BLUR_SIGNIN_DIALOG, }); +// TODO: remove the rest. + +export const updateStatus = status => ({ + type: actions.UPDATE_STATUS, + status, +}); + +export const resetSignInDialog = () => dispatch => { + dispatch({ type: actions.HIDE_SIGNIN_DIALOG }); +}; + export const showCreateUsernameDialog = () => ({ type: actions.SHOW_CREATEUSERNAME_DIALOG, }); @@ -276,70 +278,6 @@ export const logout = () => async ( pym.sendMessage('coral-auth-changed'); }; -//============================================================================== -// CHECK LOGIN -//============================================================================== - -const checkLoginRequest = () => ({ type: actions.CHECK_LOGIN_REQUEST }); -const checkLoginFailure = error => ({ - type: actions.CHECK_LOGIN_FAILURE, - error, -}); - -const checkLoginSuccess = (user, isAdmin) => ({ - type: actions.CHECK_LOGIN_SUCCESS, - user, - isAdmin, -}); - -const ErrNotLoggedIn = new Error('Not logged in'); - -export const checkLogin = () => ( - dispatch, - _, - { rest, client, pym, localStorage } -) => { - dispatch(checkLoginRequest()); - rest('/auth') - .then(result => { - if (!result.user) { - if (localStorage) { - localStorage.removeItem('token'); - localStorage.removeItem('exp'); - } - throw ErrNotLoggedIn; - } - - // Reset the websocket. - client.resetWebsocket(); - - dispatch(checkLoginSuccess(result.user)); - pym.sendMessage('coral-auth-changed', JSON.stringify(result.user)); - - // This is for login via social. Usernames should be set. - if ( - get(result.user, 'status.username.status') === 'UNSET' && - !get(result.user, 'status.banned.status') - ) { - dispatch(showCreateUsernameDialog()); - } - }) - .catch(error => { - if (error !== ErrNotLoggedIn) { - console.error(error); - } - if (error.status && error.status === 401 && localStorage) { - // Unauthorized. - localStorage.removeItem('token'); - localStorage.removeItem('exp'); - } - const errorMessage = error.translation_key - ? t(`error.${error.translation_key}`) - : error.toString(); - dispatch(checkLoginFailure(errorMessage)); - }); -}; - export const validForm = () => ({ type: actions.VALID_FORM }); export const invalidForm = error => ({ type: actions.INVALID_FORM, error }); diff --git a/client/coral-embed-stream/src/components/Embed.js b/client/coral-embed-stream/src/components/Embed.js index 059e72ed3..b7eb6d580 100644 --- a/client/coral-embed-stream/src/components/Embed.js +++ b/client/coral-embed-stream/src/components/Embed.js @@ -62,7 +62,7 @@ export default class Embed extends React.Component { blurSignInDialog, focusSignInDialog, hideSignInDialog, - router: { location: { query: { parentUrl } } }, + parentUrl, } = this.props; const hasHighlightedComment = !!commentId; @@ -75,9 +75,7 @@ export default class Embed extends React.Component { ); } @@ -297,6 +296,7 @@ EmbedContainer.propTypes = { commentId: PropTypes.string, root: PropTypes.object, activeTab: PropTypes.string, + parentUrl: PropTypes.string, data: PropTypes.object, fetchAssetSuccess: PropTypes.func, showSignInDialog: PropTypes.bool, @@ -315,13 +315,12 @@ const mapStateToProps = state => ({ sortBy: state.stream.sortBy, showSignInDialog: state.login.showSignInDialog, signInDialogFocus: state.login.signInDialogFocus, + parentUrl: state.login.parentUrl, }); const mapDispatchToProps = dispatch => bindActionCreators( { - logout, - checkLogin, setActiveTab, fetchAssetSuccess, notify, diff --git a/client/coral-embed-stream/src/index.js b/client/coral-embed-stream/src/index.js index 2ab279eb8..a4c6bcd39 100644 --- a/client/coral-embed-stream/src/index.js +++ b/client/coral-embed-stream/src/index.js @@ -1,9 +1,9 @@ import React from 'react'; import { render } from 'react-dom'; +import Embed from './containers/Embed'; import graphqlExtension from './graphql'; import { createContext } from 'coral-framework/services/bootstrap'; -import AppRouter from './AppRouter'; import reducers from './reducers'; import TalkProvider from 'coral-framework/components/TalkProvider'; import pluginsConfig from 'pluginsConfig'; @@ -16,7 +16,7 @@ async function main() { }); render( - + , document.querySelector('#talk-embed-stream-container') ); diff --git a/client/coral-embed-stream/src/reducers/login.js b/client/coral-embed-stream/src/reducers/login.js index db9106691..febf4fd51 100644 --- a/client/coral-embed-stream/src/reducers/login.js +++ b/client/coral-embed-stream/src/reducers/login.js @@ -3,11 +3,14 @@ import pym from 'coral-framework/services/pym'; import merge from 'lodash/merge'; const initialState = { + parentUrl: pym.parentUrl || location.href, + showSignInDialog: false, + signInDialogFocus: false, + + // TODO: remove the rest isLoading: false, loggedIn: false, user: null, - showSignInDialog: false, - signInDialogFocus: false, showCreateUsernameDialog: false, checkedInitialLogin: false, view: 'SIGNIN', @@ -46,8 +49,16 @@ export default function login(state = initialState, action) { showSignInDialog: true, signInDialogFocus: true, }; - case actions.RESET_SIGNIN_DIALOG: + case actions.HIDE_SIGNIN_DIALOG: + return { + ...state, + showSignInDialog: false, + signInDialogFocus: false, + }; + + // TODO: remove the rest. + case actions.RESET_SIGNIN_DIALOG: return { ...state, isLoading: false, diff --git a/client/coral-embed-stream/src/tabs/stream/containers/Stream.js b/client/coral-embed-stream/src/tabs/stream/containers/Stream.js index 59a449244..5e0e3131b 100644 --- a/client/coral-embed-stream/src/tabs/stream/containers/Stream.js +++ b/client/coral-embed-stream/src/tabs/stream/containers/Stream.js @@ -14,7 +14,10 @@ import { withEditComment, } from 'coral-framework/graphql/mutations'; -import { showSignInDialog, editName } from 'coral-embed-stream/src/actions/login'; +import { + showSignInDialog, + editName, +} from 'coral-embed-stream/src/actions/login'; import { notify } from 'coral-framework/actions/notification'; import { setActiveReplyBox, diff --git a/client/coral-framework/actions/auth.js b/client/coral-framework/actions/auth.js index ed5ae4d97..0c4780548 100644 --- a/client/coral-framework/actions/auth.js +++ b/client/coral-framework/actions/auth.js @@ -98,3 +98,13 @@ export const logout = () => async ( dispatch({ type: actions.LOGOUT }); pym.sendMessage('coral-auth-changed'); }; + +export const updateStatus = status => ({ + type: actions.UPDATE_STATUS, + status, +}); + +export const updateUsername = username => ({ + type: actions.UPDATE_USERNAME, + username, +}); diff --git a/client/coral-framework/constants/auth.js b/client/coral-framework/constants/auth.js index 655c29260..25e2f6a78 100644 --- a/client/coral-framework/constants/auth.js +++ b/client/coral-framework/constants/auth.js @@ -6,3 +6,6 @@ export const CHECK_LOGIN_FAILURE = `${prefix}_CHECK_LOGIN_FAILURE`; export const LOGOUT = `${prefix}_LOGOUT`; export const HANDLE_SUCCESSFUL_LOGIN = `${prefix}_HANDLE_SUCCESSFUL_LOGIN`; + +export const UPDATE_STATUS = '${prefix}_UPDATE_STATUS'; +export const UPDATE_USERNAME = '${prefix}_UPDATE_USERNAME'; diff --git a/client/coral-framework/reducers/auth.js b/client/coral-framework/reducers/auth.js index 04e75bbb4..3af606d0b 100644 --- a/client/coral-framework/reducers/auth.js +++ b/client/coral-framework/reducers/auth.js @@ -1,4 +1,5 @@ import * as actions from '../constants/auth'; +import merge from 'lodash/merge'; const initialState = { checkedInitialLogin: false, @@ -36,6 +37,24 @@ export default function auth(state = initialState, action) { ...state, user: null, }; + case actions.UPDATE_STATUS: { + return { + ...state, + user: { + ...state.user, + status: merge({}, state.user.status, action.status), + }, + }; + } + case actions.UPDATE_USERNAME: + return { + ...state, + user: { + ...state.user, + username: action.username, + lowercaseUsername: action.username.toLowerCase(), + }, + }; default: return state; } diff --git a/client/coral-login/src/containers/Main.js b/client/coral-login/src/containers/Main.js new file mode 100644 index 000000000..23193bbb6 --- /dev/null +++ b/client/coral-login/src/containers/Main.js @@ -0,0 +1,9 @@ +import React from 'react'; + +class Main extends React.Component { + render() { + return
Hello World
; + } +} + +export default Main; diff --git a/client/coral-login/src/index.js b/client/coral-login/src/index.js new file mode 100644 index 000000000..71eaaabe8 --- /dev/null +++ b/client/coral-login/src/index.js @@ -0,0 +1,23 @@ +import React from 'react'; +import { render } from 'react-dom'; + +import { createContext } from 'coral-framework/services/bootstrap'; +import Main from './containers/Main'; +import reducers from './reducers'; +import TalkProvider from 'coral-framework/components/TalkProvider'; +import pluginsConfig from 'pluginsConfig'; + +async function main() { + const context = await createContext({ + reducers, + pluginsConfig, + }); + render( + +
+ , + document.querySelector('#talk-login-container') + ); +} + +main(); diff --git a/client/coral-login/src/reducers/index.js b/client/coral-login/src/reducers/index.js new file mode 100644 index 000000000..ff8b4c563 --- /dev/null +++ b/client/coral-login/src/reducers/index.js @@ -0,0 +1 @@ +export default {}; diff --git a/plugins/talk-plugin-auth/client/components/UserBox.js b/plugins/talk-plugin-auth/client/components/UserBox.js index 96d66cc7b..09e4302b6 100644 --- a/plugins/talk-plugin-auth/client/components/UserBox.js +++ b/plugins/talk-plugin-auth/client/components/UserBox.js @@ -3,11 +3,11 @@ import styles from './styles.css'; import { connect } from 'react-redux'; import { bindActionCreators } from 'redux'; import t from 'coral-framework/services/i18n'; -import { logout } from 'coral-embed-stream/src/actions/login'; +import { logout } from 'coral-framework/actions/auth'; -const UserBox = ({ loggedIn, user, logout, onShowProfile }) => ( +const UserBox = ({ user, logout, onShowProfile }) => (
- {loggedIn ? ( + {user ? (
{t('sign_in.logged_in_as')} @@ -25,7 +25,6 @@ const UserBox = ({ loggedIn, user, logout, onShowProfile }) => ( ); const mapStateToProps = ({ auth }) => ({ - loggedIn: auth.loggedIn, user: auth.user, }); diff --git a/routes/index.js b/routes/index.js index 48981faff..242b753ce 100644 --- a/routes/index.js +++ b/routes/index.js @@ -160,6 +160,10 @@ if (process.env.NODE_ENV !== 'production') { }); } +router.use('/login', staticTemplate, async (req, res, next) => { + return res.render('login'); +}); + // Inject server route plugins. plugins.get('server', 'router').forEach(plugin => { debug(`added plugin '${plugin.plugin.name}'`); diff --git a/views/login.ejs b/views/login.ejs new file mode 100644 index 000000000..634054074 --- /dev/null +++ b/views/login.ejs @@ -0,0 +1,20 @@ + + + + + + + + <%_ if (locals.customCssUrl) { _%> + + <%_ } _%> + <%_ if (data != null) { _%> + + <%_ } _%> + + + +
+ + + diff --git a/webpack.config.js b/webpack.config.js index 6a018caba..fb6240d07 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -21,6 +21,7 @@ debug(`Using ${pluginsPath} as the plugin configuration path`); const buildTargets = [ 'coral-admin', + 'coral-login', 'coral-docs', { name: 'coral-auth-callback', disablePolyfill: true }, ];