diff --git a/i18n/en.i18n.json b/i18n/en.i18n.json index 4d02048519de..65f227d3a5e9 100644 --- a/i18n/en.i18n.json +++ b/i18n/en.i18n.json @@ -1,6 +1,7 @@ { "Access_online_demo" : "Access the online demo", "Access_Online_Demo" : "Access the Online Demo", + "Access_not_authorized" : "Access not authorized", "Accounts" : "Accounts", "Accounts_AllowedDomainsList" : "Allowed Domains List", "Accounts_AllowedDomainsList_Description" : "Comma-separated list of allowed domains", @@ -271,6 +272,7 @@ "No_permission_to_view_room" : "You don't have permission to view this room", "No_user_with_username_%s_was_found" : "No user with username \"%s\" was found!", "Not_allowed" : "Not allowed", + "Not_authorized" : "Not authorized", "Not_found_or_not_allowed" : "Not Found or Not Allowed", "Nothing_found" : "Nothing found", "Notify_all_in_this_room" : "Notify all in this room", @@ -456,4 +458,4 @@ "You_will_not_be_able_to_recover" : "You will not be able to recover this message!", "Your_entry_has_been_deleted" : "Your entry has been deleted.", "Your_Open_Source_solution" : "Your own Open Source chat solution" -} \ No newline at end of file +} diff --git a/i18n/pt.i18n.json b/i18n/pt.i18n.json index 9ee0d172ae0c..ccff59f961fe 100644 --- a/i18n/pt.i18n.json +++ b/i18n/pt.i18n.json @@ -1,6 +1,7 @@ { "Access_online_demo" : "Acesse o demo online", "Access_Online_Demo" : "Acesse o Demo Online", + "Access_not_authorized" : "Accesso não autorizado", "Accounts" : "Contas", "Accounts_AllowedDomainsList" : "Lista de domínios permitidos (separados por vírgula)", "Accounts_AllowUsernameChange" : "Permitir alterar usuário", @@ -238,6 +239,7 @@ "No_permission_to_view_room" : "Sem permissões para ver a sala", "No_user_with_username_%s_was_found" : "Nenhum usuário com nome de usuário \"%s\" foi encontrado!", "Not_allowed" : "Não permitido", + "Not_authorized" : "Não autorizado", "Not_found_or_not_allowed" : "Não encontrado ou não permitido", "Nothing_found" : "Nada encontrado", "Notify_all_in_this_room" : "Notificar todos nesta sala", diff --git a/packages/rocketchat-authorization/package.js b/packages/rocketchat-authorization/package.js index d9cb3f715618..9d349afef96d 100644 --- a/packages/rocketchat-authorization/package.js +++ b/packages/rocketchat-authorization/package.js @@ -10,6 +10,7 @@ Package.onUse(function(api) { api.versionsFrom('1.0'); api.use([ 'coffeescript', + 'underscore', 'rocketchat:lib@0.0.1', 'alanning:roles@1.2.12' ]); diff --git a/packages/rocketchat-lib/client/lib/roomTypes.coffee b/packages/rocketchat-lib/client/lib/roomTypes.coffee index c3cdfc84c9db..f292dceba09e 100644 --- a/packages/rocketchat-lib/client/lib/roomTypes.coffee +++ b/packages/rocketchat-lib/client/lib/roomTypes.coffee @@ -3,6 +3,17 @@ RocketChat.roomTypes = new class roomTypes = {} mainOrder = 1 + protectedAction = (item) -> + if not item.permissions? or RocketChat.authz.hasAtLeastOnePermission item.permissions + return item.route.action + + return -> + BlazeLayout.render 'main', + center: 'pageContainer' + # @TODO text Not_authorized don't get the correct language + pageTitle: t('Not_authorized') + pageTemplate: 'notAuthorized' + ### Adds a room type to app @param identifier An identifier to the room type. If a real room, MUST BE the same of `db.rocketchat_room.t` field, if not, can be null @param order Order number of the type @@ -34,7 +45,7 @@ RocketChat.roomTypes = new class if config.route?.path? and config.route?.name? and config.route?.action? FlowRouter.route config.route.path, name: config.route.name - action: config.route.action + action: protectedAction config triggersExit: [roomExit] ### diff --git a/packages/rocketchat-livechat/client/ui.js b/packages/rocketchat-livechat/client/ui.js index c5a58fe2b411..823f9e46ecb2 100644 --- a/packages/rocketchat-livechat/client/ui.js +++ b/packages/rocketchat-livechat/client/ui.js @@ -9,10 +9,29 @@ RocketChat.roomTypes.add('l', 5, { openRoom('l', params.name); }, link: (sub) => { - return { name: sub.name } + return { + name: sub.name + } } }, - permissions: [ 'view-l-room' ] + permissions: ['view-l-room'] }); -AccountBox.addOption({ name: 'Livechat', icon: 'icon-chat-empty', class: 'livechat-manager', roles: ['livechat-manager'] }); +AccountBox.addItem({ + name: 'Livechat', + icon: 'icon-chat-empty', + class: 'livechat-manager', + route: { + name: 'livechat-manager', + path: '/livechat-manager', + action(params, queryParams) { + Session.set('openedRoom'); + BlazeLayout.render('main', { + center: 'page-container', + pageTitle: 'Live Chat Manager', + pageTemplate: 'livechat-manager' + }); + } + }, + permissions: ['view-livechat-manager'] +}); diff --git a/packages/rocketchat-livechat/client/views/app/livechat-manager.html b/packages/rocketchat-livechat/client/views/app/livechat-manager.html new file mode 100644 index 000000000000..75e0725e6962 --- /dev/null +++ b/packages/rocketchat-livechat/client/views/app/livechat-manager.html @@ -0,0 +1,4 @@ + diff --git a/packages/rocketchat-livechat/package.js b/packages/rocketchat-livechat/package.js index ca8eb3627d0b..049d7317e8cb 100644 --- a/packages/rocketchat-livechat/package.js +++ b/packages/rocketchat-livechat/package.js @@ -35,6 +35,8 @@ Package.onUse(function(api) { api.addFiles('client/ui.js', 'client'); api.addFiles('client/route.js', 'client'); + + api.addFiles('client/views/app/livechat-manager.html', 'client'); api.addFiles('client/views/sideNav/livechat.html', 'client'); api.addFiles('client/views/sideNav/livechat.js', 'client'); diff --git a/packages/rocketchat-livechat/permissions.js b/packages/rocketchat-livechat/permissions.js index 0239df4a1e2c..3bb956726892 100644 --- a/packages/rocketchat-livechat/permissions.js +++ b/packages/rocketchat-livechat/permissions.js @@ -8,5 +8,6 @@ Meteor.startup(() => { } if (RocketChat.models && RocketChat.models.Permissions) { RocketChat.models.Permissions.createOrUpdate('view-l-room', ['livechat-agent', 'livechat-manager']); + RocketChat.models.Permissions.createOrUpdate('view-livechat-manager', ['livechat-manager']); } }); diff --git a/packages/rocketchat-theme/assets/stylesheets/base.less b/packages/rocketchat-theme/assets/stylesheets/base.less index c8a913a1aa36..b98b198610ff 100644 --- a/packages/rocketchat-theme/assets/stylesheets/base.less +++ b/packages/rocketchat-theme/assets/stylesheets/base.less @@ -460,6 +460,15 @@ input.search { } } +form.inline { + input[type='text'], + input[type='number'], + input[type='email'], + input[type='password'] { + width: auto; + } +} + .search-form { position: relative; } diff --git a/packages/rocketchat-ui-sidenav/side-nav/sideNav.coffee b/packages/rocketchat-ui-sidenav/side-nav/sideNav.coffee index 7c9d2574f8a5..227023ce43f8 100644 --- a/packages/rocketchat-ui-sidenav/side-nav/sideNav.coffee +++ b/packages/rocketchat-ui-sidenav/side-nav/sideNav.coffee @@ -36,7 +36,10 @@ Template.sideNav.helpers return RocketChat.authz.hasAtLeastOnePermission( ['view-statistics', 'view-room-administration', 'view-user-administration', 'view-privileged-setting']) registeredMenus: -> - return AccountBox.getOptions() + return AccountBox.getItems() + + itemPath: -> + FlowRouter.path @route.name Template.sideNav.events 'click .close-flex': -> diff --git a/packages/rocketchat-ui-sidenav/side-nav/sideNav.html b/packages/rocketchat-ui-sidenav/side-nav/sideNav.html index 605c277d14e0..69de45698bd6 100644 --- a/packages/rocketchat-ui-sidenav/side-nav/sideNav.html +++ b/packages/rocketchat-ui-sidenav/side-nav/sideNav.html @@ -21,7 +21,7 @@

{{username}}

{{_ "Invisible"}} {{_ "My_Account"}} {{#each registeredMenus}} - {{name}} + {{name}} {{/each}} {{#if showAdminOption }} {{_ "Administration"}} diff --git a/packages/rocketchat-ui/lib/accountBox.coffee b/packages/rocketchat-ui/lib/accountBox.coffee index c575f1760f7d..ee12f6afec5f 100644 --- a/packages/rocketchat-ui/lib/accountBox.coffee +++ b/packages/rocketchat-ui/lib/accountBox.coffee @@ -1,7 +1,7 @@ @AccountBox = (-> status = 0 self = {} - options = new ReactiveVar [] + items = new ReactiveVar [] setStatus = (status) -> Meteor.call('UserPresence:setDefaultStatus', status) @@ -28,22 +28,38 @@ self.box = $(".account-box") self.options = self.box.find(".options") + protectedAction = (item) -> + if not item.permissions? or RocketChat.authz.hasAllPermission item.permissions + return item.route.action + + return -> + BlazeLayout.render 'main', + center: 'pageContainer' + # @TODO text Not_authorized don't get the correct language + pageTitle: t('Not_authorized') + pageTemplate: 'notAuthorized' + ### # @param newOption: - # name: Button label - # icon: Button icon - # class: Class of item - # roles: Which roles see this options + # name: Button label + # icon: Button icon + # class: Class of the item + # permissions: Which permissions a user should have (all of them) to see this item ### - addOption = (newOption) -> + addItem = (newItem) -> Tracker.nonreactive -> - actual = options.get() - actual.push newOption - options.set actual + actual = items.get() + actual.push newItem + items.set actual - getOptions = -> - return _.filter options.get(), (option) -> - if not option.roles? or RocketChat.authz.hasRole(Meteor.userId(), option.roles) + if newItem.route?.path? and newItem.route?.name? and newItem.route?.action? + FlowRouter.route newItem.route.path, + name: newItem.route.name + action: protectedAction newItem + + getItems = -> + return _.filter items.get(), (item) -> + if not item.permissions? or RocketChat.authz.hasAllPermission item.permissions return true setStatus: setStatus @@ -51,6 +67,7 @@ open: open close: close init: init - addOption: addOption - getOptions: getOptions + + addItem: addItem + getItems: getItems )() diff --git a/packages/rocketchat-ui/package.js b/packages/rocketchat-ui/package.js index 34ddea1afb05..97aa9cda8346 100644 --- a/packages/rocketchat-ui/package.js +++ b/packages/rocketchat-ui/package.js @@ -28,6 +28,8 @@ Package.onUse(function(api) { 'raix:ui-dropped-event' ]); + api.use('kadira:flow-router', 'client'); + // LIB FILES api.addFiles('lib/accountBox.coffee', 'client'); api.addFiles('lib/accounts.coffee', 'client'); @@ -74,6 +76,8 @@ Package.onUse(function(api) { api.addFiles('views/app/audioNotification.html', 'client'); api.addFiles('views/app/burguer.html', 'client'); api.addFiles('views/app/home.html', 'client'); + api.addFiles('views/app/notAuthorized.html', 'client'); + api.addFiles('views/app/pageContainer.html', 'client'); api.addFiles('views/app/privateHistory.html', 'client'); api.addFiles('views/app/room.html', 'client'); api.addFiles('views/app/roomSearch.html', 'client'); diff --git a/packages/rocketchat-ui/views/app/notAuthorized.html b/packages/rocketchat-ui/views/app/notAuthorized.html new file mode 100644 index 000000000000..9d4c6db2bf51 --- /dev/null +++ b/packages/rocketchat-ui/views/app/notAuthorized.html @@ -0,0 +1,3 @@ + diff --git a/packages/rocketchat-ui/views/app/pageContainer.html b/packages/rocketchat-ui/views/app/pageContainer.html new file mode 100644 index 000000000000..7c8af10e1c4d --- /dev/null +++ b/packages/rocketchat-ui/views/app/pageContainer.html @@ -0,0 +1,13 @@ +