Skip to content
Snippets Groups Projects
Commit 6e51f5b3 authored by Gabriel Engel's avatar Gabriel Engel
Browse files

Merge branch 'develop'

* develop: (103 commits)
  Tokenize message on message render to prevent re processing
  using branding image from main app
  Remove unecessary logs
  Do not load all settings to process.env
  Fix preview of images in mobile
  re order settings
  code formatting
  Enforce data in body params
  Get integration name from body
  Set user role in integration update too
  Added new color variables to the theme editor
  embarrassing mistake
  make sample data into array
  fix livechat triggers not triggering
  added livechat branding
  Added infinite scroll to files list
  Allow searching for logged in user in userAutocomplete
  Added "Jump to" and infinite scroll to message search results
  Enable triggers in messages to users
  Rename integration api routes, add apis remove, info and sample
  ...
parents c6cc6153 07a22635
No related branches found
No related tags found
No related merge requests found
Showing
with 347 additions and 50 deletions
......@@ -66,3 +66,4 @@ tramp
ecosystem.json
pm2.json
settings.json
build.sh
......@@ -41,6 +41,7 @@ rocketchat:lib
rocketchat:authorization
rocketchat:autolinker
rocketchat:channel-settings
rocketchat:channel-settings-mail-messages
rocketchat:colors
rocketchat:custom-oauth
rocketchat:emojione
......
......@@ -7,7 +7,7 @@ accounts-oauth@1.1.8
accounts-password@1.1.4
accounts-twitter@1.0.6
alanning:roles@1.2.14
aldeed:simple-schema@1.5.1
aldeed:simple-schema@1.5.2
arunoda:streams@0.1.17
autoupdate@1.2.4
babel-compiler@5.8.24_1
......@@ -25,7 +25,7 @@ cfs:http-methods@0.0.30
check@1.1.0
chrismbeckett:toastr@2.1.2_1
coffeescript@1.0.11
cosmos:browserify@0.9.2
cosmos:browserify@0.9.3
dandv:caret-position@2.1.1
ddp@1.2.2
ddp-client@1.2.1
......@@ -39,7 +39,7 @@ ecmascript@0.1.6
ecmascript-runtime@0.2.6
ejson@1.0.7
email@1.0.8
emojione:emojione@1.5.2
emojione:emojione@2.0.0
facebook@1.2.2
fastclick@1.0.7
francocatena:status@1.5.0
......@@ -75,7 +75,7 @@ livedata@1.0.15
localstorage@1.0.5
logging@1.0.8
matb33:collection-hooks@0.8.1
mdg:validation-error@0.1.0
mdg:validation-error@0.2.0
meteor@1.1.10
meteor-base@1.0.1
meteor-developer@1.1.5
......@@ -125,6 +125,7 @@ rocketchat:assets@0.0.1
rocketchat:authorization@0.0.1
rocketchat:autolinker@0.0.1
rocketchat:channel-settings@0.0.1
rocketchat:channel-settings-mail-messages@0.0.1
rocketchat:colors@0.0.1
rocketchat:cors@0.0.1
rocketchat:custom-oauth@1.0.0
......
......@@ -16,7 +16,7 @@ RUN gpg --keyserver ha.pool.sks-keyservers.net --recv-keys 0E163286C20D07B9787EB
WORKDIR /app
RUN curl -fSL "https://s3.amazonaws.com/rocketchatbuild/develop.rocket.chat-v.latest.tgz" -o rocket.chat.tgz \
RUN curl -fSL "https://s3.amazonaws.com/rocketchatbuild/rocket.chat-develop.tgz" -o rocket.chat.tgz \
&& tar zxvf ./rocket.chat.tgz \
&& rm ./rocket.chat.tgz \
&& cd /app/bundle/programs/server \
......
Meteor.methods
saveRoomName: (rid, name) ->
if not Meteor.userId()
throw new Meteor.Error 203, t('User_logged_out')
room = ChatRoom.findOne rid
if room.u._id isnt Meteor.userId() or room.t not in ['c', 'p']
throw new Meteor.Error 403, t('Not allowed')
if RocketChat.settings.get 'UTF8_Names_Slugify'
name = _.slugify name
if name is room.name
return
ChatRoom.update rid,
$set:
name: name
ChatSubscription.update
rid: rid
,
$set:
name: name
return name
......@@ -10,7 +10,7 @@ Meteor.startup ->
window.lastMessageWindow = {}
window.lastMessageWindowHistory = {}
@defaultUserLanguage = ->
@defaultAppLanguage = ->
lng = window.navigator.userLanguage || window.navigator.language || 'en'
# Fix browsers having all-lowercase language settings eg. pt-br, en-us
re = /([a-z]{2}-)([a-z]{2})/
......@@ -18,6 +18,9 @@ Meteor.startup ->
lng = lng.replace re, (match, parts...) -> return parts[0] + parts[1].toUpperCase()
return lng
@defaultUserLanguage = ->
return RocketChat.settings.get('Language') || defaultAppLanguage()
loadedLaguages = []
setLanguage = (language) ->
......@@ -35,17 +38,14 @@ Meteor.startup ->
Function(localeFn)()
moment.locale(language)
Tracker.autorun (c) ->
if Meteor.user()?.language?
c.stop()
if localStorage.getItem('userLanguage') isnt Meteor.user().language
localStorage.setItem("userLanguage", Meteor.user().language)
setLanguage Meteor.user().language
if isRtl localStorage.getItem "userLanguage"
$('html').addClass "rtl"
Meteor.subscribe("userData", () ->
userLanguage = Meteor.user()?.language
userLanguage ?= defaultUserLanguage()
userLanguage = localStorage.getItem("userLanguage")
userLanguage ?= defaultUserLanguage()
if localStorage.getItem('userLanguage') isnt userLanguage
localStorage.setItem('userLanguage', userLanguage)
if isRtl localStorage.getItem 'userLanguage'
$('html').addClass "rtl"
setLanguage userLanguage
setLanguage userLanguage
)
File moved
......@@ -76,6 +76,7 @@
"API_Embed" : "Embed",
"API_EmbedDisabledFor" : "Disable Embed for Users",
"API_EmbedDisabledFor_Description" : "Comma-separated list of usernames",
"Archive" : "Archive",
"are_also_typing" : "are also typing",
"are_typing" : "are typing",
"Are_you_sure" : "Are you sure?",
......@@ -139,6 +140,8 @@
"Disable_New_Room_Notification" : "Disable New Room Notification",
"Do_you_want_to_change_to_s_question" : "Do you want to change to <strong>%s</strong>?",
"Drop_to_upload_file" : "Drop to upload file",
"Duplicate_archived_channel_name" : "An archived Channel with name '%s' exists",
"Duplicate_archived_private_group_name" : "An archived Private Group with name '%s' exists",
"Duplicate_channel_name" : "A Channel with name '%s' exists",
"Duplicate_private_group_name" : "A Private Group with name '%s' exists",
"E-mail" : "E-mail",
......@@ -200,6 +203,7 @@
"Invalid_name" : "The name must not be empty",
"Invalid_pass" : "The password must not be empty",
"Invalid_room_name" : "<strong>%s</strong> is not a valid room name,<br/> use only letters, numbers and dashes",
"Invalid_room_type" : "<strong>%s</strong> is not a valid room type.",
"Invalid_Secret_URL" : "Invalid Secret URL",
"Invalid_secret_URL_message" : "The URL provided is invalid.",
"invisible" : "invisible",
......@@ -216,8 +220,8 @@
"italics" : "italics",
"join" : "Join",
"Join_the_Community" : "Join the Community",
"Jump_to_recent_messages" : "Jump to recent messages",
"Jump_to_message" : "Jump to message",
"Jump_to_recent_messages" : "Jump to recent messages",
"Language" : "Language",
"Language_Version" : "English Version",
"Last_login" : "Last login",
......@@ -314,6 +318,7 @@
"No_groups_yet" : "You have no private groups yet.",
"No_livechats" : "You have no livechats.",
"No_permission_to_view_room" : "You don't have permission to view this room",
"No_results_found" : "No results found",
"no_tokens_for_this_user" : "There are no tokens for this user",
"No_user_with_username_%s_was_found" : "No user with username <strong>\"%s\"</strong> was found!",
"Not_allowed" : "Not allowed",
......@@ -382,10 +387,12 @@
"Restart" : "Restart",
"Restart_the_server" : "Restart the server",
"Room" : "Room",
"Room_archived" : "Room archived",
"Room_has_been_deleted" : "Room has been deleted",
"Room_name_changed" : "Room name changed to: <em>__room_name__</em> by <em>__user_by__</em>",
"Room_name_changed_successfully" : "Room name changed successfully",
"Room_not_found" : "Room not found",
"Room_unarchived" : "Room unarchived",
"Room_uploaded_file_list" : "Files List",
"Room_uploaded_file_list_empty" : "No files available.",
"room_user_count" : "%s users",
......@@ -425,6 +432,7 @@
"Settings_updated" : "Settings updated",
"Should_be_a_URL_of_an_image" : "Should be a URL of an image.",
"Should_exists_a_user_with_this_username" : "The user must already exist.",
"Showing_archived_results" : "<p>Showing <b>%s</b> archived results</p>",
"Showing_online_users" : "Showing <b>__total_online__</b> of __total__ users",
"Showing_results" : "<p>Showing <b>%s</b> results</p>",
"Silence" : "Silence",
......@@ -476,6 +484,7 @@
"There_is_no_integrations" : "There is no integrations",
"This_is_a_push_test_messsage" : "This is a push test messsage",
"True" : "True",
"Unarchive" : "Unarchive",
"Unmute_user" : "Unmute user",
"Unnamed" : "Unnamed",
"Unread_Rooms" : "Unread Rooms",
......@@ -547,4 +556,4 @@
"Your_entry_has_been_deleted" : "Your entry has been deleted.",
"Your_Open_Source_solution" : "Your own Open Source chat solution",
"Your_push_was_sent_to_s_devices" : "Your push was sent to %s devices"
}
\ No newline at end of file
}
......@@ -8,7 +8,7 @@ if [ "$1" == "development" ]; then
fi
cd $ROOTPATH
curl -fSL "https://s3.amazonaws.com/rocketchatbuild/demo.rocket.chat-v.latest.tgz" -o rocket.chat.tgz
curl -fSL "https://s3.amazonaws.com/rocketchatbuild/rocket.chat-develop.tgz" -o rocket.chat.tgz
tar zxf rocket.chat.tgz && rm rocket.chat.tgz
cd $ROOTPATH/bundle/programs/server
npm install
......
......@@ -73,6 +73,10 @@ if UploadFS?
uid = cookie.get('rc_uid', rawCookies) if rawCookies?
token = cookie.get('rc_token', rawCookies) if rawCookies?
if not uid?
uid = req.query.rc_uid
token = req.query.rc_token
unless uid and token and RocketChat.models.Users.findOneByIdAndLoginToken(uid, token)
res.writeHead 403
return false
......
......@@ -27,6 +27,9 @@ Meteor.startup ->
{ _id: 'edit-other-user-info',
roles : ['admin']}
{ _id: 'edit-other-user-password',
roles : ['admin']}
{ _id: 'assign-admin-role',
roles : ['admin']}
......@@ -100,14 +103,14 @@ Meteor.startup ->
roles : ['admin']}
{ _id: 'manage-integrations',
roles : ['admin']}
roles : ['admin', 'bot']}
]
#alanning:roles
roles = _.pluck(Roles.getAllRoles().fetch(), 'name');
for permission in permissions
RocketChat.models.Permissions.upsert( permission._id, {$setOnInsert : permission })
RocketChat.models.Permissions.upsert( permission._id, {$set: permission })
for role in permission.roles
unless role in roles
Roles.createRole role
......
Meteor.startup ->
RocketChat.ChannelSettings.addOption
id: 'mail-messages'
template: 'channelSettingsMailMessages'
validation: ->
return RocketChat.authz.hasAllPermission('mail-messages')
RocketChat.callbacks.add 'roomExit', (mainNode) ->
messagesBox = $('.messages-box')
if messagesBox.get(0)?
instance = Blaze.getView(messagesBox.get(0))?.templateInstance()
instance?.resetSelection(false)
, RocketChat.callbacks.priority.MEDIUM, 'room-exit-mail-messages'
.flex-tab {
.mail-message {
form {
margin-top: 20px;
.input-line.double-col {
margin-bottom: 20px;
label {
line-height: 15px;
}
div {
line-height: 15px;
i.octicon {
font-size: 13px;
opacity: 0.4;
vertical-align: top;
}
}
}
}
}
}
Template.channelSettingsMailMessages.events
'click button.mail-messages': (e, t) ->
Session.set 'channelSettingsMailMessages', Session.get('openedRoom')
RocketChat.TabBar.setTemplate('mailMessagesInstructions')
view = Blaze.getView($('.messages-box')[0])
view?.templateInstance?().resetSelection?(true)
Template.channelSettingsMailMessages.onCreated ->
view = Blaze.getView($('.messages-box')[0])
view?.templateInstance?().resetSelection?(false)
<template name="channelSettingsMailMessages">
<li>
<label>{{_ "Mail_Messages"}}</label>
<div>
<button type="button" class="button primary mail-messages">{{_ "Choose_messages"}}</button>
</div>
</li>
</template>
Template.mailMessagesInstructions.helpers
name: ->
return Meteor.user().name
email: ->
return Meteor.user().emails?[0]?.address
roomName: ->
return ChatRoom.findOne(Session.get('openedRoom'))?.name
erroredEmails: ->
return Template.instance()?.erroredEmails.get().join(', ')
autocompleteSettings: ->
return {
limit: 10
# inputDelay: 300
rules: [
{
# @TODO maybe change this 'collection' and/or template
collection: 'CachedChannelList'
subscription: 'userAutocomplete'
field: 'username'
template: Template.userSearch
noMatchTemplate: Template.userSearchEmpty
matchAll: true
filter:
exceptions: Template.instance().selectedUsers.get()
selector: (match) ->
return { username: match }
sort: 'username'
}
]
}
selectedUsers: ->
return Template.instance().selectedUsers.get()
Template.mailMessagesInstructions.events
'click .cancel': (e, t) ->
t.reset()
'click .send': (e, t) ->
t.$('.error').hide()
$btn = t.$('button.send')
oldBtnValue = $btn.html()
$btn.html(TAPi18n.__('Sending'))
selectedMessages = $('.messages-box .message.selected')
error = false
if selectedMessages.length is 0
t.$('.error-select').show()
error = true
if t.$('input[name=to_emails]').val().trim()
rfcMailPatternWithName = /^(?:.*<)?([a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)(?:>?)$/
emails = t.$('input[name=to_emails]').val().trim().split(',')
erroredEmails = []
for email in emails
unless rfcMailPatternWithName.test email.trim()
erroredEmails.push email.trim()
t.erroredEmails.set erroredEmails
if erroredEmails.length > 0
t.$('.error-invalid-emails').show()
error = true
else if not t.selectedUsers.get().length
t.$('.error-missing-to').show()
error = true
if error
$btn.html(oldBtnValue)
else
data =
rid: Session.get('openedRoom')
to_users: t.selectedUsers.get()
to_emails: t.$('input[name=to_emails]').val().trim()
subject: t.$('input[name=subject]').val().trim()
messages: selectedMessages.map((i, message) -> return message.id).toArray()
language: localStorage.getItem('userLanguage')
Meteor.call 'mailMessages', data, (err, result) ->
$btn.html(oldBtnValue)
if err?
return toastr.error(err.reason or err.message)
console.log(result)
toastr.success(TAPi18n.__('Your_email_has_been_queued_for_sending'))
t.reset()
'click .select-all': (e, t) ->
t.$('.error-select').hide()
view = Blaze.getView($('.messages-box')[0])
view?.templateInstance?().selectedMessages = _.pluck(ChatMessage.find({rid: Session.get('openedRoom')})?.fetch(), '_id')
$(".messages-box .message").addClass('selected')
'autocompleteselect #to_users': (event, instance, doc) ->
instance.selectedUsers.set instance.selectedUsers.get().concat doc.username
event.currentTarget.value = ''
event.currentTarget.focus()
'click .remove-to-user': (e, instance) ->
self = @
users = Template.instance().selectedUsers.get()
users = _.reject Template.instance().selectedUsers.get(), (_id) ->
return _id is self.valueOf()
Template.instance().selectedUsers.set(users)
$('#to_users').focus()
Template.mailMessagesInstructions.onCreated ->
@autoCompleteCollection = new Mongo.Collection null
@selectedUsers = new ReactiveVar []
@erroredEmails = new ReactiveVar []
@reset = =>
@selectedUsers.set []
RocketChat.TabBar.setTemplate('channelSettings')
view = Blaze.getView($('.messages-box')[0])
view?.templateInstance?().resetSelection?(false)
@autorun =>
if Session.get('channelSettingsMailMessages') isnt Session.get('openedRoom')
this.reset()
<template name="mailMessagesInstructions">
<div class="content">
<div class="list-view mail-message">
<div class="status">
<h2>{{_ "Mail_Messages"}}</h2>
</div>
<p>{{_ "Mail_Messages_Instructions"}}</p>
<form>
<fieldset>
<div class="input-line double-col">
<label>{{_ "From"}}</label>
<div>{{name}}</div>
<div>{{email}}</div>
</div>
<div class="input-line double-col">
<label>{{_ "To_users"}}</label>
<div>
{{> inputAutocomplete settings=autocompleteSettings id="to_users" name="to_users" class="search" autocomplete="off"}}
<ul class="selected-users">
{{#each selectedUsers}}
<li>{{.}} <i class="icon-cancel remove-to-user"></i></li>
{{/each}}
</ul>
</div>
</div>
<div class="input-line double-col">
<label>{{_ "Additional_emails"}}</label>
<div>
<input type="text" name="to_emails" value="" />
</div>
</div>
<div class="input-line double-col">
<label>{{_ "Subject"}}</label>
<div>
<input type="text" name="subject" value="{{_ "Mail_Messages_Subject" roomName}}" />
</div>
</div>
</fieldset>
</form>
<div class="error error-missing-to alert alert-danger" style="display: none">
{{_ "Mail_Message_Missing_to"}}
</div>
<div class="error error-invalid-emails alert alert-danger" style="display: none">
{{_ "Mail_Message_Invalid_emails" erroredEmails}}
</div>
<div class="error error-select alert alert-danger" style="display: none">
{{{_ "Mail_Message_No_messages_selected_select_all"}}}
</div>
<p style="margin-top: 30px">
<button type="button" class="button secondary cancel">{{_ "Cancel"}}</button>
<button type="button" class="button primary send">{{_ "Send"}}</button>
</p>
</div>
</div>
</template>
{
"Additional_emails" : "Additional E-mails",
"Body" : "Body",
"Cancel" : "Cancel",
"Choose_messages" : "Choose messages",
"From" : "From",
"Mail_Message_Invalid_emails" : "You have provided one or more invalid e-mails: %s",
"Mail_Message_Missing_to" : "You must select one or more users or provide one or more e-mail addresses, separated by commas.",
"Mail_Message_No_messages_selected_select_all" : "You haven't selected any messages. Would you like to <a href='#' class='select-all'>select all</a> visible messages?",
"Mail_Messages" : "Mail Messages",
"Mail_Messages_Instructions" : "Choose which messages you want to send via e-mail by clicking the messages",
"Mail_Messages_Subject" : "Here's a selected portion of %s messages",
"Send" : "Send",
"Sending" : "Sending...",
"Subject" : "Subject",
"To_users" : "To Users",
"Your_email_has_been_queued_for_sending" : "Your email has been queued for sending"
}
Package.describe({
name: 'rocketchat:channel-settings-mail-messages',
version: '0.0.1',
summary: 'Channel Settings - Mail Messages',
git: ''
});
Package.onUse(function(api) {
api.versionsFrom('1.0');
api.use([
'coffeescript',
'templating',
'reactive-var',
'less@2.5.0',
'rocketchat:lib@0.0.1',
'rocketchat:channel-settings',
'momentjs:moment'
]);
api.addFiles([
'client/lib/startup.coffee',
'client/stylesheets/mail-messages.less',
'client/views/channelSettingsMailMessages.html',
'client/views/channelSettingsMailMessages.coffee',
'client/views/mailMessagesInstructions.html',
'client/views/mailMessagesInstructions.coffee'
], 'client');
api.addFiles([
'server/lib/startup.coffee',
'server/methods/mailMessages.coffee'
], 'server');
// TAPi18n
var _ = Npm.require('underscore');
var fs = Npm.require('fs');
tapi18nFiles = _.compact(_.map(fs.readdirSync('packages/rocketchat-channel-settings-mail-messages/i18n'), function(filename) {
if (fs.statSync('packages/rocketchat-channel-settings-mail-messages/i18n/' + filename).size > 16) {
return 'i18n/' + filename;
}
}));
api.use('tap:i18n@1.6.1');
api.imply('tap:i18n');
api.addFiles(tapi18nFiles);
});
Package.onTest(function(api) {
});
Meteor.startup ->
permission = { _id: 'mail-messages', roles : [ 'admin' ] }
RocketChat.models.Permissions.upsert( permission._id, { $setOnInsert : permission })
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment