{"version":3,"file":"index.mjs","sources":["../../../projects/security/src/security.service.ts","../../../projects/security/src/index.ts"],"sourcesContent":["import { Injectable, Injector, OnDestroy } from '@angular/core';\nimport { Location } from '@angular/common';\nimport { ActivatedRoute, Router } from '@angular/router';\n\nimport {\n    AbstractHttpService,\n    App,\n    getClonedObject,\n    getWmProjectProperties,\n    triggerFn\n} from '@wm/core';\nimport {each, forEach, get, isEmpty, join, set} from \"lodash-es\";\ndeclare const _WM_APP_PROPERTIES;\n// Todo[Shubham]: Move below constants to a common file\nconst XSRF_COOKIE_NAME = 'wm_xsrf_token',\n    isApplicationType = true;\n\n@Injectable()\nexport class SecurityService implements OnDestroy {\n    config;\n    lastLoggedInUser;\n    loggedInUser;\n    loadPromise: Promise<any>;\n    requestQueue: any = {};\n    private queryParamsSubscriptions: Array<{ unsubscribe: () => void }> = []; // MEMORY LEAK FIX: Track subscriptions\n    private appSubscriptions: Array<() => void> = []; // MEMORY LEAK FIX: Track App subscriptions\n\n    constructor(\n        private injector: Injector,\n        private $http: AbstractHttpService,\n        private routerService: Router,\n        private activatedRoute: ActivatedRoute,\n        private _location: Location\n    ) {}\n\n    isLoaded() {\n        return this.config;\n    }\n\n    get() {\n        return this.config;\n    }\n\n    load(forceFlag?: boolean) {\n        if(this.loadPromise) {return this.loadPromise;}\n       // Check securityEnabled flag in _WM_APP_PROPERTIES\n       if (!_WM_APP_PROPERTIES?.securityEnabled) {\n        return Promise.resolve(null);\n        }\n        if (!forceFlag && this.config) {return Promise.resolve(this.config);}\n        this.loadPromise = new Promise((resolve, reject) => {\n                this.$http.send({'url': 'services/security/info', 'method': 'GET'}).then((response) => {\n                    this.config = response.body;\n                    _WM_APP_PROPERTIES['securityInfo'] = this.config\n                    this.lastLoggedInUser = getClonedObject(this.loggedInUser);\n                    this.loggedInUser = this.config.userInfo;\n                    resolve(response.body);\n                }).catch((err)=>{\n                    reject(err);\n                }).finally(()=>{\n                    this.loadPromise = null;\n                });\n        });\n        return this.loadPromise;\n    }\n\n    /**\n     * gets the security config from the deployed app (backend call)\n     * @param success\n     * @param error\n     */\n    getWebConfig(success, error) {\n        if (this.get()) {\n            // if already fetched, return it\n            triggerFn(success, this.get());\n            return;\n        }\n        this.load()\n            .then(config => {\n                triggerFn(success, config);\n            }, error);\n    }\n\n    /**\n     * Returns security config\n     * @param successCallback\n     * @param failureCallback\n     */\n    getConfig(successCallback, failureCallback) {\n        function invokeQueuedCallbacks(id, method, data) {\n            forEach(this.requestQueue[id], fn => triggerFn(fn[method], data));\n            this.requestQueue[id] = null;\n        }\n\n        function onSuccess(config) {\n            config = config ? config : {}\n            config.homePage = getWmProjectProperties().homePage;\n            if (config.userInfo) {\n                // Backend returns landingPage instead of homePage, hence this statement(for consistency)\n                // config.userInfo.homePage = config.userInfo.landingPage;\n            }\n            this.config = config;\n            this.lastLoggedInUser = getClonedObject(this.loggedInUser);\n            this.loggedInUser = config.userInfo;\n            invokeQueuedCallbacks.call(this, 'config', 'success', this.get());\n        }\n\n        function onError(error) {\n            /*if ($rootScope.isMobileApplicationType) {\n             this.config = {\n             'securityEnabled': false,\n             'authenticated': false,\n             'homePage': _WM_APP_PROPERTIES.homePage,\n             'userInfo': null,\n             'login': null\n             };\n             invokeQueuedCallbacks('config', 'success', this.get());\n             } else {*/\n            invokeQueuedCallbacks.call(this, 'config', 'error', error);\n            // }\n        }\n\n        if (this.get()) {\n            // if already fetched, return it\n            triggerFn(successCallback, this.get());\n            return;\n        }\n\n        // Queue check, if same queue is already in progress, do not send another request\n        this.requestQueue.config = this.requestQueue.config || [];\n        this.requestQueue.config.push({\n            success: successCallback,\n            error: failureCallback\n        });\n        if (this.requestQueue.config.length > 1) {\n            return;\n        }\n\n            // for web project, return config returned from backend API call.\n            this.getWebConfig(onSuccess.bind(this), onError.bind(this));\n        /* else {\n         /!*\n         * for mobile app, first get the mobile config (saved in the apk)\n         * - if security not enabled, just return mobile config (no backend call required)\n         * - else, get Web config (will be  the same API hit for login) and merge the config with _mobileconfig\n         *!/\n         getMobileConfig(function (mobileconfig) {\n         if (!mobileconfig.securityEnabled) {\n         onSuccess(mobileconfig);\n         } else {\n         getWebConfig(function (config) {\n         config = mergeWebAndMobileConfig(config);\n         onSuccess(config);\n         }, function () {onSuccess(mobileconfig); });\n         }\n         }, onError);\n         }*/\n    }\n\n    getLastLoggedInUsername() {\n        return this.lastLoggedInUser && this.lastLoggedInUser.userName;\n    }\n\n    /**\n     * Returns the current page name\n     * @returns {string}\n     */\n    getCurrentRoutePage() {\n        const p = this._location.path();\n        let lIndex = p.indexOf('?');\n        lIndex = lIndex === -1 ? p.length : lIndex - 1;\n        return p.substr(1, lIndex); // ignore the query params\n    }\n\n    /**\n     * Returns Query params for specified param name in current Route\n     * @param paramName, the param name whose query param value is to be retrieved\n     * @returns {any}\n     */\n    getCurrentRouteQueryParam(paramName) {\n        let paramVal;\n        // MEMORY LEAK FIX: Store subscription for cleanup (though this is a synchronous read)\n        // Note: This method is called synchronously, so the subscription completes immediately\n        // but we still store it to be safe\n        const subscription = this.activatedRoute.queryParams.subscribe(params => {\n            paramVal = params[paramName];\n        });\n        subscription.unsubscribe(); // Immediate unsubscribe since we only need first value\n        return paramVal;\n    }\n\n    isNoPageLoaded() {\n        return !isEmpty(this.getCurrentRoutePage());\n    }\n\n    getPageByLoggedInUser() {\n        const that = this;\n        return new Promise((resolve) => {\n            let page;\n            if (!isApplicationType) {\n                if (that.isNoPageLoaded()) {\n                    page = getWmProjectProperties().homePage;\n                    resolve(page);\n                }\n            } else {\n                that.getConfig((config) => {\n                    if (config.securityEnabled && config.authenticated) {\n                        page = config.userInfo.landingPage || getWmProjectProperties().homePage;\n                        // override the default xsrf cookie name and xsrf header names with WaveMaker specific values\n                        if (that.isXsrfEnabled()) {\n                            // this.$http.defaults.xsrfCookieName = XSRF_COOKIE;\n                            // this.$http.defaults.xsrfHeaderName = config.csrfHeaderName;\n                        }\n                    } else {\n                        page = getWmProjectProperties().homePage;\n                    }\n                    resolve(page);\n                }, function () {\n                    resolve(getWmProjectProperties().homePage);\n                });\n            }\n        });\n    }\n\n    /**\n     * Loads the App page as follows:\n     * Security disabled:\n     *      - Home page\n     * Security enabled:\n     *      - User is logged in, respective landing page is loaded\n     *      - Not logged in:\n     *          - Home page is public, loads the home page\n     *          - Home page not public, Login page(in config) is loaded\n     * @param forcePageLoad\n     * @returns {Promise<T>}\n     */\n    loadPageByUserRole(forcePageLoad?) {\n        const that = this;\n        return this.getPageByLoggedInUser().then(page => {\n            if (that.isNoPageLoaded() || forcePageLoad) {\n                // Reload the page when current page and post login landing page are same\n                if (that.getCurrentRoutePage() === page) {\n                    (window.location as any).reload();\n                } else {\n                    that.routerService.navigate([`/${page}`]);\n                }\n            }\n        });\n    }\n\n    /**\n     * Navigates to the current user's homePage based on the config in SecurityService\n     * Assumption is the SecurityService is updated with the latest security config before making call to this function\n     */\n    navigateOnLogin() {\n        this.loadPageByUserRole(true);\n    }\n\n    /**\n     * Gets the page which needs to be redirected to on successful login\n     * @param config,\n     * @param page, page name for redirection\n     * @returns {any|string}\n     */\n    getRedirectPage(config, page?) {\n        const homePage = getWmProjectProperties().homePage,\n            loginPage = get(config, 'loginConfig.pageName');\n        let prevRedirectPage,\n            redirectPage = page || this.getCurrentRoutePage();\n\n        // if user is already on Home page or Login page, they should not be redirected to that page, hence return undefined\n        if (redirectPage === homePage || redirectPage === loginPage) {\n            /*\n             * find previous redirect page from URL, if exists, user should redirect to that page.\n             * USE CASE:\n             *  user is on http://localhost:8080/app/#/Login?redirectTo=page\n             *  a variable call fails resulting 401\n             *  in this case, redirectTo page should be 'page' and not undefined\n             */\n            prevRedirectPage = this.getCurrentRouteQueryParam('redirectTo');\n            redirectPage = !isEmpty(prevRedirectPage) ? prevRedirectPage : undefined;\n        }\n\n        return redirectPage;\n    }\n\n    /**\n     * Returns all the query params(including page params and redirect to params) associated with redirected page\n     */\n    getRedirectedRouteQueryParams() {\n        let queryParams = {};\n        // MEMORY LEAK FIX: Store subscription for cleanup (though this is a synchronous read)\n        // Note: This method is called synchronously, so the subscription completes immediately\n        // but we still store it to be safe\n        const subscription = this.activatedRoute.queryParams.subscribe((paramVal) => {\n            forEach(paramVal, (val, key) => {\n                queryParams[key] = val;\n            });\n        });\n        subscription.unsubscribe(); // Immediate unsubscribe since we only need first value\n        return queryParams;\n    }\n\n    // accepts query object like {a:1, b:2} and returns a=1&b=2 string\n    getQueryString(queryObject) {\n        const params = [];\n        forEach(queryObject, function (value, key) {\n            params.push(key + '=' + value);\n        });\n        return join(params, '&');\n    }\n\n    appLogin(params, successCallback, failureCallback) {\n        let payload = '';\n\n        // encode all parameters\n        each(params, function (value, name) {\n            payload += (payload ? '&' : '') + encodeURIComponent(name) + '=' + encodeURIComponent(value);\n        });\n\n        return this.$http.send({\n            method: 'POST',\n            headers: {\n                'Content-Type': 'application/x-www-form-urlencoded'\n            },\n            url: 'j_spring_security_check',\n            'data': payload\n        }).then((response) => {\n            const xsrfCookieValue = response.body ? response.body[XSRF_COOKIE_NAME] : '';\n\n            // override the default xsrf cookie name and xsrf header names with WaveMaker specific values\n            if (xsrfCookieValue) {\n            }\n            // After the successful login in device, this function triggers the pending onLoginCallbacks.\n            this.injector.get(App).notify('userLoggedIn', {});\n            triggerFn(successCallback, response);\n        }, failureCallback);\n    }\n\n    /**\n     * The API is used to check if the user is authenticated in the RUN mode.\n     *\n     * @param {function} successCallback to be called on success\n     * @param {function} failureCallback to be called on failure\n     */\n    isAuthenticated(successCallback, failureCallback) {\n        this.getConfig(function (config) {\n            triggerFn(successCallback, config.authenticated);\n        }, failureCallback);\n    }\n\n    /**\n     * The API is used to logout of the app.\n     *\n     * @param {function} successCallback to be called on success\n     * @param {function} failureCallback to be called on failure\n     */\n    appLogout(successCallback, failureCallback) {\n        return this.$http.send({\n            target: 'Security',\n            url: 'j_spring_security_logout',\n            method: 'POST',\n            responseType: 'text',\n            byPassResult: true\n        }).then((response) => {\n            set(this.get(), 'authenticated', false);\n            set(this.get(), 'userInfo', null);\n            this.injector.get(App).notify('userLoggedOut', {});\n            triggerFn(successCallback, response);\n        }, failureCallback);\n    }\n\n    /**\n     * Checks and return the cookie\n     * @param name, cookie key\n     * @returns {string}\n     */\n    getCookieByName(name) {\n        // Todo: Shubham Implement cookie native js\n        return 'cookie';\n    }\n\n    /**\n     * This function returns the cookieValue if xsrf is enabled.\n     * In device, xsrf cookie is stored in localStorage.\n     * @returns xsrf cookie value\n     */\n    isXsrfEnabled() {\n        return this.getCookieByName(XSRF_COOKIE_NAME);\n    }\n\n    /**\n     * This function returns a promise. Promise is resolved when security is\n     * 1. disabled\n     * 2. enabled and user is authenticated\n     * 3. enabled and user is not authenticated, then promise is resolved on user login\n     * @returns {*} promise\n     */\n    public onUserLogin(): Promise<any> {\n        return new Promise<void>((resolve, reject) => {\n            this.getConfig(config => {\n                if (config.securityEnabled) {\n                    if (config.authenticated) {\n                        resolve();\n                    } else {\n                        // MEMORY LEAK FIX: Store unsubscribe function for cleanup\n                        const unsubscribe = this.injector.get(App).subscribe('userLoggedIn', () => {\n                            resolve();\n                            unsubscribe();\n                            // Remove from tracking array\n                            const index = this.appSubscriptions.indexOf(unsubscribe);\n                            if (index > -1) {\n                                this.appSubscriptions.splice(index, 1);\n                            }\n                        });\n                        this.appSubscriptions.push(unsubscribe);\n                    }\n                } else {\n                    resolve();\n                }\n            }, reject);\n        });\n    }\n\n    /**\n     * @returns a promise that is resolved with logged-in-user\n     */\n    getLoggedInUser() {\n        return new Promise<any>((resolve, reject) => {\n            this.getConfig((config) => {\n                if (config && config.userInfo) {\n                    resolve(config.userInfo);\n                } else {\n                    reject();\n                }\n            }, reject);\n        });\n    }\n\n    /**\n     * This is for mobile apps to authenticate via browser.\n     *\n     * @returns a promise that is resolved after login\n     */\n    authInBrowser(): Promise<any> {\n        return Promise.reject('This authInBrowser should not be called');\n    }\n\n    ngOnDestroy() {\n        // MEMORY LEAK FIX: Unsubscribe from all query params subscriptions\n        this.queryParamsSubscriptions.forEach(sub => {\n            if (sub && sub.unsubscribe) {\n                sub.unsubscribe();\n            }\n        });\n        this.queryParamsSubscriptions = [];\n\n        // MEMORY LEAK FIX: Unsubscribe from all App subscriptions\n        this.appSubscriptions.forEach(unsubscribe => {\n            if (unsubscribe) {\n                unsubscribe();\n            }\n        });\n        this.appSubscriptions = [];\n\n        // MEMORY LEAK FIX: Clear references\n        this.config = null;\n        this.lastLoggedInUser = null;\n        this.loggedInUser = null;\n        this.requestQueue = null;\n        this.loadPromise = null;\n    }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}