From 9583a2dbad7169aa91b7631c7421f50c159d0ffa Mon Sep 17 00:00:00 2001 From: Pranav Raj S Date: Thu, 3 Mar 2022 20:49:51 +0530 Subject: [PATCH] chore: Pass sso_account_id to select the account during SSO Login (#4103) --- app/javascript/dashboard/api/auth.js | 2 +- app/javascript/dashboard/helper/URLHelper.js | 12 +++++++++++ .../dashboard/helper/specs/URLHelper.spec.js | 21 +++++++++++++++++++ app/javascript/dashboard/routes/index.js | 13 ++++++++++++ .../dashboard/routes/login/Login.vue | 2 ++ .../dashboard/routes/login/login.routes.js | 1 + .../dashboard/store/modules/auth.js | 9 ++++---- app/javascript/dashboard/store/utils/api.js | 10 +++++---- 8 files changed, 61 insertions(+), 9 deletions(-) diff --git a/app/javascript/dashboard/api/auth.js b/app/javascript/dashboard/api/auth.js index 18ec9e811..a8806f7fd 100644 --- a/app/javascript/dashboard/api/auth.js +++ b/app/javascript/dashboard/api/auth.js @@ -13,7 +13,7 @@ export default { .post('auth/sign_in', creds) .then(response => { setAuthCredentials(response); - resolve(); + resolve(response.data); }) .catch(error => { reject(error.response); diff --git a/app/javascript/dashboard/helper/URLHelper.js b/app/javascript/dashboard/helper/URLHelper.js index e229ce7e4..583a99c7c 100644 --- a/app/javascript/dashboard/helper/URLHelper.js +++ b/app/javascript/dashboard/helper/URLHelper.js @@ -1,10 +1,22 @@ import queryString from 'query-string'; +import { DEFAULT_REDIRECT_URL } from '../constants'; export const frontendURL = (path, params) => { const stringifiedParams = params ? `?${queryString.stringify(params)}` : ''; return `/app/${path}${stringifiedParams}`; }; +export const getLoginRedirectURL = (ssoAccountId, user) => { + const { accounts = [] } = user || {}; + const ssoAccount = accounts.find( + account => account.id === Number(ssoAccountId) + ); + if (ssoAccount) { + return frontendURL(`accounts/${ssoAccountId}/dashboard`); + } + return DEFAULT_REDIRECT_URL; +}; + export const conversationUrl = ({ accountId, activeInbox, diff --git a/app/javascript/dashboard/helper/specs/URLHelper.spec.js b/app/javascript/dashboard/helper/specs/URLHelper.spec.js index ade735642..832d90577 100644 --- a/app/javascript/dashboard/helper/specs/URLHelper.spec.js +++ b/app/javascript/dashboard/helper/specs/URLHelper.spec.js @@ -3,6 +3,7 @@ import { conversationUrl, accountIdFromPathname, isValidURL, + getLoginRedirectURL, } from '../URLHelper'; describe('#URL Helpers', () => { @@ -58,4 +59,24 @@ describe('#URL Helpers', () => { expect(isValidURL('alert.window')).toBe(false); }); }); + + describe('getLoginRedirectURL', () => { + it('should return correct Account URL if account id is present', () => { + expect( + getLoginRedirectURL('7500', { + accounts: [{ id: 7500, name: 'Test Account 7500' }], + }) + ).toBe('/app/accounts/7500/dashboard'); + }); + + it('should return default URL if account id is not present', () => { + expect(getLoginRedirectURL('7500', {})).toBe('/app/'); + expect( + getLoginRedirectURL('7500', { + accounts: [{ id: '7501', name: 'Test Account 7501' }], + }) + ).toBe('/app/'); + expect(getLoginRedirectURL('7500', null)).toBe('/app/'); + }); + }); }); diff --git a/app/javascript/dashboard/routes/index.js b/app/javascript/dashboard/routes/index.js index b2d19cf7f..14ef77bc3 100644 --- a/app/javascript/dashboard/routes/index.js +++ b/app/javascript/dashboard/routes/index.js @@ -5,6 +5,7 @@ import login from './login/login.routes'; import dashboard from './dashboard/dashboard.routes'; import authRoute from './auth/auth.routes'; import { frontendURL } from '../helper/URLHelper'; +import { clearBrowserSessionCookies } from '../store/utils/api'; const routes = [ ...login.routes, @@ -101,6 +102,13 @@ export const validateAuthenticateRoutePermission = (to, from, next) => { return nextRoute ? next(frontendURL(nextRoute)) : next(); }; +const validateSSOLoginParams = to => { + const isLoginRoute = to.name === 'login'; + const { email, sso_auth_token: ssoAuthToken } = to.query || {}; + const hasValidSSOParams = email && ssoAuthToken; + return isLoginRoute && hasValidSSOParams; +}; + const validateRouteAccess = (to, from, next) => { if ( window.chatwootConfig.signupEnabled !== 'true' && @@ -111,6 +119,11 @@ const validateRouteAccess = (to, from, next) => { next(frontendURL(`accounts/${user.account_id}/dashboard`)); } + if (validateSSOLoginParams(to)) { + clearBrowserSessionCookies(); + return next(); + } + if (authIgnoreRoutes.includes(to.name)) { return next(); } diff --git a/app/javascript/dashboard/routes/login/Login.vue b/app/javascript/dashboard/routes/login/Login.vue index 92fea2e36..428974af7 100644 --- a/app/javascript/dashboard/routes/login/Login.vue +++ b/app/javascript/dashboard/routes/login/Login.vue @@ -80,6 +80,7 @@ export default { mixins: [globalConfigMixin], props: { ssoAuthToken: { type: String, default: '' }, + ssoAccountId: { type: String, default: '' }, redirectUrl: { type: String, default: '' }, config: { type: String, default: '' }, email: { type: String, default: '' }, @@ -138,6 +139,7 @@ export default { : this.credentials.email, password: this.credentials.password, sso_auth_token: this.ssoAuthToken, + ssoAccountId: this.ssoAccountId, }; this.$store .dispatch('login', credentials) diff --git a/app/javascript/dashboard/routes/login/login.routes.js b/app/javascript/dashboard/routes/login/login.routes.js index c53cffa92..f43e632bf 100644 --- a/app/javascript/dashboard/routes/login/login.routes.js +++ b/app/javascript/dashboard/routes/login/login.routes.js @@ -12,6 +12,7 @@ export default { email: route.query.email, ssoAuthToken: route.query.sso_auth_token, redirectUrl: route.query.route_url, + ssoAccountId: route.query.sso_account_id, }), }, ], diff --git a/app/javascript/dashboard/store/modules/auth.js b/app/javascript/dashboard/store/modules/auth.js index d9ec54564..5b2feef11 100644 --- a/app/javascript/dashboard/store/modules/auth.js +++ b/app/javascript/dashboard/store/modules/auth.js @@ -6,7 +6,7 @@ import authAPI from '../../api/auth'; import createAxios from '../../helper/APIHelper'; import actionCable from '../../helper/actionCable'; import { setUser, getHeaderExpiry, clearCookiesOnLogout } from '../utils/api'; -import { DEFAULT_REDIRECT_URL } from '../../constants'; +import { getLoginRedirectURL } from '../../helper/URLHelper'; const state = { currentUser: { @@ -88,15 +88,16 @@ export const getters = { // actions export const actions = { - login({ commit }, credentials) { + login({ commit }, { ssoAccountId, ...credentials }) { return new Promise((resolve, reject) => { authAPI .login(credentials) - .then(() => { + .then(response => { commit(types.default.SET_CURRENT_USER); window.axios = createAxios(axios); actionCable.init(Vue); - window.location = DEFAULT_REDIRECT_URL; + + window.location = getLoginRedirectURL(ssoAccountId, response.data); resolve(); }) .catch(error => { diff --git a/app/javascript/dashboard/store/utils/api.js b/app/javascript/dashboard/store/utils/api.js index 651f0cd61..37fd68c7b 100644 --- a/app/javascript/dashboard/store/utils/api.js +++ b/app/javascript/dashboard/store/utils/api.js @@ -38,13 +38,15 @@ export const setAuthCredentials = response => { setUser(response.data.data, expiryDate); }; +export const clearBrowserSessionCookies = () => { + Cookies.remove('auth_data'); + Cookies.remove('user'); +}; + export const clearCookiesOnLogout = () => { window.bus.$emit(CHATWOOT_RESET); window.bus.$emit(ANALYTICS_RESET); - - Cookies.remove('auth_data'); - Cookies.remove('user'); - + clearBrowserSessionCookies(); const globalConfig = window.globalConfig || {}; const logoutRedirectLink = globalConfig.LOGOUT_REDIRECT_LINK || frontendURL('login');