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