mirror of
https://github.com/wassname/talk.git
synced 2026-08-11 11:27:10 +08:00
Auth refactor part 3
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
||||
import jwtDecode from 'jwt-decode';
|
||||
import bowser from 'bowser';
|
||||
import * as actions from '../constants/auth';
|
||||
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';
|
||||
@@ -16,17 +16,10 @@ import cn from 'classnames';
|
||||
|
||||
export default class Embed extends React.Component {
|
||||
changeTab = tab => {
|
||||
// TODO: move data fetching to appropiate containers.
|
||||
switch (tab) {
|
||||
case 'profile':
|
||||
this.props.data.refetch();
|
||||
break;
|
||||
}
|
||||
this.props.setActiveTab(tab);
|
||||
};
|
||||
|
||||
getTabs() {
|
||||
const { user } = this.props.auth;
|
||||
const tabs = [
|
||||
<Tab
|
||||
key="stream"
|
||||
@@ -43,7 +36,7 @@ export default class Embed extends React.Component {
|
||||
{t('framework.my_profile')}
|
||||
</Tab>,
|
||||
];
|
||||
if (can(user, 'UPDATE_ASSET_CONFIG')) {
|
||||
if (can(this.props.currentUser, 'UPDATE_ASSET_CONFIG')) {
|
||||
tabs.push(
|
||||
<Tab
|
||||
key="config"
|
||||
@@ -64,7 +57,8 @@ export default class Embed extends React.Component {
|
||||
root,
|
||||
root: { asset },
|
||||
data,
|
||||
auth: { showSignInDialog, signInDialogFocus },
|
||||
showSignInDialog,
|
||||
signInDialogFocus,
|
||||
blurSignInDialog,
|
||||
focusSignInDialog,
|
||||
hideSignInDialog,
|
||||
@@ -138,7 +132,9 @@ export default class Embed extends React.Component {
|
||||
|
||||
Embed.propTypes = {
|
||||
setActiveTab: PropTypes.func,
|
||||
auth: PropTypes.object,
|
||||
currentUser: PropTypes.object,
|
||||
showSignInDialog: PropTypes.bool,
|
||||
signInDialogFocus: PropTypes.bool,
|
||||
blurSignInDialog: PropTypes.func,
|
||||
focusSignInDialog: PropTypes.func,
|
||||
hideSignInDialog: PropTypes.func,
|
||||
|
||||
@@ -8,8 +8,15 @@ import branch from 'recompose/branch';
|
||||
import renderComponent from 'recompose/renderComponent';
|
||||
|
||||
import { Spinner } from 'coral-ui';
|
||||
import * as authActions from '../actions/auth';
|
||||
import * as assetActions from '../actions/asset';
|
||||
import {
|
||||
logout,
|
||||
checkLogin,
|
||||
focusSignInDialog,
|
||||
blurSignInDialog,
|
||||
hideSignInDialog,
|
||||
updateStatus,
|
||||
} from '../actions/login';
|
||||
import { fetchAssetSuccess } from '../actions/asset';
|
||||
import {
|
||||
getDefinitionName,
|
||||
getSlotFragmentSpreads,
|
||||
@@ -24,16 +31,6 @@ import t from 'coral-framework/services/i18n';
|
||||
import PropTypes from 'prop-types';
|
||||
import { setActiveTab } from '../actions/embed';
|
||||
|
||||
const {
|
||||
logout,
|
||||
checkLogin,
|
||||
focusSignInDialog,
|
||||
blurSignInDialog,
|
||||
hideSignInDialog,
|
||||
updateStatus,
|
||||
} = authActions;
|
||||
const { fetchAssetSuccess } = assetActions;
|
||||
|
||||
class EmbedContainer extends React.Component {
|
||||
static contextTypes = {
|
||||
pym: PropTypes.object,
|
||||
@@ -42,7 +39,7 @@ class EmbedContainer extends React.Component {
|
||||
subscriptions = [];
|
||||
|
||||
subscribeToUpdates(props = this.props) {
|
||||
if (props.auth.loggedIn) {
|
||||
if (props.currentUser) {
|
||||
const newSubscriptions = [
|
||||
{
|
||||
document: USER_BANNED_SUBSCRIPTION,
|
||||
@@ -80,7 +77,7 @@ class EmbedContainer extends React.Component {
|
||||
props.data.subscribeToMore({
|
||||
document: s.document,
|
||||
variables: {
|
||||
user_id: props.auth.user.id,
|
||||
user_id: props.currentUser.id,
|
||||
},
|
||||
updateQuery: s.updateQuery,
|
||||
})
|
||||
@@ -107,7 +104,7 @@ class EmbedContainer extends React.Component {
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (this.props.auth.loggedIn !== nextProps.auth.loggedIn) {
|
||||
if (this.props.currentUser !== nextProps.currentUser) {
|
||||
// Refetch after login/logout.
|
||||
this.props.data.refetch();
|
||||
this.resubscribe(nextProps);
|
||||
@@ -138,7 +135,22 @@ class EmbedContainer extends React.Component {
|
||||
if (!this.props.root.asset) {
|
||||
return <Spinner />;
|
||||
}
|
||||
return <Embed {...this.props} />;
|
||||
return (
|
||||
<Embed
|
||||
setActiveTab={this.props.setActiveTab}
|
||||
currentUser={this.props.currentUser}
|
||||
blurSignInDialog={this.props.blurSignInDialog}
|
||||
focusSignInDialog={this.props.focusSignInDialog}
|
||||
hideSignInDialog={this.props.hideSignInDialog}
|
||||
router={this.props.router}
|
||||
commentId={this.props.commentId}
|
||||
root={this.props.root}
|
||||
activeTab={this.props.activeTab}
|
||||
data={this.props.data}
|
||||
showSignInDialog={this.props.showSignInDialog}
|
||||
signInDialogFocus={this.props.signInDialogFocus}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -255,21 +267,45 @@ const EMBED_QUERY = gql`
|
||||
`;
|
||||
|
||||
export const withEmbedQuery = withQuery(EMBED_QUERY, {
|
||||
options: ({ auth, commentId, assetId, assetUrl, sortBy, sortOrder }) => ({
|
||||
options: ({
|
||||
currentUser,
|
||||
commentId,
|
||||
assetId,
|
||||
assetUrl,
|
||||
sortBy,
|
||||
sortOrder,
|
||||
}) => ({
|
||||
variables: {
|
||||
assetId,
|
||||
assetUrl,
|
||||
commentId,
|
||||
hasComment: commentId !== '',
|
||||
excludeIgnored: Boolean(auth && auth.user && auth.user.id),
|
||||
excludeIgnored: Boolean(currentUser && currentUser.id),
|
||||
sortBy,
|
||||
sortOrder,
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
EmbedContainer.propTypes = {
|
||||
setActiveTab: PropTypes.func,
|
||||
currentUser: PropTypes.object,
|
||||
blurSignInDialog: PropTypes.func,
|
||||
focusSignInDialog: PropTypes.func,
|
||||
hideSignInDialog: PropTypes.func,
|
||||
router: PropTypes.object,
|
||||
commentId: PropTypes.string,
|
||||
root: PropTypes.object,
|
||||
activeTab: PropTypes.string,
|
||||
data: PropTypes.object,
|
||||
fetchAssetSuccess: PropTypes.func,
|
||||
showSignInDialog: PropTypes.bool,
|
||||
signInDialogFocus: PropTypes.bool,
|
||||
};
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
auth: state.auth,
|
||||
currentUser: state.auth.user,
|
||||
checkedInitialLogin: state.auth.checkedInitialLogin,
|
||||
commentId: state.stream.commentId,
|
||||
assetId: state.stream.assetId,
|
||||
assetUrl: state.stream.assetUrl,
|
||||
@@ -277,6 +313,8 @@ const mapStateToProps = state => ({
|
||||
config: state.config,
|
||||
sortOrder: state.stream.sortOrder,
|
||||
sortBy: state.stream.sortBy,
|
||||
showSignInDialog: state.login.showSignInDialog,
|
||||
signInDialogFocus: state.login.signInDialogFocus,
|
||||
});
|
||||
|
||||
const mapDispatchToProps = dispatch =>
|
||||
@@ -297,6 +335,6 @@ const mapDispatchToProps = dispatch =>
|
||||
|
||||
export default compose(
|
||||
connect(mapStateToProps, mapDispatchToProps),
|
||||
branch(props => !props.auth.checkedInitialLogin, renderComponent(Spinner)),
|
||||
branch(props => !props.checkedInitialLogin, renderComponent(Spinner)),
|
||||
withEmbedQuery
|
||||
)(EmbedContainer);
|
||||
|
||||
@@ -1,55 +1,18 @@
|
||||
import React from 'react';
|
||||
import { render } from 'react-dom';
|
||||
|
||||
import {
|
||||
checkLogin,
|
||||
handleAuthToken,
|
||||
logout,
|
||||
} from 'coral-embed-stream/src/actions/auth';
|
||||
import graphqlExtension from './graphql';
|
||||
import { addExternalConfig } from 'coral-embed-stream/src/actions/config';
|
||||
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';
|
||||
|
||||
// TODO: move init code into `bootstrap` service after auth has been refactored.
|
||||
function preInit({ store, pym, inIframe }) {
|
||||
// TODO: This is popup specific code and needs to be refactored.
|
||||
if (!inIframe) {
|
||||
store.dispatch(addExternalConfig({}));
|
||||
store.dispatch(checkLogin());
|
||||
return;
|
||||
}
|
||||
|
||||
pym.onMessage('login', token => {
|
||||
if (token) {
|
||||
store.dispatch(handleAuthToken(token));
|
||||
}
|
||||
store.dispatch(checkLogin());
|
||||
});
|
||||
|
||||
pym.onMessage('logout', () => {
|
||||
store.dispatch(logout());
|
||||
});
|
||||
|
||||
return new Promise(resolve => {
|
||||
pym.sendMessage('getConfig');
|
||||
pym.onMessage('config', config => {
|
||||
store.dispatch(addExternalConfig(JSON.parse(config)));
|
||||
store.dispatch(checkLogin());
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const context = await createContext({
|
||||
reducers,
|
||||
graphqlExtension,
|
||||
pluginsConfig,
|
||||
preInit,
|
||||
});
|
||||
render(
|
||||
<TalkProvider {...context}>
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
import auth from './auth';
|
||||
import login from './login';
|
||||
import asset from './asset';
|
||||
import embed from './embed';
|
||||
import config from './config';
|
||||
import configure from './configure';
|
||||
import stream from './stream';
|
||||
|
||||
export default {
|
||||
auth,
|
||||
login,
|
||||
asset,
|
||||
embed,
|
||||
config,
|
||||
configure,
|
||||
stream,
|
||||
};
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
import * as actions from '../constants/auth';
|
||||
import * as actions from '../constants/login';
|
||||
import pym from 'coral-framework/services/pym';
|
||||
import merge from 'lodash/merge';
|
||||
|
||||
@@ -28,7 +28,7 @@ const purge = user => {
|
||||
return userData;
|
||||
};
|
||||
|
||||
export default function auth(state = initialState, action) {
|
||||
export default function login(state = initialState, action) {
|
||||
switch (action.type) {
|
||||
case actions.FOCUS_SIGNIN_DIALOG:
|
||||
return {
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as actions from '../constants/stream';
|
||||
import * as authActions from '../constants/auth';
|
||||
import * as authActions from 'coral-framework/constants/auth';
|
||||
|
||||
function getQueryVariable(variable) {
|
||||
let query = window.location.search.substring(1);
|
||||
|
||||
@@ -10,12 +10,7 @@ import NotLoggedIn from '../components/NotLoggedIn';
|
||||
import { Spinner } from 'coral-ui';
|
||||
import CommentHistory from '../components/CommentHistory';
|
||||
|
||||
// TODO: Auth logic needs refactoring.
|
||||
import {
|
||||
showSignInDialog,
|
||||
checkLogin,
|
||||
} from 'coral-embed-stream/src/actions/auth';
|
||||
|
||||
import { showSignInDialog } from 'coral-embed-stream/src/actions/login';
|
||||
import { appendNewNodes } from 'plugin-api/beta/client/utils';
|
||||
import update from 'immutability-helper';
|
||||
import { getSlotFragmentSpreads } from 'coral-framework/utils';
|
||||
@@ -24,7 +19,7 @@ import t from 'coral-framework/services/i18n';
|
||||
|
||||
class ProfileContainer extends Component {
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (!this.props.auth.loggedIn && nextProps.auth.loggedIn) {
|
||||
if (!this.props.currentUser && nextProps.currentUser) {
|
||||
// Refetch after login.
|
||||
this.props.data.refetch();
|
||||
}
|
||||
@@ -55,13 +50,7 @@ class ProfileContainer extends Component {
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
auth,
|
||||
auth: { user: authUser },
|
||||
showSignInDialog,
|
||||
root,
|
||||
data,
|
||||
} = this.props;
|
||||
const { currentUser, showSignInDialog, root, data } = this.props;
|
||||
const { me } = this.props.root;
|
||||
const loading = this.props.data.loading;
|
||||
|
||||
@@ -69,7 +58,7 @@ class ProfileContainer extends Component {
|
||||
return <div>{this.props.data.error.message}</div>;
|
||||
}
|
||||
|
||||
if (!auth.loggedIn) {
|
||||
if (!currentUser) {
|
||||
return <NotLoggedIn showSignInDialog={showSignInDialog} />;
|
||||
}
|
||||
|
||||
@@ -77,7 +66,7 @@ class ProfileContainer extends Component {
|
||||
return <Spinner />;
|
||||
}
|
||||
|
||||
const localProfile = authUser.profiles.find(p => p.provider === 'local');
|
||||
const localProfile = currentUser.profiles.find(p => p.provider === 'local');
|
||||
const emailAddress = localProfile && localProfile.id;
|
||||
|
||||
return (
|
||||
@@ -168,15 +157,20 @@ const withProfileQuery = withQuery(
|
||||
${getSlotFragmentSpreads(slots, 'root')}
|
||||
}
|
||||
${CommentFragment}
|
||||
`
|
||||
`,
|
||||
{
|
||||
options: {
|
||||
fetchPolicy: 'network-only',
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
auth: state.auth,
|
||||
currentUser: state.auth.user,
|
||||
});
|
||||
|
||||
const mapDispatchToProps = dispatch =>
|
||||
bindActionCreators({ showSignInDialog, checkLogin }, dispatch);
|
||||
bindActionCreators({ showSignInDialog }, dispatch);
|
||||
|
||||
export default compose(
|
||||
connect(mapStateToProps, mapDispatchToProps),
|
||||
|
||||
@@ -59,7 +59,7 @@ class Stream extends React.Component {
|
||||
deleteAction,
|
||||
showSignInDialog,
|
||||
loadNewReplies,
|
||||
auth: { user },
|
||||
currentUser,
|
||||
emit,
|
||||
viewAllComments,
|
||||
} = this.props;
|
||||
@@ -111,7 +111,7 @@ class Stream extends React.Component {
|
||||
disableReply={!open}
|
||||
postComment={postComment}
|
||||
asset={asset}
|
||||
currentUser={user}
|
||||
currentUser={currentUser}
|
||||
highlighted={comment.id}
|
||||
postFlag={postFlag}
|
||||
postDontAgree={postDontAgree}
|
||||
@@ -150,7 +150,7 @@ class Stream extends React.Component {
|
||||
setActiveStreamTab,
|
||||
loadNewReplies,
|
||||
loadMoreComments,
|
||||
auth: { user },
|
||||
currentUser,
|
||||
emit,
|
||||
sortOrder,
|
||||
sortBy,
|
||||
@@ -200,7 +200,7 @@ class Stream extends React.Component {
|
||||
notify={notify}
|
||||
disableReply={asset.isClosed}
|
||||
postComment={postComment}
|
||||
currentUser={user}
|
||||
currentUser={currentUser}
|
||||
postFlag={postFlag}
|
||||
postDontAgree={postDontAgree}
|
||||
loadMore={loadMoreComments}
|
||||
@@ -230,21 +230,23 @@ class Stream extends React.Component {
|
||||
postComment,
|
||||
notify,
|
||||
updateItem,
|
||||
auth: { loggedIn, user },
|
||||
currentUser,
|
||||
} = this.props;
|
||||
const { keepCommentBox } = this.state;
|
||||
const open = !asset.isClosed;
|
||||
|
||||
const banned = get(user, 'status.banned.status');
|
||||
const suspensionUntil = get(user, 'status.suspension.until');
|
||||
const rejectedUsername = get(user, 'status.username.status') === 'REJECTED';
|
||||
const changedUsername = get(user, 'status.username.status') === 'CHANGED';
|
||||
const banned = get(currentUser, 'status.banned.status');
|
||||
const suspensionUntil = get(currentUser, 'status.suspension.until');
|
||||
const rejectedUsername =
|
||||
get(currentUser, 'status.username.status') === 'REJECTED';
|
||||
const changedUsername =
|
||||
get(currentUser, 'status.username.status') === 'CHANGED';
|
||||
|
||||
const temporarilySuspended =
|
||||
user && suspensionUntil && new Date(suspensionUntil) > new Date();
|
||||
currentUser && suspensionUntil && new Date(suspensionUntil) > new Date();
|
||||
|
||||
const showCommentBox =
|
||||
loggedIn &&
|
||||
currentUser &&
|
||||
((!banned &&
|
||||
!temporarilySuspended &&
|
||||
!rejectedUsername &&
|
||||
@@ -289,7 +291,8 @@ class Stream extends React.Component {
|
||||
</RestrictedMessageBox>
|
||||
)}
|
||||
{changedUsername && <ChangedUsername />}
|
||||
{!banned && rejectedUsername && <ChangeUsername user={user} />}
|
||||
{!banned &&
|
||||
rejectedUsername && <ChangeUsername user={currentUser} />}
|
||||
{banned && <BannedAccount />}
|
||||
{showCommentBox && (
|
||||
<CommentBox
|
||||
@@ -300,7 +303,7 @@ class Stream extends React.Component {
|
||||
assetId={asset.id}
|
||||
premod={asset.settings.moderation}
|
||||
isReply={false}
|
||||
currentUser={user}
|
||||
currentUser={currentUser}
|
||||
charCountEnable={asset.settings.charCountEnable}
|
||||
maxCharCount={asset.settings.charCount}
|
||||
/>
|
||||
@@ -312,10 +315,10 @@ class Stream extends React.Component {
|
||||
|
||||
<Slot fill="stream" queryData={slotQueryData} {...slotProps} />
|
||||
|
||||
{loggedIn && (
|
||||
{currentUser && (
|
||||
<ModerationLink
|
||||
assetId={asset.id}
|
||||
isAdmin={can(user, 'MODERATE_COMMENTS')}
|
||||
isAdmin={can(currentUser, 'MODERATE_COMMENTS')}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -342,7 +345,7 @@ Stream.propTypes = {
|
||||
deleteAction: PropTypes.func,
|
||||
showSignInDialog: PropTypes.func,
|
||||
loadNewReplies: PropTypes.func,
|
||||
auth: PropTypes.object,
|
||||
currentUser: PropTypes.object,
|
||||
emit: PropTypes.func,
|
||||
sortOrder: PropTypes.string,
|
||||
sortBy: PropTypes.string,
|
||||
|
||||
@@ -14,8 +14,8 @@ import {
|
||||
withEditComment,
|
||||
} from 'coral-framework/graphql/mutations';
|
||||
|
||||
import * as authActions from 'coral-embed-stream/src/actions/auth';
|
||||
import * as notificationActions from 'coral-framework/actions/notification';
|
||||
import { showSignInDialog, editName } from 'coral-embed-stream/src/actions/login';
|
||||
import { notify } from 'coral-framework/actions/notification';
|
||||
import {
|
||||
setActiveReplyBox,
|
||||
setActiveTab,
|
||||
@@ -40,9 +40,6 @@ import {
|
||||
} from '../../../graphql/utils';
|
||||
import StreamError from '../components/StreamError';
|
||||
|
||||
const { showSignInDialog, editName } = authActions;
|
||||
const { notify } = notificationActions;
|
||||
|
||||
class StreamContainer extends React.Component {
|
||||
commentsAddedSubscription = null;
|
||||
commentsEditedSubscription = null;
|
||||
@@ -60,8 +57,8 @@ class StreamContainer extends React.Component {
|
||||
// Ignore mutations from me.
|
||||
// TODO: need way to detect mutations created by this client, and allow mutations from other clients.
|
||||
if (
|
||||
this.props.auth.user &&
|
||||
commentEdited.user.id === this.props.auth.user.id
|
||||
this.props.currentUser &&
|
||||
commentEdited.user.id === this.props.currentUser.id
|
||||
) {
|
||||
return prev;
|
||||
}
|
||||
@@ -92,8 +89,8 @@ class StreamContainer extends React.Component {
|
||||
// Ignore mutations from me.
|
||||
// TODO: need way to detect mutations created by this client, and allow mutations from other clients.
|
||||
if (
|
||||
this.props.auth.user &&
|
||||
commentAdded.user.id === this.props.auth.user.id
|
||||
this.props.currentUser &&
|
||||
commentAdded.user.id === this.props.currentUser.id
|
||||
) {
|
||||
return prev;
|
||||
}
|
||||
@@ -204,8 +201,8 @@ class StreamContainer extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
userIsDegraged({ auth: { user } } = this.props) {
|
||||
return !can(user, 'INTERACT_WITH_COMMUNITY');
|
||||
userIsDegraged({ currentUser } = this.props) {
|
||||
return !can(currentUser, 'INTERACT_WITH_COMMUNITY');
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -396,7 +393,7 @@ const fragments = {
|
||||
};
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
auth: state.auth,
|
||||
currentUser: state.auth.user,
|
||||
activeReplyBox: state.stream.activeReplyBox,
|
||||
commentId: state.stream.commentId,
|
||||
assetId: state.stream.assetId,
|
||||
|
||||
@@ -6,9 +6,6 @@ function cleanAuthData(localStorage) {
|
||||
localStorage.removeItem('exp');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check Login
|
||||
*/
|
||||
export const checkLogin = () => (
|
||||
dispatch,
|
||||
_,
|
||||
@@ -54,9 +51,15 @@ const checkLoginSuccess = user => ({
|
||||
user,
|
||||
});
|
||||
|
||||
/**
|
||||
* Login
|
||||
*/
|
||||
export const setAuthToken = token => (dispatch, _, { localStorage }) => {
|
||||
if (localStorage) {
|
||||
localStorage.setItem('exp', jwtDecode(token).exp);
|
||||
localStorage.setItem('token', token);
|
||||
}
|
||||
|
||||
dispatch(checkLogin());
|
||||
};
|
||||
|
||||
export const handleSuccessfulLogin = (user, token) => (
|
||||
dispatch,
|
||||
_,
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
import { MERGE_CONFIG } from '../constants/config';
|
||||
|
||||
export const mergeConfig = config => ({
|
||||
type: MERGE_CONFIG,
|
||||
config,
|
||||
});
|
||||
@@ -1,6 +0,0 @@
|
||||
import * as actions from '../constants/static';
|
||||
|
||||
export const setStaticConfiguration = config => ({
|
||||
type: actions.SET_STATIC_CONFIGURATION,
|
||||
config,
|
||||
});
|
||||
@@ -19,7 +19,7 @@ class Recaptcha extends React.Component {
|
||||
// This should be fine because it's static and will never change.
|
||||
// Prefer this to connect HOC because wie expose the instance method
|
||||
// `reset`
|
||||
return this.context.store.getState().static.TALK_RECAPTCHA_PUBLIC;
|
||||
return this.context.store.getState().config.static.TALK_RECAPTCHA_PUBLIC;
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
const prefix = `TALK_FRAMEWORK`;
|
||||
|
||||
export const MERGE_CONFIG = `${prefix}_MERGE_CONFIG`;
|
||||
@@ -1,3 +0,0 @@
|
||||
const prefix = `TALK_FRAMEWORK`;
|
||||
|
||||
export const SET_STATIC_CONFIGURATION = `${prefix}_SET_STATIC_CONFIGURATION`;
|
||||
@@ -48,8 +48,8 @@ export default hoistStatics(WrappedComponent => {
|
||||
}
|
||||
const changeSet = { loading: false, error };
|
||||
if (error.translation_key === 'LOGIN_MAXIMUM_EXCEEDED') {
|
||||
changeSet.requireRecaptcha = !!this.context.store.getState().static
|
||||
.TALK_RECAPTCHA_PUBLIC;
|
||||
changeSet.requireRecaptcha = !!this.context.store.getState().config
|
||||
.static.TALK_RECAPTCHA_PUBLIC;
|
||||
}
|
||||
this.setState(changeSet);
|
||||
});
|
||||
|
||||
+3
-3
@@ -1,10 +1,10 @@
|
||||
import * as actions from '../constants/static';
|
||||
import { MERGE_CONFIG } from '../constants/config';
|
||||
|
||||
const initialState = {};
|
||||
|
||||
export default function auth(state = initialState, action) {
|
||||
export default function config(state = initialState, action) {
|
||||
switch (action.type) {
|
||||
case actions.SET_STATIC_CONFIGURATION:
|
||||
case MERGE_CONFIG:
|
||||
return {
|
||||
...state,
|
||||
...action.config,
|
||||
@@ -1,7 +1,8 @@
|
||||
import auth from './auth';
|
||||
import staticConfiguration from './static';
|
||||
import config from './config';
|
||||
|
||||
export default {
|
||||
auth,
|
||||
static: staticConfiguration,
|
||||
login: auth,
|
||||
config,
|
||||
};
|
||||
|
||||
+49
-7
@@ -23,8 +23,9 @@ import { createHistory } from 'coral-framework/services/history';
|
||||
import { createIntrospection } from 'coral-framework/services/introspection';
|
||||
import introspectionData from 'coral-framework/graphql/introspection.json';
|
||||
import coreReducers from '../reducers';
|
||||
import { checkLogin } from '../actions/auth';
|
||||
import { setStaticConfiguration } from '../actions/static';
|
||||
import { checkLogin as checkLoginAction } from '../actions/auth';
|
||||
import { mergeConfig } from '../actions/config';
|
||||
import { setAuthToken, logout } from '../actions/auth';
|
||||
|
||||
/**
|
||||
* getAuthToken returns the active auth token or null
|
||||
@@ -54,6 +55,19 @@ function areWeInIframe() {
|
||||
}
|
||||
}
|
||||
|
||||
function initExternalConfig({ store, pym, inIframe }) {
|
||||
if (!inIframe) {
|
||||
return;
|
||||
}
|
||||
return new Promise(resolve => {
|
||||
pym.sendMessage('getConfig');
|
||||
pym.onMessage('config', config => {
|
||||
store.dispatch(mergeConfig(JSON.parse(config)));
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* createContext setups and returns Talk dependencies that should be
|
||||
* passed to `TalkProvider`.
|
||||
@@ -73,6 +87,8 @@ export async function createContext({
|
||||
notification,
|
||||
preInit,
|
||||
init = noop,
|
||||
checkLogin = true,
|
||||
addExternalConfig = true,
|
||||
} = {}) {
|
||||
const inIframe = areWeInIframe();
|
||||
const eventEmitter = new EventEmitter({ wildcard: true });
|
||||
@@ -166,7 +182,6 @@ export async function createContext({
|
||||
// Create our redux store.
|
||||
const finalReducers = {
|
||||
...coreReducers,
|
||||
authCore: coreReducers.auth,
|
||||
...reducers,
|
||||
...plugins.getReducers(),
|
||||
};
|
||||
@@ -186,12 +201,39 @@ export async function createContext({
|
||||
[client.middleware(), apolloErrorReporter, createReduxEmitter(eventEmitter)]
|
||||
);
|
||||
|
||||
store.dispatch(setStaticConfiguration(staticConfig));
|
||||
store.dispatch(checkLogin());
|
||||
if (inIframe) {
|
||||
pym.onMessage('login', token => {
|
||||
if (token) {
|
||||
store.dispatch(setAuthToken(token));
|
||||
}
|
||||
});
|
||||
|
||||
pym.onMessage('logout', () => {
|
||||
store.dispatch(logout());
|
||||
});
|
||||
}
|
||||
|
||||
const preInitList = [];
|
||||
|
||||
store.dispatch(
|
||||
mergeConfig({
|
||||
static: staticConfig,
|
||||
})
|
||||
);
|
||||
|
||||
if (preInit) {
|
||||
preInitList.push(preInit(context));
|
||||
}
|
||||
|
||||
if (addExternalConfig) {
|
||||
preInitList.push(initExternalConfig(context));
|
||||
}
|
||||
|
||||
// Run pre initialization.
|
||||
if (preInit) {
|
||||
await preInit(context);
|
||||
await Promise.all(preInitList);
|
||||
|
||||
if (checkLogin) {
|
||||
store.dispatch(checkLoginAction());
|
||||
}
|
||||
|
||||
// Run initialization.
|
||||
|
||||
@@ -15,8 +15,7 @@ import * as PropTypes from 'prop-types';
|
||||
import { getDefinitionName } from '../utils';
|
||||
import { t, can } from 'plugin-api/beta/client/services';
|
||||
|
||||
// TODO: Auth logic needs refactoring.
|
||||
import { showSignInDialog } from 'coral-embed-stream/src/actions/auth';
|
||||
import { showSignInDialog } from 'coral-embed-stream/src/actions/login';
|
||||
|
||||
/*
|
||||
* Disable false-positive warning below, as it doesn't work well with how we currently
|
||||
|
||||
@@ -17,7 +17,7 @@ import {
|
||||
invalidForm,
|
||||
validForm,
|
||||
updateUsername,
|
||||
} from 'coral-embed-stream/src/actions/auth';
|
||||
} from 'coral-embed-stream/src/actions/login';
|
||||
|
||||
class ChangeUsernameContainer extends React.Component {
|
||||
constructor(props) {
|
||||
|
||||
@@ -2,12 +2,12 @@ import React from 'react';
|
||||
import { Button } from 'plugin-api/beta/client/components/ui';
|
||||
import { connect } from 'react-redux';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import { showSignInDialog } from 'coral-embed-stream/src/actions/auth';
|
||||
import { showSignInDialog } from 'coral-embed-stream/src/actions/login';
|
||||
import t from 'coral-framework/services/i18n';
|
||||
|
||||
const SignInButton = ({ loggedIn, showSignInDialog }) => (
|
||||
const SignInButton = ({ currentUser, showSignInDialog }) => (
|
||||
<div className="talk-stream-auth-sign-in-button">
|
||||
{!loggedIn ? (
|
||||
{!currentUser ? (
|
||||
<Button id="coralSignInButton" onClick={showSignInDialog} full>
|
||||
{t('sign_in.sign_in_to_comment')}
|
||||
</Button>
|
||||
@@ -16,7 +16,7 @@ const SignInButton = ({ loggedIn, showSignInDialog }) => (
|
||||
);
|
||||
|
||||
const mapStateToProps = ({ auth }) => ({
|
||||
loggedIn: auth.loggedIn,
|
||||
currentUser: auth.user,
|
||||
});
|
||||
|
||||
const mapDispatchToProps = dispatch =>
|
||||
|
||||
@@ -19,7 +19,7 @@ import {
|
||||
facebookCallback,
|
||||
invalidForm,
|
||||
validForm,
|
||||
} from 'coral-embed-stream/src/actions/auth';
|
||||
} from 'coral-embed-stream/src/actions/login';
|
||||
|
||||
class SignInContainer extends React.Component {
|
||||
constructor(props) {
|
||||
|
||||
@@ -3,7 +3,7 @@ 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/auth';
|
||||
import { logout } from 'coral-embed-stream/src/actions/login';
|
||||
|
||||
const UserBox = ({ loggedIn, user, logout, onShowProfile }) => (
|
||||
<div>
|
||||
|
||||
Reference in New Issue
Block a user