diff --git a/frontend/app/Router.js b/frontend/app/Router.js index e99ee2546..8ee29802a 100644 --- a/frontend/app/Router.js +++ b/frontend/app/Router.js @@ -90,7 +90,7 @@ const MULTIVIEW_INDEX_PATH = routes.multiviewIndex(); @connect( (state) => { const siteId = state.getIn(['site', 'siteId']); - const jwt = state.get('jwt'); + const jwt = state.getIn(['user', 'jwt']); const changePassword = state.getIn(['user', 'account', 'changePassword']); const userInfoLoading = state.getIn(['user', 'fetchUserInfoRequest', 'loading']); return { diff --git a/frontend/app/api_client.js b/frontend/app/api_client.js index b60c0dbb7..c0ccf9bcd 100644 --- a/frontend/app/api_client.js +++ b/frontend/app/api_client.js @@ -58,7 +58,7 @@ export const clean = (obj, forbidenValues = [ undefined, '' ]) => { export default class APIClient { constructor() { - const jwt = store.getState().get('jwt'); + const jwt = store.getState().getIn(['user', 'jwt']); const siteId = store.getState().getIn([ 'site', 'siteId' ]); this.init = { headers: { diff --git a/frontend/app/api_middleware.js b/frontend/app/api_middleware.js index 1846a9dbc..8ccc6bc37 100644 --- a/frontend/app/api_middleware.js +++ b/frontend/app/api_middleware.js @@ -1,8 +1,8 @@ import logger from 'App/logger'; import APIClient from './api_client'; -import { UPDATE, DELETE } from './duck/jwt'; +import { UPDATE_JWT } from './duck/user'; -export default (store) => (next) => (action) => { +export default () => (next) => (action) => { const { types, call, ...rest } = action; if (!call) { return next(action); @@ -14,7 +14,7 @@ export default (store) => (next) => (action) => { return call(client) .then(async (response) => { if (response.status === 403) { - next({ type: DELETE }); + next({ type: UPDATE_JWT, data: null }); } if (!response.ok) { const text = await response.text(); @@ -30,7 +30,7 @@ export default (store) => (next) => (action) => { next({ type: SUCCESS, data, ...rest }); } if (jwt) { - next({ type: UPDATE, data: jwt }); + next({ type: UPDATE_JWT, data: jwt }); } }) .catch((e) => { diff --git a/frontend/app/components/Login/Login.js b/frontend/app/components/Login/Login.js index c04e83f12..70ee0f74e 100644 --- a/frontend/app/components/Login/Login.js +++ b/frontend/app/components/Login/Login.js @@ -8,7 +8,7 @@ import ReCAPTCHA from 'react-google-recaptcha'; import { withRouter } from 'react-router-dom'; import stl from './login.module.css'; import cn from 'classnames'; -import { setJwt } from 'Duck/jwt'; +import { setJwt } from 'Duck/user'; const FORGOT_PASSWORD = forgotPassword(); const SIGNUP_ROUTE = signup(); diff --git a/frontend/app/components/Session/WebPlayer.tsx b/frontend/app/components/Session/WebPlayer.tsx index 6e169777e..e6f091b2c 100644 --- a/frontend/app/components/Session/WebPlayer.tsx +++ b/frontend/app/components/Session/WebPlayer.tsx @@ -115,7 +115,7 @@ function WebPlayer(props: any) { export default connect( (state: any) => ({ session: state.getIn(['sessions', 'current']), - jwt: state.get('jwt'), + jwt: state.getIn(['user', 'jwt']), fullscreen: state.getIn(['components', 'player', 'fullscreen']), showEvents: state.get('showEvents'), members: state.getIn(['members', 'list']), diff --git a/frontend/app/duck/index.ts b/frontend/app/duck/index.ts index fd4b0a655..0371396bf 100644 --- a/frontend/app/duck/index.ts +++ b/frontend/app/duck/index.ts @@ -1,6 +1,5 @@ import { combineReducers } from 'redux-immutable'; -import jwt from './jwt'; import user from './user'; import sessions from './sessions'; import assignments from './assignments'; @@ -34,7 +33,6 @@ import search from './search'; import liveSearch from './liveSearch'; const rootReducer = combineReducers({ - jwt, user, sessions, assignments, diff --git a/frontend/app/duck/jwt.js b/frontend/app/duck/jwt.js deleted file mode 100644 index 4d4147f34..000000000 --- a/frontend/app/duck/jwt.js +++ /dev/null @@ -1,19 +0,0 @@ -export const UPDATE = 'jwt/UPDATE'; -export const DELETE = 'jwt/DELETE'; - -export default (state = null, action = {}) => { - switch (action.type) { - case UPDATE: - return action.data; - case DELETE: - return null; - } - return state; -}; - -export function setJwt(data) { - return { - type: UPDATE, - data, - }; -} diff --git a/frontend/app/duck/user.js b/frontend/app/duck/user.js index 5b39d34db..8ef2bf5ab 100644 --- a/frontend/app/duck/user.js +++ b/frontend/app/duck/user.js @@ -20,7 +20,7 @@ const PUT_CLIENT = new RequestTypes('user/PUT_CLIENT'); const PUSH_NEW_SITE = 'user/PUSH_NEW_SITE'; const SET_ONBOARDING = 'user/SET_ONBOARDING'; -const initialState = Map({ +export const initialState = Map({ account: Account(), siteId: null, passwordRequestError: false, @@ -28,7 +28,8 @@ const initialState = Map({ tenants: [], authDetails: {}, onboarding: false, - sites: List() + sites: List(), + jwt: null }); const setClient = (state, data) => { @@ -36,8 +37,19 @@ const setClient = (state, data) => { return state.set('client', client) } +export const UPDATE_JWT = 'jwt/UPDATE'; +export function setJwt(data) { + return { + type: UPDATE_JWT, + data, + }; +} + + const reducer = (state = initialState, action = {}) => { switch (action.type) { + case UPDATE_JWT: + return state.set('jwt', action.data); case RESET_PASSWORD.SUCCESS: case UPDATE_PASSWORD.SUCCESS: case LOGIN.SUCCESS: @@ -54,9 +66,11 @@ const reducer = (state = initialState, action = {}) => { // return state.set('tenants', action.data.map(i => ({ text: i.name, value: i.tenantId}))); case UPDATE_PASSWORD.FAILURE: return state.set('passwordErrors', List(action.errors)) + case FETCH_ACCOUNT.FAILURE: + case LOGIN.FAILURE: case DELETE: + console.log('hi') deleteCookie('jwt', '/', '.openreplay.com') - console.log('called') return initialState; case PUT_CLIENT.REQUEST: return state.mergeIn([ 'account' ], action.params); @@ -115,16 +129,10 @@ export function fetchTenants() { } } -export const fetchUserInfo = () => dispatch => Promise.all([ - dispatch({ +export const fetchUserInfo = () => ({ types: FETCH_ACCOUNT.toArray(), call: client => client.get('/account'), - }), - // dispatch({ - // types: FETCH_CLIENT.toArray(), - // call: client => client.get('/client'), - // }), -]); + }); export function logout() { return { diff --git a/frontend/app/store.js b/frontend/app/store.js index dd1434a0c..a2379496c 100644 --- a/frontend/app/store.js +++ b/frontend/app/store.js @@ -4,26 +4,32 @@ import { Map } from 'immutable'; import indexReducer from './duck'; import apiMiddleware from './api_middleware'; import LocalStorage from './local_storage'; +import { initialState as initUserState, UPDATE_JWT } from './duck/user' const storage = new LocalStorage({ - jwt: String, + user: Object, }); const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ && window.env.NODE_ENV === "development" ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ : compose; const storageState = storage.state(); -const initialState = Map({ - jwt: storageState.jwt, - // TODO: store user -}); +const initialState = Map({ user: initUserState.update('jwt', () => storageState.user?.jwt || null) }); const store = createStore(indexReducer, initialState, composeEnhancers(applyMiddleware(thunk, apiMiddleware))); store.subscribe(() => { const state = store.getState(); + storage.sync({ - jwt: state.get('jwt') + user: state.get('user') }); }); +window.getJWT = () => { + console.log(JSON.stringify(storage.state().user?.jwt || 'not logged in')); +} +window.setJWT = (jwt) => { + store.dispatch({ type: UPDATE_JWT, data: jwt }) +} + export default store;