mirror of
				https://github.com/lingble/chatwoot.git
				synced 2025-10-31 19:17:48 +00:00 
			
		
		
		
	chore: Move frontend authorization to permission based system (#9709)
We previously relied on user roles to determine whether to render specific routes in our frontend components. A permissions-based model is replacing this approach. Follow up: #9695 Co-authored-by: Pranav <pranavrajs@gmail.com>
This commit is contained in:
		| @@ -20,7 +20,7 @@ | ||||
|       :teams="teams" | ||||
|       :custom-views="customViews" | ||||
|       :menu-config="activeSecondaryMenu" | ||||
|       :current-role="currentRole" | ||||
|       :current-user="currentUser" | ||||
|       :is-on-chatwoot-cloud="isOnChatwootCloud" | ||||
|       @add-label="showAddLabelPopup" | ||||
|       @toggle-accounts="toggleAccountModal" | ||||
| @@ -37,7 +37,8 @@ import alertMixin from 'shared/mixins/alertMixin'; | ||||
| import PrimarySidebar from './sidebarComponents/Primary.vue'; | ||||
| import SecondarySidebar from './sidebarComponents/Secondary.vue'; | ||||
| import keyboardEventListenerMixins from 'shared/mixins/keyboardEventListenerMixins'; | ||||
| import router from '../../routes'; | ||||
| import router, { routesWithPermissions } from '../../routes'; | ||||
| import { hasPermissions } from '../../helper/permissionsHelper'; | ||||
|  | ||||
| export default { | ||||
|   components: { | ||||
| @@ -98,9 +99,13 @@ export default { | ||||
|       return getSidebarItems(this.accountId); | ||||
|     }, | ||||
|     primaryMenuItems() { | ||||
|       const userPermissions = this.currentUser.permissions; | ||||
|       const menuItems = this.sideMenuConfig.primaryMenu; | ||||
|       return menuItems.filter(menuItem => { | ||||
|         const isAvailableForTheUser = menuItem.roles.includes(this.currentRole); | ||||
|         const isAvailableForTheUser = hasPermissions( | ||||
|           routesWithPermissions[menuItem.toStateName], | ||||
|           userPermissions | ||||
|         ); | ||||
|  | ||||
|         if (!isAvailableForTheUser) { | ||||
|           return false; | ||||
|   | ||||
| @@ -9,7 +9,6 @@ const primaryMenuItems = accountId => [ | ||||
|     featureFlag: FEATURE_FLAGS.INBOX_VIEW, | ||||
|     toState: frontendURL(`accounts/${accountId}/inbox-view`), | ||||
|     toStateName: 'inbox_view', | ||||
|     roles: ['administrator', 'agent'], | ||||
|   }, | ||||
|   { | ||||
|     icon: 'chat', | ||||
| @@ -17,7 +16,6 @@ const primaryMenuItems = accountId => [ | ||||
|     label: 'CONVERSATIONS', | ||||
|     toState: frontendURL(`accounts/${accountId}/dashboard`), | ||||
|     toStateName: 'home', | ||||
|     roles: ['administrator', 'agent'], | ||||
|   }, | ||||
|   { | ||||
|     icon: 'book-contacts', | ||||
| @@ -26,7 +24,6 @@ const primaryMenuItems = accountId => [ | ||||
|     featureFlag: FEATURE_FLAGS.CRM, | ||||
|     toState: frontendURL(`accounts/${accountId}/contacts`), | ||||
|     toStateName: 'contacts_dashboard', | ||||
|     roles: ['administrator', 'agent'], | ||||
|   }, | ||||
|   { | ||||
|     icon: 'arrow-trending-lines', | ||||
| @@ -34,8 +31,7 @@ const primaryMenuItems = accountId => [ | ||||
|     label: 'REPORTS', | ||||
|     featureFlag: FEATURE_FLAGS.REPORTS, | ||||
|     toState: frontendURL(`accounts/${accountId}/reports`), | ||||
|     toStateName: 'settings_account_reports', | ||||
|     roles: ['administrator'], | ||||
|     toStateName: 'account_overview_reports', | ||||
|   }, | ||||
|   { | ||||
|     icon: 'megaphone', | ||||
| @@ -44,7 +40,6 @@ const primaryMenuItems = accountId => [ | ||||
|     featureFlag: FEATURE_FLAGS.CAMPAIGNS, | ||||
|     toState: frontendURL(`accounts/${accountId}/campaigns`), | ||||
|     toStateName: 'ongoing_campaigns', | ||||
|     roles: ['administrator'], | ||||
|   }, | ||||
|   { | ||||
|     icon: 'library', | ||||
| @@ -54,7 +49,6 @@ const primaryMenuItems = accountId => [ | ||||
|     alwaysVisibleOnChatwootInstances: true, | ||||
|     toState: frontendURL(`accounts/${accountId}/portals`), | ||||
|     toStateName: 'default_portal_articles', | ||||
|     roles: ['administrator'], | ||||
|   }, | ||||
|   { | ||||
|     icon: 'settings', | ||||
| @@ -62,7 +56,6 @@ const primaryMenuItems = accountId => [ | ||||
|     label: 'SETTINGS', | ||||
|     toState: frontendURL(`accounts/${accountId}/settings`), | ||||
|     toStateName: 'settings_home', | ||||
|     roles: ['administrator', 'agent'], | ||||
|   }, | ||||
| ]; | ||||
|  | ||||
|   | ||||
| @@ -24,7 +24,6 @@ const settings = accountId => ({ | ||||
|     'settings_inbox_list', | ||||
|     'settings_inbox_new', | ||||
|     'settings_inbox_show', | ||||
|     'settings_inbox', | ||||
|     'settings_inboxes_add_agents', | ||||
|     'settings_inboxes_page_channel', | ||||
|     'settings_integrations_dashboard_apps', | ||||
| @@ -46,6 +45,9 @@ const settings = accountId => ({ | ||||
|       icon: 'briefcase', | ||||
|       label: 'ACCOUNT_SETTINGS', | ||||
|       hasSubMenu: false, | ||||
|       meta: { | ||||
|         permissions: ['administrator'], | ||||
|       }, | ||||
|       toState: frontendURL(`accounts/${accountId}/settings/general`), | ||||
|       toStateName: 'general_settings_index', | ||||
|     }, | ||||
| @@ -53,6 +55,9 @@ const settings = accountId => ({ | ||||
|       icon: 'people', | ||||
|       label: 'AGENTS', | ||||
|       hasSubMenu: false, | ||||
|       meta: { | ||||
|         permissions: ['administrator'], | ||||
|       }, | ||||
|       toState: frontendURL(`accounts/${accountId}/settings/agents/list`), | ||||
|       toStateName: 'agent_list', | ||||
|       featureFlag: FEATURE_FLAGS.AGENT_MANAGEMENT, | ||||
| @@ -61,6 +66,9 @@ const settings = accountId => ({ | ||||
|       icon: 'people-team', | ||||
|       label: 'TEAMS', | ||||
|       hasSubMenu: false, | ||||
|       meta: { | ||||
|         permissions: ['administrator'], | ||||
|       }, | ||||
|       toState: frontendURL(`accounts/${accountId}/settings/teams/list`), | ||||
|       toStateName: 'settings_teams_list', | ||||
|       featureFlag: FEATURE_FLAGS.TEAM_MANAGEMENT, | ||||
| @@ -69,6 +77,9 @@ const settings = accountId => ({ | ||||
|       icon: 'mail-inbox-all', | ||||
|       label: 'INBOXES', | ||||
|       hasSubMenu: false, | ||||
|       meta: { | ||||
|         permissions: ['administrator'], | ||||
|       }, | ||||
|       toState: frontendURL(`accounts/${accountId}/settings/inboxes/list`), | ||||
|       toStateName: 'settings_inbox_list', | ||||
|       featureFlag: FEATURE_FLAGS.INBOX_MANAGEMENT, | ||||
| @@ -77,6 +88,9 @@ const settings = accountId => ({ | ||||
|       icon: 'tag', | ||||
|       label: 'LABELS', | ||||
|       hasSubMenu: false, | ||||
|       meta: { | ||||
|         permissions: ['administrator'], | ||||
|       }, | ||||
|       toState: frontendURL(`accounts/${accountId}/settings/labels/list`), | ||||
|       toStateName: 'labels_list', | ||||
|       featureFlag: FEATURE_FLAGS.LABELS, | ||||
| @@ -85,6 +99,9 @@ const settings = accountId => ({ | ||||
|       icon: 'code', | ||||
|       label: 'CUSTOM_ATTRIBUTES', | ||||
|       hasSubMenu: false, | ||||
|       meta: { | ||||
|         permissions: ['administrator'], | ||||
|       }, | ||||
|       toState: frontendURL( | ||||
|         `accounts/${accountId}/settings/custom-attributes/list` | ||||
|       ), | ||||
| @@ -95,6 +112,9 @@ const settings = accountId => ({ | ||||
|       icon: 'automation', | ||||
|       label: 'AUTOMATION', | ||||
|       hasSubMenu: false, | ||||
|       meta: { | ||||
|         permissions: ['administrator'], | ||||
|       }, | ||||
|       toState: frontendURL(`accounts/${accountId}/settings/automation/list`), | ||||
|       toStateName: 'automation_list', | ||||
|       featureFlag: FEATURE_FLAGS.AUTOMATIONS, | ||||
| @@ -103,6 +123,9 @@ const settings = accountId => ({ | ||||
|       icon: 'bot', | ||||
|       label: 'AGENT_BOTS', | ||||
|       hasSubMenu: false, | ||||
|       meta: { | ||||
|         permissions: ['administrator'], | ||||
|       }, | ||||
|       globalConfigFlag: 'csmlEditorHost', | ||||
|       toState: frontendURL(`accounts/${accountId}/settings/agent-bots`), | ||||
|       toStateName: 'agent_bots', | ||||
| @@ -112,6 +135,9 @@ const settings = accountId => ({ | ||||
|       icon: 'flash-settings', | ||||
|       label: 'MACROS', | ||||
|       hasSubMenu: false, | ||||
|       meta: { | ||||
|         permissions: ['administrator', 'agent'], | ||||
|       }, | ||||
|       toState: frontendURL(`accounts/${accountId}/settings/macros`), | ||||
|       toStateName: 'macros_wrapper', | ||||
|       featureFlag: FEATURE_FLAGS.MACROS, | ||||
| @@ -120,6 +146,9 @@ const settings = accountId => ({ | ||||
|       icon: 'chat-multiple', | ||||
|       label: 'CANNED_RESPONSES', | ||||
|       hasSubMenu: false, | ||||
|       meta: { | ||||
|         permissions: ['administrator', 'agent'], | ||||
|       }, | ||||
|       toState: frontendURL( | ||||
|         `accounts/${accountId}/settings/canned-response/list` | ||||
|       ), | ||||
| @@ -130,6 +159,9 @@ const settings = accountId => ({ | ||||
|       icon: 'flash-on', | ||||
|       label: 'INTEGRATIONS', | ||||
|       hasSubMenu: false, | ||||
|       meta: { | ||||
|         permissions: ['administrator'], | ||||
|       }, | ||||
|       toState: frontendURL(`accounts/${accountId}/settings/integrations`), | ||||
|       toStateName: 'settings_integrations', | ||||
|       featureFlag: FEATURE_FLAGS.INTEGRATIONS, | ||||
| @@ -138,6 +170,9 @@ const settings = accountId => ({ | ||||
|       icon: 'star-emphasis', | ||||
|       label: 'APPLICATIONS', | ||||
|       hasSubMenu: false, | ||||
|       meta: { | ||||
|         permissions: ['administrator'], | ||||
|       }, | ||||
|       toState: frontendURL(`accounts/${accountId}/settings/applications`), | ||||
|       toStateName: 'settings_applications', | ||||
|       featureFlag: FEATURE_FLAGS.INTEGRATIONS, | ||||
| @@ -146,6 +181,9 @@ const settings = accountId => ({ | ||||
|       icon: 'key', | ||||
|       label: 'AUDIT_LOGS', | ||||
|       hasSubMenu: false, | ||||
|       meta: { | ||||
|         permissions: ['administrator'], | ||||
|       }, | ||||
|       toState: frontendURL(`accounts/${accountId}/settings/audit-log/list`), | ||||
|       toStateName: 'auditlogs_list', | ||||
|       isEnterpriseOnly: true, | ||||
| @@ -156,6 +194,9 @@ const settings = accountId => ({ | ||||
|       icon: 'document-list-clock', | ||||
|       label: 'SLA', | ||||
|       hasSubMenu: false, | ||||
|       meta: { | ||||
|         permissions: ['administrator'], | ||||
|       }, | ||||
|       toState: frontendURL(`accounts/${accountId}/settings/sla/list`), | ||||
|       toStateName: 'sla_list', | ||||
|       isEnterpriseOnly: true, | ||||
| @@ -166,6 +207,9 @@ const settings = accountId => ({ | ||||
|       icon: 'credit-card-person', | ||||
|       label: 'BILLING', | ||||
|       hasSubMenu: false, | ||||
|       meta: { | ||||
|         permissions: ['administrator'], | ||||
|       }, | ||||
|       toState: frontendURL(`accounts/${accountId}/settings/billing`), | ||||
|       toStateName: 'billing_settings_index', | ||||
|       showOnlyOnCloud: true, | ||||
|   | ||||
| @@ -29,6 +29,8 @@ import SecondaryNavItem from './SecondaryNavItem.vue'; | ||||
| import AccountContext from './AccountContext.vue'; | ||||
| import { mapGetters } from 'vuex'; | ||||
| import { FEATURE_FLAGS } from '../../../featureFlags'; | ||||
| import { hasPermissions } from '../../../helper/permissionsHelper'; | ||||
| import { routesWithPermissions } from '../../../routes'; | ||||
|  | ||||
| export default { | ||||
|   components: { | ||||
| @@ -60,9 +62,9 @@ export default { | ||||
|       type: Object, | ||||
|       default: () => {}, | ||||
|     }, | ||||
|     currentRole: { | ||||
|       type: String, | ||||
|       default: '', | ||||
|     currentUser: { | ||||
|       type: Object, | ||||
|       default: () => {}, | ||||
|     }, | ||||
|     isOnChatwootCloud: { | ||||
|       type: Boolean, | ||||
| @@ -80,16 +82,16 @@ export default { | ||||
|       return this.customViews.filter(view => view.filter_type === 'contact'); | ||||
|     }, | ||||
|     accessibleMenuItems() { | ||||
|       if (!this.currentRole) { | ||||
|         return []; | ||||
|       } | ||||
|       const menuItemsFilteredByRole = this.menuConfig.menuItems.filter( | ||||
|         menuItem => | ||||
|           window.roleWiseRoutes[this.currentRole].indexOf( | ||||
|             menuItem.toStateName | ||||
|           ) > -1 | ||||
|       const menuItemsFilteredByPermissions = this.menuConfig.menuItems.filter( | ||||
|         menuItem => { | ||||
|           const { permissions: userPermissions = [] } = this.currentUser; | ||||
|           return hasPermissions( | ||||
|             routesWithPermissions[menuItem.toStateName], | ||||
|             userPermissions | ||||
|           ); | ||||
|         } | ||||
|       ); | ||||
|       return menuItemsFilteredByRole.filter(item => { | ||||
|       return menuItemsFilteredByPermissions.filter(item => { | ||||
|         if (item.showOnlyOnCloud) { | ||||
|           return this.isOnChatwootCloud; | ||||
|         } | ||||
|   | ||||
| @@ -65,27 +65,29 @@ | ||||
|         :show-child-count="showChildCount(child.count)" | ||||
|         :child-item-count="child.count" | ||||
|       /> | ||||
|       <router-link | ||||
|         v-if="showItem(menuItem)" | ||||
|         v-slot="{ href, navigate }" | ||||
|         :to="menuItem.toState" | ||||
|         custom | ||||
|       > | ||||
|         <li class="pl-1"> | ||||
|           <a :href="href"> | ||||
|             <woot-button | ||||
|               size="tiny" | ||||
|               variant="clear" | ||||
|               color-scheme="secondary" | ||||
|               icon="add" | ||||
|               :data-testid="menuItem.dataTestid" | ||||
|               @click="e => newLinkClick(e, navigate)" | ||||
|             > | ||||
|               {{ $t(`SIDEBAR.${menuItem.newLinkTag}`) }} | ||||
|             </woot-button> | ||||
|           </a> | ||||
|         </li> | ||||
|       </router-link> | ||||
|       <Policy :permissions="['administrator']"> | ||||
|         <router-link | ||||
|           v-if="menuItem.newLink" | ||||
|           v-slot="{ href, navigate }" | ||||
|           :to="menuItem.toState" | ||||
|           custom | ||||
|         > | ||||
|           <li class="pl-1"> | ||||
|             <a :href="href"> | ||||
|               <woot-button | ||||
|                 size="tiny" | ||||
|                 variant="clear" | ||||
|                 color-scheme="secondary" | ||||
|                 icon="add" | ||||
|                 :data-testid="menuItem.dataTestid" | ||||
|                 @click="e => newLinkClick(e, navigate)" | ||||
|               > | ||||
|                 {{ $t(`SIDEBAR.${menuItem.newLinkTag}`) }} | ||||
|               </woot-button> | ||||
|             </a> | ||||
|           </li> | ||||
|         </router-link> | ||||
|       </Policy> | ||||
|     </ul> | ||||
|   </li> | ||||
| </template> | ||||
| @@ -105,9 +107,10 @@ import { | ||||
|   isOnMentionsView, | ||||
|   isOnUnattendedView, | ||||
| } from '../../../store/modules/conversations/helpers/actionHelpers'; | ||||
| import Policy from '../../policy.vue'; | ||||
|  | ||||
| export default { | ||||
|   components: { SecondaryChildNavItem }, | ||||
|   components: { SecondaryChildNavItem, Policy }, | ||||
|   mixins: [adminMixin, configMixin], | ||||
|   props: { | ||||
|     menuItem: { | ||||
|   | ||||
							
								
								
									
										23
									
								
								app/javascript/dashboard/components/policy.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								app/javascript/dashboard/components/policy.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| <script setup> | ||||
| import { useStoreGetters } from 'dashboard/composables/store'; | ||||
| import { computed } from 'vue'; | ||||
| import { hasPermissions } from '../helper/permissionsHelper'; | ||||
| const props = defineProps({ | ||||
|   permissions: { | ||||
|     type: Array, | ||||
|     required: true, | ||||
|   }, | ||||
| }); | ||||
|  | ||||
| const getters = useStoreGetters(); | ||||
| const user = getters.getCurrentUser.value; | ||||
| const hasPermission = computed(() => | ||||
|   hasPermissions(props.permissions, user.permissions) | ||||
| ); | ||||
| </script> | ||||
|  | ||||
| <template> | ||||
|   <div v-if="hasPermission"> | ||||
|     <slot /> | ||||
|   </div> | ||||
| </template> | ||||
							
								
								
									
										34
									
								
								app/javascript/dashboard/helper/permissionsHelper.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								app/javascript/dashboard/helper/permissionsHelper.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| export const hasPermissions = ( | ||||
|   requiredPermissions = [], | ||||
|   availablePermissions = [] | ||||
| ) => { | ||||
|   return requiredPermissions.some(permission => | ||||
|     availablePermissions.includes(permission) | ||||
|   ); | ||||
| }; | ||||
|  | ||||
| const isPermissionsPresentInRoute = route => | ||||
|   route.meta && route.meta.permissions; | ||||
|  | ||||
| export const buildPermissionsFromRouter = (routes = []) => | ||||
|   routes.reduce((acc, route) => { | ||||
|     if (route.name) { | ||||
|       if (!isPermissionsPresentInRoute(route)) { | ||||
|         // eslint-disable-next-line | ||||
|         console.error(route); | ||||
|         throw new Error( | ||||
|           "The route doesn't have the required permissions defined" | ||||
|         ); | ||||
|       } | ||||
|       acc[route.name] = route.meta.permissions; | ||||
|     } | ||||
|  | ||||
|     if (route.children) { | ||||
|       acc = { | ||||
|         ...acc, | ||||
|         ...buildPermissionsFromRouter(route.children), | ||||
|       }; | ||||
|     } | ||||
|  | ||||
|     return acc; | ||||
|   }, {}); | ||||
| @@ -1,19 +1,16 @@ | ||||
| import { hasPermissions } from './permissionsHelper'; | ||||
|  | ||||
| // eslint-disable-next-line default-param-last | ||||
| export const getCurrentAccount = ({ accounts } = {}, accountId) => { | ||||
|   return accounts.find(account => account.id === accountId); | ||||
| }; | ||||
|  | ||||
| // eslint-disable-next-line default-param-last | ||||
| export const getUserRole = ({ accounts } = {}, accountId) => { | ||||
|   const currentAccount = getCurrentAccount({ accounts }, accountId) || {}; | ||||
|   return currentAccount.role || null; | ||||
| export const routeIsAccessibleFor = (route, userPermissions = []) => { | ||||
|   const { meta: { permissions: routePermissions = [] } = {} } = route; | ||||
|   return hasPermissions(routePermissions, userPermissions); | ||||
| }; | ||||
|  | ||||
| export const routeIsAccessibleFor = (route, role, roleWiseRoutes) => { | ||||
|   return roleWiseRoutes[role].includes(route); | ||||
| }; | ||||
|  | ||||
| const validateActiveAccountRoutes = (to, user, roleWiseRoutes) => { | ||||
| const validateActiveAccountRoutes = (to, user) => { | ||||
|   // If the current account is active, then check for the route permissions | ||||
|   const accountDashboardURL = `accounts/${to.params.accountId}/dashboard`; | ||||
|  | ||||
| @@ -22,15 +19,13 @@ const validateActiveAccountRoutes = (to, user, roleWiseRoutes) => { | ||||
|     return accountDashboardURL; | ||||
|   } | ||||
|  | ||||
|   const userRole = getUserRole(user, Number(to.params.accountId)); | ||||
|   const isAccessible = routeIsAccessibleFor(to.name, userRole, roleWiseRoutes); | ||||
|   const isAccessible = routeIsAccessibleFor(to, user.permissions); | ||||
|   // If the route is not accessible for the user, return to dashboard screen | ||||
|   return isAccessible ? null : accountDashboardURL; | ||||
| }; | ||||
|  | ||||
| export const validateLoggedInRoutes = (to, user, roleWiseRoutes) => { | ||||
| export const validateLoggedInRoutes = (to, user) => { | ||||
|   const currentAccount = getCurrentAccount(user, Number(to.params.accountId)); | ||||
|  | ||||
|   // If current account is missing, either user does not have | ||||
|   // access to the account or the account is deleted, return to login screen | ||||
|   if (!currentAccount) { | ||||
| @@ -40,7 +35,7 @@ export const validateLoggedInRoutes = (to, user, roleWiseRoutes) => { | ||||
|   const isCurrentAccountActive = currentAccount.status === 'active'; | ||||
|  | ||||
|   if (isCurrentAccountActive) { | ||||
|     return validateActiveAccountRoutes(to, user, roleWiseRoutes); | ||||
|     return validateActiveAccountRoutes(to, user); | ||||
|   } | ||||
|  | ||||
|   // If the current account is not active, then redirect the user to the suspended screen | ||||
|   | ||||
| @@ -0,0 +1,84 @@ | ||||
| import { | ||||
|   buildPermissionsFromRouter, | ||||
|   hasPermissions, | ||||
| } from '../permissionsHelper'; | ||||
|  | ||||
| describe('hasPermissions', () => { | ||||
|   it('returns true if permission is present', () => { | ||||
|     expect( | ||||
|       hasPermissions(['contact_manage'], ['team_manage', 'contact_manage']) | ||||
|     ).toBe(true); | ||||
|   }); | ||||
|  | ||||
|   it('returns true if permission is not present', () => { | ||||
|     expect( | ||||
|       hasPermissions(['contact_manage'], ['team_manage', 'user_manage']) | ||||
|     ).toBe(false); | ||||
|     expect(hasPermissions()).toBe(false); | ||||
|     expect(hasPermissions([])).toBe(false); | ||||
|   }); | ||||
| }); | ||||
|  | ||||
| describe('buildPermissionsFromRouter', () => { | ||||
|   it('returns a valid object when routes have permissions defined', () => { | ||||
|     expect( | ||||
|       buildPermissionsFromRouter([ | ||||
|         { | ||||
|           path: 'agent', | ||||
|           name: 'agent_list', | ||||
|           meta: { permissions: ['agent_admin'] }, | ||||
|         }, | ||||
|         { | ||||
|           path: 'inbox', | ||||
|           children: [ | ||||
|             { | ||||
|               path: '', | ||||
|               name: 'inbox_list', | ||||
|               meta: { permissions: ['inbox_admin'] }, | ||||
|             }, | ||||
|           ], | ||||
|         }, | ||||
|         { | ||||
|           path: 'conversations', | ||||
|           children: [ | ||||
|             { | ||||
|               path: '', | ||||
|               children: [ | ||||
|                 { | ||||
|                   path: 'attachments', | ||||
|                   name: 'attachments_list', | ||||
|                   meta: { permissions: ['conversation_admin'] }, | ||||
|                 }, | ||||
|               ], | ||||
|             }, | ||||
|           ], | ||||
|         }, | ||||
|       ]) | ||||
|     ).toEqual({ | ||||
|       agent_list: ['agent_admin'], | ||||
|       inbox_list: ['inbox_admin'], | ||||
|       attachments_list: ['conversation_admin'], | ||||
|     }); | ||||
|   }); | ||||
|  | ||||
|   it('throws an error if a named routed does not have permissions defined', () => { | ||||
|     expect(() => { | ||||
|       buildPermissionsFromRouter([ | ||||
|         { | ||||
|           path: 'agent', | ||||
|           name: 'agent_list', | ||||
|         }, | ||||
|       ]); | ||||
|     }).toThrow("The route doesn't have the required permissions defined"); | ||||
|  | ||||
|     expect(() => { | ||||
|       buildPermissionsFromRouter([ | ||||
|         { | ||||
|           path: 'agent', | ||||
|           name: 'agent_list', | ||||
|           meta: {}, | ||||
|         }, | ||||
|       ]); | ||||
|     }).toThrow("The route doesn't have the required permissions defined"); | ||||
|   }); | ||||
| }); | ||||
| @@ -1,7 +1,6 @@ | ||||
| import { | ||||
|   getConversationDashboardRoute, | ||||
|   getCurrentAccount, | ||||
|   getUserRole, | ||||
|   isAConversationRoute, | ||||
|   routeIsAccessibleFor, | ||||
|   validateLoggedInRoutes, | ||||
| @@ -15,24 +14,11 @@ describe('#getCurrentAccount', () => { | ||||
|   }); | ||||
| }); | ||||
|  | ||||
| describe('#getUserRole', () => { | ||||
|   it('should return the current role', () => { | ||||
|     expect( | ||||
|       getUserRole({ accounts: [{ id: 1, role: 'administrator' }] }, 1) | ||||
|     ).toEqual('administrator'); | ||||
|     expect(getUserRole({ accounts: [] }, 1)).toEqual(null); | ||||
|   }); | ||||
| }); | ||||
|  | ||||
| describe('#routeIsAccessibleFor', () => { | ||||
|   it('should return the correct access', () => { | ||||
|     const roleWiseRoutes = { agent: ['conversations'], admin: ['billing'] }; | ||||
|     expect(routeIsAccessibleFor('billing', 'agent', roleWiseRoutes)).toEqual( | ||||
|       false | ||||
|     ); | ||||
|     expect(routeIsAccessibleFor('billing', 'admin', roleWiseRoutes)).toEqual( | ||||
|       true | ||||
|     ); | ||||
|     let route = { meta: { permissions: ['administrator'] } }; | ||||
|     expect(routeIsAccessibleFor(route, ['agent'])).toEqual(false); | ||||
|     expect(routeIsAccessibleFor(route, ['administrator'])).toEqual(true); | ||||
|   }); | ||||
| }); | ||||
|  | ||||
| @@ -40,11 +26,7 @@ describe('#validateLoggedInRoutes', () => { | ||||
|   describe('when account access is missing', () => { | ||||
|     it('should return the login route', () => { | ||||
|       expect( | ||||
|         validateLoggedInRoutes( | ||||
|           { params: { accountId: 1 } }, | ||||
|           { accounts: [] }, | ||||
|           {} | ||||
|         ) | ||||
|         validateLoggedInRoutes({ params: { accountId: 1 } }, { accounts: [] }) | ||||
|       ).toEqual(`app/login`); | ||||
|     }); | ||||
|   }); | ||||
| @@ -53,9 +35,12 @@ describe('#validateLoggedInRoutes', () => { | ||||
|       it('return suspended route', () => { | ||||
|         expect( | ||||
|           validateLoggedInRoutes( | ||||
|             { name: 'conversations', params: { accountId: 1 } }, | ||||
|             { accounts: [{ id: 1, role: 'agent', status: 'suspended' }] }, | ||||
|             { agent: ['conversations'] } | ||||
|             { | ||||
|               name: 'conversations', | ||||
|               params: { accountId: 1 }, | ||||
|               meta: { permissions: ['agent'] }, | ||||
|             }, | ||||
|             { accounts: [{ id: 1, role: 'agent', status: 'suspended' }] } | ||||
|           ) | ||||
|         ).toEqual(`accounts/1/suspended`); | ||||
|       }); | ||||
| @@ -65,9 +50,22 @@ describe('#validateLoggedInRoutes', () => { | ||||
|         it('returns null (no action required)', () => { | ||||
|           expect( | ||||
|             validateLoggedInRoutes( | ||||
|               { name: 'conversations', params: { accountId: 1 } }, | ||||
|               { accounts: [{ id: 1, role: 'agent', status: 'active' }] }, | ||||
|               { agent: ['conversations'] } | ||||
|               { | ||||
|                 name: 'conversations', | ||||
|                 params: { accountId: 1 }, | ||||
|                 meta: { permissions: ['agent'] }, | ||||
|               }, | ||||
|               { | ||||
|                 permissions: ['agent'], | ||||
|                 accounts: [ | ||||
|                   { | ||||
|                     id: 1, | ||||
|                     role: 'agent', | ||||
|                     permissions: ['agent'], | ||||
|                     status: 'active', | ||||
|                   }, | ||||
|                 ], | ||||
|               } | ||||
|             ) | ||||
|           ).toEqual(null); | ||||
|         }); | ||||
| @@ -76,9 +74,12 @@ describe('#validateLoggedInRoutes', () => { | ||||
|         it('returns dashboard url', () => { | ||||
|           expect( | ||||
|             validateLoggedInRoutes( | ||||
|               { name: 'conversations', params: { accountId: 1 } }, | ||||
|               { accounts: [{ id: 1, role: 'agent', status: 'active' }] }, | ||||
|               { admin: ['conversations'], agent: [] } | ||||
|               { | ||||
|                 name: 'billing', | ||||
|                 params: { accountId: 1 }, | ||||
|                 meta: { permissions: ['administrator'] }, | ||||
|               }, | ||||
|               { accounts: [{ id: 1, role: 'agent', status: 'active' }] } | ||||
|             ) | ||||
|           ).toEqual(`accounts/1/dashboard`); | ||||
|         }); | ||||
| @@ -88,8 +89,7 @@ describe('#validateLoggedInRoutes', () => { | ||||
|           expect( | ||||
|             validateLoggedInRoutes( | ||||
|               { name: 'account_suspended', params: { accountId: 1 } }, | ||||
|               { accounts: [{ id: 1, role: 'agent', status: 'active' }] }, | ||||
|               { agent: ['account_suspended'] } | ||||
|               { accounts: [{ id: 1, role: 'agent', status: 'active' }] } | ||||
|             ) | ||||
|           ).toEqual(`accounts/1/dashboard`); | ||||
|         }); | ||||
|   | ||||
| @@ -7,7 +7,9 @@ export const routes = [ | ||||
|   { | ||||
|     path: frontendURL('accounts/:accountId/search'), | ||||
|     name: 'search', | ||||
|     roles: ['administrator', 'agent'], | ||||
|     meta: { | ||||
|       permissions: ['administrator', 'agent'], | ||||
|     }, | ||||
|     component: SearchView, | ||||
|   }, | ||||
| ]; | ||||
|   | ||||
| @@ -7,13 +7,17 @@ export const routes = [ | ||||
|   { | ||||
|     path: frontendURL('accounts/:accountId/contacts'), | ||||
|     name: 'contacts_dashboard', | ||||
|     roles: ['administrator', 'agent'], | ||||
|     meta: { | ||||
|       permissions: ['administrator', 'agent'], | ||||
|     }, | ||||
|     component: ContactsView, | ||||
|   }, | ||||
|   { | ||||
|     path: frontendURL('accounts/:accountId/contacts/custom_view/:id'), | ||||
|     name: 'contacts_segments_dashboard', | ||||
|     roles: ['administrator', 'agent'], | ||||
|     meta: { | ||||
|       permissions: ['administrator', 'agent'], | ||||
|     }, | ||||
|     component: ContactsView, | ||||
|     props: route => { | ||||
|       return { segmentsId: route.params.id }; | ||||
| @@ -22,7 +26,9 @@ export const routes = [ | ||||
|   { | ||||
|     path: frontendURL('accounts/:accountId/labels/:label/contacts'), | ||||
|     name: 'contacts_labels_dashboard', | ||||
|     roles: ['administrator', 'agent'], | ||||
|     meta: { | ||||
|       permissions: ['administrator', 'agent'], | ||||
|     }, | ||||
|     component: ContactsView, | ||||
|     props: route => { | ||||
|       return { label: route.params.label }; | ||||
| @@ -31,7 +37,9 @@ export const routes = [ | ||||
|   { | ||||
|     path: frontendURL('accounts/:accountId/contacts/:contactId'), | ||||
|     name: 'contact_profile_dashboard', | ||||
|     roles: ['administrator', 'agent'], | ||||
|     meta: { | ||||
|       permissions: ['administrator', 'agent'], | ||||
|     }, | ||||
|     component: ContactManageView, | ||||
|     props: route => { | ||||
|       return { contactId: route.params.contactId }; | ||||
|   | ||||
| @@ -7,7 +7,9 @@ export default { | ||||
|     { | ||||
|       path: frontendURL('accounts/:accountId/dashboard'), | ||||
|       name: 'home', | ||||
|       roles: ['administrator', 'agent'], | ||||
|       meta: { | ||||
|         permissions: ['administrator', 'agent'], | ||||
|       }, | ||||
|       component: ConversationView, | ||||
|       props: () => { | ||||
|         return { inboxId: 0 }; | ||||
| @@ -16,7 +18,9 @@ export default { | ||||
|     { | ||||
|       path: frontendURL('accounts/:accountId/conversations/:conversation_id'), | ||||
|       name: 'inbox_conversation', | ||||
|       roles: ['administrator', 'agent'], | ||||
|       meta: { | ||||
|         permissions: ['administrator', 'agent'], | ||||
|       }, | ||||
|       component: ConversationView, | ||||
|       props: route => { | ||||
|         return { inboxId: 0, conversationId: route.params.conversation_id }; | ||||
| @@ -25,7 +29,9 @@ export default { | ||||
|     { | ||||
|       path: frontendURL('accounts/:accountId/inbox/:inbox_id'), | ||||
|       name: 'inbox_dashboard', | ||||
|       roles: ['administrator', 'agent'], | ||||
|       meta: { | ||||
|         permissions: ['administrator', 'agent'], | ||||
|       }, | ||||
|       component: ConversationView, | ||||
|       props: route => { | ||||
|         return { inboxId: route.params.inbox_id }; | ||||
| @@ -36,7 +42,9 @@ export default { | ||||
|         'accounts/:accountId/inbox/:inbox_id/conversations/:conversation_id' | ||||
|       ), | ||||
|       name: 'conversation_through_inbox', | ||||
|       roles: ['administrator', 'agent'], | ||||
|       meta: { | ||||
|         permissions: ['administrator', 'agent'], | ||||
|       }, | ||||
|       component: ConversationView, | ||||
|       props: route => { | ||||
|         return { | ||||
| @@ -48,7 +56,9 @@ export default { | ||||
|     { | ||||
|       path: frontendURL('accounts/:accountId/label/:label'), | ||||
|       name: 'label_conversations', | ||||
|       roles: ['administrator', 'agent'], | ||||
|       meta: { | ||||
|         permissions: ['administrator', 'agent'], | ||||
|       }, | ||||
|       component: ConversationView, | ||||
|       props: route => ({ label: route.params.label }), | ||||
|     }, | ||||
| @@ -57,7 +67,9 @@ export default { | ||||
|         'accounts/:accountId/label/:label/conversations/:conversation_id' | ||||
|       ), | ||||
|       name: 'conversations_through_label', | ||||
|       roles: ['administrator', 'agent'], | ||||
|       meta: { | ||||
|         permissions: ['administrator', 'agent'], | ||||
|       }, | ||||
|       component: ConversationView, | ||||
|       props: route => ({ | ||||
|         conversationId: route.params.conversation_id, | ||||
| @@ -67,7 +79,9 @@ export default { | ||||
|     { | ||||
|       path: frontendURL('accounts/:accountId/team/:teamId'), | ||||
|       name: 'team_conversations', | ||||
|       roles: ['administrator', 'agent'], | ||||
|       meta: { | ||||
|         permissions: ['administrator', 'agent'], | ||||
|       }, | ||||
|       component: ConversationView, | ||||
|       props: route => ({ teamId: route.params.teamId }), | ||||
|     }, | ||||
| @@ -76,7 +90,9 @@ export default { | ||||
|         'accounts/:accountId/team/:teamId/conversations/:conversationId' | ||||
|       ), | ||||
|       name: 'conversations_through_team', | ||||
|       roles: ['administrator', 'agent'], | ||||
|       meta: { | ||||
|         permissions: ['administrator', 'agent'], | ||||
|       }, | ||||
|       component: ConversationView, | ||||
|       props: route => ({ | ||||
|         conversationId: route.params.conversationId, | ||||
| @@ -86,7 +102,9 @@ export default { | ||||
|     { | ||||
|       path: frontendURL('accounts/:accountId/custom_view/:id'), | ||||
|       name: 'folder_conversations', | ||||
|       roles: ['administrator', 'agent'], | ||||
|       meta: { | ||||
|         permissions: ['administrator', 'agent'], | ||||
|       }, | ||||
|       component: ConversationView, | ||||
|       props: route => ({ foldersId: route.params.id }), | ||||
|     }, | ||||
| @@ -95,7 +113,9 @@ export default { | ||||
|         'accounts/:accountId/custom_view/:id/conversations/:conversation_id' | ||||
|       ), | ||||
|       name: 'conversations_through_folders', | ||||
|       roles: ['administrator', 'agent'], | ||||
|       meta: { | ||||
|         permissions: ['administrator', 'agent'], | ||||
|       }, | ||||
|       component: ConversationView, | ||||
|       props: route => ({ | ||||
|         conversationId: route.params.conversation_id, | ||||
| @@ -105,7 +125,9 @@ export default { | ||||
|     { | ||||
|       path: frontendURL('accounts/:accountId/mentions/conversations'), | ||||
|       name: 'conversation_mentions', | ||||
|       roles: ['administrator', 'agent'], | ||||
|       meta: { | ||||
|         permissions: ['administrator', 'agent'], | ||||
|       }, | ||||
|       component: ConversationView, | ||||
|       props: () => ({ conversationType: 'mention' }), | ||||
|     }, | ||||
| @@ -114,7 +136,9 @@ export default { | ||||
|         'accounts/:accountId/mentions/conversations/:conversationId' | ||||
|       ), | ||||
|       name: 'conversation_through_mentions', | ||||
|       roles: ['administrator', 'agent'], | ||||
|       meta: { | ||||
|         permissions: ['administrator', 'agent'], | ||||
|       }, | ||||
|       component: ConversationView, | ||||
|       props: route => ({ | ||||
|         conversationId: route.params.conversationId, | ||||
| @@ -124,7 +148,9 @@ export default { | ||||
|     { | ||||
|       path: frontendURL('accounts/:accountId/unattended/conversations'), | ||||
|       name: 'conversation_unattended', | ||||
|       roles: ['administrator', 'agent'], | ||||
|       meta: { | ||||
|         permissions: ['administrator', 'agent'], | ||||
|       }, | ||||
|       component: ConversationView, | ||||
|       props: () => ({ conversationType: 'unattended' }), | ||||
|     }, | ||||
| @@ -133,7 +159,9 @@ export default { | ||||
|         'accounts/:accountId/unattended/conversations/:conversationId' | ||||
|       ), | ||||
|       name: 'conversation_through_unattended', | ||||
|       roles: ['administrator', 'agent'], | ||||
|       meta: { | ||||
|         permissions: ['administrator', 'agent'], | ||||
|       }, | ||||
|       component: ConversationView, | ||||
|       props: route => ({ | ||||
|         conversationId: route.params.conversationId, | ||||
| @@ -143,7 +171,9 @@ export default { | ||||
|     { | ||||
|       path: frontendURL('accounts/:accountId/participating/conversations'), | ||||
|       name: 'conversation_participating', | ||||
|       roles: ['administrator', 'agent'], | ||||
|       meta: { | ||||
|         permissions: ['administrator', 'agent'], | ||||
|       }, | ||||
|       component: ConversationView, | ||||
|       props: () => ({ conversationType: 'participating' }), | ||||
|     }, | ||||
| @@ -152,7 +182,9 @@ export default { | ||||
|         'accounts/:accountId/participating/conversations/:conversationId' | ||||
|       ), | ||||
|       name: 'conversation_through_participating', | ||||
|       roles: ['administrator', 'agent'], | ||||
|       meta: { | ||||
|         permissions: ['administrator', 'agent'], | ||||
|       }, | ||||
|       component: ConversationView, | ||||
|       props: route => ({ | ||||
|         conversationId: route.params.conversationId, | ||||
|   | ||||
| @@ -28,7 +28,9 @@ export default { | ||||
|     { | ||||
|       path: frontendURL('accounts/:accountId/suspended'), | ||||
|       name: 'account_suspended', | ||||
|       roles: ['administrator', 'agent'], | ||||
|       meta: { | ||||
|         permissions: ['administrator', 'agent'], | ||||
|       }, | ||||
|       component: Suspended, | ||||
|     }, | ||||
|   ], | ||||
|   | ||||
| @@ -30,13 +30,17 @@ const portalRoutes = [ | ||||
|   { | ||||
|     path: getPortalRoute(''), | ||||
|     name: 'default_portal_articles', | ||||
|     roles: ['administrator', 'agent'], | ||||
|     meta: { | ||||
|       permissions: ['administrator'], | ||||
|     }, | ||||
|     component: DefaultPortalArticles, | ||||
|   }, | ||||
|   { | ||||
|     path: getPortalRoute('all'), | ||||
|     name: 'list_all_portals', | ||||
|     roles: ['administrator', 'agent'], | ||||
|     meta: { | ||||
|       permissions: ['administrator', 'agent'], | ||||
|     }, | ||||
|     component: ListAllPortals, | ||||
|   }, | ||||
|   { | ||||
| @@ -47,55 +51,73 @@ const portalRoutes = [ | ||||
|         path: '', | ||||
|         name: 'new_portal_information', | ||||
|         component: PortalDetails, | ||||
|         roles: ['administrator'], | ||||
|         meta: { | ||||
|           permissions: ['administrator'], | ||||
|         }, | ||||
|       }, | ||||
|       { | ||||
|         path: ':portalSlug/customization', | ||||
|         name: 'portal_customization', | ||||
|         component: PortalCustomization, | ||||
|         roles: ['administrator'], | ||||
|         meta: { | ||||
|           permissions: ['administrator'], | ||||
|         }, | ||||
|       }, | ||||
|       { | ||||
|         path: ':portalSlug/finish', | ||||
|         name: 'portal_finish', | ||||
|         component: PortalSettingsFinish, | ||||
|         roles: ['administrator'], | ||||
|         meta: { | ||||
|           permissions: ['administrator'], | ||||
|         }, | ||||
|       }, | ||||
|     ], | ||||
|   }, | ||||
|   { | ||||
|     path: getPortalRoute(':portalSlug'), | ||||
|     name: 'portalSlug', | ||||
|     roles: ['administrator', 'agent'], | ||||
|     meta: { | ||||
|       permissions: ['administrator', 'agent'], | ||||
|     }, | ||||
|     component: ShowPortal, | ||||
|   }, | ||||
|   { | ||||
|     path: getPortalRoute(':portalSlug/edit'), | ||||
|     roles: ['administrator', 'agent'], | ||||
|     meta: { | ||||
|       permissions: ['administrator', 'agent'], | ||||
|     }, | ||||
|     component: EditPortal, | ||||
|     children: [ | ||||
|       { | ||||
|         path: '', | ||||
|         name: 'edit_portal_information', | ||||
|         component: EditPortalBasic, | ||||
|         roles: ['administrator'], | ||||
|         meta: { | ||||
|           permissions: ['administrator'], | ||||
|         }, | ||||
|       }, | ||||
|       { | ||||
|         path: 'customizations', | ||||
|         name: 'edit_portal_customization', | ||||
|         component: EditPortalCustomization, | ||||
|         roles: ['administrator'], | ||||
|         meta: { | ||||
|           permissions: ['administrator'], | ||||
|         }, | ||||
|       }, | ||||
|       { | ||||
|         path: 'locales', | ||||
|         name: 'edit_portal_locales', | ||||
|         component: EditPortalLocales, | ||||
|         roles: ['administrator'], | ||||
|         meta: { | ||||
|           permissions: ['administrator'], | ||||
|         }, | ||||
|       }, | ||||
|       { | ||||
|         path: 'categories', | ||||
|         name: 'list_all_locale_categories', | ||||
|         roles: ['administrator', 'agent'], | ||||
|         meta: { | ||||
|           permissions: ['administrator', 'agent'], | ||||
|         }, | ||||
|         component: ListAllCategories, | ||||
|       }, | ||||
|     ], | ||||
| @@ -106,39 +128,51 @@ const articleRoutes = [ | ||||
|   { | ||||
|     path: getPortalRoute(':portalSlug/:locale/articles'), | ||||
|     name: 'list_all_locale_articles', | ||||
|     roles: ['administrator', 'agent'], | ||||
|     meta: { | ||||
|       permissions: ['administrator', 'agent'], | ||||
|     }, | ||||
|     component: ListAllArticles, | ||||
|   }, | ||||
|   { | ||||
|     path: getPortalRoute(':portalSlug/:locale/articles/new'), | ||||
|     name: 'new_article', | ||||
|     roles: ['administrator', 'agent'], | ||||
|     meta: { | ||||
|       permissions: ['administrator', 'agent'], | ||||
|     }, | ||||
|     component: NewArticle, | ||||
|   }, | ||||
|   { | ||||
|     path: getPortalRoute(':portalSlug/:locale/articles/mine'), | ||||
|     name: 'list_mine_articles', | ||||
|     roles: ['administrator', 'agent'], | ||||
|     meta: { | ||||
|       permissions: ['administrator', 'agent'], | ||||
|     }, | ||||
|     component: ListAllArticles, | ||||
|   }, | ||||
|   { | ||||
|     path: getPortalRoute(':portalSlug/:locale/articles/archived'), | ||||
|     name: 'list_archived_articles', | ||||
|     roles: ['administrator', 'agent'], | ||||
|     meta: { | ||||
|       permissions: ['administrator', 'agent'], | ||||
|     }, | ||||
|     component: ListAllArticles, | ||||
|   }, | ||||
|  | ||||
|   { | ||||
|     path: getPortalRoute(':portalSlug/:locale/articles/draft'), | ||||
|     name: 'list_draft_articles', | ||||
|     roles: ['administrator', 'agent'], | ||||
|     meta: { | ||||
|       permissions: ['administrator', 'agent'], | ||||
|     }, | ||||
|     component: ListAllArticles, | ||||
|   }, | ||||
|  | ||||
|   { | ||||
|     path: getPortalRoute(':portalSlug/:locale/articles/:articleSlug'), | ||||
|     name: 'edit_article', | ||||
|     roles: ['administrator', 'agent'], | ||||
|     meta: { | ||||
|       permissions: ['administrator', 'agent'], | ||||
|     }, | ||||
|     component: EditArticle, | ||||
|   }, | ||||
| ]; | ||||
| @@ -147,19 +181,25 @@ const categoryRoutes = [ | ||||
|   { | ||||
|     path: getPortalRoute(':portalSlug/:locale/categories'), | ||||
|     name: 'all_locale_categories', | ||||
|     roles: ['administrator', 'agent'], | ||||
|     meta: { | ||||
|       permissions: ['administrator', 'agent'], | ||||
|     }, | ||||
|     component: ListAllCategories, | ||||
|   }, | ||||
|   { | ||||
|     path: getPortalRoute(':portalSlug/:locale/categories/new'), | ||||
|     name: 'new_category_in_locale', | ||||
|     roles: ['administrator', 'agent'], | ||||
|     meta: { | ||||
|       permissions: ['administrator', 'agent'], | ||||
|     }, | ||||
|     component: NewCategory, | ||||
|   }, | ||||
|   { | ||||
|     path: getPortalRoute(':portalSlug/:locale/categories/:categorySlug'), | ||||
|     name: 'show_category', | ||||
|     roles: ['administrator', 'agent'], | ||||
|     meta: { | ||||
|       permissions: ['administrator', 'agent'], | ||||
|     }, | ||||
|     component: ListAllArticles, | ||||
|   }, | ||||
|   { | ||||
| @@ -167,13 +207,17 @@ const categoryRoutes = [ | ||||
|       ':portalSlug/:locale/categories/:categorySlug/articles' | ||||
|     ), | ||||
|     name: 'show_category_articles', | ||||
|     roles: ['administrator', 'agent'], | ||||
|     meta: { | ||||
|       permissions: ['administrator', 'agent'], | ||||
|     }, | ||||
|     component: ListCategoryArticles, | ||||
|   }, | ||||
|   { | ||||
|     path: getPortalRoute(':portalSlug/:locale/categories/:categorySlug'), | ||||
|     name: 'edit_category', | ||||
|     roles: ['administrator', 'agent'], | ||||
|     meta: { | ||||
|       permissions: ['administrator', 'agent'], | ||||
|     }, | ||||
|     component: EditCategory, | ||||
|   }, | ||||
| ]; | ||||
|   | ||||
| @@ -12,13 +12,17 @@ export const routes = [ | ||||
|         path: '', | ||||
|         name: 'inbox_view', | ||||
|         component: InboxEmptyStateView, | ||||
|         roles: ['administrator', 'agent'], | ||||
|         meta: { | ||||
|           permissions: ['administrator', 'agent'], | ||||
|         }, | ||||
|       }, | ||||
|       { | ||||
|         path: ':notification_id', | ||||
|         name: 'inbox_view_conversation', | ||||
|         component: InboxDetailView, | ||||
|         roles: ['administrator', 'agent'], | ||||
|         meta: { | ||||
|           permissions: ['administrator', 'agent'], | ||||
|         }, | ||||
|       }, | ||||
|     ], | ||||
|   }, | ||||
|   | ||||
| @@ -18,7 +18,9 @@ export const routes = [ | ||||
|         path: '', | ||||
|         name: 'notifications_index', | ||||
|         component: NotificationsView, | ||||
|         roles: ['administrator', 'agent'], | ||||
|         meta: { | ||||
|           permissions: ['administrator', 'agent'], | ||||
|         }, | ||||
|       }, | ||||
|     ], | ||||
|   }, | ||||
|   | ||||
| @@ -6,7 +6,9 @@ export default { | ||||
|   routes: [ | ||||
|     { | ||||
|       path: frontendURL('accounts/:accountId/settings/general'), | ||||
|       roles: ['administrator'], | ||||
|       meta: { | ||||
|         permissions: ['administrator'], | ||||
|       }, | ||||
|       component: SettingsContent, | ||||
|       props: { | ||||
|         headerTitle: 'GENERAL_SETTINGS.TITLE', | ||||
| @@ -18,7 +20,9 @@ export default { | ||||
|           path: '', | ||||
|           name: 'general_settings_index', | ||||
|           component: Index, | ||||
|           roles: ['administrator'], | ||||
|           meta: { | ||||
|             permissions: ['administrator'], | ||||
|           }, | ||||
|         }, | ||||
|       ], | ||||
|     }, | ||||
|   | ||||
| @@ -8,7 +8,9 @@ export default { | ||||
|   routes: [ | ||||
|     { | ||||
|       path: frontendURL('accounts/:accountId/settings/agent-bots'), | ||||
|       roles: ['administrator'], | ||||
|       meta: { | ||||
|         permissions: ['administrator'], | ||||
|       }, | ||||
|       component: SettingsContent, | ||||
|       props: { | ||||
|         headerTitle: 'AGENT_BOTS.HEADER', | ||||
| @@ -20,19 +22,25 @@ export default { | ||||
|           path: '', | ||||
|           name: 'agent_bots', | ||||
|           component: Bot, | ||||
|           roles: ['administrator'], | ||||
|           meta: { | ||||
|             permissions: ['administrator'], | ||||
|           }, | ||||
|         }, | ||||
|         { | ||||
|           path: 'csml/new', | ||||
|           name: 'agent_bots_csml_new', | ||||
|           component: CsmlNewBot, | ||||
|           roles: ['administrator'], | ||||
|           meta: { | ||||
|             permissions: ['administrator'], | ||||
|           }, | ||||
|         }, | ||||
|         { | ||||
|           path: 'csml/:botId', | ||||
|           name: 'agent_bots_csml_edit', | ||||
|           component: CsmlEditBot, | ||||
|           roles: ['administrator'], | ||||
|           meta: { | ||||
|             permissions: ['administrator'], | ||||
|           }, | ||||
|         }, | ||||
|       ], | ||||
|     }, | ||||
|   | ||||
| @@ -15,14 +15,15 @@ export default { | ||||
|       children: [ | ||||
|         { | ||||
|           path: '', | ||||
|           name: 'agents_wrapper', | ||||
|           redirect: 'list', | ||||
|         }, | ||||
|         { | ||||
|           path: 'list', | ||||
|           name: 'agent_list', | ||||
|           component: AgentHome, | ||||
|           roles: ['administrator'], | ||||
|           meta: { | ||||
|             permissions: ['administrator'], | ||||
|           }, | ||||
|         }, | ||||
|       ], | ||||
|     }, | ||||
|   | ||||
| @@ -15,14 +15,15 @@ export default { | ||||
|       children: [ | ||||
|         { | ||||
|           path: '', | ||||
|           name: 'attributes_wrapper', | ||||
|           redirect: 'list', | ||||
|         }, | ||||
|         { | ||||
|           path: 'list', | ||||
|           name: 'attributes_list', | ||||
|           component: AttributesHome, | ||||
|           roles: ['administrator'], | ||||
|           meta: { | ||||
|             permissions: ['administrator'], | ||||
|           }, | ||||
|         }, | ||||
|       ], | ||||
|     }, | ||||
|   | ||||
| @@ -16,13 +16,14 @@ export default { | ||||
|       children: [ | ||||
|         { | ||||
|           path: '', | ||||
|           name: 'auditlogs_wrapper', | ||||
|           redirect: 'list', | ||||
|         }, | ||||
|         { | ||||
|           path: 'list', | ||||
|           name: 'auditlogs_list', | ||||
|           roles: ['administrator'], | ||||
|           meta: { | ||||
|             permissions: ['administrator'], | ||||
|           }, | ||||
|           component: AuditLogsHome, | ||||
|         }, | ||||
|       ], | ||||
|   | ||||
| @@ -15,14 +15,15 @@ export default { | ||||
|       children: [ | ||||
|         { | ||||
|           path: '', | ||||
|           name: 'automation_wrapper', | ||||
|           redirect: 'list', | ||||
|         }, | ||||
|         { | ||||
|           path: 'list', | ||||
|           name: 'automation_list', | ||||
|           component: Automation, | ||||
|           roles: ['administrator'], | ||||
|           meta: { | ||||
|             permissions: ['administrator'], | ||||
|           }, | ||||
|         }, | ||||
|       ], | ||||
|     }, | ||||
|   | ||||
| @@ -6,7 +6,9 @@ export default { | ||||
|   routes: [ | ||||
|     { | ||||
|       path: frontendURL('accounts/:accountId/settings/billing'), | ||||
|       roles: ['administrator'], | ||||
|       meta: { | ||||
|         permissions: ['administrator'], | ||||
|       }, | ||||
|       component: SettingsContent, | ||||
|       props: { | ||||
|         headerTitle: 'BILLING_SETTINGS.TITLE', | ||||
| @@ -18,7 +20,9 @@ export default { | ||||
|           path: '', | ||||
|           name: 'billing_settings_index', | ||||
|           component: Index, | ||||
|           roles: ['administrator'], | ||||
|           meta: { | ||||
|             permissions: ['administrator'], | ||||
|           }, | ||||
|         }, | ||||
|       ], | ||||
|     }, | ||||
|   | ||||
| @@ -19,7 +19,9 @@ export default { | ||||
|         { | ||||
|           path: 'ongoing', | ||||
|           name: 'ongoing_campaigns', | ||||
|           roles: ['administrator'], | ||||
|           meta: { | ||||
|             permissions: ['administrator'], | ||||
|           }, | ||||
|           component: Index, | ||||
|         }, | ||||
|       ], | ||||
| @@ -35,7 +37,9 @@ export default { | ||||
|         { | ||||
|           path: 'one_off', | ||||
|           name: 'one_off', | ||||
|           roles: ['administrator'], | ||||
|           meta: { | ||||
|             permissions: ['administrator'], | ||||
|           }, | ||||
|           component: Index, | ||||
|         }, | ||||
|       ], | ||||
|   | ||||
| @@ -16,13 +16,14 @@ export default { | ||||
|       children: [ | ||||
|         { | ||||
|           path: '', | ||||
|           name: 'canned_wrapper', | ||||
|           redirect: 'list', | ||||
|         }, | ||||
|         { | ||||
|           path: 'list', | ||||
|           name: 'canned_list', | ||||
|           roles: ['administrator', 'agent'], | ||||
|           meta: { | ||||
|             permissions: ['administrator', 'agent'], | ||||
|           }, | ||||
|           component: CannedHome, | ||||
|         }, | ||||
|       ], | ||||
|   | ||||
| @@ -28,14 +28,15 @@ export default { | ||||
|       children: [ | ||||
|         { | ||||
|           path: '', | ||||
|           name: 'settings_inbox', | ||||
|           redirect: 'list', | ||||
|         }, | ||||
|         { | ||||
|           path: 'list', | ||||
|           name: 'settings_inbox_list', | ||||
|           component: InboxHome, | ||||
|           roles: ['administrator'], | ||||
|           meta: { | ||||
|             permissions: ['administrator'], | ||||
|           }, | ||||
|         }, | ||||
|         { | ||||
|           path: 'new', | ||||
| @@ -45,19 +46,25 @@ export default { | ||||
|               path: '', | ||||
|               name: 'settings_inbox_new', | ||||
|               component: ChannelList, | ||||
|               roles: ['administrator'], | ||||
|               meta: { | ||||
|                 permissions: ['administrator'], | ||||
|               }, | ||||
|             }, | ||||
|             { | ||||
|               path: ':inbox_id/finish', | ||||
|               name: 'settings_inbox_finish', | ||||
|               component: FinishSetup, | ||||
|               roles: ['administrator'], | ||||
|               meta: { | ||||
|                 permissions: ['administrator'], | ||||
|               }, | ||||
|             }, | ||||
|             { | ||||
|               path: ':sub_page', | ||||
|               name: 'settings_inboxes_page_channel', | ||||
|               component: channelFactory.create(), | ||||
|               roles: ['administrator'], | ||||
|               meta: { | ||||
|                 permissions: ['administrator'], | ||||
|               }, | ||||
|               props: route => { | ||||
|                 return { channel_name: route.params.sub_page }; | ||||
|               }, | ||||
| @@ -65,7 +72,9 @@ export default { | ||||
|             { | ||||
|               path: ':inbox_id/agents', | ||||
|               name: 'settings_inboxes_add_agents', | ||||
|               roles: ['administrator'], | ||||
|               meta: { | ||||
|                 permissions: ['administrator'], | ||||
|               }, | ||||
|               component: AddAgents, | ||||
|             }, | ||||
|           ], | ||||
| @@ -74,7 +83,9 @@ export default { | ||||
|           path: ':inboxId', | ||||
|           name: 'settings_inbox_show', | ||||
|           component: Settings, | ||||
|           roles: ['administrator'], | ||||
|           meta: { | ||||
|             permissions: ['administrator'], | ||||
|           }, | ||||
|         }, | ||||
|       ], | ||||
|     }, | ||||
|   | ||||
| @@ -26,13 +26,17 @@ export default { | ||||
|           path: '', | ||||
|           name: 'settings_applications', | ||||
|           component: Index, | ||||
|           roles: ['administrator'], | ||||
|           meta: { | ||||
|             permissions: ['administrator'], | ||||
|           }, | ||||
|         }, | ||||
|         { | ||||
|           path: ':integration_id', | ||||
|           name: 'settings_applications_integration', | ||||
|           component: IntegrationHooks, | ||||
|           roles: ['administrator'], | ||||
|           meta: { | ||||
|             permissions: ['administrator'], | ||||
|           }, | ||||
|           props: route => ({ | ||||
|             integrationId: route.params.integration_id, | ||||
|           }), | ||||
|   | ||||
| @@ -30,32 +30,42 @@ export default { | ||||
|           path: '', | ||||
|           name: 'settings_integrations', | ||||
|           component: Index, | ||||
|           roles: ['administrator'], | ||||
|           meta: { | ||||
|             permissions: ['administrator'], | ||||
|           }, | ||||
|         }, | ||||
|         { | ||||
|           path: 'webhook', | ||||
|           component: Webhook, | ||||
|           name: 'settings_integrations_webhook', | ||||
|           roles: ['administrator'], | ||||
|           meta: { | ||||
|             permissions: ['administrator'], | ||||
|           }, | ||||
|         }, | ||||
|         { | ||||
|           path: 'dashboard-apps', | ||||
|           component: DashboardApps, | ||||
|           name: 'settings_integrations_dashboard_apps', | ||||
|           roles: ['administrator'], | ||||
|           meta: { | ||||
|             permissions: ['administrator'], | ||||
|           }, | ||||
|         }, | ||||
|         { | ||||
|           path: 'slack', | ||||
|           name: 'settings_integrations_slack', | ||||
|           component: Slack, | ||||
|           roles: ['administrator'], | ||||
|           meta: { | ||||
|             permissions: ['administrator'], | ||||
|           }, | ||||
|           props: route => ({ code: route.query.code }), | ||||
|         }, | ||||
|         { | ||||
|           path: ':integration_id', | ||||
|           name: 'settings_integrations_integration', | ||||
|           component: ShowIntegration, | ||||
|           roles: ['administrator'], | ||||
|           meta: { | ||||
|             permissions: ['administrator'], | ||||
|           }, | ||||
|           props: route => { | ||||
|             return { | ||||
|               integrationId: route.params.integration_id, | ||||
|   | ||||
| @@ -17,13 +17,17 @@ export default { | ||||
|         { | ||||
|           path: '', | ||||
|           name: 'labels_wrapper', | ||||
|           roles: ['administrator'], | ||||
|           meta: { | ||||
|             permissions: ['administrator'], | ||||
|           }, | ||||
|           redirect: 'list', | ||||
|         }, | ||||
|         { | ||||
|           path: 'list', | ||||
|           name: 'labels_list', | ||||
|           roles: ['administrator'], | ||||
|           meta: { | ||||
|             permissions: ['administrator'], | ||||
|           }, | ||||
|           component: Index, | ||||
|         }, | ||||
|       ], | ||||
|   | ||||
| @@ -23,19 +23,25 @@ export default { | ||||
|           path: '', | ||||
|           name: 'macros_wrapper', | ||||
|           component: Macros, | ||||
|           roles: ['administrator', 'agent'], | ||||
|           meta: { | ||||
|             permissions: ['administrator', 'agent'], | ||||
|           }, | ||||
|         }, | ||||
|         { | ||||
|           path: 'new', | ||||
|           name: 'macros_new', | ||||
|           component: MacroEditor, | ||||
|           roles: ['administrator', 'agent'], | ||||
|           meta: { | ||||
|             permissions: ['administrator', 'agent'], | ||||
|           }, | ||||
|         }, | ||||
|         { | ||||
|           path: ':macroId/edit', | ||||
|           name: 'macros_edit', | ||||
|           component: MacroEditor, | ||||
|           roles: ['administrator', 'agent'], | ||||
|           meta: { | ||||
|             permissions: ['administrator', 'agent'], | ||||
|           }, | ||||
|         }, | ||||
|       ], | ||||
|     }, | ||||
|   | ||||
| @@ -8,14 +8,18 @@ export default { | ||||
|     { | ||||
|       path: frontendURL('accounts/:accountId/profile'), | ||||
|       name: 'profile_settings', | ||||
|       roles: ['administrator', 'agent'], | ||||
|       meta: { | ||||
|         permissions: ['administrator', 'agent'], | ||||
|       }, | ||||
|       component: SettingsContent, | ||||
|       children: [ | ||||
|         { | ||||
|           path: 'settings', | ||||
|           name: 'profile_settings_index', | ||||
|           component: Index, | ||||
|           roles: ['administrator', 'agent'], | ||||
|           meta: { | ||||
|             permissions: ['administrator', 'agent'], | ||||
|           }, | ||||
|         }, | ||||
|       ], | ||||
|     }, | ||||
|   | ||||
| @@ -29,7 +29,9 @@ export default { | ||||
|         { | ||||
|           path: 'overview', | ||||
|           name: 'account_overview_reports', | ||||
|           roles: ['administrator'], | ||||
|           meta: { | ||||
|             permissions: ['administrator'], | ||||
|           }, | ||||
|           component: LiveReports, | ||||
|         }, | ||||
|       ], | ||||
| @@ -46,7 +48,9 @@ export default { | ||||
|         { | ||||
|           path: 'conversation', | ||||
|           name: 'conversation_reports', | ||||
|           roles: ['administrator'], | ||||
|           meta: { | ||||
|             permissions: ['administrator'], | ||||
|           }, | ||||
|           component: Index, | ||||
|         }, | ||||
|       ], | ||||
| @@ -63,7 +67,9 @@ export default { | ||||
|         { | ||||
|           path: 'csat', | ||||
|           name: 'csat_reports', | ||||
|           roles: ['administrator'], | ||||
|           meta: { | ||||
|             permissions: ['administrator'], | ||||
|           }, | ||||
|           component: CsatResponses, | ||||
|         }, | ||||
|       ], | ||||
| @@ -80,7 +86,9 @@ export default { | ||||
|         { | ||||
|           path: 'bot', | ||||
|           name: 'bot_reports', | ||||
|           roles: ['administrator'], | ||||
|           meta: { | ||||
|             permissions: ['administrator'], | ||||
|           }, | ||||
|           component: BotReports, | ||||
|         }, | ||||
|       ], | ||||
| @@ -97,7 +105,9 @@ export default { | ||||
|         { | ||||
|           path: 'agent', | ||||
|           name: 'agent_reports', | ||||
|           roles: ['administrator'], | ||||
|           meta: { | ||||
|             permissions: ['administrator'], | ||||
|           }, | ||||
|           component: AgentReports, | ||||
|         }, | ||||
|       ], | ||||
| @@ -114,7 +124,9 @@ export default { | ||||
|         { | ||||
|           path: 'label', | ||||
|           name: 'label_reports', | ||||
|           roles: ['administrator'], | ||||
|           meta: { | ||||
|             permissions: ['administrator'], | ||||
|           }, | ||||
|           component: LabelReports, | ||||
|         }, | ||||
|       ], | ||||
| @@ -131,7 +143,9 @@ export default { | ||||
|         { | ||||
|           path: 'inboxes', | ||||
|           name: 'inbox_reports', | ||||
|           roles: ['administrator'], | ||||
|           meta: { | ||||
|             permissions: ['administrator'], | ||||
|           }, | ||||
|           component: InboxReports, | ||||
|         }, | ||||
|       ], | ||||
| @@ -147,7 +161,9 @@ export default { | ||||
|         { | ||||
|           path: 'teams', | ||||
|           name: 'team_reports', | ||||
|           roles: ['administrator'], | ||||
|           meta: { | ||||
|             permissions: ['administrator'], | ||||
|           }, | ||||
|           component: TeamReports, | ||||
|         }, | ||||
|       ], | ||||
| @@ -164,7 +180,9 @@ export default { | ||||
|         { | ||||
|           path: 'sla', | ||||
|           name: 'sla_reports', | ||||
|           roles: ['administrator'], | ||||
|           meta: { | ||||
|             permissions: ['administrator'], | ||||
|           }, | ||||
|           component: SLAReports, | ||||
|         }, | ||||
|       ], | ||||
|   | ||||
| @@ -24,7 +24,9 @@ export default { | ||||
|     { | ||||
|       path: frontendURL('accounts/:accountId/settings'), | ||||
|       name: 'settings_home', | ||||
|       roles: ['administrator', 'agent'], | ||||
|       meta: { | ||||
|         permissions: ['administrator', 'agent'], | ||||
|       }, | ||||
|       redirect: () => { | ||||
|         if (store.getters.getCurrentRole === 'administrator') { | ||||
|           return frontendURL('accounts/:accountId/settings/general'); | ||||
|   | ||||
| @@ -13,13 +13,17 @@ export default { | ||||
|         { | ||||
|           path: '', | ||||
|           name: 'sla_wrapper', | ||||
|           roles: ['administrator'], | ||||
|           meta: { | ||||
|             permissions: ['administrator'], | ||||
|           }, | ||||
|           redirect: 'list', | ||||
|         }, | ||||
|         { | ||||
|           path: 'list', | ||||
|           name: 'sla_list', | ||||
|           roles: ['administrator'], | ||||
|           meta: { | ||||
|             permissions: ['administrator'], | ||||
|           }, | ||||
|           component: Index, | ||||
|         }, | ||||
|       ], | ||||
|   | ||||
| @@ -29,14 +29,15 @@ export default { | ||||
|       children: [ | ||||
|         { | ||||
|           path: '', | ||||
|           name: 'settings_teams', | ||||
|           redirect: 'list', | ||||
|         }, | ||||
|         { | ||||
|           path: 'list', | ||||
|           name: 'settings_teams_list', | ||||
|           component: TeamsHome, | ||||
|           roles: ['administrator'], | ||||
|           meta: { | ||||
|             permissions: ['administrator'], | ||||
|           }, | ||||
|         }, | ||||
|         { | ||||
|           path: 'new', | ||||
| @@ -46,18 +47,24 @@ export default { | ||||
|               path: '', | ||||
|               name: 'settings_teams_new', | ||||
|               component: CreateTeam, | ||||
|               roles: ['administrator'], | ||||
|               meta: { | ||||
|                 permissions: ['administrator'], | ||||
|               }, | ||||
|             }, | ||||
|             { | ||||
|               path: ':teamId/finish', | ||||
|               name: 'settings_teams_finish', | ||||
|               component: FinishSetup, | ||||
|               roles: ['administrator'], | ||||
|               meta: { | ||||
|                 permissions: ['administrator'], | ||||
|               }, | ||||
|             }, | ||||
|             { | ||||
|               path: ':teamId/agents', | ||||
|               name: 'settings_teams_add_agents', | ||||
|               roles: ['administrator'], | ||||
|               meta: { | ||||
|                 permissions: ['administrator'], | ||||
|               }, | ||||
|               component: AddAgents, | ||||
|             }, | ||||
|           ], | ||||
| @@ -70,18 +77,24 @@ export default { | ||||
|               path: '', | ||||
|               name: 'settings_teams_edit', | ||||
|               component: EditTeam, | ||||
|               roles: ['administrator'], | ||||
|               meta: { | ||||
|                 permissions: ['administrator'], | ||||
|               }, | ||||
|             }, | ||||
|             { | ||||
|               path: 'agents', | ||||
|               name: 'settings_teams_edit_members', | ||||
|               component: EditAgents, | ||||
|               roles: ['administrator'], | ||||
|               meta: { | ||||
|                 permissions: ['administrator'], | ||||
|               }, | ||||
|             }, | ||||
|             { | ||||
|               path: 'finish', | ||||
|               name: 'settings_teams_edit_finish', | ||||
|               roles: ['administrator'], | ||||
|               meta: { | ||||
|                 permissions: ['administrator'], | ||||
|               }, | ||||
|               component: FinishSetup, | ||||
|             }, | ||||
|           ], | ||||
|   | ||||
| @@ -5,33 +5,12 @@ import dashboard from './dashboard/dashboard.routes'; | ||||
| import store from '../store'; | ||||
| import { validateLoggedInRoutes } from '../helper/routeHelpers'; | ||||
| import AnalyticsHelper from '../helper/AnalyticsHelper'; | ||||
| import { buildPermissionsFromRouter } from '../helper/permissionsHelper'; | ||||
|  | ||||
| const routes = [...dashboard.routes]; | ||||
|  | ||||
| window.roleWiseRoutes = { | ||||
|   agent: [], | ||||
|   administrator: [], | ||||
| }; | ||||
|  | ||||
| // generateRoleWiseRoute - updates window object with agent/admin route | ||||
| const generateRoleWiseRoute = route => { | ||||
|   route.forEach(element => { | ||||
|     if (element.children) { | ||||
|       generateRoleWiseRoute(element.children); | ||||
|     } | ||||
|     if (element.roles) { | ||||
|       element.roles.forEach(roleEl => { | ||||
|         window.roleWiseRoutes[roleEl].push(element.name); | ||||
|       }); | ||||
|     } | ||||
|   }); | ||||
| }; | ||||
| // Create a object of routes | ||||
| // accessible by each role. | ||||
| // returns an object with roles as keys and routeArr as values | ||||
| generateRoleWiseRoute(routes); | ||||
|  | ||||
| export const router = new VueRouter({ mode: 'history', routes }); | ||||
| export const routesWithPermissions = buildPermissionsFromRouter(routes); | ||||
|  | ||||
| export const validateAuthenticateRoutePermission = (to, next, { getters }) => { | ||||
|   const { isLoggedIn, getCurrentUser: user } = getters; | ||||
| @@ -45,11 +24,7 @@ export const validateAuthenticateRoutePermission = (to, next, { getters }) => { | ||||
|     return next(frontendURL(`accounts/${user.account_id}/dashboard`)); | ||||
|   } | ||||
|  | ||||
|   const nextRoute = validateLoggedInRoutes( | ||||
|     to, | ||||
|     getters.getCurrentUser, | ||||
|     window.roleWiseRoutes | ||||
|   ); | ||||
|   const nextRoute = validateLoggedInRoutes(to, getters.getCurrentUser); | ||||
|   return nextRoute ? next(frontendURL(nextRoute)) : next(); | ||||
| }; | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Sojan Jose
					Sojan Jose