| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| import angular from 'angular'; |
| import uiRouter from 'angular-ui-router'; |
| import {HIDE_INTERSTITIAL_SPINNER_EVENT} from 'brooklyn-ui-utils/interstitial-spinner/interstitial-spinner'; |
| |
| const MODULE_NAME = 'main.state'; |
| |
| angular.module(MODULE_NAME, [uiRouter]) |
| .config(['$stateProvider', mainStateConfig]); |
| |
| export default MODULE_NAME; |
| |
| export const mainState = { |
| name: 'mainRoot', |
| url: '/?debug&keepCreds&useGet&salt', |
| // experimental/test options: |
| // * useGet means to make a GET request instead of POST |
| // * keepCreds means not to request a 200 on successful logout instead of a 401; |
| // this will prevent the browser from clearing cache |
| template: require('ejs-html!./main.template.html'), |
| controller: ['$scope', '$http', '$state', '$stateParams', '$log', '$timeout', mainStateController], |
| controllerAs: 'vm' |
| }; |
| export const promptState = { |
| name: 'prompt', |
| url: '/prompt?debug', |
| params: { prompt: true }, |
| template: require('ejs-html!./main.template.html'), |
| controller: ['$scope', '$http', '$state', '$stateParams', mainStateController], |
| controllerAs: 'vm' |
| }; |
| |
| export function mainStateConfig($stateProvider) { |
| $stateProvider.state(promptState).state(mainState); |
| } |
| |
| export function mainStateController($scope, $http, $state, $stateParams, $log, $timeout) { |
| if (!$scope.state) $scope.state = {}; |
| if ($stateParams.prompt) $scope.state.status = "prompt"; |
| if (!$scope.state.status) $scope.state.status = "do-logout"; |
| |
| /* There is a lot of complexity in here to support debug pathways with confirmation, |
| * use of http GET instead of POST, and use of API which returns 200 instead of 401. |
| * This is because logging out nicely is quite tricky. |
| * Currently we think we have a good pathway without any of that complexity, |
| * so if you haven't set "?debug=true" or other special option in the URL it is |
| * mostly disabled and follows the happy path where it just logs out and prompts |
| * you to log back in. But the debug stuff is left in, in case we encounter edge cases. |
| */ |
| |
| $scope.debug = $stateParams.debug; |
| if ($scope.debug) { |
| $log.info("Logout page running in debug mode. state=", $state, "state params=", $stateParams); |
| } |
| if ($stateParams.salt) { |
| // specify some salt to ensure links change in dev mode |
| $scope.salt = (parseInt($stateParams.salt) || 0); |
| } |
| |
| $scope.$emit(HIDE_INTERSTITIAL_SPINNER_EVENT); |
| |
| function clearLocalCache() { |
| let ua = window.navigator.userAgent; |
| if (ua.indexOf('MSIE ') >= 0 || ua.indexOf(' Edge/') >= 0 || ua.indexOf(' Trident/') >= 0) { |
| document.execCommand('ClearAuthenticationCache', 'false'); |
| } |
| } |
| |
| function handleError(phase, response, expectAlreadyLoggedOut) { |
| if (response && response.status >= 300 && response.status < 400 || response.status == 401) { |
| // auth required |
| if (expectAlreadyLoggedOut) { |
| $scope.state = { status: "logout-confirmed", code: response.status }; |
| } else { |
| $scope.state = { status: "already-logged-out", code: response.status }; |
| } |
| } else if (response && response.status && response.status>0) { |
| $log.warn("Server failure "+phase, response); |
| $scope.state = { status: "failed", message: "server failure ("+response.status+") "+phase+ |
| (response.message ? ": "+response.message : ""), code: response.status }; |
| } else { |
| $log.info("Connection failure "+phase, response); |
| $scope.state = { status: "failed", message: "connection failure "+phase, code: response.status }; |
| } |
| clearLocalCache(); |
| } |
| |
| this.logout = (expectAlreadyLoggedOut) => { |
| let useGet = $stateParams.useGet; |
| let keepCreds = $stateParams.keepCreds; |
| |
| $scope.state = { status: "logging-out" }; |
| let params = {}; |
| let ourToken = 'logging-out-from-webapp'; // used to ensure the 401 is because we logged out |
| if (!keepCreds) params.unauthorize = ourToken; |
| //let httpCall = useGet ? $http.get('/v1/logout', { params }) : $http.post('/v1/logout', params); |
| //httpCall |
| $timeout(()=> |
| $http({ url: '/v1/logout', method: useGet ? "GET" : "POST", params }) |
| .then(response => { |
| if ($scope.debug) $log.info("Logout response", response); |
| $scope.state = { status: "just-logged-out" }; |
| clearLocalCache(); |
| |
| }, error => { |
| if (error.data && error.data.message == ourToken) { |
| if ($scope.debug) $log.info("Logout response 401 - ", error); |
| if (expectAlreadyLoggedOut) { |
| $scope.state = { status: "success-after-logout" }; |
| } else { |
| $scope.state = { status: "just-logged-out" }; |
| } |
| clearLocalCache(); |
| |
| } else { |
| handleError(expectAlreadyLoggedOut ? "confirming logout" : "logging out", error, expectAlreadyLoggedOut); |
| } |
| }), 500 /* delay 500ms so other requests finish loading */); |
| } |
| |
| this.retry = () => this.logout(); |
| |
| this.prompt = () => { |
| $scope.state.status = "prompt"; |
| } |
| |
| this.confirm = () => { |
| clearLocalCache(); |
| this.logout(true); |
| } |
| |
| if ($scope.state.status == "do-logout") this.logout(); |
| } |