"use strict"; (function () { 'use strict'; angular.module('myitsmApp') .controller('MainController', ['$scope', '$state', '$filter', 'session', 'l10nModel', 'authModel', 'ccsModel', 'userModel', 'searchModel', 'studioModel', '$window', 'AUTH_EVENTS', '$timeout', 'chatModel', 'emailModel', 'mobileClientCheckerService', 'systemAlertService', 'i18nService', '$rootScope', '$http', '$modal', '$cookies', '$sce', 'events', 'personModel', 'localStorageService', 'utilityFunctions', 'configurationModel', '$q', '$location', 'browser', 'gainsightModel', function ($scope, $state, $filter, session, l10nModel, authModel, ccsModel, userModel, searchModel, studioModel, $window, AUTH_EVENTS, $timeout, chatModel, emailModel, mobileClientCheckerService, systemAlertService, i18nService, $rootScope, $http, $modal, $cookies, $sce, events, personModel, localStorageService, utilityFunctions, configurationModel, $q, $location, browser, gainsightModel) { 'ngInject'; var APP_STATES = { INDETERMINATE: -1, SHOW_LOGIN: 0, SHOW_MAIN: 1, SHOW_WINDOW: 2 }, ANCHORS = { DashBoardWithHash: '#/', 'Ticket Console': 'ticket-consoleStudio', 'Asset Console': 'asset-consoleStudio', 'Knowledge Console': 'knowledge-console', 'Smart Recorder': 'create/smart-recorder', 'Calendar': 'calendarStudio' }; $scope.homeServerDefer = $q.defer(); $scope.isMobile = browser.isMobile; $scope.insideChangeCalendar = false; $scope.$on(events.INSIDE_CHANGE_CALENDAR, function (event) { $scope.insideChangeCalendar = true; }); $scope.studioCCSDetailsDefer = $q.defer(); $rootScope.showStudioFrame = false; //$scope.studioFrameUrl = $sce.trustAsResourceUrl('https://smtdev1-is.dsmlab.bmc.com/helix/index.html#/com.bmc.arsys.rx.innovationstudio/workspace'); $rootScope.studioFrameUrl = $sce.trustAsResourceUrl(''); function callKeepAlive() { $http({ method: 'GET', url: '/smartit/rest/keepAlive' }).then(function () { }, function (response) { console.error('keepAlive : ' + response); }); } function callKeepAlive() { $http({ method: 'GET', url: '/smartit/rest/keepAlive' }).then(function () { }, function (response) { console.error('keepAlive : ' + response); }); } window.onmessage = handleMessage; function handleMessage(e) { if (typeof e.data === 'string' && utilityFunctions.checkIfJson(e.data)) { var parcelObject = JSON.parse(e.data); if (parcelObject.action && parcelObject.action === 'keepAlive') { // ' just a dummy call, keeping the session Alive for PWA'); callKeepAlive(); } else if (parcelObject.homeServer) { localStorage.setItem('homeServer', parcelObject.homeServer); // If SSO enabled send a message to PV once homeServer is set. if (authModel.isSSOEnabled()) { $scope.sendMessageToPwaDomain({ isSsoEnabled: true }); } $scope.homeServerDefer.resolve(); } // hide navigation bar if Smart IT is embedded in another app if (parcelObject.parent && parcelObject.action && parcelObject.action === 'hideNavigationBar') { $rootScope.hasParent = true; $rootScope.hideNavigationBar = true; } } } $scope.iframeLoadedCallBack = function () { $scope.pwaFrameLoaded = true; $rootScope.$broadcast(events.PWA_IFRAME_LOADED); }; function checkMidtierUrl(url) { var lastSlashIndex = url.lastIndexOf('/'); if (lastSlashIndex === url.length - 1) { url = url.substr(0, lastSlashIndex); } if (url.search('/arsys') > -1) { return url; } return url + '/arsys'; } $scope.midTierUrlDeferred = $q.defer(); // Setting the PWA home for logout and login synchronization. $rootScope.$on(events.MIDTIER_URL_LOADED, function (event, data) { var midtierUrl = authModel.getMidtierUrl(); var midtierUrlArsys = checkMidtierUrl(midtierUrl); localStorage.setItem('midtierUrl', midtierUrlArsys); localStorage.setItem('pwaDomain', (midtierUrl.search('arsys') > -1) ? midtierUrl.substr(0, midtierUrl.lastIndexOf("/")) : midtierUrl); if (midtierUrl) { $scope.pwaHomeSrc = $sce.trustAsResourceUrl(midtierUrlArsys + '/pwa/login-light.html?origin=' + window.location.origin); } $scope.midTierUrlDeferred.resolve(); }); $scope.APP_STATES = APP_STATES; $scope.appState = APP_STATES.INDETERMINATE; $scope.state = $state; var unbind = $rootScope.$on('i18nResourcesUpdated', function () { mobileClientCheckerService.checkForMobileDevice(); }); $scope.$on('$destroy', function () { console.log('destroy root scope events bound from here'); unbind(); }); $(document).ready(function () { if (window.localStorage.tabCount) { window.localStorage.tabCount++; } else { window.localStorage.tabCount = 1; } }); window.addEventListener('beforeunload', function (evt) { if (window.localStorage.tabCount) { window.localStorage.tabCount--; } if (window.localStorage.tabCount == 0 && window.localStorage.sessionActive == 'true') { if (navigator.sendBeacon) { navigator.sendBeacon('/smartit/rest/arlicense/timeout/register'); } else { var request = new XMLHttpRequest(); request.open('POST', '/smartit/rest/arlicense/timeout/register', false); request.send(); } } }); // just a dummy call, keeping the session Alive for PV setInterval(function () { if (window.localStorage.smartITActivity == "true") { $scope.sendMessageToPwaDomain({ keepAlive: 'true' }); window.localStorage.smartITActivity = "false"; } }, 60000); function setPwaFrameUrl() { var pwaFrame = document.getElementsByClassName('app__pwa-iframe'); console.info('Inside setPwaFrameUrl method - url : ' + $scope.finalUrl); if (pwaFrame && pwaFrame.length !== 0) { if ($scope.finalUrl) { setTimeout(function () { pwaFrame[0].contentWindow.location.replace($scope.finalUrl); }); console.info('Inside setPwaFrameUrl method - location url changed'); } } else { console.error('Inside setPwaFrameUrl method : pwa iframe not loaded'); } } // IS has to provide the blank fake url function setFakeStudioFrameUrl() { if (studioModel.enableISCalendar || studioModel.enableSharedConsole || studioModel.enableISAssetConsole) { var studioFrame = document.getElementsByClassName('app__studio-iframe'); console.info('Inside setStudioFrameUrl method - url : Setting iframe blank'); if (studioFrame && studioFrame.length !== 0) { var studioFrameUrl = studioModel.baseUrlForIS + '/helix/index.html#/com.bmc.dsm.itsm-applications/iview/com.bmc.dsm.itsm-applications:Placeholder%20view%20for%20nav%20items'; //var studioFrameUrl = "about:blank"; setTimeout(function () { studioFrame[0].contentWindow.location.replace(studioFrameUrl); }); console.info('Inside setStudioFrameUrl method - Setting iframe blank: ' + studioFrameUrl); } else { setTimeout(function () { var studioFrame = document.getElementsByClassName('app__studio-iframe'); console.info('Inside setStudioFrameUrl method - url : Setting iframe blank'); if (studioFrame && studioFrame.length !== 0) { var studioFrameUrl = studioModel.baseUrlForIS + '/helix/index.html#/com.bmc.dsm.itsm-applications/iview/com.bmc.dsm.itsm-applications:Placeholder%20view%20for%20nav%20items'; studioFrame[0].contentWindow.location.replace(studioFrameUrl); console.info('Inside setStudioFrameUrl method - Setting iframe blank: ' + studioFrameUrl); } else { console.error('Inside setStudioFrameUrl method : studio iframe not loaded'); } }, 1000); } } } function getContext(toState, crossLaunchContext) { switch (toState.name) { case 'pwaDraftIncident': if (crossLaunchContext) { return crossLaunchContext + '_CREATEINCIDENT'; } return 'SMARTRECORDER_CREATEINCIDENT'; case 'pwaDraftWorkorder': if (crossLaunchContext) { return crossLaunchContext + '_CREATEWORKORDER'; } return 'SMARTRECORDER_CREATEWORKORDER'; case 'pwaDraftProblem': if (crossLaunchContext) { return crossLaunchContext + '_CREATEPROBLEM'; } return ''; case 'pwaDraftKnownerror': if (crossLaunchContext) { return crossLaunchContext + '_CREATEKNOWNERROR'; } return ''; case 'pwaDraftChange': if (crossLaunchContext) { return crossLaunchContext + '_CREATECHANGE'; } return ''; break; default: return ''; } } function stateChangeSuccess(event, toState, toParams) { $rootScope.hideNavigationBar = $rootScope.hasParent ? true : (toState && toState.name.indexOf('changeCalendar') !== -1); if (toState && toState.name && _.endsWith(toState.name, 'Studio')) { $rootScope.showStudioFrame = true; $scope.finalUrl = getPwaBaseUrl(); } else if (localStorage.getItem('midtierUrl')) { $rootScope.showStudioFrame = false; if (studioModel.ccsFetched) { setFakeStudioFrameUrl(); } else { $scope.studioCCSDetailsDefer.promise.then(function () { setFakeStudioFrameUrl(); }); } var guid = toParams && toParams.id ? toParams.id : null; if (toState && (toState.name === 'assetPV' || toState.name === 'editAssetPV')) { guid = toParams.assetId + '|' + toParams.assetClassId; } var crossLaunchContext = toParams && toParams.crossLaunchContext ? toParams.crossLaunchContext : ''; var isPvState = toState && toState.name && (_.endsWith(toState.name, 'PV') || toState.name.indexOf('pwaDraft') >= 0); var excludeStates = ['search.incidentPV', 'search.workorderPV', 'search.taskPV', 'search.problemPV', 'search.problemPV', 'search.knownerrorPV', 'search.personPV', 'search.assetPV', 'search.changePV']; if (isPvState && !_.includes(excludeStates, toState.name)) { var finalUrl = getPwaBaseUrl(toState); if (toState.data.targetForm) { finalUrl += '&targetForm=' + toState.data.targetForm; } if (toState.data.targetView) { finalUrl += '&targetView=' + toState.data.targetView; } if (toState.data.mode) { finalUrl += '&mode=' + toState.data.mode; } if (guid) { if (toState.data.targetForm) { finalUrl += '&targetId=' + guid; } else { finalUrl += '&guid=' + guid; } } if (toState.name.indexOf('pwaDraft') >= 0) { finalUrl += '&context=' + getContext(toState, crossLaunchContext); } else if (toState.name.indexOf('edit') != -1 && toParams.context) { finalUrl += '&context=' + toParams.context; } $rootScope.showFrame = true; $scope.finalUrl = finalUrl + '&rand=' + Math.random(); } else if (toState.name.indexOf("pwaAction") >= 0 && toParams.data && toParams.data.formName) { $rootScope.showFrame = true; $scope.finalUrl = getPwaBaseUrl(toParams, true); } else { $rootScope.showFrame = false; $scope.finalUrl = getPwaBaseUrl(); } } else { $rootScope.showStudioFrame = false; $scope.midTierUrlDeferred.promise.then(function () { stateChangeSuccess(event, toState, toParams); }); } } function getPwaBaseUrl(toState, excludeOrigin) { var midtierUrl = localStorage.getItem('midtierUrl'); if (!midtierUrl) { console.warn("Mid-tier URL is not available"); return "about:blank"; } var homeServer = localStorage.getItem('homeServer'); //if (!homeServer) { //$scope.$broadcast(AUTH_EVENTS.SESSION_EXPIRED); //} var origin = window.location.origin; var path = 'goto', baseUrl = ""; if (homeServer) { path = 'forms/' + homeServer; } var formName = toState && toState.data && toState.data.formName ? (path + '/' + toState.data.formName) : 'fake-route'; baseUrl = midtierUrl + '/pwa/#/' + formName; if (!excludeOrigin) { baseUrl += '?origin=' + origin; } return baseUrl; } $scope.$on('$stateChangeSuccess', function (event, toState, toParams) { stateChangeSuccess(event, toState, toParams); }); /** * Public functions */ $scope.sendMessageToPwaDomain = function (data) { if (localStorage.getItem('midtierUrl')) { var domain = localStorage.getItem('pwaDomain'); if (domain) { console.info('pwa iframe load status : ' + $scope.pwaFrameLoaded); var elemFound = setInterval(function () { console.info('sendMessageToPwaDomain - setInterval'); var iframeContent = document.getElementsByClassName('app__pwa-home-iframe') && document.getElementsByClassName('app__pwa-home-iframe').length ? document.getElementsByClassName('app__pwa-home-iframe')[0].contentWindow : null; if (iframeContent != null && $scope.pwaFrameLoaded) { console.info('message sent to pwa iframe '); utilityFunctions.windowPostMessage(iframeContent, data, domain); clearInterval(elemFound); } }); } } }; $scope.onLogoutClick = function () { logoutPWA(); logoutLiveChat(); // timeout added so that the logout event can be passed to the iframes $timeout(function () { $scope.appState = APP_STATES.INDETERMINATE; authModel.logout(); }, 1000); }; $scope.onOptinConfigClick = function () { gainsightModel.showOptinConfig(); }; $scope.onAboutClick = function () { $modal.open({ templateUrl: 'views/about.html', windowClass: 'bmc-system-about-modal', size: 'lg' }); }; $scope.toggleAccessibility = function () { userModel.isAccessibleUser = !userModel.isAccessibleUser; $scope.setAccessibility(); }; $scope.setAccessibility = function () { var expDate = new Date(); expDate.setDate(expDate.getDate() + 365); if ($location.protocol() === "https") { $cookies.put('accessibility', userModel.isAccessibleUser, { expires: expDate, httpOnly: true, secure: true }); } else { $cookies.put('accessibility', userModel.isAccessibleUser, { expires: expDate, httpOnly: true }); } userModel.updateUserPreferences('interface', { id: userModel.isAccessibleUserPreferenceId, name: 'accessibility', value: userModel.isAccessibleUser }); }; $scope.setFocus = function (id) { $('#' + id).focus(); }; $scope.$on(AUTH_EVENTS.LOGIN_SUCCESS, function (event, params) { console.log('$scope.$on(AUTH_EVENTS.LOGIN_SUCCESS)'); var promises = []; if (ANCHORS.DashBoardWithHash === window.location.hash) { promises.push(ccsModel.getCCSParameters()); if (localStorage.midtierUrl && !params.isSsoEnabled && localStorage.getItem('overridePV') !== 'T') { promises.push($scope.homeServerDefer.promise); } $q.all(promises).then(function (response) { $scope.ccsProperties = response[0]; if ($scope.ccsProperties && $scope.ccsProperties.landingPage && ANCHORS[$scope.ccsProperties.landingPage]) { if (ANCHORS[$scope.ccsProperties.landingPage] === 'calendar' && $scope.ccsProperties.calendarFeatureEnabled && $scope.ccsProperties.calendarFeatureEnabled.trim() === 'false') { console.log('Landing page :: Dashboard. calendarFeatureEnabled :' + $scope.ccsProperties.calendarFeatureEnabled); } else { console.log('Landing page :: Diverting to === ' + ANCHORS[$scope.ccsProperties.landingPage]); if ($scope.isMobile) { window.location.hash = ANCHORS['Ticket Console']; } else { window.location.hash = ANCHORS[$scope.ccsProperties.landingPage]; } } } if (!params.isSsoEnabled) { window.location.reload(false); } else if (session.alive) { console.info('location hash : session alive'); $scope.sendMessageToPwaDomain({ isSsoEnabled: params.isSsoEnabled }); sessionActiveCallback(); if ($scope.isMobile) { window.location.hash = ANCHORS['Ticket Console']; } } }); } else { if (!params.isSsoEnabled) { localStorage.midtierUrl ? promises.push($scope.homeServerDefer.promise) : promises.push(Promise.resolve()); $q.all(promises).then(function () { window.location.reload(false); }); } else if (session.alive) { console.info('session alive'); $scope.sendMessageToPwaDomain({ isSsoEnabled: params.isSsoEnabled }); sessionActiveCallback(); } } }); $scope.$on(AUTH_EVENTS.LOGOUT_SUCCESS, function (event, eventData) { console.log('$scope.$on(AUTH_EVENTS.LOGOUT_SUCCESS)'); localStorage.removeItem('tabCount'); window.localStorage.sessionActive = false; localStorage.removeItem('smartITActivity'); $scope.sendMessageToPwaDomain({ smartITsessionActive: window.localStorage.sessionActive }); if (authModel.isSSOEnabled()) { if (eventData && eventData.postLogoutUrl) { var url = eventData.postLogoutUrl; if (url.indexOf('?') > -1) { url += '&callback=JSON_CALLBACK'; } else { url += '?callback=JSON_CALLBACK'; } $http.jsonp(url) .finally(function () { $window.location.href = './?' + moment().valueOf(); }); } else if (eventData && eventData.redirectUrl) { $window.location.href = eventData.redirectUrl; } else { $window.location.href = './?' + moment().valueOf(); } } else { $window.location.href = './'; } }); function sessionActiveCallback() { console.log('$scope.$on(AUTH_EVENTS.SESSION_ACTIVE)'); window.localStorage.sessionActive = true; $scope.sendMessageToPwaDomain({ smartITsessionActive: window.localStorage.sessionActive }); if (window.localStorage.tabCount == 1) { authModel.deRegister(); } //Below commented line causes page reload and since we are still in resolve in case of knowledge related screens, the current state is not KA but blank //And this causes user to redirect to unauthorised page. Couldnt find any valid use case where below call is required. //$rootScope.$emit('$stateChangeStart', $scope.state.current); loadApplicationData(); } $scope.$on(AUTH_EVENTS.SESSION_ACTIVE, sessionActiveCallback); $scope.$on(AUTH_EVENTS.NOT_AUTHENTICATED, function () { console.log('$scope.$on(AUTH_EVENTS.NOT_AUTHENTICATED)'); $scope.appState = APP_STATES.SHOW_LOGIN; }); $scope.$on(AUTH_EVENTS.AR_CONNECTION_FAILED, function (event, response) { console.log('$scope.$on(AUTH_EVENTS.AR_CONNECTION_FAILED)'); systemAlertService.error({ text: response.data.error }); }); $scope.$on(AUTH_EVENTS.SESSION_EXPIRED, function () { console.log('$scope.$on(AUTH_EVENTS.SESSION_EXPIRED)'); window.localStorage.sessionActive = false; $scope.sendMessageToPwaDomain({ smartITsessionActive: window.localStorage.sessionActive }); localStorage.removeItem('tabCount'); localStorage.removeItem('smartITActivity'); if (authModel.isSSOEnabled()) { $scope.appState = APP_STATES.INDETERMINATE; //For RSSO show session expired alert var modalInstance = systemAlertService.modal({ title: $filter('i18n')('error.sessionExpired.title'), text: $filter('i18n')('error.sessionExpired.message'), backdrop: 'static', buttons: [ { text: i18nService.getLocalizedString('common.button.signInAgain'), data: true } ] }); modalInstance.result.then(function (data) { if (data) { localStorage.removeItem('homeServer'); $window.location.reload(); } }); } else { logoutPWA(); $scope.appState = APP_STATES.SHOW_LOGIN; } }); $scope.$on(AUTH_EVENTS.INITIALIZE_METADATA_ERROR, function () { if (!$scope.showingErrorModal) { $scope.appState = APP_STATES.INDETERMINATE; $scope.showingErrorModal = true; console.log('$scope.$on(AUTH_EVENTS.INITIALIZE_METADATA_ERROR)'); window.localStorage.sessionActive = false; $scope.sendMessageToPwaDomain({ smartITsessionActive: window.localStorage.sessionActive }); localStorage.removeItem('tabCount'); localStorage.removeItem('smartITActivity'); var modalInstance = systemAlertService.modal({ title: $filter('i18n')('error.invalidMetadata.title'), text: $filter('i18n')('error.invalidMetadata.message'), backdrop: 'static', buttons: [ { text: i18nService.getLocalizedString('common.button.signInAgain'), data: true } ] }); modalInstance.result.then(function (data) { $scope.showingErrorModal = false; if (data && authModel.isSSOEnabled()) { $window.location.reload(); } else if (data) { clearApplicationData(); } }); } }); function clearApplicationData() { logoutPWA(); logoutLiveChat(); // timeout added so that the logout event can be passed to the iframes $timeout(function () { $scope.appState = APP_STATES.INDETERMINATE; localStorageService.remove('user.userId'); // ITSM calendar related storage. sessionStorage.removeItem('calendarFilterState'); sessionStorage.removeItem('calendarFilterView'); sessionStorage.removeItem('calendarFilterDate'); session.destroy(); localStorage.removeItem('tabCount'); localStorage.sessionActive = false; localStorage.removeItem('smartITActivity'); $scope.sendMessageToPwaDomain({ smartITsessionActive: window.localStorage.sessionActive }); $window.location.href = './'; }, 1000); } /** * Private functions */ /** * Loads all data required for application */ function loadApplicationData() { $scope.appState = APP_STATES.INDETERMINATE; // show loading spinner userModel.getUserDataForCurrentSession(); l10nModel.loadSystemMessages(); init(); } function logoutPWA() { if (localStorage.homeServer) { localStorage.removeItem('homeServer'); } $scope.sendMessageToPwaDomain({ message: 'logout', logout: true }); } function logoutLiveChat() { var domain = localStorageService.get('eschatServerUrl'); if (domain) { var targetFrame = window.frames.liveChatFrame; if (targetFrame !== undefined && targetFrame !== null) { var message = { event: 'app_logout', data: { logout: true, isRSSO: authModel.isSSOEnabled() } }; targetFrame.postMessage(message, domain); console.log("Message Sent To LiveChat Frame:" + JSON.stringify(message)); localStorageService.remove('eschatServerUrl'); } return true; } return false; } /** * Entry point */ function init() { $scope.showMeridian = window.showMeridian; studioModel.init().then(function (studioMetaVals) { $scope.studioCCSDetailsDefer.resolve(studioMetaVals); }); searchModel.init(); $scope.chatModel = chatModel; $scope.userModel = userModel; $scope.emailModel = { emailInstances: emailModel.emailInstances }; if ($scope.state.$current.data && $scope.state.$current.data.separateWindowMode) { $scope.appState = APP_STATES.SHOW_WINDOW; } else { var accessibilityCookie = $cookies.get('accessibility') ? JSON.parse($cookies.get('accessibility')) : false; userModel.getUserPreferences('interface').then(function (accessibleConfig) { if (_.isObject(accessibleConfig[0]) || accessibilityCookie) { userModel.isAccessibleUser = _.isObject(accessibleConfig[0]) ? accessibleConfig[0].value : false; userModel.isAccessibleUserPreferenceId = _.isObject(accessibleConfig[0]) ? accessibleConfig[0].id : null; if (userModel.isAccessibleUser !== accessibilityCookie) { $scope.setAccessibility(); } } }).finally(function () { $scope.appState = APP_STATES.SHOW_MAIN; }); } $scope.$on('$viewContentLoaded', function () { if (!chatModel.connected && !$scope.isMobile) { chatModel.openChatConnection(); } setPwaFrameUrl(); }); } }]); })();