export function mainStateController()

in ui-modules/logout/app/views/main/main.controller.js [54:174]


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');
        } else if (ua.indexOf('Mozilla') >= 0) {
            // // the code below clears some locally remembered-and-resent Authorization headers that make it look as though the user is still logged in.
            // // however it has the unfortunate side effect that a user might be repeatedly prompted for credentials after logout,
            // // as the behavior on some newer browsers is (stupidly) to ignore user-prompted creds -- but repeatedly prompt for them! -- if an Authorization header is present.
            // // setting something like `window.location.protocol + '//' + 'logout:logout@' + window.location.hostname + ':' + window.location.port + '/'` can stop that behavior.
            // // but best is not to make any extra crazy request, which seems to suit modern browsers which no longer seem to silently re-send the Authorization.
            // // https://stackoverflow.com/questions/233507/how-to-log-out-user-from-web-site-using-basic-authentication
            // const url = '/';
            // // url = window.location.protocol + '//' + 'logout:logout@' + window.location.hostname + ':' + window.location.port + '/';
            // $http({
            //     method: 'GET',
            //     url,
            //     headers: {
            //         'Authorization': 'Basic ' + btoa("logout:logout")
            //     }
            // }).then((success)=>{
            //     console.log("Post-logout confirmation request completed", success);
            // }, (error)=>{
            //     console.log("Post-logout confirmation request gave error (expected)", error);
            // });
            // //// could try setting this, even before
            // // setTimeout(function () {
            // //     window.location.href = 'http://logout:logout@localhost:8080/';
            // // }, 200);
        }
    }

    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();
}