From 62e2cb2740423899c996c7b12a5fc5a3b3979143 Mon Sep 17 00:00:00 2001 From: "damian.przygodzki" Date: Mon, 22 May 2017 13:25:03 +0200 Subject: [PATCH] #767 Notification SockJS client enclosured to service --- src/actions/AppActions.js | 51 ++++++------- src/components/app/LoginForm.js | 4 +- src/containers/App.js | 122 +++++++++++++++++--------------- src/containers/Login.js | 4 +- src/routes.js | 9 +-- src/services/Auth.js | 26 +++++++ 6 files changed, 122 insertions(+), 94 deletions(-) create mode 100644 src/services/Auth.js diff --git a/src/actions/AppActions.js b/src/actions/AppActions.js index 852d2d30c..2178a0519 100644 --- a/src/actions/AppActions.js +++ b/src/actions/AppActions.js @@ -1,40 +1,32 @@ import * as types from '../constants/ActionTypes' import axios from 'axios'; import {replace} from 'react-router-redux'; -import SockJs from 'sockjs-client'; -import Stomp from 'stompjs/lib/stomp.min.js'; -export function loginSuccess() { +export function loginSuccess(auth) { return dispatch => { localStorage.setItem('isLogged', true); dispatch(getNotificationsEndpoint()).then(topic => { - let sock = new SockJs(config.WS_URL); - let client = Stomp.Stomp.over(sock); - client.debug = null; - - client.connect({}, () => { - client.subscribe(topic.data, msg => { - const notification = JSON.parse(msg.body); - - if(notification.eventType === 'Read'){ - dispatch(updateNotification( - notification.notification, notification.unreadCount - )); - }else if(notification.eventType === 'New'){ - dispatch(newNotification( - notification.notification, notification.unreadCount - )); - const notif = notification.notification; - if(notif.important){ - dispatch(addNotification( - 'Important notification', notif.message, 5000, - 'primary' - )) - } + auth.initNotificationClient(topic, msg => { + const notification = JSON.parse(msg.body); + + if(notification.eventType === 'Read'){ + dispatch(updateNotification( + notification.notification, notification.unreadCount + )); + }else if(notification.eventType === 'New'){ + dispatch(newNotification( + notification.notification, notification.unreadCount + )); + const notif = notification.notification; + if(notif.important){ + dispatch(addNotification( + 'Important notification', notif.message, 5000, + 'primary' + )) } - }); - }) + } + }); }) dispatch(getNotifications()).then(response => { @@ -46,8 +38,9 @@ export function loginSuccess() { } } -export function logoutSuccess() { +export function logoutSuccess(auth) { return () => { + auth.closeNotificationClient(); localStorage.removeItem('isLogged'); } } diff --git a/src/components/app/LoginForm.js b/src/components/app/LoginForm.js index 311b0677a..9915aab8e 100644 --- a/src/components/app/LoginForm.js +++ b/src/components/app/LoginForm.js @@ -76,7 +76,7 @@ class LoginForm extends Component { } handleLogin = () => { - const {dispatch} = this.props; + const {dispatch, auth} = this.props; const {roleSelect, role} = this.state; this.setState({ @@ -85,7 +85,7 @@ class LoginForm extends Component { if(roleSelect){ return dispatch(loginCompletionRequest(role)) .then(() => { - dispatch(loginSuccess()); + dispatch(loginSuccess(auth)); this.handleSuccess(); }) } diff --git a/src/containers/App.js b/src/containers/App.js index a8b6fba33..3d650edb4 100644 --- a/src/containers/App.js +++ b/src/containers/App.js @@ -8,6 +8,8 @@ import { getRoutes } from '../routes.js'; import { syncHistoryWithStore, push } from 'react-router-redux'; import { Router, browserHistory } from 'react-router'; +import Auth from '../services/Auth'; + import Moment from 'moment'; import NotificationHandler @@ -29,68 +31,74 @@ import '../assets/css/styles.css'; const store = configureStore(browserHistory); const history = syncHistoryWithStore(browserHistory, store); -axios.defaults.withCredentials = true; - -axios.interceptors.response.use(function (response) { - return response; -}, function (error) { - if(!error.response){ - store.dispatch(noConnection(true)); - } - - /* - * Authorization error - */ - if(error.response.status == 401){ - store.dispatch(setProcessSaved()); - store.dispatch(logoutSuccess()); - store.dispatch(push('/login?redirect=true')); - }else if(error.response.status != 404){ - if(localStorage.isLogged){ - const errorMessenger = (code) => { - switch(code){ - case 500: - return 'Server error'; - case 400: - return 'Client error'; - } - } - const { - data, status - } = error.response; +export default class App extends Component { + constructor() { + super(); - const errorTitle = errorMessenger(status); + this.auth = new Auth(); - console.error(data.message); + axios.defaults.withCredentials = true; - // Chart disabled notifications - if(error.response.request.responseURL.includes('silentError=true')){ - return; + axios.interceptors.response.use(function (response) { + return response; + }, function (error) { + if(!error.response){ + store.dispatch(noConnection(true)); } - store.dispatch(addNotification( - 'Error: ' + data.message.split(' ', 4).join(' ') + '...', - data.message, 5000, 'error', errorTitle) - ); - } - } - if(error.response.request.responseURL.includes('showError=true')){ - const { - data - } = error.response; - - store.dispatch(addNotification( - 'Error: ' + data.message.split(' ', 4).join(' ') + '...', - data.message, 5000, 'error', '') - ); - } else { - return Promise.reject(error); - } -}); + /* + * Authorization error + */ + if(error.response.status == 401){ + store.dispatch(setProcessSaved()); + store.dispatch(logoutSuccess(this.auth)); + store.dispatch(push('/login?redirect=true')); + }else if(error.response.status != 404){ + if(localStorage.isLogged){ + const errorMessenger = (code) => { + switch(code){ + case 500: + return 'Server error'; + case 400: + return 'Client error'; + } + } + const { + data, status + } = error.response; + + const errorTitle = errorMessenger(status); + + console.error(data.message); + + // Chart disabled notifications + if( + error.response.request.responseURL + .includes('silentError=true') + ){ + return; + } + + store.dispatch(addNotification( + 'Error: ' + data.message.split(' ', 4).join(' ') + + '...', data.message, 5000, 'error', errorTitle) + ); + } + } -export default class App extends Component { - constructor() { - super(); + if(error.response.request.responseURL.includes('showError=true')){ + const { + data + } = error.response; + + store.dispatch(addNotification( + 'Error: ' + data.message.split(' ', 4).join(' ') + '...', + data.message, 5000, 'error', '') + ); + } else { + return Promise.reject(error); + } + }.bind(this)); store.dispatch(getAvailableLang()).then(response => { const {defaultValue, values} = response.data; @@ -110,7 +118,7 @@ export default class App extends Component { diff --git a/src/containers/Login.js b/src/containers/Login.js index 5f4a4f461..7ad12f9c8 100644 --- a/src/containers/Login.js +++ b/src/containers/Login.js @@ -63,13 +63,13 @@ class Login extends Component { } render() { - const {redirect} = this.props; + const {redirect, auth} = this.props; const isYourBrowserSupported = this.browserSupport('chrome'); return (
{! isYourBrowserSupported &&
diff --git a/src/routes.js b/src/routes.js index 1aac01924..5d3c48797 100644 --- a/src/routes.js +++ b/src/routes.js @@ -21,12 +21,12 @@ import { createWindow } from './actions/WindowActions'; -export const getRoutes = (store) => { +export const getRoutes = (store, auth) => { const authRequired = (nextState, replace, callback) => { if( !localStorage.isLogged ){ store.dispatch(localLoginRequest()).then((resp) => { if(resp.data){ - store.dispatch(loginSuccess()); + store.dispatch(loginSuccess(auth)); callback(null, nextState.location.pathname); }else{ //redirect tells that there should be @@ -35,14 +35,14 @@ export const getRoutes = (store) => { } }) }else{ - store.dispatch(loginSuccess()); + store.dispatch(loginSuccess(auth)); callback(); } } const logout = () => { store.dispatch(logoutRequest()).then(()=> - store.dispatch(logoutSuccess()) + store.dispatch(logoutSuccess(auth)) ).then(()=> store.dispatch(push('/login')) ); @@ -79,6 +79,7 @@ export const getRoutes = (store) => { } /> diff --git a/src/services/Auth.js b/src/services/Auth.js new file mode 100644 index 000000000..8ca2c42eb --- /dev/null +++ b/src/services/Auth.js @@ -0,0 +1,26 @@ +import SockJs from 'sockjs-client'; +import Stomp from 'stompjs/lib/stomp.min.js'; + +class Auth { + constructor() { + this.notificationClient = null; + } + + initNotificationClient = (topic, cb) => { + const sock = new SockJs(config.WS_URL); + this.notificationClient = Stomp.Stomp.over(sock); + this.notificationClient.debug = null; + this.notificationClient.connect({}, () => { + this.notificationClient.connected && + this.notificationClient.subscribe(topic.data, msg => { + cb && cb(msg); + }); + }); + } + + closeNotificationClient = () => { + this.notificationClient && this.notificationClient.disconnect(); + } +} + +export default Auth;