diff --git a/app/javascript/dashboard/components/layout/Sidebar.vue b/app/javascript/dashboard/components/layout/Sidebar.vue index 0f3a1a857..4ccaa97df 100644 --- a/app/javascript/dashboard/components/layout/Sidebar.vue +++ b/app/javascript/dashboard/components/layout/Sidebar.vue @@ -20,7 +20,7 @@ :teams="teams" :custom-views="customViews" :menu-config="activeSecondaryMenu" - :current-role="currentRole" + :current-user="currentUser" :is-on-chatwoot-cloud="isOnChatwootCloud" @add-label="showAddLabelPopup" @toggle-accounts="toggleAccountModal" @@ -37,7 +37,8 @@ import alertMixin from 'shared/mixins/alertMixin'; import PrimarySidebar from './sidebarComponents/Primary.vue'; import SecondarySidebar from './sidebarComponents/Secondary.vue'; import keyboardEventListenerMixins from 'shared/mixins/keyboardEventListenerMixins'; -import router from '../../routes'; +import router, { routesWithPermissions } from '../../routes'; +import { hasPermissions } from '../../helper/permissionsHelper'; export default { components: { @@ -98,9 +99,13 @@ export default { return getSidebarItems(this.accountId); }, primaryMenuItems() { + const userPermissions = this.currentUser.permissions; const menuItems = this.sideMenuConfig.primaryMenu; return menuItems.filter(menuItem => { - const isAvailableForTheUser = menuItem.roles.includes(this.currentRole); + const isAvailableForTheUser = hasPermissions( + routesWithPermissions[menuItem.toStateName], + userPermissions + ); if (!isAvailableForTheUser) { return false; diff --git a/app/javascript/dashboard/components/layout/config/sidebarItems/primaryMenu.js b/app/javascript/dashboard/components/layout/config/sidebarItems/primaryMenu.js index 7513e3d1c..92b8765c6 100644 --- a/app/javascript/dashboard/components/layout/config/sidebarItems/primaryMenu.js +++ b/app/javascript/dashboard/components/layout/config/sidebarItems/primaryMenu.js @@ -9,7 +9,6 @@ const primaryMenuItems = accountId => [ featureFlag: FEATURE_FLAGS.INBOX_VIEW, toState: frontendURL(`accounts/${accountId}/inbox-view`), toStateName: 'inbox_view', - roles: ['administrator', 'agent'], }, { icon: 'chat', @@ -17,7 +16,6 @@ const primaryMenuItems = accountId => [ label: 'CONVERSATIONS', toState: frontendURL(`accounts/${accountId}/dashboard`), toStateName: 'home', - roles: ['administrator', 'agent'], }, { icon: 'book-contacts', @@ -26,7 +24,6 @@ const primaryMenuItems = accountId => [ featureFlag: FEATURE_FLAGS.CRM, toState: frontendURL(`accounts/${accountId}/contacts`), toStateName: 'contacts_dashboard', - roles: ['administrator', 'agent'], }, { icon: 'arrow-trending-lines', @@ -34,8 +31,7 @@ const primaryMenuItems = accountId => [ label: 'REPORTS', featureFlag: FEATURE_FLAGS.REPORTS, toState: frontendURL(`accounts/${accountId}/reports`), - toStateName: 'settings_account_reports', - roles: ['administrator'], + toStateName: 'account_overview_reports', }, { icon: 'megaphone', @@ -44,7 +40,6 @@ const primaryMenuItems = accountId => [ featureFlag: FEATURE_FLAGS.CAMPAIGNS, toState: frontendURL(`accounts/${accountId}/campaigns`), toStateName: 'ongoing_campaigns', - roles: ['administrator'], }, { icon: 'library', @@ -54,7 +49,6 @@ const primaryMenuItems = accountId => [ alwaysVisibleOnChatwootInstances: true, toState: frontendURL(`accounts/${accountId}/portals`), toStateName: 'default_portal_articles', - roles: ['administrator'], }, { icon: 'settings', @@ -62,7 +56,6 @@ const primaryMenuItems = accountId => [ label: 'SETTINGS', toState: frontendURL(`accounts/${accountId}/settings`), toStateName: 'settings_home', - roles: ['administrator', 'agent'], }, ]; diff --git a/app/javascript/dashboard/components/layout/config/sidebarItems/settings.js b/app/javascript/dashboard/components/layout/config/sidebarItems/settings.js index f450bd7a7..f7d63f6a1 100644 --- a/app/javascript/dashboard/components/layout/config/sidebarItems/settings.js +++ b/app/javascript/dashboard/components/layout/config/sidebarItems/settings.js @@ -24,7 +24,6 @@ const settings = accountId => ({ 'settings_inbox_list', 'settings_inbox_new', 'settings_inbox_show', - 'settings_inbox', 'settings_inboxes_add_agents', 'settings_inboxes_page_channel', 'settings_integrations_dashboard_apps', @@ -46,6 +45,9 @@ const settings = accountId => ({ icon: 'briefcase', label: 'ACCOUNT_SETTINGS', hasSubMenu: false, + meta: { + permissions: ['administrator'], + }, toState: frontendURL(`accounts/${accountId}/settings/general`), toStateName: 'general_settings_index', }, @@ -53,6 +55,9 @@ const settings = accountId => ({ icon: 'people', label: 'AGENTS', hasSubMenu: false, + meta: { + permissions: ['administrator'], + }, toState: frontendURL(`accounts/${accountId}/settings/agents/list`), toStateName: 'agent_list', featureFlag: FEATURE_FLAGS.AGENT_MANAGEMENT, @@ -61,6 +66,9 @@ const settings = accountId => ({ icon: 'people-team', label: 'TEAMS', hasSubMenu: false, + meta: { + permissions: ['administrator'], + }, toState: frontendURL(`accounts/${accountId}/settings/teams/list`), toStateName: 'settings_teams_list', featureFlag: FEATURE_FLAGS.TEAM_MANAGEMENT, @@ -69,6 +77,9 @@ const settings = accountId => ({ icon: 'mail-inbox-all', label: 'INBOXES', hasSubMenu: false, + meta: { + permissions: ['administrator'], + }, toState: frontendURL(`accounts/${accountId}/settings/inboxes/list`), toStateName: 'settings_inbox_list', featureFlag: FEATURE_FLAGS.INBOX_MANAGEMENT, @@ -77,6 +88,9 @@ const settings = accountId => ({ icon: 'tag', label: 'LABELS', hasSubMenu: false, + meta: { + permissions: ['administrator'], + }, toState: frontendURL(`accounts/${accountId}/settings/labels/list`), toStateName: 'labels_list', featureFlag: FEATURE_FLAGS.LABELS, @@ -85,6 +99,9 @@ const settings = accountId => ({ icon: 'code', label: 'CUSTOM_ATTRIBUTES', hasSubMenu: false, + meta: { + permissions: ['administrator'], + }, toState: frontendURL( `accounts/${accountId}/settings/custom-attributes/list` ), @@ -95,6 +112,9 @@ const settings = accountId => ({ icon: 'automation', label: 'AUTOMATION', hasSubMenu: false, + meta: { + permissions: ['administrator'], + }, toState: frontendURL(`accounts/${accountId}/settings/automation/list`), toStateName: 'automation_list', featureFlag: FEATURE_FLAGS.AUTOMATIONS, @@ -103,6 +123,9 @@ const settings = accountId => ({ icon: 'bot', label: 'AGENT_BOTS', hasSubMenu: false, + meta: { + permissions: ['administrator'], + }, globalConfigFlag: 'csmlEditorHost', toState: frontendURL(`accounts/${accountId}/settings/agent-bots`), toStateName: 'agent_bots', @@ -112,6 +135,9 @@ const settings = accountId => ({ icon: 'flash-settings', label: 'MACROS', hasSubMenu: false, + meta: { + permissions: ['administrator', 'agent'], + }, toState: frontendURL(`accounts/${accountId}/settings/macros`), toStateName: 'macros_wrapper', featureFlag: FEATURE_FLAGS.MACROS, @@ -120,6 +146,9 @@ const settings = accountId => ({ icon: 'chat-multiple', label: 'CANNED_RESPONSES', hasSubMenu: false, + meta: { + permissions: ['administrator', 'agent'], + }, toState: frontendURL( `accounts/${accountId}/settings/canned-response/list` ), @@ -130,6 +159,9 @@ const settings = accountId => ({ icon: 'flash-on', label: 'INTEGRATIONS', hasSubMenu: false, + meta: { + permissions: ['administrator'], + }, toState: frontendURL(`accounts/${accountId}/settings/integrations`), toStateName: 'settings_integrations', featureFlag: FEATURE_FLAGS.INTEGRATIONS, @@ -138,6 +170,9 @@ const settings = accountId => ({ icon: 'star-emphasis', label: 'APPLICATIONS', hasSubMenu: false, + meta: { + permissions: ['administrator'], + }, toState: frontendURL(`accounts/${accountId}/settings/applications`), toStateName: 'settings_applications', featureFlag: FEATURE_FLAGS.INTEGRATIONS, @@ -146,6 +181,9 @@ const settings = accountId => ({ icon: 'key', label: 'AUDIT_LOGS', hasSubMenu: false, + meta: { + permissions: ['administrator'], + }, toState: frontendURL(`accounts/${accountId}/settings/audit-log/list`), toStateName: 'auditlogs_list', isEnterpriseOnly: true, @@ -156,6 +194,9 @@ const settings = accountId => ({ icon: 'document-list-clock', label: 'SLA', hasSubMenu: false, + meta: { + permissions: ['administrator'], + }, toState: frontendURL(`accounts/${accountId}/settings/sla/list`), toStateName: 'sla_list', isEnterpriseOnly: true, @@ -166,6 +207,9 @@ const settings = accountId => ({ icon: 'credit-card-person', label: 'BILLING', hasSubMenu: false, + meta: { + permissions: ['administrator'], + }, toState: frontendURL(`accounts/${accountId}/settings/billing`), toStateName: 'billing_settings_index', showOnlyOnCloud: true, diff --git a/app/javascript/dashboard/components/layout/sidebarComponents/Secondary.vue b/app/javascript/dashboard/components/layout/sidebarComponents/Secondary.vue index f291d221e..b4cd3ca90 100644 --- a/app/javascript/dashboard/components/layout/sidebarComponents/Secondary.vue +++ b/app/javascript/dashboard/components/layout/sidebarComponents/Secondary.vue @@ -29,6 +29,8 @@ import SecondaryNavItem from './SecondaryNavItem.vue'; import AccountContext from './AccountContext.vue'; import { mapGetters } from 'vuex'; import { FEATURE_FLAGS } from '../../../featureFlags'; +import { hasPermissions } from '../../../helper/permissionsHelper'; +import { routesWithPermissions } from '../../../routes'; export default { components: { @@ -60,9 +62,9 @@ export default { type: Object, default: () => {}, }, - currentRole: { - type: String, - default: '', + currentUser: { + type: Object, + default: () => {}, }, isOnChatwootCloud: { type: Boolean, @@ -80,16 +82,16 @@ export default { return this.customViews.filter(view => view.filter_type === 'contact'); }, accessibleMenuItems() { - if (!this.currentRole) { - return []; - } - const menuItemsFilteredByRole = this.menuConfig.menuItems.filter( - menuItem => - window.roleWiseRoutes[this.currentRole].indexOf( - menuItem.toStateName - ) > -1 + const menuItemsFilteredByPermissions = this.menuConfig.menuItems.filter( + menuItem => { + const { permissions: userPermissions = [] } = this.currentUser; + return hasPermissions( + routesWithPermissions[menuItem.toStateName], + userPermissions + ); + } ); - return menuItemsFilteredByRole.filter(item => { + return menuItemsFilteredByPermissions.filter(item => { if (item.showOnlyOnCloud) { return this.isOnChatwootCloud; } diff --git a/app/javascript/dashboard/components/layout/sidebarComponents/SecondaryNavItem.vue b/app/javascript/dashboard/components/layout/sidebarComponents/SecondaryNavItem.vue index a7009523a..bc3b03646 100644 --- a/app/javascript/dashboard/components/layout/sidebarComponents/SecondaryNavItem.vue +++ b/app/javascript/dashboard/components/layout/sidebarComponents/SecondaryNavItem.vue @@ -65,27 +65,29 @@ :show-child-count="showChildCount(child.count)" :child-item-count="child.count" /> - -
  • - - - {{ $t(`SIDEBAR.${menuItem.newLinkTag}`) }} - - -
  • -
    + + +
  • + + + {{ $t(`SIDEBAR.${menuItem.newLinkTag}`) }} + + +
  • +
    +
    @@ -105,9 +107,10 @@ import { isOnMentionsView, isOnUnattendedView, } from '../../../store/modules/conversations/helpers/actionHelpers'; +import Policy from '../../policy.vue'; export default { - components: { SecondaryChildNavItem }, + components: { SecondaryChildNavItem, Policy }, mixins: [adminMixin, configMixin], props: { menuItem: { diff --git a/app/javascript/dashboard/components/policy.vue b/app/javascript/dashboard/components/policy.vue new file mode 100644 index 000000000..f888de5a2 --- /dev/null +++ b/app/javascript/dashboard/components/policy.vue @@ -0,0 +1,23 @@ + + + diff --git a/app/javascript/dashboard/helper/permissionsHelper.js b/app/javascript/dashboard/helper/permissionsHelper.js new file mode 100644 index 000000000..135238371 --- /dev/null +++ b/app/javascript/dashboard/helper/permissionsHelper.js @@ -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; + }, {}); diff --git a/app/javascript/dashboard/helper/routeHelpers.js b/app/javascript/dashboard/helper/routeHelpers.js index 68cf0a627..6c4036dd1 100644 --- a/app/javascript/dashboard/helper/routeHelpers.js +++ b/app/javascript/dashboard/helper/routeHelpers.js @@ -1,19 +1,16 @@ +import { hasPermissions } from './permissionsHelper'; + // eslint-disable-next-line default-param-last export const getCurrentAccount = ({ accounts } = {}, accountId) => { return accounts.find(account => account.id === accountId); }; -// eslint-disable-next-line default-param-last -export const getUserRole = ({ accounts } = {}, accountId) => { - const currentAccount = getCurrentAccount({ accounts }, accountId) || {}; - return currentAccount.role || null; +export const routeIsAccessibleFor = (route, userPermissions = []) => { + const { meta: { permissions: routePermissions = [] } = {} } = route; + return hasPermissions(routePermissions, userPermissions); }; -export const routeIsAccessibleFor = (route, role, roleWiseRoutes) => { - return roleWiseRoutes[role].includes(route); -}; - -const validateActiveAccountRoutes = (to, user, roleWiseRoutes) => { +const validateActiveAccountRoutes = (to, user) => { // If the current account is active, then check for the route permissions const accountDashboardURL = `accounts/${to.params.accountId}/dashboard`; @@ -22,15 +19,13 @@ const validateActiveAccountRoutes = (to, user, roleWiseRoutes) => { return accountDashboardURL; } - const userRole = getUserRole(user, Number(to.params.accountId)); - const isAccessible = routeIsAccessibleFor(to.name, userRole, roleWiseRoutes); + const isAccessible = routeIsAccessibleFor(to, user.permissions); // If the route is not accessible for the user, return to dashboard screen return isAccessible ? null : accountDashboardURL; }; -export const validateLoggedInRoutes = (to, user, roleWiseRoutes) => { +export const validateLoggedInRoutes = (to, user) => { const currentAccount = getCurrentAccount(user, Number(to.params.accountId)); - // If current account is missing, either user does not have // access to the account or the account is deleted, return to login screen if (!currentAccount) { @@ -40,7 +35,7 @@ export const validateLoggedInRoutes = (to, user, roleWiseRoutes) => { const isCurrentAccountActive = currentAccount.status === 'active'; if (isCurrentAccountActive) { - return validateActiveAccountRoutes(to, user, roleWiseRoutes); + return validateActiveAccountRoutes(to, user); } // If the current account is not active, then redirect the user to the suspended screen diff --git a/app/javascript/dashboard/helper/specs/permissionsHelper.spec.js b/app/javascript/dashboard/helper/specs/permissionsHelper.spec.js new file mode 100644 index 000000000..34f434f7d --- /dev/null +++ b/app/javascript/dashboard/helper/specs/permissionsHelper.spec.js @@ -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"); + }); +}); diff --git a/app/javascript/dashboard/helper/specs/routeHelpers.spec.js b/app/javascript/dashboard/helper/specs/routeHelpers.spec.js index 1e100a678..5aa9c4ee2 100644 --- a/app/javascript/dashboard/helper/specs/routeHelpers.spec.js +++ b/app/javascript/dashboard/helper/specs/routeHelpers.spec.js @@ -1,7 +1,6 @@ import { getConversationDashboardRoute, getCurrentAccount, - getUserRole, isAConversationRoute, routeIsAccessibleFor, validateLoggedInRoutes, @@ -15,24 +14,11 @@ describe('#getCurrentAccount', () => { }); }); -describe('#getUserRole', () => { - it('should return the current role', () => { - expect( - getUserRole({ accounts: [{ id: 1, role: 'administrator' }] }, 1) - ).toEqual('administrator'); - expect(getUserRole({ accounts: [] }, 1)).toEqual(null); - }); -}); - describe('#routeIsAccessibleFor', () => { it('should return the correct access', () => { - const roleWiseRoutes = { agent: ['conversations'], admin: ['billing'] }; - expect(routeIsAccessibleFor('billing', 'agent', roleWiseRoutes)).toEqual( - false - ); - expect(routeIsAccessibleFor('billing', 'admin', roleWiseRoutes)).toEqual( - true - ); + let route = { meta: { permissions: ['administrator'] } }; + expect(routeIsAccessibleFor(route, ['agent'])).toEqual(false); + expect(routeIsAccessibleFor(route, ['administrator'])).toEqual(true); }); }); @@ -40,11 +26,7 @@ describe('#validateLoggedInRoutes', () => { describe('when account access is missing', () => { it('should return the login route', () => { expect( - validateLoggedInRoutes( - { params: { accountId: 1 } }, - { accounts: [] }, - {} - ) + validateLoggedInRoutes({ params: { accountId: 1 } }, { accounts: [] }) ).toEqual(`app/login`); }); }); @@ -53,9 +35,12 @@ describe('#validateLoggedInRoutes', () => { it('return suspended route', () => { expect( validateLoggedInRoutes( - { name: 'conversations', params: { accountId: 1 } }, - { accounts: [{ id: 1, role: 'agent', status: 'suspended' }] }, - { agent: ['conversations'] } + { + name: 'conversations', + params: { accountId: 1 }, + meta: { permissions: ['agent'] }, + }, + { accounts: [{ id: 1, role: 'agent', status: 'suspended' }] } ) ).toEqual(`accounts/1/suspended`); }); @@ -65,9 +50,22 @@ describe('#validateLoggedInRoutes', () => { it('returns null (no action required)', () => { expect( validateLoggedInRoutes( - { name: 'conversations', params: { accountId: 1 } }, - { accounts: [{ id: 1, role: 'agent', status: 'active' }] }, - { agent: ['conversations'] } + { + name: 'conversations', + params: { accountId: 1 }, + meta: { permissions: ['agent'] }, + }, + { + permissions: ['agent'], + accounts: [ + { + id: 1, + role: 'agent', + permissions: ['agent'], + status: 'active', + }, + ], + } ) ).toEqual(null); }); @@ -76,9 +74,12 @@ describe('#validateLoggedInRoutes', () => { it('returns dashboard url', () => { expect( validateLoggedInRoutes( - { name: 'conversations', params: { accountId: 1 } }, - { accounts: [{ id: 1, role: 'agent', status: 'active' }] }, - { admin: ['conversations'], agent: [] } + { + name: 'billing', + params: { accountId: 1 }, + meta: { permissions: ['administrator'] }, + }, + { accounts: [{ id: 1, role: 'agent', status: 'active' }] } ) ).toEqual(`accounts/1/dashboard`); }); @@ -88,8 +89,7 @@ describe('#validateLoggedInRoutes', () => { expect( validateLoggedInRoutes( { name: 'account_suspended', params: { accountId: 1 } }, - { accounts: [{ id: 1, role: 'agent', status: 'active' }] }, - { agent: ['account_suspended'] } + { accounts: [{ id: 1, role: 'agent', status: 'active' }] } ) ).toEqual(`accounts/1/dashboard`); }); diff --git a/app/javascript/dashboard/modules/search/search.routes.js b/app/javascript/dashboard/modules/search/search.routes.js index 320f64a44..d2d7b19c4 100644 --- a/app/javascript/dashboard/modules/search/search.routes.js +++ b/app/javascript/dashboard/modules/search/search.routes.js @@ -7,7 +7,9 @@ export const routes = [ { path: frontendURL('accounts/:accountId/search'), name: 'search', - roles: ['administrator', 'agent'], + meta: { + permissions: ['administrator', 'agent'], + }, component: SearchView, }, ]; diff --git a/app/javascript/dashboard/routes/dashboard/contacts/routes.js b/app/javascript/dashboard/routes/dashboard/contacts/routes.js index 10a560740..a07ca6bf3 100644 --- a/app/javascript/dashboard/routes/dashboard/contacts/routes.js +++ b/app/javascript/dashboard/routes/dashboard/contacts/routes.js @@ -7,13 +7,17 @@ export const routes = [ { path: frontendURL('accounts/:accountId/contacts'), name: 'contacts_dashboard', - roles: ['administrator', 'agent'], + meta: { + permissions: ['administrator', 'agent'], + }, component: ContactsView, }, { path: frontendURL('accounts/:accountId/contacts/custom_view/:id'), name: 'contacts_segments_dashboard', - roles: ['administrator', 'agent'], + meta: { + permissions: ['administrator', 'agent'], + }, component: ContactsView, props: route => { return { segmentsId: route.params.id }; @@ -22,7 +26,9 @@ export const routes = [ { path: frontendURL('accounts/:accountId/labels/:label/contacts'), name: 'contacts_labels_dashboard', - roles: ['administrator', 'agent'], + meta: { + permissions: ['administrator', 'agent'], + }, component: ContactsView, props: route => { return { label: route.params.label }; @@ -31,7 +37,9 @@ export const routes = [ { path: frontendURL('accounts/:accountId/contacts/:contactId'), name: 'contact_profile_dashboard', - roles: ['administrator', 'agent'], + meta: { + permissions: ['administrator', 'agent'], + }, component: ContactManageView, props: route => { return { contactId: route.params.contactId }; diff --git a/app/javascript/dashboard/routes/dashboard/conversation/conversation.routes.js b/app/javascript/dashboard/routes/dashboard/conversation/conversation.routes.js index 14487682e..7a81e2f4e 100644 --- a/app/javascript/dashboard/routes/dashboard/conversation/conversation.routes.js +++ b/app/javascript/dashboard/routes/dashboard/conversation/conversation.routes.js @@ -7,7 +7,9 @@ export default { { path: frontendURL('accounts/:accountId/dashboard'), name: 'home', - roles: ['administrator', 'agent'], + meta: { + permissions: ['administrator', 'agent'], + }, component: ConversationView, props: () => { return { inboxId: 0 }; @@ -16,7 +18,9 @@ export default { { path: frontendURL('accounts/:accountId/conversations/:conversation_id'), name: 'inbox_conversation', - roles: ['administrator', 'agent'], + meta: { + permissions: ['administrator', 'agent'], + }, component: ConversationView, props: route => { return { inboxId: 0, conversationId: route.params.conversation_id }; @@ -25,7 +29,9 @@ export default { { path: frontendURL('accounts/:accountId/inbox/:inbox_id'), name: 'inbox_dashboard', - roles: ['administrator', 'agent'], + meta: { + permissions: ['administrator', 'agent'], + }, component: ConversationView, props: route => { return { inboxId: route.params.inbox_id }; @@ -36,7 +42,9 @@ export default { 'accounts/:accountId/inbox/:inbox_id/conversations/:conversation_id' ), name: 'conversation_through_inbox', - roles: ['administrator', 'agent'], + meta: { + permissions: ['administrator', 'agent'], + }, component: ConversationView, props: route => { return { @@ -48,7 +56,9 @@ export default { { path: frontendURL('accounts/:accountId/label/:label'), name: 'label_conversations', - roles: ['administrator', 'agent'], + meta: { + permissions: ['administrator', 'agent'], + }, component: ConversationView, props: route => ({ label: route.params.label }), }, @@ -57,7 +67,9 @@ export default { 'accounts/:accountId/label/:label/conversations/:conversation_id' ), name: 'conversations_through_label', - roles: ['administrator', 'agent'], + meta: { + permissions: ['administrator', 'agent'], + }, component: ConversationView, props: route => ({ conversationId: route.params.conversation_id, @@ -67,7 +79,9 @@ export default { { path: frontendURL('accounts/:accountId/team/:teamId'), name: 'team_conversations', - roles: ['administrator', 'agent'], + meta: { + permissions: ['administrator', 'agent'], + }, component: ConversationView, props: route => ({ teamId: route.params.teamId }), }, @@ -76,7 +90,9 @@ export default { 'accounts/:accountId/team/:teamId/conversations/:conversationId' ), name: 'conversations_through_team', - roles: ['administrator', 'agent'], + meta: { + permissions: ['administrator', 'agent'], + }, component: ConversationView, props: route => ({ conversationId: route.params.conversationId, @@ -86,7 +102,9 @@ export default { { path: frontendURL('accounts/:accountId/custom_view/:id'), name: 'folder_conversations', - roles: ['administrator', 'agent'], + meta: { + permissions: ['administrator', 'agent'], + }, component: ConversationView, props: route => ({ foldersId: route.params.id }), }, @@ -95,7 +113,9 @@ export default { 'accounts/:accountId/custom_view/:id/conversations/:conversation_id' ), name: 'conversations_through_folders', - roles: ['administrator', 'agent'], + meta: { + permissions: ['administrator', 'agent'], + }, component: ConversationView, props: route => ({ conversationId: route.params.conversation_id, @@ -105,7 +125,9 @@ export default { { path: frontendURL('accounts/:accountId/mentions/conversations'), name: 'conversation_mentions', - roles: ['administrator', 'agent'], + meta: { + permissions: ['administrator', 'agent'], + }, component: ConversationView, props: () => ({ conversationType: 'mention' }), }, @@ -114,7 +136,9 @@ export default { 'accounts/:accountId/mentions/conversations/:conversationId' ), name: 'conversation_through_mentions', - roles: ['administrator', 'agent'], + meta: { + permissions: ['administrator', 'agent'], + }, component: ConversationView, props: route => ({ conversationId: route.params.conversationId, @@ -124,7 +148,9 @@ export default { { path: frontendURL('accounts/:accountId/unattended/conversations'), name: 'conversation_unattended', - roles: ['administrator', 'agent'], + meta: { + permissions: ['administrator', 'agent'], + }, component: ConversationView, props: () => ({ conversationType: 'unattended' }), }, @@ -133,7 +159,9 @@ export default { 'accounts/:accountId/unattended/conversations/:conversationId' ), name: 'conversation_through_unattended', - roles: ['administrator', 'agent'], + meta: { + permissions: ['administrator', 'agent'], + }, component: ConversationView, props: route => ({ conversationId: route.params.conversationId, @@ -143,7 +171,9 @@ export default { { path: frontendURL('accounts/:accountId/participating/conversations'), name: 'conversation_participating', - roles: ['administrator', 'agent'], + meta: { + permissions: ['administrator', 'agent'], + }, component: ConversationView, props: () => ({ conversationType: 'participating' }), }, @@ -152,7 +182,9 @@ export default { 'accounts/:accountId/participating/conversations/:conversationId' ), name: 'conversation_through_participating', - roles: ['administrator', 'agent'], + meta: { + permissions: ['administrator', 'agent'], + }, component: ConversationView, props: route => ({ conversationId: route.params.conversationId, diff --git a/app/javascript/dashboard/routes/dashboard/dashboard.routes.js b/app/javascript/dashboard/routes/dashboard/dashboard.routes.js index 9e18ca42c..b02f29342 100644 --- a/app/javascript/dashboard/routes/dashboard/dashboard.routes.js +++ b/app/javascript/dashboard/routes/dashboard/dashboard.routes.js @@ -28,7 +28,9 @@ export default { { path: frontendURL('accounts/:accountId/suspended'), name: 'account_suspended', - roles: ['administrator', 'agent'], + meta: { + permissions: ['administrator', 'agent'], + }, component: Suspended, }, ], diff --git a/app/javascript/dashboard/routes/dashboard/helpcenter/helpcenter.routes.js b/app/javascript/dashboard/routes/dashboard/helpcenter/helpcenter.routes.js index a165b0277..0326534f3 100644 --- a/app/javascript/dashboard/routes/dashboard/helpcenter/helpcenter.routes.js +++ b/app/javascript/dashboard/routes/dashboard/helpcenter/helpcenter.routes.js @@ -30,13 +30,17 @@ const portalRoutes = [ { path: getPortalRoute(''), name: 'default_portal_articles', - roles: ['administrator', 'agent'], + meta: { + permissions: ['administrator'], + }, component: DefaultPortalArticles, }, { path: getPortalRoute('all'), name: 'list_all_portals', - roles: ['administrator', 'agent'], + meta: { + permissions: ['administrator', 'agent'], + }, component: ListAllPortals, }, { @@ -47,55 +51,73 @@ const portalRoutes = [ path: '', name: 'new_portal_information', component: PortalDetails, - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, }, { path: ':portalSlug/customization', name: 'portal_customization', component: PortalCustomization, - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, }, { path: ':portalSlug/finish', name: 'portal_finish', component: PortalSettingsFinish, - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, }, ], }, { path: getPortalRoute(':portalSlug'), name: 'portalSlug', - roles: ['administrator', 'agent'], + meta: { + permissions: ['administrator', 'agent'], + }, component: ShowPortal, }, { path: getPortalRoute(':portalSlug/edit'), - roles: ['administrator', 'agent'], + meta: { + permissions: ['administrator', 'agent'], + }, component: EditPortal, children: [ { path: '', name: 'edit_portal_information', component: EditPortalBasic, - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, }, { path: 'customizations', name: 'edit_portal_customization', component: EditPortalCustomization, - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, }, { path: 'locales', name: 'edit_portal_locales', component: EditPortalLocales, - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, }, { path: 'categories', name: 'list_all_locale_categories', - roles: ['administrator', 'agent'], + meta: { + permissions: ['administrator', 'agent'], + }, component: ListAllCategories, }, ], @@ -106,39 +128,51 @@ const articleRoutes = [ { path: getPortalRoute(':portalSlug/:locale/articles'), name: 'list_all_locale_articles', - roles: ['administrator', 'agent'], + meta: { + permissions: ['administrator', 'agent'], + }, component: ListAllArticles, }, { path: getPortalRoute(':portalSlug/:locale/articles/new'), name: 'new_article', - roles: ['administrator', 'agent'], + meta: { + permissions: ['administrator', 'agent'], + }, component: NewArticle, }, { path: getPortalRoute(':portalSlug/:locale/articles/mine'), name: 'list_mine_articles', - roles: ['administrator', 'agent'], + meta: { + permissions: ['administrator', 'agent'], + }, component: ListAllArticles, }, { path: getPortalRoute(':portalSlug/:locale/articles/archived'), name: 'list_archived_articles', - roles: ['administrator', 'agent'], + meta: { + permissions: ['administrator', 'agent'], + }, component: ListAllArticles, }, { path: getPortalRoute(':portalSlug/:locale/articles/draft'), name: 'list_draft_articles', - roles: ['administrator', 'agent'], + meta: { + permissions: ['administrator', 'agent'], + }, component: ListAllArticles, }, { path: getPortalRoute(':portalSlug/:locale/articles/:articleSlug'), name: 'edit_article', - roles: ['administrator', 'agent'], + meta: { + permissions: ['administrator', 'agent'], + }, component: EditArticle, }, ]; @@ -147,19 +181,25 @@ const categoryRoutes = [ { path: getPortalRoute(':portalSlug/:locale/categories'), name: 'all_locale_categories', - roles: ['administrator', 'agent'], + meta: { + permissions: ['administrator', 'agent'], + }, component: ListAllCategories, }, { path: getPortalRoute(':portalSlug/:locale/categories/new'), name: 'new_category_in_locale', - roles: ['administrator', 'agent'], + meta: { + permissions: ['administrator', 'agent'], + }, component: NewCategory, }, { path: getPortalRoute(':portalSlug/:locale/categories/:categorySlug'), name: 'show_category', - roles: ['administrator', 'agent'], + meta: { + permissions: ['administrator', 'agent'], + }, component: ListAllArticles, }, { @@ -167,13 +207,17 @@ const categoryRoutes = [ ':portalSlug/:locale/categories/:categorySlug/articles' ), name: 'show_category_articles', - roles: ['administrator', 'agent'], + meta: { + permissions: ['administrator', 'agent'], + }, component: ListCategoryArticles, }, { path: getPortalRoute(':portalSlug/:locale/categories/:categorySlug'), name: 'edit_category', - roles: ['administrator', 'agent'], + meta: { + permissions: ['administrator', 'agent'], + }, component: EditCategory, }, ]; diff --git a/app/javascript/dashboard/routes/dashboard/inbox/routes.js b/app/javascript/dashboard/routes/dashboard/inbox/routes.js index 9c26fa64e..729fee76d 100644 --- a/app/javascript/dashboard/routes/dashboard/inbox/routes.js +++ b/app/javascript/dashboard/routes/dashboard/inbox/routes.js @@ -12,13 +12,17 @@ export const routes = [ path: '', name: 'inbox_view', component: InboxEmptyStateView, - roles: ['administrator', 'agent'], + meta: { + permissions: ['administrator', 'agent'], + }, }, { path: ':notification_id', name: 'inbox_view_conversation', component: InboxDetailView, - roles: ['administrator', 'agent'], + meta: { + permissions: ['administrator', 'agent'], + }, }, ], }, diff --git a/app/javascript/dashboard/routes/dashboard/notifications/routes.js b/app/javascript/dashboard/routes/dashboard/notifications/routes.js index 38812fc92..e3d125333 100644 --- a/app/javascript/dashboard/routes/dashboard/notifications/routes.js +++ b/app/javascript/dashboard/routes/dashboard/notifications/routes.js @@ -18,7 +18,9 @@ export const routes = [ path: '', name: 'notifications_index', component: NotificationsView, - roles: ['administrator', 'agent'], + meta: { + permissions: ['administrator', 'agent'], + }, }, ], }, diff --git a/app/javascript/dashboard/routes/dashboard/settings/account/account.routes.js b/app/javascript/dashboard/routes/dashboard/settings/account/account.routes.js index 0acfd5bd5..2742621e9 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/account/account.routes.js +++ b/app/javascript/dashboard/routes/dashboard/settings/account/account.routes.js @@ -6,7 +6,9 @@ export default { routes: [ { path: frontendURL('accounts/:accountId/settings/general'), - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, component: SettingsContent, props: { headerTitle: 'GENERAL_SETTINGS.TITLE', @@ -18,7 +20,9 @@ export default { path: '', name: 'general_settings_index', component: Index, - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, }, ], }, diff --git a/app/javascript/dashboard/routes/dashboard/settings/agentBots/agentBot.routes.js b/app/javascript/dashboard/routes/dashboard/settings/agentBots/agentBot.routes.js index 382594c73..55210397f 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/agentBots/agentBot.routes.js +++ b/app/javascript/dashboard/routes/dashboard/settings/agentBots/agentBot.routes.js @@ -8,7 +8,9 @@ export default { routes: [ { path: frontendURL('accounts/:accountId/settings/agent-bots'), - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, component: SettingsContent, props: { headerTitle: 'AGENT_BOTS.HEADER', @@ -20,19 +22,25 @@ export default { path: '', name: 'agent_bots', component: Bot, - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, }, { path: 'csml/new', name: 'agent_bots_csml_new', component: CsmlNewBot, - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, }, { path: 'csml/:botId', name: 'agent_bots_csml_edit', component: CsmlEditBot, - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, }, ], }, diff --git a/app/javascript/dashboard/routes/dashboard/settings/agents/agent.routes.js b/app/javascript/dashboard/routes/dashboard/settings/agents/agent.routes.js index cd23432ff..854450c5d 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/agents/agent.routes.js +++ b/app/javascript/dashboard/routes/dashboard/settings/agents/agent.routes.js @@ -15,14 +15,15 @@ export default { children: [ { path: '', - name: 'agents_wrapper', redirect: 'list', }, { path: 'list', name: 'agent_list', component: AgentHome, - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, }, ], }, diff --git a/app/javascript/dashboard/routes/dashboard/settings/attributes/attributes.routes.js b/app/javascript/dashboard/routes/dashboard/settings/attributes/attributes.routes.js index 72d79a9de..93c4f8eda 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/attributes/attributes.routes.js +++ b/app/javascript/dashboard/routes/dashboard/settings/attributes/attributes.routes.js @@ -15,14 +15,15 @@ export default { children: [ { path: '', - name: 'attributes_wrapper', redirect: 'list', }, { path: 'list', name: 'attributes_list', component: AttributesHome, - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, }, ], }, diff --git a/app/javascript/dashboard/routes/dashboard/settings/auditlogs/audit.routes.js b/app/javascript/dashboard/routes/dashboard/settings/auditlogs/audit.routes.js index 00c1fda74..acf061288 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/auditlogs/audit.routes.js +++ b/app/javascript/dashboard/routes/dashboard/settings/auditlogs/audit.routes.js @@ -16,13 +16,14 @@ export default { children: [ { path: '', - name: 'auditlogs_wrapper', redirect: 'list', }, { path: 'list', name: 'auditlogs_list', - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, component: AuditLogsHome, }, ], diff --git a/app/javascript/dashboard/routes/dashboard/settings/automation/automation.routes.js b/app/javascript/dashboard/routes/dashboard/settings/automation/automation.routes.js index 3a5d6c887..14b03a45a 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/automation/automation.routes.js +++ b/app/javascript/dashboard/routes/dashboard/settings/automation/automation.routes.js @@ -15,14 +15,15 @@ export default { children: [ { path: '', - name: 'automation_wrapper', redirect: 'list', }, { path: 'list', name: 'automation_list', component: Automation, - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, }, ], }, diff --git a/app/javascript/dashboard/routes/dashboard/settings/billing/billing.routes.js b/app/javascript/dashboard/routes/dashboard/settings/billing/billing.routes.js index 7a37f320a..f1042e81a 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/billing/billing.routes.js +++ b/app/javascript/dashboard/routes/dashboard/settings/billing/billing.routes.js @@ -6,7 +6,9 @@ export default { routes: [ { path: frontendURL('accounts/:accountId/settings/billing'), - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, component: SettingsContent, props: { headerTitle: 'BILLING_SETTINGS.TITLE', @@ -18,7 +20,9 @@ export default { path: '', name: 'billing_settings_index', component: Index, - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, }, ], }, diff --git a/app/javascript/dashboard/routes/dashboard/settings/campaigns/campaigns.routes.js b/app/javascript/dashboard/routes/dashboard/settings/campaigns/campaigns.routes.js index 1ac007ed6..5c8581981 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/campaigns/campaigns.routes.js +++ b/app/javascript/dashboard/routes/dashboard/settings/campaigns/campaigns.routes.js @@ -19,7 +19,9 @@ export default { { path: 'ongoing', name: 'ongoing_campaigns', - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, component: Index, }, ], @@ -35,7 +37,9 @@ export default { { path: 'one_off', name: 'one_off', - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, component: Index, }, ], diff --git a/app/javascript/dashboard/routes/dashboard/settings/canned/canned.routes.js b/app/javascript/dashboard/routes/dashboard/settings/canned/canned.routes.js index 73b370e2a..236801c8c 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/canned/canned.routes.js +++ b/app/javascript/dashboard/routes/dashboard/settings/canned/canned.routes.js @@ -16,13 +16,14 @@ export default { children: [ { path: '', - name: 'canned_wrapper', redirect: 'list', }, { path: 'list', name: 'canned_list', - roles: ['administrator', 'agent'], + meta: { + permissions: ['administrator', 'agent'], + }, component: CannedHome, }, ], diff --git a/app/javascript/dashboard/routes/dashboard/settings/inbox/inbox.routes.js b/app/javascript/dashboard/routes/dashboard/settings/inbox/inbox.routes.js index 4e4c14c00..3866b96bd 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/inbox/inbox.routes.js +++ b/app/javascript/dashboard/routes/dashboard/settings/inbox/inbox.routes.js @@ -28,14 +28,15 @@ export default { children: [ { path: '', - name: 'settings_inbox', redirect: 'list', }, { path: 'list', name: 'settings_inbox_list', component: InboxHome, - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, }, { path: 'new', @@ -45,19 +46,25 @@ export default { path: '', name: 'settings_inbox_new', component: ChannelList, - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, }, { path: ':inbox_id/finish', name: 'settings_inbox_finish', component: FinishSetup, - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, }, { path: ':sub_page', name: 'settings_inboxes_page_channel', component: channelFactory.create(), - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, props: route => { return { channel_name: route.params.sub_page }; }, @@ -65,7 +72,9 @@ export default { { path: ':inbox_id/agents', name: 'settings_inboxes_add_agents', - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, component: AddAgents, }, ], @@ -74,7 +83,9 @@ export default { path: ':inboxId', name: 'settings_inbox_show', component: Settings, - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, }, ], }, diff --git a/app/javascript/dashboard/routes/dashboard/settings/integrationapps/integrations.routes.js b/app/javascript/dashboard/routes/dashboard/settings/integrationapps/integrations.routes.js index a0f8477b2..d3074f62d 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/integrationapps/integrations.routes.js +++ b/app/javascript/dashboard/routes/dashboard/settings/integrationapps/integrations.routes.js @@ -26,13 +26,17 @@ export default { path: '', name: 'settings_applications', component: Index, - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, }, { path: ':integration_id', name: 'settings_applications_integration', component: IntegrationHooks, - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, props: route => ({ integrationId: route.params.integration_id, }), diff --git a/app/javascript/dashboard/routes/dashboard/settings/integrations/integrations.routes.js b/app/javascript/dashboard/routes/dashboard/settings/integrations/integrations.routes.js index 542cf591e..bdebc0329 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/integrations/integrations.routes.js +++ b/app/javascript/dashboard/routes/dashboard/settings/integrations/integrations.routes.js @@ -30,32 +30,42 @@ export default { path: '', name: 'settings_integrations', component: Index, - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, }, { path: 'webhook', component: Webhook, name: 'settings_integrations_webhook', - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, }, { path: 'dashboard-apps', component: DashboardApps, name: 'settings_integrations_dashboard_apps', - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, }, { path: 'slack', name: 'settings_integrations_slack', component: Slack, - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, props: route => ({ code: route.query.code }), }, { path: ':integration_id', name: 'settings_integrations_integration', component: ShowIntegration, - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, props: route => { return { integrationId: route.params.integration_id, diff --git a/app/javascript/dashboard/routes/dashboard/settings/labels/labels.routes.js b/app/javascript/dashboard/routes/dashboard/settings/labels/labels.routes.js index 4fc514da6..088c565d0 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/labels/labels.routes.js +++ b/app/javascript/dashboard/routes/dashboard/settings/labels/labels.routes.js @@ -17,13 +17,17 @@ export default { { path: '', name: 'labels_wrapper', - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, redirect: 'list', }, { path: 'list', name: 'labels_list', - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, component: Index, }, ], diff --git a/app/javascript/dashboard/routes/dashboard/settings/macros/macros.routes.js b/app/javascript/dashboard/routes/dashboard/settings/macros/macros.routes.js index 58a26819f..06d0014b9 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/macros/macros.routes.js +++ b/app/javascript/dashboard/routes/dashboard/settings/macros/macros.routes.js @@ -23,19 +23,25 @@ export default { path: '', name: 'macros_wrapper', component: Macros, - roles: ['administrator', 'agent'], + meta: { + permissions: ['administrator', 'agent'], + }, }, { path: 'new', name: 'macros_new', component: MacroEditor, - roles: ['administrator', 'agent'], + meta: { + permissions: ['administrator', 'agent'], + }, }, { path: ':macroId/edit', name: 'macros_edit', component: MacroEditor, - roles: ['administrator', 'agent'], + meta: { + permissions: ['administrator', 'agent'], + }, }, ], }, diff --git a/app/javascript/dashboard/routes/dashboard/settings/profile/profile.routes.js b/app/javascript/dashboard/routes/dashboard/settings/profile/profile.routes.js index 357c20e85..31f386e37 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/profile/profile.routes.js +++ b/app/javascript/dashboard/routes/dashboard/settings/profile/profile.routes.js @@ -8,14 +8,18 @@ export default { { path: frontendURL('accounts/:accountId/profile'), name: 'profile_settings', - roles: ['administrator', 'agent'], + meta: { + permissions: ['administrator', 'agent'], + }, component: SettingsContent, children: [ { path: 'settings', name: 'profile_settings_index', component: Index, - roles: ['administrator', 'agent'], + meta: { + permissions: ['administrator', 'agent'], + }, }, ], }, diff --git a/app/javascript/dashboard/routes/dashboard/settings/reports/reports.routes.js b/app/javascript/dashboard/routes/dashboard/settings/reports/reports.routes.js index 3792567da..eaca0e76d 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/reports/reports.routes.js +++ b/app/javascript/dashboard/routes/dashboard/settings/reports/reports.routes.js @@ -29,7 +29,9 @@ export default { { path: 'overview', name: 'account_overview_reports', - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, component: LiveReports, }, ], @@ -46,7 +48,9 @@ export default { { path: 'conversation', name: 'conversation_reports', - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, component: Index, }, ], @@ -63,7 +67,9 @@ export default { { path: 'csat', name: 'csat_reports', - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, component: CsatResponses, }, ], @@ -80,7 +86,9 @@ export default { { path: 'bot', name: 'bot_reports', - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, component: BotReports, }, ], @@ -97,7 +105,9 @@ export default { { path: 'agent', name: 'agent_reports', - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, component: AgentReports, }, ], @@ -114,7 +124,9 @@ export default { { path: 'label', name: 'label_reports', - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, component: LabelReports, }, ], @@ -131,7 +143,9 @@ export default { { path: 'inboxes', name: 'inbox_reports', - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, component: InboxReports, }, ], @@ -147,7 +161,9 @@ export default { { path: 'teams', name: 'team_reports', - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, component: TeamReports, }, ], @@ -164,7 +180,9 @@ export default { { path: 'sla', name: 'sla_reports', - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, component: SLAReports, }, ], diff --git a/app/javascript/dashboard/routes/dashboard/settings/settings.routes.js b/app/javascript/dashboard/routes/dashboard/settings/settings.routes.js index dd5291fe8..2829ed1d9 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/settings.routes.js +++ b/app/javascript/dashboard/routes/dashboard/settings/settings.routes.js @@ -24,7 +24,9 @@ export default { { path: frontendURL('accounts/:accountId/settings'), name: 'settings_home', - roles: ['administrator', 'agent'], + meta: { + permissions: ['administrator', 'agent'], + }, redirect: () => { if (store.getters.getCurrentRole === 'administrator') { return frontendURL('accounts/:accountId/settings/general'); diff --git a/app/javascript/dashboard/routes/dashboard/settings/sla/sla.routes.js b/app/javascript/dashboard/routes/dashboard/settings/sla/sla.routes.js index a9c68470a..762d85d58 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/sla/sla.routes.js +++ b/app/javascript/dashboard/routes/dashboard/settings/sla/sla.routes.js @@ -13,13 +13,17 @@ export default { { path: '', name: 'sla_wrapper', - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, redirect: 'list', }, { path: 'list', name: 'sla_list', - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, component: Index, }, ], diff --git a/app/javascript/dashboard/routes/dashboard/settings/teams/teams.routes.js b/app/javascript/dashboard/routes/dashboard/settings/teams/teams.routes.js index 4228e72e7..c968351f4 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/teams/teams.routes.js +++ b/app/javascript/dashboard/routes/dashboard/settings/teams/teams.routes.js @@ -29,14 +29,15 @@ export default { children: [ { path: '', - name: 'settings_teams', redirect: 'list', }, { path: 'list', name: 'settings_teams_list', component: TeamsHome, - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, }, { path: 'new', @@ -46,18 +47,24 @@ export default { path: '', name: 'settings_teams_new', component: CreateTeam, - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, }, { path: ':teamId/finish', name: 'settings_teams_finish', component: FinishSetup, - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, }, { path: ':teamId/agents', name: 'settings_teams_add_agents', - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, component: AddAgents, }, ], @@ -70,18 +77,24 @@ export default { path: '', name: 'settings_teams_edit', component: EditTeam, - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, }, { path: 'agents', name: 'settings_teams_edit_members', component: EditAgents, - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, }, { path: 'finish', name: 'settings_teams_edit_finish', - roles: ['administrator'], + meta: { + permissions: ['administrator'], + }, component: FinishSetup, }, ], diff --git a/app/javascript/dashboard/routes/index.js b/app/javascript/dashboard/routes/index.js index e2245e20f..70d870700 100644 --- a/app/javascript/dashboard/routes/index.js +++ b/app/javascript/dashboard/routes/index.js @@ -5,33 +5,12 @@ import dashboard from './dashboard/dashboard.routes'; import store from '../store'; import { validateLoggedInRoutes } from '../helper/routeHelpers'; import AnalyticsHelper from '../helper/AnalyticsHelper'; +import { buildPermissionsFromRouter } from '../helper/permissionsHelper'; const routes = [...dashboard.routes]; -window.roleWiseRoutes = { - agent: [], - administrator: [], -}; - -// generateRoleWiseRoute - updates window object with agent/admin route -const generateRoleWiseRoute = route => { - route.forEach(element => { - if (element.children) { - generateRoleWiseRoute(element.children); - } - if (element.roles) { - element.roles.forEach(roleEl => { - window.roleWiseRoutes[roleEl].push(element.name); - }); - } - }); -}; -// Create a object of routes -// accessible by each role. -// returns an object with roles as keys and routeArr as values -generateRoleWiseRoute(routes); - export const router = new VueRouter({ mode: 'history', routes }); +export const routesWithPermissions = buildPermissionsFromRouter(routes); export const validateAuthenticateRoutePermission = (to, next, { getters }) => { const { isLoggedIn, getCurrentUser: user } = getters; @@ -45,11 +24,7 @@ export const validateAuthenticateRoutePermission = (to, next, { getters }) => { return next(frontendURL(`accounts/${user.account_id}/dashboard`)); } - const nextRoute = validateLoggedInRoutes( - to, - getters.getCurrentUser, - window.roleWiseRoutes - ); + const nextRoute = validateLoggedInRoutes(to, getters.getCurrentUser); return nextRoute ? next(frontendURL(nextRoute)) : next(); };