diff --git a/.eslintignore b/.eslintignore
index 03b1ad39e1a6..984ba1d5dc35 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -5,7 +5,7 @@ packages/meteor-timesync/
packages/rocketchat-emoji-emojione/generateEmojiIndex.js
packages/rocketchat-favico/favico.js
packages/rocketchat-katex/client/katex/katex.min.js
-packages/rocketchat-livechat/app/node_modules
+packages/rocketchat-livechat/.app/node_modules
packages/rocketchat-livechat/assets/rocketchat-livechat.min.js
packages/rocketchat-livechat/assets/rocket-livechat.js
packages/rocketchat-migrations/
diff --git a/.travis.yml b/.travis.yml
index 49f5d7d3972d..fb956d945ea3 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -32,8 +32,8 @@ cache:
- "$HOME/build/RocketChat/Rocket.Chat/node_modules"
- "$HOME/build/RocketChat/Rocket.Chat/.meteor/local"
- "$HOME/build/RocketChat/Rocket.Chat/packages/rocketchat-livechat/.npm"
- - "$HOME/build/RocketChat/Rocket.Chat/packages/rocketchat-livechat/app/node_modules"
- - "$HOME/build/RocketChat/Rocket.Chat/packages/rocketchat-livechat/app/.meteor/local"
+ - "$HOME/build/RocketChat/Rocket.Chat/packages/rocketchat-livechat/.app/node_modules"
+ - "$HOME/build/RocketChat/Rocket.Chat/packages/rocketchat-livechat/.app/.meteor/local"
before_install:
- if [ ! -e "$HOME/.meteor/meteor" ]; then curl https://install.meteor.com | sed s/--progress-bar/-sL/g | /bin/sh; fi
# Start X Virtual Frame Buffer for headless testing with real browsers
diff --git a/package-lock.json b/package-lock.json
index 20b6c455da7d..9cd72042cbdc 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -7167,7 +7167,7 @@
"postcss-custom-properties": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-6.2.0.tgz",
- "integrity": "sha512-eNR2h9T9ciKMoQEORrPjH33XeN/nuvVuxArOKmHtsFbGbNss631tgTrKou3/pmjAZbA4QQkhLIkPQkIk3WW+8w==",
+ "integrity": "sha1-XZKafwbpuE4PETNBlMC6mjCs++k=",
"dev": true,
"requires": {
"balanced-match": "1.0.0",
diff --git a/packages/rocketchat-authorization/server/functions/canAccessRoom.js b/packages/rocketchat-authorization/server/functions/canAccessRoom.js
index 82a6b761c1bb..31a6e17674de 100644
--- a/packages/rocketchat-authorization/server/functions/canAccessRoom.js
+++ b/packages/rocketchat-authorization/server/functions/canAccessRoom.js
@@ -17,9 +17,9 @@ RocketChat.authz.roomAccessValidators = [
}
];
-RocketChat.authz.canAccessRoom = function(room, user) {
+RocketChat.authz.canAccessRoom = function(room, user, extraData) {
return RocketChat.authz.roomAccessValidators.some((validator) => {
- return validator.call(this, room, user);
+ return validator.call(this, room, user, extraData);
});
};
diff --git a/packages/rocketchat-i18n/i18n/en.i18n.json b/packages/rocketchat-i18n/i18n/en.i18n.json
index 3738e834d63b..75188fe03472 100644
--- a/packages/rocketchat-i18n/i18n/en.i18n.json
+++ b/packages/rocketchat-i18n/i18n/en.i18n.json
@@ -1061,6 +1061,8 @@
"LDAP_Username_Field": "Username Field",
"LDAP_Username_Field_Description": "Which field will be used as *username* for new users. Leave empty to use the username informed on login page.
You can use template tags too, like `#{givenName}.#{sn}`.
Default value is `sAMAccountName`.",
"Execute_Synchronization_Now": "Execute Synchronization Now",
+ "Lead_capture_email_regex": "Lead capture email regex",
+ "Lead_capture_phone_regex": "Lead capture phone regex",
"Least_Amount": "Least Amount",
"Leave_Group_Warning": "Are you sure you want to leave the group \"%s\"?",
"Leave_Livechat_Warning": "Are you sure you want to leave the livechat with \"%s\"?",
@@ -1587,6 +1589,7 @@
"Send_invitation_email_info": "You can send multiple email invitations at once.",
"Send_invitation_email_success": "You have successfully sent an invitation email to the following addresses:",
"Send_request_on_chat_close": "Send Request on Chat Close",
+ "Send_request_on_lead_capture": "Send request on lead capture",
"Send_request_on_offline_messages": "Send Request on Offline Messages",
"Send_Test": "Send Test",
"Send_welcome_email": "Send welcome email",
@@ -2058,4 +2061,4 @@
"your_message_optional": "your message (optional)",
"Your_password_is_wrong": "Your password is wrong!",
"Your_push_was_sent_to_s_devices": "Your push was sent to %s devices"
-}
\ No newline at end of file
+}
diff --git a/packages/rocketchat-lib/package.js b/packages/rocketchat-lib/package.js
index d7eedb158ad6..48c4c7217eae 100644
--- a/packages/rocketchat-lib/package.js
+++ b/packages/rocketchat-lib/package.js
@@ -97,6 +97,7 @@ Package.onUse(function(api) {
api.addFiles('server/functions/deleteUser.js', 'server');
api.addFiles('server/functions/getFullUserData.js', 'server');
api.addFiles('server/functions/getRoomByNameOrIdWithOptionToJoin.js', 'server');
+ api.addFiles('server/functions/loadMessageHistory.js', 'server');
api.addFiles('server/functions/removeUserFromRoom.js', 'server');
api.addFiles('server/functions/saveUser.js', 'server');
api.addFiles('server/functions/saveCustomFields.js', 'server');
diff --git a/packages/rocketchat-lib/server/functions/Notifications.js b/packages/rocketchat-lib/server/functions/Notifications.js
index 1ebd77f6e8d9..808d0b8bb902 100644
--- a/packages/rocketchat-lib/server/functions/Notifications.js
+++ b/packages/rocketchat-lib/server/functions/Notifications.js
@@ -25,10 +25,7 @@ RocketChat.Notifications = new class {
this.streamUser.allowWrite('logged');
this.streamAll.allowRead('all');
this.streamLogged.allowRead('logged');
- this.streamRoom.allowRead(function(eventName) {
- if (this.userId == null) {
- return false;
- }
+ this.streamRoom.allowRead(function(eventName, extraData) {
const [roomId] = eventName.split('/');
const user = Meteor.users.findOne(this.userId, {
fields: {
@@ -40,9 +37,12 @@ RocketChat.Notifications = new class {
console.warn(`Invalid streamRoom eventName: "${ eventName }"`);
return false;
}
- if (room.t === 'l' && room.v._id === user._id) {
+ if (room.t === 'l' && extraData && extraData.token && room.v.token === extraData.token) {
return true;
}
+ if (this.userId == null) {
+ return false;
+ }
return room.usernames.indexOf(user.username) > -1;
});
this.streamRoomUsers.allowRead('none');
@@ -117,12 +117,21 @@ RocketChat.Notifications = new class {
}
};
-RocketChat.Notifications.streamRoom.allowWrite(function(eventName, username) {
- const [, e] = eventName.split('/');
+RocketChat.Notifications.streamRoom.allowWrite(function(eventName, username, typing, extraData) {
+ const [roomId, e] = eventName.split('/');
if (e === 'webrtc') {
return true;
}
if (e === 'typing') {
+
+ // typing from livechat widget
+ if (extraData && extraData.token) {
+ const room = RocketChat.models.Rooms.findOneById(roomId);
+ if (room && room.t === 'l' && room.v.token === extraData.token) {
+ return true;
+ }
+ }
+
const user = Meteor.users.findOne(this.userId, {
fields: {
username: 1
diff --git a/packages/rocketchat-lib/server/functions/loadMessageHistory.js b/packages/rocketchat-lib/server/functions/loadMessageHistory.js
new file mode 100644
index 000000000000..f09d9030353f
--- /dev/null
+++ b/packages/rocketchat-lib/server/functions/loadMessageHistory.js
@@ -0,0 +1,88 @@
+import _ from 'underscore';
+
+const hideMessagesOfType = [];
+
+RocketChat.settings.get(/Message_HideType_.+/, function(key, value) {
+ const type = key.replace('Message_HideType_', '');
+ const types = type === 'mute_unmute' ? ['user-muted', 'user-unmuted'] : [type];
+
+ return types.forEach((type) => {
+ const index = hideMessagesOfType.indexOf(type);
+
+ if (value === true && index === -1) {
+ return hideMessagesOfType.push(type);
+ }
+
+ if (index > -1) {
+ return hideMessagesOfType.splice(index, 1);
+ }
+ });
+});
+
+RocketChat.loadMessageHistory = function loadMessageHistory({ userId, rid, end, limit = 20, ls }) {
+ const options = {
+ sort: {
+ ts: -1
+ },
+ limit
+ };
+
+ if (!RocketChat.settings.get('Message_ShowEditedStatus')) {
+ options.fields = {
+ editedAt: 0
+ };
+ }
+
+ let records;
+ if (end != null) {
+ records = RocketChat.models.Messages.findVisibleByRoomIdBeforeTimestampNotContainingTypes(rid, end, hideMessagesOfType, options).fetch();
+ } else {
+ records = RocketChat.models.Messages.findVisibleByRoomIdNotContainingTypes(rid, hideMessagesOfType, options).fetch();
+ }
+
+ const UI_Use_Real_Name = RocketChat.settings.get('UI_Use_Real_Name') === true;
+
+ const messages = records.map((message) => {
+ message.starred = _.findWhere(message.starred, {
+ _id: userId
+ });
+ if (message.u && message.u._id && UI_Use_Real_Name) {
+ const user = RocketChat.models.Users.findOneById(message.u._id);
+ message.u.name = user && user.name;
+ }
+ if (message.mentions && message.mentions.length && UI_Use_Real_Name) {
+ message.mentions.forEach((mention) => {
+ const user = RocketChat.models.Users.findOneById(mention._id);
+ mention.name = user && user.name;
+ });
+ }
+ return message;
+ });
+
+ let unreadNotLoaded = 0;
+ let firstUnread;
+
+ if (ls != null) {
+ const firstMessage = messages[messages.length - 1];
+
+ if ((firstMessage != null ? firstMessage.ts : undefined) > ls) {
+ delete options.limit;
+
+ const unreadMessages = RocketChat.models.Messages.findVisibleByRoomIdBetweenTimestampsNotContainingTypes(rid, ls, firstMessage.ts, hideMessagesOfType, {
+ limit: 1,
+ sort: {
+ ts: 1
+ }
+ });
+
+ firstUnread = unreadMessages.fetch()[0];
+ unreadNotLoaded = unreadMessages.count();
+ }
+ }
+
+ return {
+ messages,
+ firstUnread,
+ unreadNotLoaded
+ };
+};
diff --git a/packages/rocketchat-lib/server/lib/sendNotificationsOnMessage.js b/packages/rocketchat-lib/server/lib/sendNotificationsOnMessage.js
index 401491bbec6e..dab8e6de7fa0 100644
--- a/packages/rocketchat-lib/server/lib/sendNotificationsOnMessage.js
+++ b/packages/rocketchat-lib/server/lib/sendNotificationsOnMessage.js
@@ -166,6 +166,11 @@ RocketChat.callbacks.add('afterSaveMessage', function(message, room, userId) {
const user = RocketChat.models.Users.findOneById(message.u._id);
+ // might be a livechat visitor
+ if (!user) {
+ return message;
+ }
+
/*
Increment unread couter if direct messages
*/
diff --git a/packages/rocketchat-livechat/app/.meteor/.finished-upgraders b/packages/rocketchat-livechat/.app/.meteor/.finished-upgraders
similarity index 100%
rename from packages/rocketchat-livechat/app/.meteor/.finished-upgraders
rename to packages/rocketchat-livechat/.app/.meteor/.finished-upgraders
diff --git a/packages/rocketchat-livechat/app/.meteor/.gitignore b/packages/rocketchat-livechat/.app/.meteor/.gitignore
similarity index 100%
rename from packages/rocketchat-livechat/app/.meteor/.gitignore
rename to packages/rocketchat-livechat/.app/.meteor/.gitignore
diff --git a/packages/rocketchat-livechat/app/.meteor/.id b/packages/rocketchat-livechat/.app/.meteor/.id
similarity index 100%
rename from packages/rocketchat-livechat/app/.meteor/.id
rename to packages/rocketchat-livechat/.app/.meteor/.id
diff --git a/packages/rocketchat-livechat/app/.meteor/packages b/packages/rocketchat-livechat/.app/.meteor/packages
similarity index 97%
rename from packages/rocketchat-livechat/app/.meteor/packages
rename to packages/rocketchat-livechat/.app/.meteor/packages
index 3735ede0dccc..f688a528da4f 100644
--- a/packages/rocketchat-livechat/app/.meteor/packages
+++ b/packages/rocketchat-livechat/.app/.meteor/packages
@@ -38,3 +38,5 @@ standard-minifier-css@1.3.5
standard-minifier-js@2.2.0
shell-server@0.3.0
dynamic-import@0.2.0
+
+konecty:user-presence
diff --git a/packages/rocketchat-livechat/app/.meteor/platforms b/packages/rocketchat-livechat/.app/.meteor/platforms
similarity index 100%
rename from packages/rocketchat-livechat/app/.meteor/platforms
rename to packages/rocketchat-livechat/.app/.meteor/platforms
diff --git a/packages/rocketchat-livechat/app/.meteor/release b/packages/rocketchat-livechat/.app/.meteor/release
similarity index 100%
rename from packages/rocketchat-livechat/app/.meteor/release
rename to packages/rocketchat-livechat/.app/.meteor/release
diff --git a/packages/rocketchat-livechat/app/.meteor/versions b/packages/rocketchat-livechat/.app/.meteor/versions
similarity index 97%
rename from packages/rocketchat-livechat/app/.meteor/versions
rename to packages/rocketchat-livechat/.app/.meteor/versions
index b421e82bb665..9de32a733006 100644
--- a/packages/rocketchat-livechat/app/.meteor/versions
+++ b/packages/rocketchat-livechat/.app/.meteor/versions
@@ -39,6 +39,7 @@ jquery@1.11.10
kadira:blaze-layout@2.3.0
kadira:flow-router@2.12.1
konecty:nrr@2.0.2
+konecty:user-presence@2.0.0
less@2.7.11
livedata@1.0.18
localstorage@1.2.0
@@ -56,6 +57,7 @@ momentjs:moment@2.20.1
mongo@1.3.1
mongo-dev-server@1.1.0
mongo-id@1.0.6
+nooitaf:colors@1.1.2_1
npm-bcrypt@0.9.3
npm-mongo@2.2.33
observe-sequence@1.0.16
diff --git a/packages/rocketchat-livechat/app/client/components/modal.html b/packages/rocketchat-livechat/.app/client/components/modal.html
similarity index 100%
rename from packages/rocketchat-livechat/app/client/components/modal.html
rename to packages/rocketchat-livechat/.app/client/components/modal.html
diff --git a/packages/rocketchat-livechat/app/client/lib/CustomFields.js b/packages/rocketchat-livechat/.app/client/lib/CustomFields.js
similarity index 89%
rename from packages/rocketchat-livechat/app/client/lib/CustomFields.js
rename to packages/rocketchat-livechat/.app/client/lib/CustomFields.js
index 4f984139c7db..36132c9aa714 100644
--- a/packages/rocketchat-livechat/app/client/lib/CustomFields.js
+++ b/packages/rocketchat-livechat/.app/client/lib/CustomFields.js
@@ -1,3 +1,5 @@
+import visitor from '../../imports/client/visitor';
+
this.CustomFields = (function() {
let queue = {};
let initiated = false;
@@ -13,7 +15,7 @@ this.CustomFields = (function() {
const init = function() {
Tracker.autorun(function() {
- if (Meteor.userId()) {
+ if (visitor.getId()) {
initiated = true;
Object.keys(queue).forEach((key) => {
setCustomField.call(this, queue[key].token, key, queue[key].value, queue[key].overwrite);
diff --git a/packages/rocketchat-livechat/app/client/lib/LivechatVideoCall.js b/packages/rocketchat-livechat/.app/client/lib/LivechatVideoCall.js
similarity index 97%
rename from packages/rocketchat-livechat/app/client/lib/LivechatVideoCall.js
rename to packages/rocketchat-livechat/.app/client/lib/LivechatVideoCall.js
index 88bdd62e0f2c..e31490bb45f0 100644
--- a/packages/rocketchat-livechat/app/client/lib/LivechatVideoCall.js
+++ b/packages/rocketchat-livechat/.app/client/lib/LivechatVideoCall.js
@@ -1,4 +1,5 @@
/* globals LivechatVideoCall, cordova, JitsiMeetExternalAPI */
+import visitor from '../../imports/client/visitor';
LivechatVideoCall = new (class LivechatVideoCall {
constructor() {
diff --git a/packages/rocketchat-livechat/app/client/lib/_livechat.js b/packages/rocketchat-livechat/.app/client/lib/_livechat.js
similarity index 93%
rename from packages/rocketchat-livechat/app/client/lib/_livechat.js
rename to packages/rocketchat-livechat/.app/client/lib/_livechat.js
index eb94f7b84974..c0185a16b436 100644
--- a/packages/rocketchat-livechat/app/client/lib/_livechat.js
+++ b/packages/rocketchat-livechat/.app/client/lib/_livechat.js
@@ -1,3 +1,5 @@
+import visitor from '../../imports/client/visitor';
+
this.Livechat = new (class Livechat {
constructor() {
this._online = new ReactiveVar(null);
@@ -30,17 +32,17 @@ this.Livechat = new (class Livechat {
this.stream = new Meteor.Streamer('livechat-room');
Tracker.autorun(() => {
- if (this._room.get() && Meteor.userId()) {
+ if (this._room.get() && visitor.getId()) {
RoomHistoryManager.getMoreIfIsEmpty(this._room.get());
visitor.subscribeToRoom(this._room.get());
visitor.setRoom(this._room.get());
- Meteor.call('livechat:getAgentData', this._room.get(), (error, result) => {
+ Meteor.call('livechat:getAgentData', { roomId: this._room.get(), token: visitor.getToken() }, (error, result) => {
if (!error) {
this._agent.set(result);
}
});
- this.stream.on(this._room.get(), (eventData) => {
+ this.stream.on(this._room.get(), { token: visitor.getToken() }, (eventData) => {
if (!eventData || !eventData.type) {
return;
}
diff --git a/packages/rocketchat-livechat/app/client/lib/autolinker.js b/packages/rocketchat-livechat/.app/client/lib/autolinker.js
similarity index 100%
rename from packages/rocketchat-livechat/app/client/lib/autolinker.js
rename to packages/rocketchat-livechat/.app/client/lib/autolinker.js
diff --git a/packages/rocketchat-livechat/app/client/lib/chatMessages.js b/packages/rocketchat-livechat/.app/client/lib/chatMessages.js
similarity index 89%
rename from packages/rocketchat-livechat/app/client/lib/chatMessages.js
rename to packages/rocketchat-livechat/.app/client/lib/chatMessages.js
index cb41d52ef9e9..664f7df344a8 100644
--- a/packages/rocketchat-livechat/app/client/lib/chatMessages.js
+++ b/packages/rocketchat-livechat/.app/client/lib/chatMessages.js
@@ -2,6 +2,7 @@
import _ from 'underscore';
import s from 'underscore.string';
import toastr from 'toastr';
+import visitor from '../../imports/client/visitor';
this.ChatMessages = class ChatMessages {
init(node) {
@@ -63,7 +64,7 @@ this.ChatMessages = class ChatMessages {
}
this.clearEditing();
const id = element.getAttribute('id');
- const message = ChatMessage.findOne({ _id: id, 'u._id': Meteor.userId() });
+ const message = ChatMessage.findOne({ _id: id, 'u._id': visitor.getId() });
this.input.value = message.msg;
this.editing.element = element;
this.editing.index = index || this.getEditingIndex(element);
@@ -122,12 +123,14 @@ this.ChatMessages = class ChatMessages {
ChatMessage.update(result._id, _.omit(result, '_id'));
Livechat.room = result.rid;
+ visitor.setConnected();
+
parentCall('callback', 'chat-started');
}
});
};
- if (!Meteor.userId()) {
+ if (!visitor.getId()) {
const guest = {
token: visitor.getToken()
};
@@ -141,13 +144,8 @@ this.ChatMessages = class ChatMessages {
return showError(error.reason);
}
- Meteor.loginWithToken(result.token, (error) => {
- if (error) {
- return showError(error.reason);
- }
-
- sendMessage();
- });
+ visitor.setId(result._id);
+ sendMessage();
});
} else {
sendMessage();
@@ -189,20 +187,6 @@ this.ChatMessages = class ChatMessages {
}
}
- tryCompletion(input) {
- let value = input.value.match(/[^\s]+$/);
- if (value && value.length > 0) {
- value = value[0];
-
- const re = new RegExp(value, 'i');
-
- const user = Meteor.users.findOne({ username: re }, { fields: { username: 1 } });
- if (user) {
- input.value = input.value.replace(value, `@${ user.username } `);
- }
- }
- }
-
keyup(rid, event) {
let i;
const input = event.currentTarget;
@@ -247,12 +231,6 @@ this.ChatMessages = class ChatMessages {
return;
}
- if (k === 9) {
- event.preventDefault();
- event.stopPropagation();
- this.tryCompletion(input);
- }
-
if (k === 27) {
if (this.editing.id) {
event.preventDefault();
diff --git a/packages/rocketchat-livechat/app/client/lib/collections.js b/packages/rocketchat-livechat/.app/client/lib/collections.js
similarity index 100%
rename from packages/rocketchat-livechat/app/client/lib/collections.js
rename to packages/rocketchat-livechat/.app/client/lib/collections.js
diff --git a/packages/rocketchat-livechat/app/client/lib/commands.js b/packages/rocketchat-livechat/.app/client/lib/commands.js
similarity index 79%
rename from packages/rocketchat-livechat/app/client/lib/commands.js
rename to packages/rocketchat-livechat/.app/client/lib/commands.js
index 57c21c2951a7..e63bc3d10bf2 100644
--- a/packages/rocketchat-livechat/app/client/lib/commands.js
+++ b/packages/rocketchat-livechat/.app/client/lib/commands.js
@@ -1,4 +1,6 @@
/* globals LivechatVideoCall, Livechat, swal */
+import visitor from '../../imports/client/visitor';
+
// Functions to call on messages of type 'command'
this.Commands = {
survey() {
@@ -13,8 +15,8 @@ this.Commands = {
promptTranscript() {
if (Livechat.transcript) {
- const user = Meteor.user();
- const email = user.visitorEmails && user.visitorEmails.length > 0 ? user.visitorEmails[0].address : '';
+ const visitorData = visitor.getData();
+ const email = visitorData && visitorData.visitorEmails && visitorData.visitorEmails.length > 0 ? visitorData.visitorEmails[0].address : '';
swal({
title: t('Chat_ended'),
@@ -38,7 +40,7 @@ this.Commands = {
swal.showInputError(t('please enter your email'));
return false;
} else {
- Meteor.call('livechat:sendTranscript', visitor.getRoom(), response, (err) => {
+ Meteor.call('livechat:sendTranscript', visitor.getToken(), visitor.getRoom(), response, (err) => {
if (err) {
console.error(err);
}
diff --git a/packages/rocketchat-livechat/app/client/lib/error.js b/packages/rocketchat-livechat/.app/client/lib/error.js
similarity index 100%
rename from packages/rocketchat-livechat/app/client/lib/error.js
rename to packages/rocketchat-livechat/.app/client/lib/error.js
diff --git a/packages/rocketchat-livechat/app/client/lib/fromApp/Notifications.js b/packages/rocketchat-livechat/.app/client/lib/fromApp/Notifications.js
similarity index 73%
rename from packages/rocketchat-livechat/app/client/lib/fromApp/Notifications.js
rename to packages/rocketchat-livechat/.app/client/lib/fromApp/Notifications.js
index 4c919a20b0d6..8acbe3d5da12 100644
--- a/packages/rocketchat-livechat/app/client/lib/fromApp/Notifications.js
+++ b/packages/rocketchat-livechat/.app/client/lib/fromApp/Notifications.js
@@ -1,12 +1,14 @@
+import visitor from '../../../imports/client/visitor';
+
this.Notifications = new class {
constructor() {
- this.logged = Meteor.userId() !== null;
+ this.logged = visitor.getId() !== null;
this.loginCb = [];
Tracker.autorun(() => {
- if (Meteor.userId() !== null && this.logged === false) {
+ if (visitor.getId() !== null && this.logged === false) {
this.loginCb.forEach(cb => cb());
}
- return this.logged = Meteor.userId() !== null;
+ return this.logged = visitor.getId() !== null;
});
this.debug = false;
this.streamAll = new Meteor.Streamer('notify-all');
@@ -45,23 +47,23 @@ this.Notifications = new class {
return this.streamUser.emit.apply(this.streamUser, args);
}
onAll(eventName, callback) {
- return this.streamAll.on(eventName, callback);
+ return this.streamAll.on(eventName, { token: visitor.getToken() }, callback);
}
onLogged(eventName, callback) {
return this.onLogin(() => {
- return this.streamLogged.on(eventName, callback);
+ return this.streamLogged.on(eventName, { token: visitor.getToken() }, callback);
});
}
onRoom(room, eventName, callback) {
if (this.debug === true) {
- this.streamRoom.on(room, function() {
+ this.streamRoom.on(room, { token: visitor.getToken() }, function() {
return console.log(`RocketChat.Notifications: onRoom ${ room }`, arguments);
});
}
- return this.streamRoom.on(`${ room }/${ eventName }`, callback);
+ return this.streamRoom.on(`${ room }/${ eventName }`, { token: visitor.getToken() }, callback);
}
onUser(eventName, callback) {
- return this.streamUser.on(`${ Meteor.userId() }/${ eventName }`, callback);
+ return this.streamUser.on(`${ visitor.getId() }/${ eventName }`, { token: visitor.getToken() }, callback);
}
unAll(callback) {
return this.streamAll.removeListener('notify', callback);
@@ -73,7 +75,7 @@ this.Notifications = new class {
return this.streamRoom.removeListener(`${ room }/${ eventName }`, callback);
}
unUser(eventName, callback) {
- return this.streamUser.removeListener(`${ Meteor.userId() }/${ eventName }`, callback);
+ return this.streamUser.removeListener(`${ visitor.getId() }/${ eventName }`, callback);
}
};
diff --git a/packages/rocketchat-livechat/app/client/lib/fromApp/RoomHistoryManager.js b/packages/rocketchat-livechat/.app/client/lib/fromApp/RoomHistoryManager.js
similarity index 97%
rename from packages/rocketchat-livechat/app/client/lib/fromApp/RoomHistoryManager.js
rename to packages/rocketchat-livechat/.app/client/lib/fromApp/RoomHistoryManager.js
index c53a671576d0..2d6ab8f92441 100644
--- a/packages/rocketchat-livechat/app/client/lib/fromApp/RoomHistoryManager.js
+++ b/packages/rocketchat-livechat/.app/client/lib/fromApp/RoomHistoryManager.js
@@ -1,4 +1,6 @@
/* globals readMessage UserRoles RoomRoles*/
+
+import visitor from '../../../imports/client/visitor';
import _ from 'underscore';
export const RoomHistoryManager = new class {
@@ -42,7 +44,7 @@ export const RoomHistoryManager = new class {
ts = new Date();
}
- Meteor.call('loadHistory', rid, ts, limit, undefined, (err, result) => {
+ Meteor.call('livechat:loadHistory', { token: visitor.getToken(), rid, ts, limit }, (err, result) => {
if (err) {
return;
}
diff --git a/packages/rocketchat-livechat/app/client/lib/fromApp/avatar.js b/packages/rocketchat-livechat/.app/client/lib/fromApp/avatar.js
similarity index 100%
rename from packages/rocketchat-livechat/app/client/lib/fromApp/avatar.js
rename to packages/rocketchat-livechat/.app/client/lib/fromApp/avatar.js
diff --git a/packages/rocketchat-livechat/app/client/lib/hooks.js b/packages/rocketchat-livechat/.app/client/lib/hooks.js
similarity index 95%
rename from packages/rocketchat-livechat/app/client/lib/hooks.js
rename to packages/rocketchat-livechat/.app/client/lib/hooks.js
index eb7a2e34c56c..3a525c34cf5d 100644
--- a/packages/rocketchat-livechat/app/client/lib/hooks.js
+++ b/packages/rocketchat-livechat/.app/client/lib/hooks.js
@@ -1,4 +1,6 @@
/* globals CustomFields, Livechat */
+import visitor from '../../imports/client/visitor';
+
const api = {
pageVisited(info) {
if (info.change === 'url') {
diff --git a/packages/rocketchat-livechat/app/client/lib/msgTyping.js b/packages/rocketchat-livechat/.app/client/lib/msgTyping.js
similarity index 79%
rename from packages/rocketchat-livechat/app/client/lib/msgTyping.js
rename to packages/rocketchat-livechat/.app/client/lib/msgTyping.js
index aa00b0ad5fe9..378af82a34aa 100644
--- a/packages/rocketchat-livechat/app/client/lib/msgTyping.js
+++ b/packages/rocketchat-livechat/.app/client/lib/msgTyping.js
@@ -1,4 +1,5 @@
/* globals Notifications */
+import visitor from '../../imports/client/visitor';
import _ from 'underscore';
export const MsgTyping = (function() {
@@ -15,7 +16,7 @@ export const MsgTyping = (function() {
return;
}
usersTyping[room] = { users: {} };
- return Notifications.onRoom(room, 'typing', function(username, typing) {
+ return Notifications.onRoom(room, 'typing', function(username, typing, extraData) {
const user = Meteor.user();
if (username === (user && user.username)) {
return;
@@ -36,7 +37,7 @@ export const MsgTyping = (function() {
};
Tracker.autorun(() => {
- if (visitor.getRoom() && Meteor.userId()) {
+ if (visitor.getRoom() && visitor.getId()) {
addStream(visitor.getRoom());
}
});
@@ -48,8 +49,8 @@ export const MsgTyping = (function() {
clearTimeout(timeouts[room]);
timeouts[room] = null;
}
- const user = Meteor.user();
- return Notifications.notifyRoom(room, 'typing', user && user.username, false);
+ const visitorData = visitor.getData();
+ return Notifications.notifyRoom(room, 'typing', visitorData && visitorData.username, false, { token: visitor.getToken() });
};
const start = function(room) {
if (!renew) { return; }
@@ -58,8 +59,8 @@ export const MsgTyping = (function() {
renew = false;
selfTyping.set(true);
- const user = Meteor.user();
- Notifications.notifyRoom(room, 'typing', user && user.username, true);
+ const visitorData = visitor.getData();
+ Notifications.notifyRoom(room, 'typing', visitorData && visitorData.username, true, { token: visitor.getToken() });
clearTimeout(timeouts[room]);
return timeouts[room] = Meteor.setTimeout(() => stop(room), timeout);
};
diff --git a/packages/rocketchat-livechat/app/client/lib/parentCall.js b/packages/rocketchat-livechat/.app/client/lib/parentCall.js
similarity index 100%
rename from packages/rocketchat-livechat/app/client/lib/parentCall.js
rename to packages/rocketchat-livechat/.app/client/lib/parentCall.js
diff --git a/packages/rocketchat-livechat/app/client/lib/tapi18n.js b/packages/rocketchat-livechat/.app/client/lib/tapi18n.js
similarity index 100%
rename from packages/rocketchat-livechat/app/client/lib/tapi18n.js
rename to packages/rocketchat-livechat/.app/client/lib/tapi18n.js
diff --git a/packages/rocketchat-livechat/app/client/lib/triggers.js b/packages/rocketchat-livechat/.app/client/lib/triggers.js
similarity index 95%
rename from packages/rocketchat-livechat/app/client/lib/triggers.js
rename to packages/rocketchat-livechat/.app/client/lib/triggers.js
index e303ef110937..72f68df99294 100644
--- a/packages/rocketchat-livechat/app/client/lib/triggers.js
+++ b/packages/rocketchat-livechat/.app/client/lib/triggers.js
@@ -1,3 +1,5 @@
+import visitor from '../../imports/client/visitor';
+
this.Triggers = (function() {
let triggers = [];
let initiated = false;
@@ -5,7 +7,7 @@ this.Triggers = (function() {
let enabled = true;
const fire = function(trigger) {
- if (!enabled || Meteor.userId()) {
+ if (!enabled || visitor.getId()) {
return;
}
trigger.actions.forEach(function(action) {
diff --git a/packages/rocketchat-livechat/app/client/methods/sendMessageExternal.js b/packages/rocketchat-livechat/.app/client/methods/sendMessageExternal.js
similarity index 86%
rename from packages/rocketchat-livechat/app/client/methods/sendMessageExternal.js
rename to packages/rocketchat-livechat/.app/client/methods/sendMessageExternal.js
index 0169a7e7bb09..8a2bdaebf2a7 100644
--- a/packages/rocketchat-livechat/app/client/methods/sendMessageExternal.js
+++ b/packages/rocketchat-livechat/.app/client/methods/sendMessageExternal.js
@@ -1,3 +1,4 @@
+import visitor from '../../imports/client/visitor';
import s from 'underscore.string';
Meteor.methods({
@@ -12,7 +13,7 @@ Meteor.methods({
const user = Meteor.user();
message.u = {
- _id: Meteor.userId(),
+ _id: visitor.getId(),
username: user && user.username || 'visitor'
};
diff --git a/packages/rocketchat-livechat/app/client/routes/router.js b/packages/rocketchat-livechat/.app/client/routes/router.js
similarity index 79%
rename from packages/rocketchat-livechat/app/client/routes/router.js
rename to packages/rocketchat-livechat/.app/client/routes/router.js
index 6762a019a5e2..9b6e69af2952 100644
--- a/packages/rocketchat-livechat/app/client/routes/router.js
+++ b/packages/rocketchat-livechat/.app/client/routes/router.js
@@ -1,3 +1,5 @@
+import visitor from '../../imports/client/visitor';
+
BlazeLayout.setRoot('body');
FlowRouter.route('/livechat', {
diff --git a/packages/rocketchat-livechat/app/client/startup/customFields.js b/packages/rocketchat-livechat/.app/client/startup/customFields.js
similarity index 100%
rename from packages/rocketchat-livechat/app/client/startup/customFields.js
rename to packages/rocketchat-livechat/.app/client/startup/customFields.js
diff --git a/packages/rocketchat-livechat/.app/client/startup/visitor.js b/packages/rocketchat-livechat/.app/client/startup/visitor.js
new file mode 100644
index 000000000000..92b723bc05fa
--- /dev/null
+++ b/packages/rocketchat-livechat/.app/client/startup/visitor.js
@@ -0,0 +1,29 @@
+import visitor from '../../imports/client/visitor';
+
+Meteor.startup(() => {
+ if (!localStorage.getItem('rocketChatLivechat')) {
+ localStorage.setItem('rocketChatLivechat', Random.id());
+ } else {
+ Tracker.autorun(c => {
+ if (!visitor.getId() && visitor.getToken()) {
+ Meteor.call('livechat:loginByToken', visitor.getToken(), (err, result) => {
+ if (result && result._id) {
+ visitor.setId(result._id);
+ c.stop();
+ }
+ });
+ }
+ });
+ }
+});
+
+Meteor.startup(() => {
+ let connected = false;
+ Tracker.autorun(function() {
+ var connectionStatus = Meteor.status();
+ if (visitor.getRoom() && visitor.getToken() && connectionStatus.connected && !connected) {
+ connected = connectionStatus.connected;
+ visitor.setConnected();
+ }
+ });
+});
diff --git a/packages/rocketchat-livechat/app/client/stylesheets/main.less b/packages/rocketchat-livechat/.app/client/stylesheets/main.less
similarity index 97%
rename from packages/rocketchat-livechat/app/client/stylesheets/main.less
rename to packages/rocketchat-livechat/.app/client/stylesheets/main.less
index afad4f334141..695ebb332081 100644
--- a/packages/rocketchat-livechat/app/client/stylesheets/main.less
+++ b/packages/rocketchat-livechat/.app/client/stylesheets/main.less
@@ -340,6 +340,10 @@ input:focus {
left: inherit;
}
}
+
+ .thumb {
+ display: none;
+ }
}
.delete-message {
@@ -443,18 +447,23 @@ input:focus {
text-decoration: line-through;
}
- .avatar .avatar-image {
+ .avatar {
height: 100%;
width: 100%;
- min-height: 20px;
- min-width: 20px;
- display: block;
- position: relative;
- background-color: transparent;
- background-size: cover;
- background-repeat: no-repeat;
- background-position: center;
- border-radius: 4px;
+
+ .avatar-image {
+ height: 100%;
+ width: 100%;
+ min-height: 20px;
+ min-width: 20px;
+ display: block;
+ position: relative;
+ background-color: transparent;
+ background-size: cover;
+ background-repeat: no-repeat;
+ background-position: center;
+ border-radius: 4px;
+ }
}
}
}
diff --git a/packages/rocketchat-livechat/app/client/stylesheets/utils/_keyframes.import.less b/packages/rocketchat-livechat/.app/client/stylesheets/utils/_keyframes.import.less
similarity index 100%
rename from packages/rocketchat-livechat/app/client/stylesheets/utils/_keyframes.import.less
rename to packages/rocketchat-livechat/.app/client/stylesheets/utils/_keyframes.import.less
diff --git a/packages/rocketchat-livechat/app/client/stylesheets/utils/_loading.import.less b/packages/rocketchat-livechat/.app/client/stylesheets/utils/_loading.import.less
similarity index 100%
rename from packages/rocketchat-livechat/app/client/stylesheets/utils/_loading.import.less
rename to packages/rocketchat-livechat/.app/client/stylesheets/utils/_loading.import.less
diff --git a/packages/rocketchat-livechat/app/client/stylesheets/utils/_reset.import.less b/packages/rocketchat-livechat/.app/client/stylesheets/utils/_reset.import.less
similarity index 100%
rename from packages/rocketchat-livechat/app/client/stylesheets/utils/_reset.import.less
rename to packages/rocketchat-livechat/.app/client/stylesheets/utils/_reset.import.less
diff --git a/packages/rocketchat-livechat/app/client/stylesheets/utils/_variables.import.less b/packages/rocketchat-livechat/.app/client/stylesheets/utils/_variables.import.less
similarity index 100%
rename from packages/rocketchat-livechat/app/client/stylesheets/utils/_variables.import.less
rename to packages/rocketchat-livechat/.app/client/stylesheets/utils/_variables.import.less
diff --git a/packages/rocketchat-livechat/app/client/views/avatar.html b/packages/rocketchat-livechat/.app/client/views/avatar.html
similarity index 100%
rename from packages/rocketchat-livechat/app/client/views/avatar.html
rename to packages/rocketchat-livechat/.app/client/views/avatar.html
diff --git a/packages/rocketchat-livechat/app/client/views/avatar.js b/packages/rocketchat-livechat/.app/client/views/avatar.js
similarity index 82%
rename from packages/rocketchat-livechat/app/client/views/avatar.js
rename to packages/rocketchat-livechat/.app/client/views/avatar.js
index 5ab46c366a45..62443cf49912 100644
--- a/packages/rocketchat-livechat/app/client/views/avatar.js
+++ b/packages/rocketchat-livechat/.app/client/views/avatar.js
@@ -1,3 +1,5 @@
+import visitor from '../../imports/client/visitor';
+
Template.avatar.helpers({
imageUrl() {
let username = this.username;
@@ -6,7 +8,7 @@ Template.avatar.helpers({
username = user && user.username;
}
- const currentUser = Meteor.users.findOne(Meteor.userId(), { fields: { username: 1 }});
+ const currentUser = visitor.getData();
if (!username || (currentUser && currentUser.username === username)) {
return;
}
diff --git a/packages/rocketchat-livechat/app/client/views/livechatWindow.html b/packages/rocketchat-livechat/.app/client/views/livechatWindow.html
similarity index 100%
rename from packages/rocketchat-livechat/app/client/views/livechatWindow.html
rename to packages/rocketchat-livechat/.app/client/views/livechatWindow.html
diff --git a/packages/rocketchat-livechat/app/client/views/livechatWindow.js b/packages/rocketchat-livechat/.app/client/views/livechatWindow.js
similarity index 94%
rename from packages/rocketchat-livechat/app/client/views/livechatWindow.js
rename to packages/rocketchat-livechat/.app/client/views/livechatWindow.js
index fcbe88f9587d..7651415e6b48 100644
--- a/packages/rocketchat-livechat/app/client/views/livechatWindow.js
+++ b/packages/rocketchat-livechat/.app/client/views/livechatWindow.js
@@ -1,4 +1,5 @@
/* globals Department, Livechat, LivechatVideoCall */
+import visitor from '../../imports/client/visitor';
Template.livechatWindow.helpers({
title() {
@@ -17,7 +18,7 @@ Template.livechatWindow.helpers({
return Session.get('sound');
},
showRegisterForm() {
- if (Session.get('triggered') || Meteor.userId()) {
+ if (Session.get('triggered') || visitor.getId()) {
return false;
}
return Livechat.registrationForm;
@@ -114,6 +115,12 @@ Template.livechatWindow.onCreated(function() {
if (result.room) {
Livechat.room = result.room._id;
+
+ visitor.setConnected();
+ }
+
+ if (result.visitor) {
+ visitor.setData(result.visitor);
}
if (result.agentData) {
diff --git a/packages/rocketchat-livechat/app/client/views/loading.html b/packages/rocketchat-livechat/.app/client/views/loading.html
similarity index 100%
rename from packages/rocketchat-livechat/app/client/views/loading.html
rename to packages/rocketchat-livechat/.app/client/views/loading.html
diff --git a/packages/rocketchat-livechat/app/client/views/main.html b/packages/rocketchat-livechat/.app/client/views/main.html
similarity index 100%
rename from packages/rocketchat-livechat/app/client/views/main.html
rename to packages/rocketchat-livechat/.app/client/views/main.html
diff --git a/packages/rocketchat-livechat/app/client/views/message.html b/packages/rocketchat-livechat/.app/client/views/message.html
similarity index 100%
rename from packages/rocketchat-livechat/app/client/views/message.html
rename to packages/rocketchat-livechat/.app/client/views/message.html
diff --git a/packages/rocketchat-livechat/app/client/views/message.js b/packages/rocketchat-livechat/.app/client/views/message.js
similarity index 97%
rename from packages/rocketchat-livechat/app/client/views/message.js
rename to packages/rocketchat-livechat/.app/client/views/message.js
index edf40fee5cd2..9dc31af875b1 100644
--- a/packages/rocketchat-livechat/app/client/views/message.js
+++ b/packages/rocketchat-livechat/.app/client/views/message.js
@@ -1,10 +1,11 @@
/* globals Livechat, t, tr, livechatAutolinker */
import moment from 'moment';
+import visitor from '../../imports/client/visitor';
import s from 'underscore.string';
Template.message.helpers({
own() {
- if (this.u && this.u._id === Meteor.userId()) {
+ if (this.u && this.u._id === visitor.getId()) {
return 'own';
}
},
diff --git a/packages/rocketchat-livechat/app/client/views/messages.html b/packages/rocketchat-livechat/.app/client/views/messages.html
similarity index 100%
rename from packages/rocketchat-livechat/app/client/views/messages.html
rename to packages/rocketchat-livechat/.app/client/views/messages.html
diff --git a/packages/rocketchat-livechat/app/client/views/messages.js b/packages/rocketchat-livechat/.app/client/views/messages.js
similarity index 96%
rename from packages/rocketchat-livechat/app/client/views/messages.js
rename to packages/rocketchat-livechat/.app/client/views/messages.js
index 4b7820e35cec..fb457c0fd26a 100644
--- a/packages/rocketchat-livechat/app/client/views/messages.js
+++ b/packages/rocketchat-livechat/.app/client/views/messages.js
@@ -1,4 +1,5 @@
/* globals Livechat, LivechatVideoCall, MsgTyping */
+import visitor from '../../imports/client/visitor';
import _ from 'underscore';
Template.messages.helpers({
@@ -115,19 +116,14 @@ Template.messages.events({
'click .video-button'(event) {
event.preventDefault();
- if (!Meteor.userId()) {
+ if (!visitor.getId()) {
Meteor.call('livechat:registerGuest', { token: visitor.getToken() }, (error, result) => {
if (error) {
return console.log(error.reason);
}
- Meteor.loginWithToken(result.token, (error) => {
- if (error) {
- return console.log(error.reason);
- }
-
- LivechatVideoCall.request();
- });
+ visitor.setId(result._id);
+ LivechatVideoCall.request();
});
} else {
LivechatVideoCall.request();
diff --git a/packages/rocketchat-livechat/app/client/views/offlineForm.html b/packages/rocketchat-livechat/.app/client/views/offlineForm.html
similarity index 100%
rename from packages/rocketchat-livechat/app/client/views/offlineForm.html
rename to packages/rocketchat-livechat/.app/client/views/offlineForm.html
diff --git a/packages/rocketchat-livechat/app/client/views/offlineForm.js b/packages/rocketchat-livechat/.app/client/views/offlineForm.js
similarity index 100%
rename from packages/rocketchat-livechat/app/client/views/offlineForm.js
rename to packages/rocketchat-livechat/.app/client/views/offlineForm.js
diff --git a/packages/rocketchat-livechat/app/client/views/options.html b/packages/rocketchat-livechat/.app/client/views/options.html
similarity index 100%
rename from packages/rocketchat-livechat/app/client/views/options.html
rename to packages/rocketchat-livechat/.app/client/views/options.html
diff --git a/packages/rocketchat-livechat/app/client/views/options.js b/packages/rocketchat-livechat/.app/client/views/options.js
similarity index 84%
rename from packages/rocketchat-livechat/app/client/views/options.js
rename to packages/rocketchat-livechat/.app/client/views/options.js
index 653c916a68b7..c6c38c864c77 100644
--- a/packages/rocketchat-livechat/app/client/views/options.js
+++ b/packages/rocketchat-livechat/.app/client/views/options.js
@@ -1,4 +1,5 @@
/* globals Department, Livechat, swal */
+import visitor from '../../imports/client/visitor';
Template.options.helpers({
showDepartments() {
@@ -25,7 +26,7 @@ Template.options.events({
closeOnConfirm: true,
html: false
}, () => {
- Meteor.call('livechat:closeByVisitor', visitor.getRoom(), (error) => {
+ Meteor.call('livechat:closeByVisitor', { roomId: visitor.getRoom(), token: visitor.getToken() }, (error) => {
if (error) {
return console.log('Error ->', error);
}
diff --git a/packages/rocketchat-livechat/app/client/views/poweredBy.html b/packages/rocketchat-livechat/.app/client/views/poweredBy.html
similarity index 100%
rename from packages/rocketchat-livechat/app/client/views/poweredBy.html
rename to packages/rocketchat-livechat/.app/client/views/poweredBy.html
diff --git a/packages/rocketchat-livechat/app/client/views/register.html b/packages/rocketchat-livechat/.app/client/views/register.html
similarity index 100%
rename from packages/rocketchat-livechat/app/client/views/register.html
rename to packages/rocketchat-livechat/.app/client/views/register.html
diff --git a/packages/rocketchat-livechat/app/client/views/register.js b/packages/rocketchat-livechat/.app/client/views/register.js
similarity index 93%
rename from packages/rocketchat-livechat/app/client/views/register.js
rename to packages/rocketchat-livechat/.app/client/views/register.js
index f62c8341311e..f42fe1aa5b9f 100644
--- a/packages/rocketchat-livechat/app/client/views/register.js
+++ b/packages/rocketchat-livechat/.app/client/views/register.js
@@ -1,4 +1,5 @@
/* globals Department, Livechat, LivechatVideoCall */
+import visitor from '../../imports/client/visitor';
import _ from 'underscore';
Template.register.helpers({
@@ -57,12 +58,8 @@ Template.register.events({
return instance.showError(error.reason);
}
parentCall('callback', ['pre-chat-form-submit', _.omit(guest, 'token')]);
- Meteor.loginWithToken(result.token, function(error) {
- if (error) {
- return instance.showError(error.reason);
- }
- start();
- });
+ visitor.setId(result._id);
+ start();
});
}
},
diff --git a/packages/rocketchat-livechat/app/client/views/survey.html b/packages/rocketchat-livechat/.app/client/views/survey.html
similarity index 100%
rename from packages/rocketchat-livechat/app/client/views/survey.html
rename to packages/rocketchat-livechat/.app/client/views/survey.html
diff --git a/packages/rocketchat-livechat/app/client/views/survey.js b/packages/rocketchat-livechat/.app/client/views/survey.js
similarity index 90%
rename from packages/rocketchat-livechat/app/client/views/survey.js
rename to packages/rocketchat-livechat/.app/client/views/survey.js
index 0bde47e041b8..c9c66add13a7 100644
--- a/packages/rocketchat-livechat/app/client/views/survey.js
+++ b/packages/rocketchat-livechat/.app/client/views/survey.js
@@ -1,4 +1,5 @@
/* globals swal */
+import visitor from '../../imports/client/visitor';
Template.survey.events({
'click button.skip'(e, instance) {
diff --git a/packages/rocketchat-livechat/app/client/views/switchDepartment.html b/packages/rocketchat-livechat/.app/client/views/switchDepartment.html
similarity index 100%
rename from packages/rocketchat-livechat/app/client/views/switchDepartment.html
rename to packages/rocketchat-livechat/.app/client/views/switchDepartment.html
diff --git a/packages/rocketchat-livechat/app/client/views/switchDepartment.js b/packages/rocketchat-livechat/.app/client/views/switchDepartment.js
similarity index 90%
rename from packages/rocketchat-livechat/app/client/views/switchDepartment.js
rename to packages/rocketchat-livechat/.app/client/views/switchDepartment.js
index a343e8d3334e..e6288ed920dd 100644
--- a/packages/rocketchat-livechat/app/client/views/switchDepartment.js
+++ b/packages/rocketchat-livechat/.app/client/views/switchDepartment.js
@@ -1,4 +1,5 @@
/* globals Department, Livechat, swal */
+import visitor from '../../imports/client/visitor';
Template.switchDepartment.helpers({
departments() {
@@ -44,7 +45,7 @@ Template.switchDepartment.events({
closeOnConfirm: true,
html: false
}, () => {
- Meteor.call('livechat:closeByVisitor', visitor.getRoom(), (error) => {
+ Meteor.call('livechat:closeByVisitor', { roomId: visitor.getRoom(), token: visitor.getToken() }, (error) => {
if (error) {
return console.log('Error ->', error);
}
diff --git a/packages/rocketchat-livechat/app/client/views/videoCall.html b/packages/rocketchat-livechat/.app/client/views/videoCall.html
similarity index 100%
rename from packages/rocketchat-livechat/app/client/views/videoCall.html
rename to packages/rocketchat-livechat/.app/client/views/videoCall.html
diff --git a/packages/rocketchat-livechat/app/client/views/videoCall.js b/packages/rocketchat-livechat/.app/client/views/videoCall.js
similarity index 100%
rename from packages/rocketchat-livechat/app/client/views/videoCall.js
rename to packages/rocketchat-livechat/.app/client/views/videoCall.js
diff --git a/packages/rocketchat-livechat/app/i18n/ar.i18n.json b/packages/rocketchat-livechat/.app/i18n/ar.i18n.json
similarity index 100%
rename from packages/rocketchat-livechat/app/i18n/ar.i18n.json
rename to packages/rocketchat-livechat/.app/i18n/ar.i18n.json
diff --git a/packages/rocketchat-livechat/app/i18n/az.i18n.json b/packages/rocketchat-livechat/.app/i18n/az.i18n.json
similarity index 100%
rename from packages/rocketchat-livechat/app/i18n/az.i18n.json
rename to packages/rocketchat-livechat/.app/i18n/az.i18n.json
diff --git a/packages/rocketchat-livechat/app/i18n/bg.i18n.json b/packages/rocketchat-livechat/.app/i18n/bg.i18n.json
similarity index 100%
rename from packages/rocketchat-livechat/app/i18n/bg.i18n.json
rename to packages/rocketchat-livechat/.app/i18n/bg.i18n.json
diff --git a/packages/rocketchat-livechat/app/i18n/ca.i18n.json b/packages/rocketchat-livechat/.app/i18n/ca.i18n.json
similarity index 100%
rename from packages/rocketchat-livechat/app/i18n/ca.i18n.json
rename to packages/rocketchat-livechat/.app/i18n/ca.i18n.json
diff --git a/packages/rocketchat-livechat/app/i18n/cs.i18n.json b/packages/rocketchat-livechat/.app/i18n/cs.i18n.json
similarity index 100%
rename from packages/rocketchat-livechat/app/i18n/cs.i18n.json
rename to packages/rocketchat-livechat/.app/i18n/cs.i18n.json
diff --git a/packages/rocketchat-livechat/app/i18n/da.i18n.json b/packages/rocketchat-livechat/.app/i18n/da.i18n.json
similarity index 100%
rename from packages/rocketchat-livechat/app/i18n/da.i18n.json
rename to packages/rocketchat-livechat/.app/i18n/da.i18n.json
diff --git a/packages/rocketchat-livechat/app/i18n/de-AT.i18n.json b/packages/rocketchat-livechat/.app/i18n/de-AT.i18n.json
similarity index 100%
rename from packages/rocketchat-livechat/app/i18n/de-AT.i18n.json
rename to packages/rocketchat-livechat/.app/i18n/de-AT.i18n.json
diff --git a/packages/rocketchat-livechat/app/i18n/de.i18n.json b/packages/rocketchat-livechat/.app/i18n/de.i18n.json
similarity index 100%
rename from packages/rocketchat-livechat/app/i18n/de.i18n.json
rename to packages/rocketchat-livechat/.app/i18n/de.i18n.json
diff --git a/packages/rocketchat-livechat/app/i18n/el.i18n.json b/packages/rocketchat-livechat/.app/i18n/el.i18n.json
similarity index 100%
rename from packages/rocketchat-livechat/app/i18n/el.i18n.json
rename to packages/rocketchat-livechat/.app/i18n/el.i18n.json
diff --git a/packages/rocketchat-livechat/app/i18n/en.i18n.json b/packages/rocketchat-livechat/.app/i18n/en.i18n.json
similarity index 100%
rename from packages/rocketchat-livechat/app/i18n/en.i18n.json
rename to packages/rocketchat-livechat/.app/i18n/en.i18n.json
diff --git a/packages/rocketchat-livechat/app/i18n/eo.i18n.json b/packages/rocketchat-livechat/.app/i18n/eo.i18n.json
similarity index 100%
rename from packages/rocketchat-livechat/app/i18n/eo.i18n.json
rename to packages/rocketchat-livechat/.app/i18n/eo.i18n.json
diff --git a/packages/rocketchat-livechat/app/i18n/es.i18n.json b/packages/rocketchat-livechat/.app/i18n/es.i18n.json
similarity index 100%
rename from packages/rocketchat-livechat/app/i18n/es.i18n.json
rename to packages/rocketchat-livechat/.app/i18n/es.i18n.json
diff --git a/packages/rocketchat-livechat/app/i18n/fa.i18n.json b/packages/rocketchat-livechat/.app/i18n/fa.i18n.json
similarity index 100%
rename from packages/rocketchat-livechat/app/i18n/fa.i18n.json
rename to packages/rocketchat-livechat/.app/i18n/fa.i18n.json
diff --git a/packages/rocketchat-livechat/app/i18n/fi.i18n.json b/packages/rocketchat-livechat/.app/i18n/fi.i18n.json
similarity index 100%
rename from packages/rocketchat-livechat/app/i18n/fi.i18n.json
rename to packages/rocketchat-livechat/.app/i18n/fi.i18n.json
diff --git a/packages/rocketchat-livechat/app/i18n/fr.i18n.json b/packages/rocketchat-livechat/.app/i18n/fr.i18n.json
similarity index 100%
rename from packages/rocketchat-livechat/app/i18n/fr.i18n.json
rename to packages/rocketchat-livechat/.app/i18n/fr.i18n.json
diff --git a/packages/rocketchat-livechat/app/i18n/he.i18n.json b/packages/rocketchat-livechat/.app/i18n/he.i18n.json
similarity index 100%
rename from packages/rocketchat-livechat/app/i18n/he.i18n.json
rename to packages/rocketchat-livechat/.app/i18n/he.i18n.json
diff --git a/packages/rocketchat-livechat/app/i18n/hr.i18n.json b/packages/rocketchat-livechat/.app/i18n/hr.i18n.json
similarity index 100%
rename from packages/rocketchat-livechat/app/i18n/hr.i18n.json
rename to packages/rocketchat-livechat/.app/i18n/hr.i18n.json
diff --git a/packages/rocketchat-livechat/app/i18n/hu.i18n.json b/packages/rocketchat-livechat/.app/i18n/hu.i18n.json
similarity index 100%
rename from packages/rocketchat-livechat/app/i18n/hu.i18n.json
rename to packages/rocketchat-livechat/.app/i18n/hu.i18n.json
diff --git a/packages/rocketchat-livechat/app/i18n/id.i18n.json b/packages/rocketchat-livechat/.app/i18n/id.i18n.json
similarity index 100%
rename from packages/rocketchat-livechat/app/i18n/id.i18n.json
rename to packages/rocketchat-livechat/.app/i18n/id.i18n.json
diff --git a/packages/rocketchat-livechat/app/i18n/it.i18n.json b/packages/rocketchat-livechat/.app/i18n/it.i18n.json
similarity index 100%
rename from packages/rocketchat-livechat/app/i18n/it.i18n.json
rename to packages/rocketchat-livechat/.app/i18n/it.i18n.json
diff --git a/packages/rocketchat-livechat/app/i18n/ja.i18n.json b/packages/rocketchat-livechat/.app/i18n/ja.i18n.json
similarity index 100%
rename from packages/rocketchat-livechat/app/i18n/ja.i18n.json
rename to packages/rocketchat-livechat/.app/i18n/ja.i18n.json
diff --git a/packages/rocketchat-livechat/app/i18n/km.i18n.json b/packages/rocketchat-livechat/.app/i18n/km.i18n.json
similarity index 100%
rename from packages/rocketchat-livechat/app/i18n/km.i18n.json
rename to packages/rocketchat-livechat/.app/i18n/km.i18n.json
diff --git a/packages/rocketchat-livechat/app/i18n/ko.i18n.json b/packages/rocketchat-livechat/.app/i18n/ko.i18n.json
similarity index 100%
rename from packages/rocketchat-livechat/app/i18n/ko.i18n.json
rename to packages/rocketchat-livechat/.app/i18n/ko.i18n.json
diff --git a/packages/rocketchat-livechat/app/i18n/ku.i18n.json b/packages/rocketchat-livechat/.app/i18n/ku.i18n.json
similarity index 100%
rename from packages/rocketchat-livechat/app/i18n/ku.i18n.json
rename to packages/rocketchat-livechat/.app/i18n/ku.i18n.json
diff --git a/packages/rocketchat-livechat/app/i18n/lo.i18n.json b/packages/rocketchat-livechat/.app/i18n/lo.i18n.json
similarity index 100%
rename from packages/rocketchat-livechat/app/i18n/lo.i18n.json
rename to packages/rocketchat-livechat/.app/i18n/lo.i18n.json
diff --git a/packages/rocketchat-livechat/app/i18n/lt.i18n.json b/packages/rocketchat-livechat/.app/i18n/lt.i18n.json
similarity index 100%
rename from packages/rocketchat-livechat/app/i18n/lt.i18n.json
rename to packages/rocketchat-livechat/.app/i18n/lt.i18n.json
diff --git a/packages/rocketchat-livechat/app/i18n/ms-MY.i18n.json b/packages/rocketchat-livechat/.app/i18n/ms-MY.i18n.json
similarity index 100%
rename from packages/rocketchat-livechat/app/i18n/ms-MY.i18n.json
rename to packages/rocketchat-livechat/.app/i18n/ms-MY.i18n.json
diff --git a/packages/rocketchat-livechat/app/i18n/nl.i18n.json b/packages/rocketchat-livechat/.app/i18n/nl.i18n.json
similarity index 100%
rename from packages/rocketchat-livechat/app/i18n/nl.i18n.json
rename to packages/rocketchat-livechat/.app/i18n/nl.i18n.json
diff --git a/packages/rocketchat-livechat/app/i18n/no.i18n.json b/packages/rocketchat-livechat/.app/i18n/no.i18n.json
similarity index 100%
rename from packages/rocketchat-livechat/app/i18n/no.i18n.json
rename to packages/rocketchat-livechat/.app/i18n/no.i18n.json
diff --git a/packages/rocketchat-livechat/app/i18n/pl.i18n.json b/packages/rocketchat-livechat/.app/i18n/pl.i18n.json
similarity index 100%
rename from packages/rocketchat-livechat/app/i18n/pl.i18n.json
rename to packages/rocketchat-livechat/.app/i18n/pl.i18n.json
diff --git a/packages/rocketchat-livechat/app/i18n/pt-BR.i18n.json b/packages/rocketchat-livechat/.app/i18n/pt-BR.i18n.json
similarity index 100%
rename from packages/rocketchat-livechat/app/i18n/pt-BR.i18n.json
rename to packages/rocketchat-livechat/.app/i18n/pt-BR.i18n.json
diff --git a/packages/rocketchat-livechat/app/i18n/pt.i18n.json b/packages/rocketchat-livechat/.app/i18n/pt.i18n.json
similarity index 100%
rename from packages/rocketchat-livechat/app/i18n/pt.i18n.json
rename to packages/rocketchat-livechat/.app/i18n/pt.i18n.json
diff --git a/packages/rocketchat-livechat/app/i18n/ro.i18n.json b/packages/rocketchat-livechat/.app/i18n/ro.i18n.json
similarity index 100%
rename from packages/rocketchat-livechat/app/i18n/ro.i18n.json
rename to packages/rocketchat-livechat/.app/i18n/ro.i18n.json
diff --git a/packages/rocketchat-livechat/app/i18n/ru.i18n.json b/packages/rocketchat-livechat/.app/i18n/ru.i18n.json
similarity index 100%
rename from packages/rocketchat-livechat/app/i18n/ru.i18n.json
rename to packages/rocketchat-livechat/.app/i18n/ru.i18n.json
diff --git a/packages/rocketchat-livechat/app/i18n/sq.i18n.json b/packages/rocketchat-livechat/.app/i18n/sq.i18n.json
similarity index 100%
rename from packages/rocketchat-livechat/app/i18n/sq.i18n.json
rename to packages/rocketchat-livechat/.app/i18n/sq.i18n.json
diff --git a/packages/rocketchat-livechat/app/i18n/sr.i18n.json b/packages/rocketchat-livechat/.app/i18n/sr.i18n.json
similarity index 100%
rename from packages/rocketchat-livechat/app/i18n/sr.i18n.json
rename to packages/rocketchat-livechat/.app/i18n/sr.i18n.json
diff --git a/packages/rocketchat-livechat/app/i18n/sv.i18n.json b/packages/rocketchat-livechat/.app/i18n/sv.i18n.json
similarity index 100%
rename from packages/rocketchat-livechat/app/i18n/sv.i18n.json
rename to packages/rocketchat-livechat/.app/i18n/sv.i18n.json
diff --git a/packages/rocketchat-livechat/app/i18n/ta-IN.i18n.json b/packages/rocketchat-livechat/.app/i18n/ta-IN.i18n.json
similarity index 100%
rename from packages/rocketchat-livechat/app/i18n/ta-IN.i18n.json
rename to packages/rocketchat-livechat/.app/i18n/ta-IN.i18n.json
diff --git a/packages/rocketchat-livechat/app/i18n/tr.i18n.json b/packages/rocketchat-livechat/.app/i18n/tr.i18n.json
similarity index 100%
rename from packages/rocketchat-livechat/app/i18n/tr.i18n.json
rename to packages/rocketchat-livechat/.app/i18n/tr.i18n.json
diff --git a/packages/rocketchat-livechat/app/i18n/ug.i18n.json b/packages/rocketchat-livechat/.app/i18n/ug.i18n.json
similarity index 100%
rename from packages/rocketchat-livechat/app/i18n/ug.i18n.json
rename to packages/rocketchat-livechat/.app/i18n/ug.i18n.json
diff --git a/packages/rocketchat-livechat/app/i18n/uk.i18n.json b/packages/rocketchat-livechat/.app/i18n/uk.i18n.json
similarity index 100%
rename from packages/rocketchat-livechat/app/i18n/uk.i18n.json
rename to packages/rocketchat-livechat/.app/i18n/uk.i18n.json
diff --git a/packages/rocketchat-livechat/app/i18n/zh-HK.i18n.json b/packages/rocketchat-livechat/.app/i18n/zh-HK.i18n.json
similarity index 100%
rename from packages/rocketchat-livechat/app/i18n/zh-HK.i18n.json
rename to packages/rocketchat-livechat/.app/i18n/zh-HK.i18n.json
diff --git a/packages/rocketchat-livechat/app/i18n/zh-TW.i18n.json b/packages/rocketchat-livechat/.app/i18n/zh-TW.i18n.json
similarity index 100%
rename from packages/rocketchat-livechat/app/i18n/zh-TW.i18n.json
rename to packages/rocketchat-livechat/.app/i18n/zh-TW.i18n.json
diff --git a/packages/rocketchat-livechat/app/i18n/zh.i18n.json b/packages/rocketchat-livechat/.app/i18n/zh.i18n.json
similarity index 100%
rename from packages/rocketchat-livechat/app/i18n/zh.i18n.json
rename to packages/rocketchat-livechat/.app/i18n/zh.i18n.json
diff --git a/packages/rocketchat-livechat/app/client/lib/_visitor.js b/packages/rocketchat-livechat/.app/imports/client/visitor.js
similarity index 56%
rename from packages/rocketchat-livechat/app/client/lib/_visitor.js
rename to packages/rocketchat-livechat/.app/imports/client/visitor.js
index 290ddf92b45a..bb0613cb92e0 100644
--- a/packages/rocketchat-livechat/app/client/lib/_visitor.js
+++ b/packages/rocketchat-livechat/.app/imports/client/visitor.js
@@ -1,13 +1,14 @@
/* globals Commands */
const msgStream = new Meteor.Streamer('room-messages');
-this.visitor = new class {
- constructor() {
- this.token = new ReactiveVar(null);
- this.room = new ReactiveVar(null);
- this.roomToSubscribe = new ReactiveVar(null);
- this.roomSubscribed = null;
- }
+export default {
+ id: new ReactiveVar(null),
+ token: new ReactiveVar(null),
+ room: new ReactiveVar(null),
+ data: new ReactiveVar(null),
+ roomToSubscribe: new ReactiveVar(null),
+ roomSubscribed: null,
+ connected: null,
register() {
if (!localStorage.getItem('visitorToken')) {
@@ -15,15 +16,31 @@ this.visitor = new class {
}
this.token.set(localStorage.getItem('visitorToken'));
- }
+ },
+
+ getId() {
+ return this.id.get();
+ },
+
+ setId(id) {
+ return this.id.set(id);
+ },
+
+ getData() {
+ return this.data.get();
+ },
+
+ setData(data) {
+ this.data.set(data);
+ },
getToken() {
return this.token.get();
- }
+ },
setRoom(rid) {
this.room.set(rid);
- }
+ },
getRoom(createOnEmpty = false) {
let roomId = this.room.get();
@@ -33,11 +50,11 @@ this.visitor = new class {
}
return roomId;
- }
+ },
isSubscribed(roomId) {
return this.roomSubscribed === roomId;
- }
+ },
subscribeToRoom(roomId) {
if (this.roomSubscribed && this.roomSubscribed === roomId) {
@@ -46,7 +63,7 @@ this.visitor = new class {
this.roomSubscribed = roomId;
- msgStream.on(roomId, (msg) => {
+ msgStream.on(roomId, { token: this.getToken() }, (msg) => {
if (msg.t === 'command') {
Commands[msg.msg] && Commands[msg.msg]();
} else if (msg.t !== 'livechat_video_call') {
@@ -57,13 +74,26 @@ this.visitor = new class {
}
// notification sound
- if (Session.equals('sound', true) && msg.u._id !== Meteor.userId()) {
- const audioVolume = RocketChat.getUserPreference(Meteor.user(), 'notificationsSoundVolume');
+ if (Session.equals('sound', true) && msg.u._id !== this.getId()) {
const audio = document.getElementById('chatAudioNotification');
- audio.volume = Number((audioVolume/100).toPrecision(2));
audio.play();
}
}
});
+ },
+
+ setConnected() {
+ if (this.connected) {
+ return;
+ }
+ const token = this.getToken();
+
+ this.connected = true;
+ Meteor.call('UserPresence:connect', token, { visitor: token });
+
+ Meteor.startup(function() {
+ UserPresence.awayTime = 300000; // 5 minutes
+ UserPresence.start(token);
+ });
}
};
diff --git a/packages/rocketchat-livechat/.app/package-lock.json b/packages/rocketchat-livechat/.app/package-lock.json
new file mode 100644
index 000000000000..2eda1637c29e
--- /dev/null
+++ b/packages/rocketchat-livechat/.app/package-lock.json
@@ -0,0 +1,750 @@
+{
+ "name": "rocketchat-livechat",
+ "version": "1.0.0",
+ "lockfileVersion": 1,
+ "requires": true,
+ "dependencies": {
+ "abbrev": {
+ "version": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
+ "integrity": "sha1-+PLIh60Qv2f2NPAFtph/7TF5qsg="
+ },
+ "ajv": {
+ "version": "https://registry.npmjs.org/ajv/-/ajv-5.5.0.tgz",
+ "integrity": "sha1-6yhAdG6dxIvV4GOjbj/UAMXqtak=",
+ "requires": {
+ "co": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
+ "fast-deep-equal": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz",
+ "fast-json-stable-stringify": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
+ "json-schema-traverse": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz"
+ }
+ },
+ "ansi-regex": {
+ "version": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
+ },
+ "aproba": {
+ "version": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
+ "integrity": "sha1-aALmJk79GMeQobDVF/DyYnvyyUo="
+ },
+ "are-we-there-yet": {
+ "version": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz",
+ "integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=",
+ "requires": {
+ "delegates": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
+ "readable-stream": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz"
+ }
+ },
+ "asn1": {
+ "version": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
+ "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y="
+ },
+ "assert-plus": {
+ "version": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
+ },
+ "asynckit": {
+ "version": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
+ },
+ "autolinker": {
+ "version": "https://registry.npmjs.org/autolinker/-/autolinker-1.6.0.tgz",
+ "integrity": "sha1-utN2t62OQV8i8QL8Dzf2QOZPHL8="
+ },
+ "aws-sign2": {
+ "version": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
+ "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
+ },
+ "aws4": {
+ "version": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz",
+ "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4="
+ },
+ "babel-runtime": {
+ "version": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
+ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
+ "requires": {
+ "core-js": "https://registry.npmjs.org/core-js/-/core-js-2.5.1.tgz",
+ "regenerator-runtime": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz"
+ }
+ },
+ "balanced-match": {
+ "version": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
+ },
+ "bcrypt": {
+ "version": "https://registry.npmjs.org/bcrypt/-/bcrypt-1.0.3.tgz",
+ "integrity": "sha1-sC3cbAtS6ha40883XVoy54DatUg=",
+ "requires": {
+ "nan": "https://registry.npmjs.org/nan/-/nan-2.6.2.tgz",
+ "node-pre-gyp": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.6.36.tgz"
+ }
+ },
+ "bcrypt-pbkdf": {
+ "version": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
+ "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=",
+ "optional": true,
+ "requires": {
+ "tweetnacl": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz"
+ }
+ },
+ "block-stream": {
+ "version": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz",
+ "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=",
+ "requires": {
+ "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz"
+ }
+ },
+ "boom": {
+ "version": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz",
+ "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=",
+ "requires": {
+ "hoek": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz"
+ }
+ },
+ "brace-expansion": {
+ "version": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
+ "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
+ "requires": {
+ "balanced-match": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+ "concat-map": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
+ }
+ },
+ "caseless": {
+ "version": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
+ },
+ "co": {
+ "version": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
+ "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ="
+ },
+ "code-point-at": {
+ "version": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
+ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
+ },
+ "combined-stream": {
+ "version": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz",
+ "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=",
+ "requires": {
+ "delayed-stream": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz"
+ }
+ },
+ "concat-map": {
+ "version": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
+ },
+ "console-control-strings": {
+ "version": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
+ "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4="
+ },
+ "core-js": {
+ "version": "https://registry.npmjs.org/core-js/-/core-js-2.5.1.tgz",
+ "integrity": "sha1-rmh03GaTd4m4B1T/VCjfZoGcpQs="
+ },
+ "core-util-is": {
+ "version": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
+ },
+ "cryptiles": {
+ "version": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz",
+ "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=",
+ "requires": {
+ "boom": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz"
+ },
+ "dependencies": {
+ "boom": {
+ "version": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz",
+ "integrity": "sha1-XdnabuOl8wIHdDYpDLcX0/SlTgI=",
+ "requires": {
+ "hoek": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz"
+ }
+ }
+ }
+ },
+ "dashdash": {
+ "version": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+ "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+ "requires": {
+ "assert-plus": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz"
+ }
+ },
+ "debug": {
+ "version": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=",
+ "requires": {
+ "ms": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz"
+ }
+ },
+ "deep-extend": {
+ "version": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz",
+ "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8="
+ },
+ "delayed-stream": {
+ "version": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
+ },
+ "delegates": {
+ "version": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
+ "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o="
+ },
+ "ecc-jsbn": {
+ "version": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
+ "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=",
+ "optional": true,
+ "requires": {
+ "jsbn": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz"
+ }
+ },
+ "extend": {
+ "version": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
+ "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ="
+ },
+ "extsprintf": {
+ "version": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+ "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
+ },
+ "fast-deep-equal": {
+ "version": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz",
+ "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8="
+ },
+ "fast-json-stable-stringify": {
+ "version": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
+ "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I="
+ },
+ "forever-agent": {
+ "version": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+ "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
+ },
+ "form-data": {
+ "version": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz",
+ "integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=",
+ "requires": {
+ "asynckit": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "combined-stream": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz",
+ "mime-types": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz"
+ }
+ },
+ "fs.realpath": {
+ "version": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
+ },
+ "fstream": {
+ "version": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz",
+ "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=",
+ "requires": {
+ "graceful-fs": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
+ "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "mkdirp": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+ "rimraf": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz"
+ }
+ },
+ "fstream-ignore": {
+ "version": "https://registry.npmjs.org/fstream-ignore/-/fstream-ignore-1.0.5.tgz",
+ "integrity": "sha1-nDHa40dnAY/h0kmyTa2mfQktoQU=",
+ "requires": {
+ "fstream": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz",
+ "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "minimatch": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz"
+ }
+ },
+ "gauge": {
+ "version": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
+ "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
+ "requires": {
+ "aproba": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
+ "console-control-strings": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
+ "has-unicode": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
+ "object-assign": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "signal-exit": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
+ "string-width": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "strip-ansi": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "wide-align": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz"
+ }
+ },
+ "getpass": {
+ "version": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+ "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+ "requires": {
+ "assert-plus": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz"
+ }
+ },
+ "glob": {
+ "version": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
+ "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=",
+ "requires": {
+ "fs.realpath": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "inflight": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "minimatch": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+ "once": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "path-is-absolute": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz"
+ }
+ },
+ "graceful-fs": {
+ "version": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
+ "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg="
+ },
+ "har-schema": {
+ "version": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
+ "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
+ },
+ "har-validator": {
+ "version": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz",
+ "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=",
+ "requires": {
+ "ajv": "https://registry.npmjs.org/ajv/-/ajv-5.5.0.tgz",
+ "har-schema": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz"
+ }
+ },
+ "has-unicode": {
+ "version": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
+ "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk="
+ },
+ "hawk": {
+ "version": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz",
+ "integrity": "sha1-r02RTrBl+bXOTZ0RwcshJu7MMDg=",
+ "requires": {
+ "boom": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz",
+ "cryptiles": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz",
+ "hoek": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz",
+ "sntp": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz"
+ }
+ },
+ "hoek": {
+ "version": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz",
+ "integrity": "sha1-ctnQdU9/4lyi0BrY+PmpRJqJUm0="
+ },
+ "http-signature": {
+ "version": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
+ "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
+ "requires": {
+ "assert-plus": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "jsprim": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
+ "sshpk": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz"
+ }
+ },
+ "inflight": {
+ "version": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "requires": {
+ "once": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "wrappy": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz"
+ }
+ },
+ "inherits": {
+ "version": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
+ },
+ "ini": {
+ "version": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
+ "integrity": "sha1-7uJfVtscnsYIXgwid4CD9Zar+Sc="
+ },
+ "is-fullwidth-code-point": {
+ "version": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+ "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+ "requires": {
+ "number-is-nan": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz"
+ }
+ },
+ "is-typedarray": {
+ "version": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
+ },
+ "isarray": {
+ "version": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
+ },
+ "isstream": {
+ "version": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
+ },
+ "jquery": {
+ "version": "https://registry.npmjs.org/jquery/-/jquery-3.2.1.tgz",
+ "integrity": "sha1-XE2d5lKvbNCncBVKYxu6ErAVx4c="
+ },
+ "jsbn": {
+ "version": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
+ "optional": true
+ },
+ "json-schema": {
+ "version": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
+ "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
+ },
+ "json-schema-traverse": {
+ "version": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
+ "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A="
+ },
+ "json-stringify-safe": {
+ "version": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
+ },
+ "jsprim": {
+ "version": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
+ "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
+ "requires": {
+ "assert-plus": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "extsprintf": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+ "json-schema": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
+ "verror": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz"
+ }
+ },
+ "mime-db": {
+ "version": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz",
+ "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE="
+ },
+ "mime-types": {
+ "version": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz",
+ "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=",
+ "requires": {
+ "mime-db": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz"
+ }
+ },
+ "minimatch": {
+ "version": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+ "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=",
+ "requires": {
+ "brace-expansion": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz"
+ }
+ },
+ "minimist": {
+ "version": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+ "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
+ },
+ "mkdirp": {
+ "version": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+ "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+ "requires": {
+ "minimist": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz"
+ }
+ },
+ "moment": {
+ "version": "https://registry.npmjs.org/moment/-/moment-2.19.3.tgz",
+ "integrity": "sha1-vbmdJw1tf9p4zA+6zoVeJ/59pp8="
+ },
+ "ms": {
+ "version": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ },
+ "nan": {
+ "version": "https://registry.npmjs.org/nan/-/nan-2.6.2.tgz",
+ "integrity": "sha1-5P805slf37WuzAjeZZb0NgWn20U="
+ },
+ "node-pre-gyp": {
+ "version": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.6.36.tgz",
+ "integrity": "sha1-22BBEst04NR3VU6bUFsXq936t4Y=",
+ "requires": {
+ "mkdirp": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+ "nopt": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz",
+ "npmlog": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
+ "rc": "https://registry.npmjs.org/rc/-/rc-1.2.2.tgz",
+ "request": "https://registry.npmjs.org/request/-/request-2.83.0.tgz",
+ "rimraf": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
+ "semver": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz",
+ "tar": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz",
+ "tar-pack": "https://registry.npmjs.org/tar-pack/-/tar-pack-3.4.1.tgz"
+ }
+ },
+ "nopt": {
+ "version": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz",
+ "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=",
+ "requires": {
+ "abbrev": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
+ "osenv": "https://registry.npmjs.org/osenv/-/osenv-0.1.4.tgz"
+ }
+ },
+ "npmlog": {
+ "version": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
+ "integrity": "sha1-CKfyqL9zRgR3mp76StXMcXq7lUs=",
+ "requires": {
+ "are-we-there-yet": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz",
+ "console-control-strings": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
+ "gauge": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
+ "set-blocking": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz"
+ }
+ },
+ "number-is-nan": {
+ "version": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
+ "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
+ },
+ "oauth-sign": {
+ "version": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
+ "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM="
+ },
+ "object-assign": {
+ "version": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
+ },
+ "once": {
+ "version": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "requires": {
+ "wrappy": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz"
+ }
+ },
+ "os-homedir": {
+ "version": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
+ "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M="
+ },
+ "os-tmpdir": {
+ "version": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+ "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
+ },
+ "osenv": {
+ "version": "https://registry.npmjs.org/osenv/-/osenv-0.1.4.tgz",
+ "integrity": "sha1-Qv5tWVPfBsgGS+bxdsPQWqqjRkQ=",
+ "requires": {
+ "os-homedir": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
+ "os-tmpdir": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz"
+ }
+ },
+ "path-is-absolute": {
+ "version": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
+ },
+ "performance-now": {
+ "version": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
+ },
+ "process-nextick-args": {
+ "version": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
+ "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M="
+ },
+ "punycode": {
+ "version": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+ "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
+ },
+ "qs": {
+ "version": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
+ "integrity": "sha1-NJzfbu+J7EXBLX1es/wMhwNDptg="
+ },
+ "rc": {
+ "version": "https://registry.npmjs.org/rc/-/rc-1.2.2.tgz",
+ "integrity": "sha1-2M6ctX6NZNnHut2YdsfDTL48cHc=",
+ "requires": {
+ "deep-extend": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz",
+ "ini": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
+ "minimist": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "strip-json-comments": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
+ }
+ }
+ },
+ "readable-stream": {
+ "version": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
+ "integrity": "sha1-No8lEtefnUb9/HE0mueHi7weuVw=",
+ "requires": {
+ "core-util-is": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+ "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "isarray": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "process-nextick-args": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
+ "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
+ "string_decoder": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
+ "util-deprecate": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz"
+ }
+ },
+ "regenerator-runtime": {
+ "version": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz",
+ "integrity": "sha1-flT+W1zNXWYk6mJVw0c74JC4AuE="
+ },
+ "request": {
+ "version": "https://registry.npmjs.org/request/-/request-2.83.0.tgz",
+ "integrity": "sha1-ygtl2gLtYpNYh4COb1EDgQNOM1Y=",
+ "requires": {
+ "aws-sign2": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
+ "aws4": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz",
+ "caseless": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+ "combined-stream": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz",
+ "extend": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
+ "forever-agent": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+ "form-data": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz",
+ "har-validator": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz",
+ "hawk": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz",
+ "http-signature": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
+ "is-typedarray": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+ "isstream": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+ "json-stringify-safe": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+ "mime-types": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz",
+ "oauth-sign": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
+ "performance-now": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+ "qs": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
+ "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
+ "stringstream": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
+ "tough-cookie": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz",
+ "tunnel-agent": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+ "uuid": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz"
+ }
+ },
+ "rimraf": {
+ "version": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
+ "integrity": "sha1-LtgVDSShbqhlHm1u8PR8QVjOejY=",
+ "requires": {
+ "glob": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz"
+ }
+ },
+ "safe-buffer": {
+ "version": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
+ "integrity": "sha1-iTMSr2myEj3vcfV4iQAWce6yyFM="
+ },
+ "semver": {
+ "version": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz",
+ "integrity": "sha1-4FnAnYVx8FQII3M0M1BdOi8AsY4="
+ },
+ "set-blocking": {
+ "version": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
+ },
+ "signal-exit": {
+ "version": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
+ "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0="
+ },
+ "sntp": {
+ "version": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz",
+ "integrity": "sha1-LGzsFP7cIiJznK+bXD2F0cxaLMg=",
+ "requires": {
+ "hoek": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz"
+ }
+ },
+ "sprintf-js": {
+ "version": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.1.tgz",
+ "integrity": "sha1-Nr54Mgr+WAH2zqPueLblqrlA6gw="
+ },
+ "sshpk": {
+ "version": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz",
+ "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=",
+ "requires": {
+ "asn1": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
+ "assert-plus": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "bcrypt-pbkdf": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
+ "dashdash": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+ "ecc-jsbn": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
+ "getpass": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+ "jsbn": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+ "tweetnacl": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz"
+ }
+ },
+ "string-width": {
+ "version": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+ "requires": {
+ "code-point-at": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
+ "is-fullwidth-code-point": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+ "strip-ansi": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz"
+ }
+ },
+ "string_decoder": {
+ "version": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
+ "integrity": "sha1-D8Z9fBQYJd6UKC3VNr7GubzoYKs=",
+ "requires": {
+ "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz"
+ }
+ },
+ "stringstream": {
+ "version": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
+ "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg="
+ },
+ "strip-ansi": {
+ "version": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "requires": {
+ "ansi-regex": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz"
+ }
+ },
+ "strip-json-comments": {
+ "version": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+ "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo="
+ },
+ "tar": {
+ "version": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz",
+ "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=",
+ "requires": {
+ "block-stream": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz",
+ "fstream": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz",
+ "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz"
+ }
+ },
+ "tar-pack": {
+ "version": "https://registry.npmjs.org/tar-pack/-/tar-pack-3.4.1.tgz",
+ "integrity": "sha1-4dvAOpudO6B+iWrQJzF+tnmhCh8=",
+ "requires": {
+ "debug": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "fstream": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz",
+ "fstream-ignore": "https://registry.npmjs.org/fstream-ignore/-/fstream-ignore-1.0.5.tgz",
+ "once": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "readable-stream": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
+ "rimraf": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
+ "tar": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz",
+ "uid-number": "https://registry.npmjs.org/uid-number/-/uid-number-0.0.6.tgz"
+ }
+ },
+ "toastr": {
+ "version": "https://registry.npmjs.org/toastr/-/toastr-2.1.2.tgz",
+ "integrity": "sha1-/WkGaudXilszV3JfycfDNem2gd8="
+ },
+ "tough-cookie": {
+ "version": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz",
+ "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=",
+ "requires": {
+ "punycode": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz"
+ }
+ },
+ "tunnel-agent": {
+ "version": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+ "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
+ "requires": {
+ "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz"
+ }
+ },
+ "tweetnacl": {
+ "version": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+ "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
+ "optional": true
+ },
+ "uid-number": {
+ "version": "https://registry.npmjs.org/uid-number/-/uid-number-0.0.6.tgz",
+ "integrity": "sha1-DqEOgDXo61uOREnwbaHHMGY7qoE="
+ },
+ "underscore": {
+ "version": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz",
+ "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI="
+ },
+ "underscore.string": {
+ "version": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.4.tgz",
+ "integrity": "sha1-LCo/n4PmR2L9xF5s6sZRQoZCE9s=",
+ "requires": {
+ "sprintf-js": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.1.tgz",
+ "util-deprecate": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz"
+ }
+ },
+ "util-deprecate": {
+ "version": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
+ },
+ "uuid": {
+ "version": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz",
+ "integrity": "sha1-PdPT55Crwk17DToDT/q6vijrvAQ="
+ },
+ "verror": {
+ "version": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+ "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
+ "requires": {
+ "assert-plus": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "core-util-is": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+ "extsprintf": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz"
+ }
+ },
+ "wide-align": {
+ "version": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz",
+ "integrity": "sha1-Vx4PGwYEY268DfwhsDObvjE0FxA=",
+ "requires": {
+ "string-width": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz"
+ }
+ },
+ "wrappy": {
+ "version": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
+ }
+ }
+}
diff --git a/packages/rocketchat-livechat/app/package.json b/packages/rocketchat-livechat/.app/package.json
similarity index 100%
rename from packages/rocketchat-livechat/app/package.json
rename to packages/rocketchat-livechat/.app/package.json
diff --git a/packages/rocketchat-livechat/app/run.sh b/packages/rocketchat-livechat/.app/run.sh
similarity index 100%
rename from packages/rocketchat-livechat/app/run.sh
rename to packages/rocketchat-livechat/.app/run.sh
diff --git a/packages/rocketchat-livechat/app/client/startup/visitor.js b/packages/rocketchat-livechat/app/client/startup/visitor.js
deleted file mode 100644
index bd27d17e99af..000000000000
--- a/packages/rocketchat-livechat/app/client/startup/visitor.js
+++ /dev/null
@@ -1,21 +0,0 @@
-this.visitorId = new ReactiveVar(null);
-
-Meteor.startup(() => {
- if (!localStorage.getItem('rocketChatLivechat')) {
- localStorage.setItem('rocketChatLivechat', Random.id());
- } else {
- Tracker.autorun(c => {
- if (!Meteor.userId() && visitor.getToken()) {
- Meteor.call('livechat:loginByToken', visitor.getToken(), (err, result) => {
- if (result && result.token) {
- Meteor.loginWithToken(result.token, () => {
- c.stop();
- });
- }
- });
- }
- });
- }
-
- this.visitorId.set(localStorage.getItem('rocketChatLivechat'));
-});
diff --git a/packages/rocketchat-livechat/client/collections/LivechatVisitor.js b/packages/rocketchat-livechat/client/collections/LivechatVisitor.js
new file mode 100644
index 000000000000..e2b44ef3f14f
--- /dev/null
+++ b/packages/rocketchat-livechat/client/collections/LivechatVisitor.js
@@ -0,0 +1 @@
+this.LivechatVisitor = new Mongo.Collection('rocketchat_livechat_visitor');
diff --git a/packages/rocketchat-livechat/client/views/app/tabbar/visitorForward.js b/packages/rocketchat-livechat/client/views/app/tabbar/visitorForward.js
index 97afe34d0a99..58331022a08f 100644
--- a/packages/rocketchat-livechat/client/views/app/tabbar/visitorForward.js
+++ b/packages/rocketchat-livechat/client/views/app/tabbar/visitorForward.js
@@ -68,7 +68,7 @@ Template.visitorForward.events({
},
'change #forwardUser, blur #forwardUser'(event, instance) {
- if (event.currentTarget.value) {
+ if (event.currentTarget.value && instance.find('#forwardDepartment')) {
instance.find('#forwardDepartment').value = '';
}
},
diff --git a/packages/rocketchat-livechat/client/views/app/tabbar/visitorInfo.js b/packages/rocketchat-livechat/client/views/app/tabbar/visitorInfo.js
index e23925b2a91c..d7c745ef730b 100644
--- a/packages/rocketchat-livechat/client/views/app/tabbar/visitorInfo.js
+++ b/packages/rocketchat-livechat/client/views/app/tabbar/visitorInfo.js
@@ -1,3 +1,5 @@
+/* globals LivechatVisitor */
+
import _ from 'underscore';
import s from 'underscore.string';
import moment from 'moment';
@@ -243,6 +245,6 @@ Template.visitorInfo.onCreated(function() {
}
this.autorun(() => {
- this.user.set(Meteor.users.findOne({ '_id': this.visitorId.get() }));
+ this.user.set(LivechatVisitor.findOne({ '_id': this.visitorId.get() }));
});
});
diff --git a/packages/rocketchat-livechat/config.js b/packages/rocketchat-livechat/config.js
index 2d0500d738d8..b404935af44e 100644
--- a/packages/rocketchat-livechat/config.js
+++ b/packages/rocketchat-livechat/config.js
@@ -131,6 +131,27 @@ Meteor.startup(function() {
i18nLabel: 'Send_request_on_offline_messages'
});
+ RocketChat.settings.add('Livechat_webhook_on_capture', false, {
+ type: 'boolean',
+ group: 'Livechat',
+ section: 'CRM_Integration',
+ i18nLabel: 'Send_request_on_lead_capture'
+ });
+
+ RocketChat.settings.add('Livechat_lead_email_regex', '\\b[A-Z0-9._%+-]+@(?:[A-Z0-9-]+\\.)+[A-Z]{2,4}\\b', {
+ type: 'string',
+ group: 'Livechat',
+ section: 'CRM_Integration',
+ i18nLabel: 'Lead_capture_email_regex'
+ });
+
+ RocketChat.settings.add('Livechat_lead_phone_regex', '((?:\\([0-9]{1,3}\\)|[0-9]{2})[ \\-]*?[0-9]{4,5}(?:[\\-\\s\\_]{1,2})?[0-9]{4}(?:(?=[^0-9])|$)|[0-9]{4,5}(?:[\\-\\s\\_]{1,2})?[0-9]{4}(?:(?=[^0-9])|$))', {
+ type: 'string',
+ group: 'Livechat',
+ section: 'CRM_Integration',
+ i18nLabel: 'Lead_capture_phone_regex'
+ });
+
RocketChat.settings.add('Livechat_Knowledge_Enabled', false, {
type: 'boolean',
group: 'Livechat',
diff --git a/packages/rocketchat-livechat/imports/server/rest/sms.js b/packages/rocketchat-livechat/imports/server/rest/sms.js
index c01a1b34fb06..56ca236c3b5b 100644
--- a/packages/rocketchat-livechat/imports/server/rest/sms.js
+++ b/packages/rocketchat-livechat/imports/server/rest/sms.js
@@ -1,10 +1,12 @@
+import LivechatVisitors from '../../../server/models/LivechatVisitors';
+
RocketChat.API.v1.addRoute('livechat/sms-incoming/:service', {
post() {
const SMSService = RocketChat.SMS.getService(this.urlParams.service);
const sms = SMSService.parse(this.bodyParams);
- let visitor = RocketChat.models.Users.findOneVisitorByPhone(sms.from);
+ let visitor = LivechatVisitors.findOneVisitorByPhone(sms.from);
const sendMessage = {
message: {
@@ -18,19 +20,19 @@ RocketChat.API.v1.addRoute('livechat/sms-incoming/:service', {
};
if (visitor) {
- const rooms = RocketChat.models.Rooms.findOpenByVisitorToken(visitor.profile.token).fetch();
+ const rooms = RocketChat.models.Rooms.findOpenByVisitorToken(visitor.token).fetch();
if (rooms && rooms.length > 0) {
sendMessage.message.rid = rooms[0]._id;
} else {
sendMessage.message.rid = Random.id();
}
- sendMessage.message.token = visitor.profile.token;
+ sendMessage.message.token = visitor.token;
} else {
sendMessage.message.rid = Random.id();
sendMessage.message.token = Random.id();
- const userId = RocketChat.Livechat.registerGuest({
+ const visitorId = RocketChat.Livechat.registerGuest({
username: sms.from.replace(/[^0-9]/g, ''),
token: sendMessage.message.token,
phone: {
@@ -38,7 +40,7 @@ RocketChat.API.v1.addRoute('livechat/sms-incoming/:service', {
}
});
- visitor = RocketChat.models.Users.findOneById(userId);
+ visitor = LivechatVisitors.findOneById(visitorId);
}
sendMessage.message.msg = sms.body;
diff --git a/packages/rocketchat-livechat/package.js b/packages/rocketchat-livechat/package.js
index f6312b1e8cb0..ea9bbad4675e 100644
--- a/packages/rocketchat-livechat/package.js
+++ b/packages/rocketchat-livechat/package.js
@@ -44,6 +44,7 @@ Package.onUse(function(api) {
api.addFiles('livechat.js', 'server');
api.addFiles('server/startup.js', 'server');
+ api.addFiles('server/visitorStatus.js', 'server');
api.addFiles('permissions.js', 'server');
api.addFiles('messageTypes.js');
api.addFiles('roomType.js');
@@ -66,6 +67,7 @@ Package.onUse(function(api) {
api.addFiles('client/collections/LivechatTrigger.js', 'client');
api.addFiles('client/collections/LivechatInquiry.js', 'client');
api.addFiles('client/collections/livechatOfficeHour.js', 'client');
+ api.addFiles('client/collections/LivechatVisitor.js', 'client');
api.addFiles('client/methods/changeLivechatStatus.js', 'client');
@@ -129,6 +131,7 @@ Package.onUse(function(api) {
// hooks
api.addFiles('server/hooks/externalMessage.js', 'server');
+ api.addFiles('server/hooks/leadCapture.js', 'server');
api.addFiles('server/hooks/markRoomResponded.js', 'server');
api.addFiles('server/hooks/offlineMessage.js', 'server');
api.addFiles('server/hooks/RDStation.js', 'server');
@@ -145,6 +148,7 @@ Package.onUse(function(api) {
api.addFiles('server/methods/getCustomFields.js', 'server');
api.addFiles('server/methods/getAgentData.js', 'server');
api.addFiles('server/methods/getInitialData.js', 'server');
+ api.addFiles('server/methods/loadHistory.js', 'server');
api.addFiles('server/methods/loginByToken.js', 'server');
api.addFiles('server/methods/pageVisited.js', 'server');
api.addFiles('server/methods/registerGuest.js', 'server');
diff --git a/packages/rocketchat-livechat/plugin/build.bat b/packages/rocketchat-livechat/plugin/build.bat
index d586b8120482..bf51ac5c687b 100644
--- a/packages/rocketchat-livechat/plugin/build.bat
+++ b/packages/rocketchat-livechat/plugin/build.bat
@@ -1,7 +1,7 @@
@echo off
SET NODE_ENV="production"
-cd packages/rocketchat-livechat/app
+cd packages/rocketchat-livechat/.app
call meteor npm install --production
call meteor build --headless --directory .meteor/build/
diff --git a/packages/rocketchat-livechat/plugin/build.sh b/packages/rocketchat-livechat/plugin/build.sh
index 1039e6a20717..f44175f215b0 100644
--- a/packages/rocketchat-livechat/plugin/build.sh
+++ b/packages/rocketchat-livechat/plugin/build.sh
@@ -3,7 +3,7 @@ export LIVECHAT_DIR="../../../public/livechat"
export BUILD_DIR="../build"
export BUNDLE_DIR="../build/bundle/programs/web.browser"
-cd packages/rocketchat-livechat/app
+cd packages/rocketchat-livechat/.app
meteor npm install --production
meteor build --headless --directory $BUILD_DIR
diff --git a/packages/rocketchat-livechat/roomType.js b/packages/rocketchat-livechat/roomType.js
index 19d4d1650f17..5a012f7edf5d 100644
--- a/packages/rocketchat-livechat/roomType.js
+++ b/packages/rocketchat-livechat/roomType.js
@@ -57,19 +57,13 @@ class LivechatRoomType extends RoomTypeConfig {
}
getUserStatus(roomId) {
- let guestName;
const room = Session.get(`roomData${ roomId }`);
-
if (room) {
- guestName = room.v && room.v.username;
- } else {
- const inquiry = LivechatInquiry.findOne({rid: roomId});
- guestName = inquiry && inquiry.v && inquiry.v.username;
+ return room.v && room.v.status;
}
- if (guestName) {
- return Session.get(`user_${ guestName }_status`);
- }
+ const inquiry = LivechatInquiry.findOne({ rid: roomId });
+ return inquiry && inquiry.v && inquiry.v.status;
}
allowRoomSettingChange(room, setting) {
diff --git a/packages/rocketchat-livechat/server/hooks/leadCapture.js b/packages/rocketchat-livechat/server/hooks/leadCapture.js
new file mode 100644
index 000000000000..0d3cc63e66bf
--- /dev/null
+++ b/packages/rocketchat-livechat/server/hooks/leadCapture.js
@@ -0,0 +1,53 @@
+import LivechatVisitors from '../../server/models/LivechatVisitors';
+
+function validateMessage(message, room) {
+ // skips this callback if the message was edited
+ if (message.editedAt) {
+ return false;
+ }
+
+ if (!RocketChat.settings.get('Livechat_Facebook_Enabled')) {
+ return false;
+ }
+
+ // only send the sms by SMS if it is a livechat room with SMS set to true
+ if (!(typeof room.t !== 'undefined' && room.t === 'l' && room.v && room.v.token)) {
+ return false;
+ }
+
+ // if the message hasn't a token, it was NOT sent from the visitor, so ignore it
+ if (!message.token) {
+ return false;
+ }
+
+ // if the message has a type means it is a special message (like the closing comment), so skips
+ if (message.t) {
+ return false;
+ }
+
+ return true;
+}
+
+RocketChat.callbacks.add('afterSaveMessage', function(message, room) {
+ if (!RocketChat.settings.get('Livechat_webhook_on_capture')) {
+ return message;
+ }
+
+ if (!validateMessage(message, room)) {
+ return message;
+ }
+
+ const phoneRegexp = new RegExp(RocketChat.settings.get('Livechat_lead_phone_regex'), 'g');
+ const msgPhones = message.msg.match(phoneRegexp);
+
+ const emailRegexp = new RegExp(RocketChat.settings.get('Livechat_lead_email_regex'), 'gi');
+ const msgEmails = message.msg.match(emailRegexp);
+
+ if (msgEmails || msgPhones) {
+ LivechatVisitors.saveGuestEmailPhoneById(room.v._id, msgEmails, msgPhones);
+
+ RocketChat.callbacks.run('livechat.leadCapture', room);
+ }
+
+ return message;
+}, RocketChat.callbacks.priority.LOW, 'leadCapture');
diff --git a/packages/rocketchat-livechat/server/hooks/sendToCRM.js b/packages/rocketchat-livechat/server/hooks/sendToCRM.js
index 7a09bbc0fed9..8b2926997a29 100644
--- a/packages/rocketchat-livechat/server/hooks/sendToCRM.js
+++ b/packages/rocketchat-livechat/server/hooks/sendToCRM.js
@@ -1,37 +1,27 @@
-function sendToCRM(hook, room) {
- if (!RocketChat.settings.get('Livechat_webhook_on_close')) {
- return room;
- }
-
- // Do not send to CRM if the chat is still open
- if (hook === 'saveLivechatInfo' && room.open) {
- return room;
- }
-
+function sendToCRM(type, room, includeMessages = true) {
const postData = RocketChat.Livechat.getLivechatRoomGuestInfo(room);
- if (hook === 'closeRoom') {
- postData.type = 'LivechatSession';
- } else if (hook === 'saveLivechatInfo') {
- postData.type = 'LivechatEdit';
- }
+
+ postData.type = type;
postData.messages = [];
- RocketChat.models.Messages.findVisibleByRoomId(room._id, { sort: { ts: 1 } }).forEach((message) => {
- if (message.t) {
- return;
- }
- const msg = {
- username: message.u.username,
- msg: message.msg,
- ts: message.ts
- };
-
- if (message.u.username !== postData.visitor.username) {
- msg.agentId = message.u._id;
- }
- postData.messages.push(msg);
- });
+ if (includeMessages) {
+ RocketChat.models.Messages.findVisibleByRoomId(room._id, { sort: { ts: 1 } }).forEach((message) => {
+ if (message.t) {
+ return;
+ }
+ const msg = {
+ username: message.u.username,
+ msg: message.msg,
+ ts: message.ts
+ };
+
+ if (message.u.username !== postData.visitor.username) {
+ msg.agentId = message.u._id;
+ }
+ postData.messages.push(msg);
+ });
+ }
const response = RocketChat.Livechat.sendRequest(postData);
@@ -43,9 +33,22 @@ function sendToCRM(hook, room) {
}
RocketChat.callbacks.add('livechat.closeRoom', (room) => {
- return sendToCRM('closeRoom', room);
+ if (!RocketChat.settings.get('Livechat_webhook_on_close')) {
+ return room;
+ }
+
+ return sendToCRM('LivechatSession', room);
}, RocketChat.callbacks.priority.MEDIUM, 'livechat-send-crm-close-room');
RocketChat.callbacks.add('livechat.saveInfo', (room) => {
- return sendToCRM('saveLivechatInfo', room);
+ // Do not send to CRM if the chat is still open
+ if (room.open) {
+ return room;
+ }
+
+ return sendToCRM('LivechatEdit', room);
}, RocketChat.callbacks.priority.MEDIUM, 'livechat-send-crm-save-info');
+
+RocketChat.callbacks.add('livechat.leadCapture', (room) => {
+ return sendToCRM('LeadCapture', room, false);
+}, RocketChat.callbacks.priority.MEDIUM, 'livechat-send-crm-lead-capture');
diff --git a/packages/rocketchat-livechat/server/lib/Livechat.js b/packages/rocketchat-livechat/server/lib/Livechat.js
index 11d85e9fe84a..2769b7ff2e35 100644
--- a/packages/rocketchat-livechat/server/lib/Livechat.js
+++ b/packages/rocketchat-livechat/server/lib/Livechat.js
@@ -2,6 +2,7 @@
import _ from 'underscore';
import s from 'underscore.string';
import UAParser from 'ua-parser-js';
+import LivechatVisitors from '../models/LivechatVisitors';
RocketChat.Livechat = {
historyMonitorType: 'url',
@@ -60,10 +61,9 @@ RocketChat.Livechat = {
room = RocketChat.QueueMethods[routingMethod](guest, message, roomInfo);
newRoom = true;
- } else {
- room = Meteor.call('canAccessRoom', message.rid, guest._id);
}
- if (!room) {
+
+ if (!room || room.v.token !== guest.token) {
throw new Meteor.Error('cannot-access-room');
}
@@ -78,53 +78,33 @@ RocketChat.Livechat = {
// return messages;
return _.extend(RocketChat.sendMessage(guest, message, room), { newRoom, showConnecting: this.showConnecting() });
},
- registerGuest({ token, name, email, department, phone, loginToken, username } = {}) {
+ registerGuest({ token, name, email, department, phone, username } = {}) {
check(token, String);
let userId;
const updateUser = {
$set: {
- profile: {
- guest: true,
- token
- }
+ token
}
};
- const user = RocketChat.models.Users.getVisitorByToken(token, { fields: { _id: 1 } });
+ const user = LivechatVisitors.getVisitorByToken(token, { fields: { _id: 1 } });
if (user) {
userId = user._id;
- if (loginToken) {
- if (!updateUser.$addToSet) {
- updateUser.$addToSet = {};
- }
- updateUser.$addToSet['services.resume.loginTokens'] = loginToken;
- }
} else {
if (!username) {
- username = RocketChat.models.Users.getNextVisitorUsername();
+ username = LivechatVisitors.getNextVisitorUsername();
}
let existingUser = null;
- if (s.trim(email) !== '' && (existingUser = RocketChat.models.Users.findOneGuestByEmailAddress(email))) {
- if (loginToken) {
- if (!updateUser.$addToSet) {
- updateUser.$addToSet = {};
- }
- updateUser.$addToSet['services.resume.loginTokens'] = loginToken;
- }
-
+ if (s.trim(email) !== '' && (existingUser = LivechatVisitors.findOneGuestByEmailAddress(email))) {
userId = existingUser._id;
} else {
-
const userData = {
username,
- globalRoles: ['livechat-guest'],
- department,
- type: 'visitor',
- joinDefaultChannels: false
+ department
};
if (this.connection) {
@@ -133,15 +113,7 @@ RocketChat.Livechat = {
userData.host = this.connection.httpHeaders.host;
}
- userId = Accounts.insertUserDoc({}, userData);
-
- if (loginToken) {
- updateUser.$set.services = {
- resume: {
- loginTokens: [ loginToken ]
- }
- };
- }
+ userId = LivechatVisitors.insert(userData);
}
}
@@ -158,10 +130,10 @@ RocketChat.Livechat = {
}
if (name) {
- RocketChat._setRealName(userId, name);
+ updateUser.$set.name = name;
}
- Meteor.users.update(userId, updateUser);
+ LivechatVisitors.updateById(userId, updateUser);
return userId;
},
@@ -174,7 +146,7 @@ RocketChat.Livechat = {
}
};
- const user = RocketChat.models.Users.getVisitorByToken(token, { fields: { _id: 1 } });
+ const user = LivechatVisitors.getVisitorByToken(token, { fields: { _id: 1 } });
if (user) {
return Meteor.users.update(user._id, updateUser);
}
@@ -192,7 +164,7 @@ RocketChat.Livechat = {
if (phone) {
updateData.phone = phone;
}
- const ret = RocketChat.models.Users.saveGuestById(_id, updateData);
+ const ret = LivechatVisitors.saveGuestById(_id, updateData);
Meteor.defer(() => {
RocketChat.callbacks.run('livechat.saveGuest', updateData);
@@ -201,16 +173,29 @@ RocketChat.Livechat = {
return ret;
},
- closeRoom({ user, room, comment }) {
+ closeRoom({ user, visitor, room, comment }) {
const now = new Date();
- RocketChat.models.Rooms.closeByRoomId(room._id, {
- user: {
- _id: user._id,
- username: user.username
- },
+
+ const closeData = {
closedAt: now,
chatDuration: (now.getTime() - room.ts) / 1000
- });
+ };
+
+ if (user) {
+ closeData.closer = 'user';
+ closeData.closedBy = {
+ _id: user._id,
+ username: user.username
+ };
+ } else if (visitor) {
+ closeData.closer = 'visitor';
+ closeData.closedBy = {
+ _id: visitor._id,
+ username: visitor.username
+ };
+ }
+
+ RocketChat.models.Rooms.closeByRoomId(room._id, closeData);
const message = {
t: 'livechat-close',
@@ -220,8 +205,8 @@ RocketChat.Livechat = {
RocketChat.sendMessage(user, message, room);
- RocketChat.models.Subscriptions.hideByRoomIdAndUserId(room._id, user._id);
- RocketChat.models.Messages.createCommandWithRoomIdAndUser('promptTranscript', room._id, user);
+ RocketChat.models.Subscriptions.hideByRoomIdAndUserId(room._id, room.servedBy._id);
+ RocketChat.models.Messages.createCommandWithRoomIdAndUser('promptTranscript', room._id, room.servedBy);
Meteor.defer(() => {
RocketChat.callbacks.run('livechat.closeRoom', room);
@@ -372,7 +357,7 @@ RocketChat.Livechat = {
},
getLivechatRoomGuestInfo(room) {
- const visitor = RocketChat.models.Users.findOneById(room.v._id);
+ const visitor = LivechatVisitors.findOneById(room.v._id);
const agent = RocketChat.models.Users.findOneById(room.servedBy._id);
const ua = new UAParser();
@@ -412,14 +397,14 @@ RocketChat.Livechat = {
}
if (visitor.visitorEmails && visitor.visitorEmails.length > 0) {
- postData.visitor.email = visitor.visitorEmails[0].address;
+ postData.visitor.email = visitor.visitorEmails;
}
if (visitor.phone && visitor.phone.length > 0) {
- postData.visitor.phone = visitor.phone[0].phoneNumber;
+ postData.visitor.phone = visitor.phone;
}
if (agent.emails && agent.emails.length > 0) {
- postData.agent.email = agent.emails[0].address;
+ postData.agent.email = agent.emails;
}
return postData;
@@ -538,7 +523,18 @@ RocketChat.Livechat = {
};
RocketChat.Livechat.stream = new Meteor.Streamer('livechat-room');
-RocketChat.Livechat.stream.allowRead('logged');
+
+RocketChat.Livechat.stream.allowRead((roomId, extraData) => {
+ const room = RocketChat.models.Rooms.findOneById(roomId);
+ if (!room) {
+ console.warn(`Invalid eventName: "${ roomId }"`);
+ return false;
+ }
+ if (room.t === 'l' && extraData && extraData.token && room.v.token === extraData.token) {
+ return true;
+ }
+ return false;
+});
RocketChat.settings.get('Livechat_history_monitor_type', (key, value) => {
RocketChat.Livechat.historyMonitorType = value;
diff --git a/packages/rocketchat-livechat/server/lib/QueueMethods.js b/packages/rocketchat-livechat/server/lib/QueueMethods.js
index 318ce9918f76..d882ee4f98fb 100644
--- a/packages/rocketchat-livechat/server/lib/QueueMethods.js
+++ b/packages/rocketchat-livechat/server/lib/QueueMethods.js
@@ -26,7 +26,8 @@ RocketChat.QueueMethods = {
v: {
_id: guest._id,
username: guest.username,
- token: message.token
+ token: message.token,
+ status: guest.status || 'online'
},
servedBy: {
_id: agent.agentId,
@@ -109,7 +110,8 @@ RocketChat.QueueMethods = {
v: {
_id: guest._id,
username: guest.username,
- token: message.token
+ token: message.token,
+ status: guest.status || 'online'
},
t: 'l'
};
@@ -125,7 +127,8 @@ RocketChat.QueueMethods = {
v: {
_id: guest._id,
username: guest.username,
- token: message.token
+ token: message.token,
+ status: guest.status
},
cl: false,
open: true,
diff --git a/packages/rocketchat-livechat/server/methods/closeByVisitor.js b/packages/rocketchat-livechat/server/methods/closeByVisitor.js
index 4aa20f1a1c8c..c6c54596c53d 100644
--- a/packages/rocketchat-livechat/server/methods/closeByVisitor.js
+++ b/packages/rocketchat-livechat/server/methods/closeByVisitor.js
@@ -1,21 +1,19 @@
-Meteor.methods({
- 'livechat:closeByVisitor'(roomId) {
- if (!Meteor.userId()) {
- throw new Meteor.Error('error-not-authorized', 'Not authorized', { method: 'livechat:closeByVisitor' });
- }
+import LivechatVisitors from '../models/LivechatVisitors';
- const room = RocketChat.models.Rooms.findOneOpenByVisitorId(Meteor.userId(), roomId);
+Meteor.methods({
+ 'livechat:closeByVisitor'({ roomId, token }) {
+ const room = RocketChat.models.Rooms.findOneOpenByVisitorToken(token, roomId);
if (!room || !room.open) {
return false;
}
- const user = Meteor.user();
+ const visitor = LivechatVisitors.getVisitorByToken(token);
- const language = (user && user.language) || RocketChat.settings.get('language') || 'en';
+ const language = (visitor && visitor.language) || RocketChat.settings.get('language') || 'en';
return RocketChat.Livechat.closeRoom({
- user,
+ visitor,
room,
comment: TAPi18n.__('Closed_by_visitor', { lng: language })
});
diff --git a/packages/rocketchat-livechat/server/methods/getAgentData.js b/packages/rocketchat-livechat/server/methods/getAgentData.js
index 98f8e2808ae8..75a6981abb51 100644
--- a/packages/rocketchat-livechat/server/methods/getAgentData.js
+++ b/packages/rocketchat-livechat/server/methods/getAgentData.js
@@ -1,12 +1,15 @@
+import LivechatVisitors from '../models/LivechatVisitors';
+
Meteor.methods({
- 'livechat:getAgentData'(roomId) {
+ 'livechat:getAgentData'({ roomId, token }) {
check(roomId, String);
+ check(token, String);
const room = RocketChat.models.Rooms.findOneById(roomId);
- const user = Meteor.user();
+ const visitor = LivechatVisitors.getVisitorByToken(token);
// allow to only user to send transcripts from their own chats
- if (!room || room.t !== 'l' || !room.v || !user.profile || room.v.token !== user.profile.token) {
+ if (!room || room.t !== 'l' || !room.v || room.v.token !== visitor.token) {
throw new Meteor.Error('error-invalid-room', 'Invalid room');
}
diff --git a/packages/rocketchat-livechat/server/methods/getInitialData.js b/packages/rocketchat-livechat/server/methods/getInitialData.js
index 26e99aef2ffa..bca2a9787764 100644
--- a/packages/rocketchat-livechat/server/methods/getInitialData.js
+++ b/packages/rocketchat-livechat/server/methods/getInitialData.js
@@ -1,5 +1,7 @@
import _ from 'underscore';
+import LivechatVisitors from '../models/LivechatVisitors';
+
Meteor.methods({
'livechat:getInitialData'(visitorToken) {
const info = {
@@ -8,6 +10,7 @@ Meteor.methods({
color: null,
registrationForm: null,
room: null,
+ visitor: null,
triggers: [],
departments: [],
allowSwitchingDepartments: null,
@@ -36,6 +39,18 @@ Meteor.methods({
info.room = room[0];
}
+ const visitor = LivechatVisitors.getVisitorByToken(visitorToken, {
+ fields: {
+ name: 1,
+ username: 1,
+ visitorEmails: 1
+ }
+ });
+
+ if (room) {
+ info.visitor = visitor;
+ }
+
const initSettings = RocketChat.Livechat.getInitSettings();
info.title = initSettings.Livechat_title;
diff --git a/packages/rocketchat-livechat/server/methods/loadHistory.js b/packages/rocketchat-livechat/server/methods/loadHistory.js
new file mode 100644
index 000000000000..fdbab8bcc23c
--- /dev/null
+++ b/packages/rocketchat-livechat/server/methods/loadHistory.js
@@ -0,0 +1,13 @@
+import LivechatVisitors from '../models/LivechatVisitors';
+
+Meteor.methods({
+ 'livechat:loadHistory'({ token, rid, end, limit = 20, ls}) {
+ const visitor = LivechatVisitors.getVisitorByToken(token, { fields: { _id: 1 } });
+
+ if (!visitor) {
+ return;
+ }
+
+ return RocketChat.loadMessageHistory({ userId: visitor._id, rid, end, limit, ls });
+ }
+});
diff --git a/packages/rocketchat-livechat/server/methods/loginByToken.js b/packages/rocketchat-livechat/server/methods/loginByToken.js
index 78c08a4d454f..577bceb6c9f7 100644
--- a/packages/rocketchat-livechat/server/methods/loginByToken.js
+++ b/packages/rocketchat-livechat/server/methods/loginByToken.js
@@ -1,28 +1,15 @@
+import LivechatVisitors from '../models/LivechatVisitors';
+
Meteor.methods({
'livechat:loginByToken'(token) {
- const user = RocketChat.models.Users.getVisitorByToken(token, { fields: { _id: 1 } });
+ const user = LivechatVisitors.getVisitorByToken(token, { fields: { _id: 1 } });
if (!user) {
return;
}
- const stampedToken = Accounts._generateStampedLoginToken();
- const hashStampedToken = Accounts._hashStampedToken(stampedToken);
-
- const updateUser = {
- $set: {
- services: {
- resume: {
- loginTokens: [ hashStampedToken ]
- }
- }
- }
- };
-
- Meteor.users.update(user._id, updateUser);
-
return {
- token: stampedToken.token
+ _id: user._id
};
}
});
diff --git a/packages/rocketchat-livechat/server/methods/registerGuest.js b/packages/rocketchat-livechat/server/methods/registerGuest.js
index 9dcc0b9082cd..5cef4e7c19a4 100644
--- a/packages/rocketchat-livechat/server/methods/registerGuest.js
+++ b/packages/rocketchat-livechat/server/methods/registerGuest.js
@@ -1,22 +1,17 @@
Meteor.methods({
'livechat:registerGuest'({ token, name, email, department } = {}) {
- const stampedToken = Accounts._generateStampedLoginToken();
- const hashStampedToken = Accounts._hashStampedToken(stampedToken);
-
const userId = RocketChat.Livechat.registerGuest.call(this, {
token,
name,
email,
- department,
- loginToken: hashStampedToken
+ department
});
// update visited page history to not expire
RocketChat.models.LivechatPageVisited.keepHistoryForToken(token);
return {
- userId,
- token: stampedToken.token
+ userId
};
}
});
diff --git a/packages/rocketchat-livechat/server/methods/saveSurveyFeedback.js b/packages/rocketchat-livechat/server/methods/saveSurveyFeedback.js
index fb296b9ba249..ee1ec2ebe983 100644
--- a/packages/rocketchat-livechat/server/methods/saveSurveyFeedback.js
+++ b/packages/rocketchat-livechat/server/methods/saveSurveyFeedback.js
@@ -1,4 +1,5 @@
/* eslint new-cap: [2, {"capIsNewExceptions": ["Match.ObjectIncluding"]}] */
+import LivechatVisitors from '../models/LivechatVisitors';
import _ from 'underscore';
Meteor.methods({
@@ -7,10 +8,10 @@ Meteor.methods({
check(visitorRoom, String);
check(formData, [Match.ObjectIncluding({ name: String, value: String })]);
- const visitor = RocketChat.models.Users.getVisitorByToken(visitorToken);
+ const visitor = LivechatVisitors.getVisitorByToken(visitorToken);
const room = RocketChat.models.Rooms.findOneById(visitorRoom);
- if (visitor !== undefined && room !== undefined && room.v !== undefined && visitor.profile !== undefined && room.v.token === visitor.profile.token) {
+ if (visitor !== undefined && room !== undefined && room.v !== undefined && room.v.token === visitor.token) {
const updateData = {};
for (const item of formData) {
if (_.contains(['satisfaction', 'agentKnowledge', 'agentResposiveness', 'agentFriendliness'], item.name) && _.contains(['1', '2', '3', '4', '5'], item.value)) {
diff --git a/packages/rocketchat-livechat/server/methods/sendMessageLivechat.js b/packages/rocketchat-livechat/server/methods/sendMessageLivechat.js
index b34c80019d98..b112474e4aeb 100644
--- a/packages/rocketchat-livechat/server/methods/sendMessageLivechat.js
+++ b/packages/rocketchat-livechat/server/methods/sendMessageLivechat.js
@@ -1,16 +1,33 @@
+import LivechatVisitors from '../models/LivechatVisitors';
+
Meteor.methods({
- sendMessageLivechat(message) {
- check(message.rid, String);
- check(message.token, String);
+ sendMessageLivechat({ token, _id, rid, msg }) {
+ check(token, String);
+ check(_id, String);
+ check(rid, String);
+ check(msg, String);
- const guest = Meteor.users.findOne(Meteor.userId(), {
+ const guest = LivechatVisitors.getVisitorByToken(token, {
fields: {
name: 1,
username: 1,
- department: 1
+ department: 1,
+ token: 1
}
});
- return RocketChat.Livechat.sendMessage({ guest, message });
+ if (!guest) {
+ throw new Meteor.Error('invalid-token');
+ }
+
+ return RocketChat.Livechat.sendMessage({
+ guest,
+ message: {
+ _id,
+ rid,
+ msg,
+ token
+ }
+ });
}
});
diff --git a/packages/rocketchat-livechat/server/methods/sendTranscript.js b/packages/rocketchat-livechat/server/methods/sendTranscript.js
index a37a874a9c4f..949642ab232e 100644
--- a/packages/rocketchat-livechat/server/methods/sendTranscript.js
+++ b/packages/rocketchat-livechat/server/methods/sendTranscript.js
@@ -2,17 +2,20 @@
/* Send a transcript of the room converstation to the given email */
import moment from 'moment';
+import LivechatVisitors from '../models/LivechatVisitors';
+
Meteor.methods({
- 'livechat:sendTranscript'(rid, email) {
+ 'livechat:sendTranscript'(token, rid, email) {
check(rid, String);
check(email, String);
const room = RocketChat.models.Rooms.findOneById(rid);
- const user = Meteor.user();
- const userLanguage = user.language || RocketChat.settings.get('language') || 'en';
+
+ const visitor = LivechatVisitors.getVisitorByToken(token);
+ const userLanguage = (visitor && visitor.language) || RocketChat.settings.get('language') || 'en';
// allow to only user to send transcripts from their own chats
- if (!room || room.t !== 'l' || !room.v || !user.profile || room.v.token !== user.profile.token) {
+ if (!room || room.t !== 'l' || !room.v || room.v.token !== token) {
throw new Meteor.Error('error-invalid-room', 'Invalid room');
}
@@ -27,7 +30,7 @@ Meteor.methods({
}
let author;
- if (message.u._id === Meteor.userId()) {
+ if (message.u._id === visitor._id) {
author = TAPi18n.__('You', { lng: userLanguage });
} else {
author = message.u.username;
diff --git a/packages/rocketchat-livechat/server/methods/setCustomField.js b/packages/rocketchat-livechat/server/methods/setCustomField.js
index 5187cedde36e..1ff16847a5a0 100644
--- a/packages/rocketchat-livechat/server/methods/setCustomField.js
+++ b/packages/rocketchat-livechat/server/methods/setCustomField.js
@@ -1,3 +1,5 @@
+import LivechatVisitors from '../models/LivechatVisitors';
+
Meteor.methods({
'livechat:setCustomField'(token, key, value, overwrite = true) {
const customField = RocketChat.models.LivechatCustomField.findOneById(key);
@@ -6,7 +8,7 @@ Meteor.methods({
return RocketChat.models.Rooms.updateLivechatDataByToken(token, key, value, overwrite);
} else {
// Save in user
- return RocketChat.models.Users.updateLivechatDataByToken(token, key, value, overwrite);
+ return LivechatVisitors.updateLivechatDataByToken(token, key, value, overwrite);
}
}
diff --git a/packages/rocketchat-livechat/server/methods/transfer.js b/packages/rocketchat-livechat/server/methods/transfer.js
index aa842498cd23..e2af06273488 100644
--- a/packages/rocketchat-livechat/server/methods/transfer.js
+++ b/packages/rocketchat-livechat/server/methods/transfer.js
@@ -1,4 +1,7 @@
/* eslint new-cap: [2, {"capIsNewExceptions": ["Match.Optional"]}] */
+
+import LivechatVisitors from '../models/LivechatVisitors';
+
Meteor.methods({
'livechat:transfer'(transferData) {
if (!Meteor.userId() || !RocketChat.authz.hasPermission(Meteor.userId(), 'view-l-room')) {
@@ -13,7 +16,7 @@ Meteor.methods({
const room = RocketChat.models.Rooms.findOneById(transferData.roomId);
- const guest = RocketChat.models.Users.findOneById(room.v._id);
+ const guest = LivechatVisitors.findOneById(room.v._id);
const user = Meteor.user();
diff --git a/packages/rocketchat-livechat/server/models/LivechatInquiry.js b/packages/rocketchat-livechat/server/models/LivechatInquiry.js
index 29439c3a0dbd..c7800535f61c 100644
--- a/packages/rocketchat-livechat/server/models/LivechatInquiry.js
+++ b/packages/rocketchat-livechat/server/models/LivechatInquiry.js
@@ -43,6 +43,21 @@ class LivechatInquiry extends RocketChat.models._Base {
getStatus(inquiryId) {
return this.findOne({'_id': inquiryId}).status;
}
+
+ updateVisitorStatus(token, status) {
+ const query = {
+ 'v.token': token,
+ status: 'open'
+ };
+
+ const update = {
+ $set: {
+ 'v.status': status
+ }
+ };
+
+ return this.update(query, update);
+ }
}
RocketChat.models.LivechatInquiry = new LivechatInquiry();
diff --git a/packages/rocketchat-livechat/server/models/LivechatVisitors.js b/packages/rocketchat-livechat/server/models/LivechatVisitors.js
new file mode 100644
index 000000000000..d9eb7e7ce983
--- /dev/null
+++ b/packages/rocketchat-livechat/server/models/LivechatVisitors.js
@@ -0,0 +1,195 @@
+import _ from 'underscore';
+import s from 'underscore.string';
+
+class LivechatVisitors extends RocketChat.models._Base {
+ constructor() {
+ super('livechat_visitor');
+ }
+
+ /**
+ * Gets visitor by token
+ * @param {string} token - Visitor token
+ */
+ getVisitorByToken(token, options) {
+ const query = {
+ token
+ };
+
+ return this.findOne(query, options);
+ }
+
+ /**
+ * Find visitors by _id
+ * @param {string} token - Visitor token
+ */
+ findById(_id, options) {
+ const query = {
+ _id
+ };
+
+ return this.find(query, options);
+ }
+
+ /**
+ * Gets visitor by token
+ * @param {string} token - Visitor token
+ */
+ findVisitorByToken(token) {
+ const query = {
+ token
+ };
+
+ return this.find(query);
+ }
+
+ updateLivechatDataByToken(token, key, value, overwrite = true) {
+ const query = {
+ token
+ };
+
+ if (!overwrite) {
+ const user = this.findOne(query, { fields: { livechatData: 1 } });
+ if (user.livechatData && typeof user.livechatData[key] !== 'undefined') {
+ return true;
+ }
+ }
+
+ const update = {
+ $set: {
+ [`livechatData.${ key }`]: value
+ }
+ };
+
+ return this.update(query, update);
+ }
+
+ /**
+ * Find a visitor by their phone number
+ * @return {object} User from db
+ */
+ findOneVisitorByPhone(phone) {
+ const query = {
+ 'phone.phoneNumber': phone
+ };
+
+ return this.findOne(query);
+ }
+
+ /**
+ * Get the next visitor name
+ * @return {string} The next visitor name
+ */
+ getNextVisitorUsername() {
+ const settingsRaw = RocketChat.models.Settings.model.rawCollection();
+ const findAndModify = Meteor.wrapAsync(settingsRaw.findAndModify, settingsRaw);
+
+ const query = {
+ _id: 'Livechat_guest_count'
+ };
+
+ const update = {
+ $inc: {
+ value: 1
+ }
+ };
+
+ const livechatCount = findAndModify(query, null, update);
+
+ return `guest-${ livechatCount.value.value + 1 }`;
+ }
+
+ updateById(_id, update) {
+ return this.update({ _id }, update);
+ }
+
+ saveGuestById(_id, data) {
+ const setData = {};
+ const unsetData = {};
+
+ if (data.name) {
+ if (!_.isEmpty(s.trim(data.name))) {
+ setData.name = s.trim(data.name);
+ } else {
+ unsetData.name = 1;
+ }
+ }
+
+ if (data.email) {
+ if (!_.isEmpty(s.trim(data.email))) {
+ setData.visitorEmails = [
+ { address: s.trim(data.email) }
+ ];
+ } else {
+ unsetData.visitorEmails = 1;
+ }
+ }
+
+ if (data.phone) {
+ if (!_.isEmpty(s.trim(data.phone))) {
+ setData.phone = [
+ { phoneNumber: s.trim(data.phone) }
+ ];
+ } else {
+ unsetData.phone = 1;
+ }
+ }
+
+ const update = {};
+
+ if (!_.isEmpty(setData)) {
+ update.$set = setData;
+ }
+
+ if (!_.isEmpty(unsetData)) {
+ update.$unset = unsetData;
+ }
+
+ if (_.isEmpty(update)) {
+ return true;
+ }
+
+ return this.update({ _id }, update);
+ }
+
+ findOneGuestByEmailAddress(emailAddress) {
+ const query = {
+ 'visitorEmails.address': new RegExp(`^${ s.escapeRegExp(emailAddress) }$`, 'i')
+ };
+
+ return this.findOne(query);
+ }
+
+ saveGuestEmailPhoneById(_id, emails, phones) {
+ const update = {
+ $addToSet: {}
+ };
+
+ const saveEmail = [].concat(emails)
+ .filter(email => email && email.trim())
+ .map(email => {
+ return { address: email };
+ });
+
+ if (saveEmail.length > 0) {
+ update.$addToSet.visitorEmails = { $each: saveEmail };
+ }
+
+ const savePhone = [].concat(phones)
+ .filter(phone => phone && phone.trim().replace(/[^\d]/g, ''))
+ .map(phone => {
+ return { phoneNumber: phone };
+ });
+
+ if (savePhone.length > 0) {
+ update.$addToSet.phone = { $each: savePhone };
+ }
+
+ if (!update.$addToSet.visitorEmails && !update.$addToSet.phone) {
+ return;
+ }
+
+ return this.update({ _id }, update);
+ }
+}
+
+export default new LivechatVisitors();
diff --git a/packages/rocketchat-livechat/server/models/Rooms.js b/packages/rocketchat-livechat/server/models/Rooms.js
index 7fb8e5176a61..19003d79cb8e 100644
--- a/packages/rocketchat-livechat/server/models/Rooms.js
+++ b/packages/rocketchat-livechat/server/models/Rooms.js
@@ -117,11 +117,11 @@ RocketChat.models.Rooms.findByVisitorId = function(visitorId) {
return this.find(query);
};
-RocketChat.models.Rooms.findOneOpenByVisitorId = function(visitorId, roomId) {
+RocketChat.models.Rooms.findOneOpenByVisitorToken = function(token, roomId) {
const query = {
_id: roomId,
open: true,
- 'v._id': visitorId
+ 'v.token': token
};
return this.findOne(query);
@@ -150,12 +150,11 @@ RocketChat.models.Rooms.closeByRoomId = function(roomId, closeInfo) {
_id: roomId
}, {
$set: {
- closedBy: {
- _id: closeInfo.user._id,
- username: closeInfo.user.username
- },
+ closer: closeInfo.closer,
+ closedBy: closeInfo.closedBy,
closedAt: closeInfo.closedAt,
- chatDuration: closeInfo.chatDuration
+ chatDuration: closeInfo.chatDuration,
+ 'v.status': 'offline'
},
$unset: {
open: 1
@@ -204,3 +203,18 @@ RocketChat.models.Rooms.saveCRMDataByRoomId = function(roomId, crmData) {
return this.update(query, update);
};
+
+RocketChat.models.Rooms.updateVisitorStatus = function(token, status) {
+ const query = {
+ 'v.token': token,
+ open: true
+ };
+
+ const update = {
+ $set: {
+ 'v.status': status
+ }
+ };
+
+ return this.update(query, update);
+};
diff --git a/packages/rocketchat-livechat/server/models/Users.js b/packages/rocketchat-livechat/server/models/Users.js
index e44d648afd01..d34c072964e3 100644
--- a/packages/rocketchat-livechat/server/models/Users.js
+++ b/packages/rocketchat-livechat/server/models/Users.js
@@ -1,5 +1,3 @@
-import _ from 'underscore';
-import s from 'underscore.string';
/**
* Sets an user as (non)operator
* @param {string} _id - User's _id
@@ -104,32 +102,6 @@ RocketChat.models.Users.getNextAgent = function() {
}
};
-/**
- * Gets visitor by token
- * @param {string} token - Visitor token
- */
-RocketChat.models.Users.getVisitorByToken = function(token, options) {
- const query = {
- 'profile.guest': true,
- 'profile.token': token
- };
-
- return this.findOne(query, options);
-};
-
-/**
- * Gets visitor by token
- * @param {string} token - Visitor token
- */
-RocketChat.models.Users.findVisitorByToken = function(token) {
- const query = {
- 'profile.guest': true,
- 'profile.token': token
- };
-
- return this.find(query);
-};
-
/**
* Change user's livechat status
* @param {string} token - Visitor token
@@ -168,119 +140,6 @@ RocketChat.models.Users.openOffice = function() {
});
};
-RocketChat.models.Users.updateLivechatDataByToken = function(token, key, value, overwrite = true) {
- const query = {
- 'profile.token': token
- };
-
- if (!overwrite) {
- const user = this.findOne(query, { fields: { livechatData: 1 } });
- if (user.livechatData && typeof user.livechatData[key] !== 'undefined') {
- return true;
- }
- }
-
- const update = {
- $set: {
- [`livechatData.${ key }`]: value
- }
- };
-
- return this.update(query, update);
-};
-
-/**
- * Find a visitor by their phone number
- * @return {object} User from db
- */
-RocketChat.models.Users.findOneVisitorByPhone = function(phone) {
- const query = {
- 'phone.phoneNumber': phone
- };
-
- return this.findOne(query);
-};
-
-/**
- * Get the next visitor name
- * @return {string} The next visitor name
- */
-RocketChat.models.Users.getNextVisitorUsername = function() {
- const settingsRaw = RocketChat.models.Settings.model.rawCollection();
- const findAndModify = Meteor.wrapAsync(settingsRaw.findAndModify, settingsRaw);
-
- const query = {
- _id: 'Livechat_guest_count'
- };
-
- const update = {
- $inc: {
- value: 1
- }
- };
-
- const livechatCount = findAndModify(query, null, update);
-
- return `guest-${ livechatCount.value.value + 1 }`;
-};
-
-RocketChat.models.Users.saveGuestById = function(_id, data) {
- const setData = {};
- const unsetData = {};
-
- if (data.name) {
- if (!_.isEmpty(s.trim(data.name))) {
- setData.name = s.trim(data.name);
- } else {
- unsetData.name = 1;
- }
- }
-
- if (data.email) {
- if (!_.isEmpty(s.trim(data.email))) {
- setData.visitorEmails = [
- { address: s.trim(data.email) }
- ];
- } else {
- unsetData.visitorEmails = 1;
- }
- }
-
- if (data.phone) {
- if (!_.isEmpty(s.trim(data.phone))) {
- setData.phone = [
- { phoneNumber: s.trim(data.phone) }
- ];
- } else {
- unsetData.phone = 1;
- }
- }
-
- const update = {};
-
- if (!_.isEmpty(setData)) {
- update.$set = setData;
- }
-
- if (!_.isEmpty(unsetData)) {
- update.$unset = unsetData;
- }
-
- if (_.isEmpty(update)) {
- return true;
- }
-
- return this.update({ _id }, update);
-};
-
-RocketChat.models.Users.findOneGuestByEmailAddress = function(emailAddress) {
- const query = {
- 'visitorEmails.address': new RegExp(`^${ s.escapeRegExp(emailAddress) }$`, 'i')
- };
-
- return this.findOne(query);
-};
-
RocketChat.models.Users.getAgentInfo = function(agentId) {
const query = {
_id: agentId
diff --git a/packages/rocketchat-livechat/server/publications/visitorInfo.js b/packages/rocketchat-livechat/server/publications/visitorInfo.js
index 1e1462b68d51..b09b0d9dac8f 100644
--- a/packages/rocketchat-livechat/server/publications/visitorInfo.js
+++ b/packages/rocketchat-livechat/server/publications/visitorInfo.js
@@ -1,3 +1,5 @@
+import LivechatVisitors from '../models/LivechatVisitors';
+
Meteor.publish('livechat:visitorInfo', function({ rid: roomId }) {
if (!this.userId) {
return this.error(new Meteor.Error('error-not-authorized', 'Not authorized', { publish: 'livechat:visitorInfo' }));
@@ -10,7 +12,7 @@ Meteor.publish('livechat:visitorInfo', function({ rid: roomId }) {
const room = RocketChat.models.Rooms.findOneById(roomId);
if (room && room.v && room.v._id) {
- return RocketChat.models.Users.findById(room.v._id);
+ return LivechatVisitors.findById(room.v._id);
} else {
return this.ready();
}
diff --git a/packages/rocketchat-livechat/server/sendMessageBySMS.js b/packages/rocketchat-livechat/server/sendMessageBySMS.js
index fc849bc9be9c..313d3ce6370f 100644
--- a/packages/rocketchat-livechat/server/sendMessageBySMS.js
+++ b/packages/rocketchat-livechat/server/sendMessageBySMS.js
@@ -1,3 +1,5 @@
+import LivechatVisitors from './models/LivechatVisitors';
+
RocketChat.callbacks.add('afterSaveMessage', function(message, room) {
// skips this callback if the message was edited
if (message.editedAt) {
@@ -29,7 +31,7 @@ RocketChat.callbacks.add('afterSaveMessage', function(message, room) {
return message;
}
- const visitor = RocketChat.models.Users.getVisitorByToken(room.v.token);
+ const visitor = LivechatVisitors.getVisitorByToken(room.v.token);
if (!visitor || !visitor.profile || !visitor.phone || visitor.phone.length === 0) {
return message;
diff --git a/packages/rocketchat-livechat/server/startup.js b/packages/rocketchat-livechat/server/startup.js
index 11c7792cff51..1af415b4fbdc 100644
--- a/packages/rocketchat-livechat/server/startup.js
+++ b/packages/rocketchat-livechat/server/startup.js
@@ -4,11 +4,11 @@ Meteor.startup(() => {
});
RocketChat.authz.addRoomAccessValidator(function(room, user) {
- return room.t === 'l' && RocketChat.authz.hasPermission(user._id, 'view-livechat-rooms');
+ return room.t === 'l' && user && RocketChat.authz.hasPermission(user._id, 'view-livechat-rooms');
});
- RocketChat.authz.addRoomAccessValidator(function(room, user) {
- return room.t === 'l' && room.v && room.v._id === user._id;
+ RocketChat.authz.addRoomAccessValidator(function(room, user, extraData) {
+ return room.t === 'l' && extraData && extraData.token && room.v && room.v.token === extraData.token;
});
RocketChat.callbacks.add('beforeLeaveRoom', function(user, room) {
diff --git a/packages/rocketchat-livechat/server/visitorStatus.js b/packages/rocketchat-livechat/server/visitorStatus.js
new file mode 100644
index 000000000000..4c31c386e71c
--- /dev/null
+++ b/packages/rocketchat-livechat/server/visitorStatus.js
@@ -0,0 +1,9 @@
+/* globals UserPresenceEvents */
+Meteor.startup(() => {
+ UserPresenceEvents.on('setStatus', (session, status, metadata) => {
+ if (metadata && metadata.visitor) {
+ RocketChat.models.LivechatInquiry.updateVisitorStatus(metadata.visitor, status);
+ RocketChat.models.Rooms.updateVisitorStatus(metadata.visitor, status);
+ }
+ });
+});
diff --git a/packages/rocketchat-tokenpass/server/startup.js b/packages/rocketchat-tokenpass/server/startup.js
index 143e404d94ec..e6c0acfebde2 100644
--- a/packages/rocketchat-tokenpass/server/startup.js
+++ b/packages/rocketchat-tokenpass/server/startup.js
@@ -23,7 +23,7 @@ function validateTokenAccess(userData, roomData) {
Meteor.startup(function() {
RocketChat.authz.addRoomAccessValidator(function(room, user) {
- if (!room.tokenpass) {
+ if (!room.tokenpass || !user) {
return false;
}
diff --git a/private/node_scripts/auto-translate.js b/private/node_scripts/auto-translate.js
index e78ad5eabc7f..1e7c2fc194d3 100644
--- a/private/node_scripts/auto-translate.js
+++ b/private/node_scripts/auto-translate.js
@@ -15,7 +15,7 @@ googleTranslate.getSupportedLanguages(function(err, langs) {
return;
}
- async.eachSeries(['../../packages/rocketchat-lib/i18n/', '../../packages/rocketchat-livechat/app/i18n/'], function(path, callback) {
+ async.eachSeries(['../../packages/rocketchat-lib/i18n/', '../../packages/rocketchat-livechat/.app/i18n/'], function(path, callback) {
console.log(`Translating files in: ${ path }`);
const enContents = fs.readFileSync(`${ path }en.i18n.json`, 'utf-8');
const enUnsorted = JSON.parse(enContents);
diff --git a/server/methods/canAccessRoom.js b/server/methods/canAccessRoom.js
index dbb1d468b448..a21be60f438b 100644
--- a/server/methods/canAccessRoom.js
+++ b/server/methods/canAccessRoom.js
@@ -1,16 +1,10 @@
Meteor.methods({
- canAccessRoom(rid, userId) {
+ canAccessRoom(rid, userId, extraData) {
check(rid, String);
check(userId, Match.Maybe(String));
let user;
- if (!userId && RocketChat.settings.get('Accounts_AllowAnonymousRead') === false) {
- throw new Meteor.Error('error-invalid-user', 'Invalid user', {
- method: 'canAccessRoom'
- });
- }
-
if (userId) {
user = RocketChat.models.Users.findOneById(userId, {
fields: {
@@ -33,13 +27,19 @@ Meteor.methods({
const room = RocketChat.models.Rooms.findOneById(rid);
if (room) {
- if (RocketChat.authz.canAccessRoom.call(this, room, user)) {
+ if (RocketChat.authz.canAccessRoom.call(this, room, user, extraData)) {
if (user) {
room.username = user.username;
}
return room;
}
+ if (!userId && RocketChat.settings.get('Accounts_AllowAnonymousRead') === false) {
+ throw new Meteor.Error('error-invalid-user', 'Invalid user', {
+ method: 'canAccessRoom'
+ });
+ }
+
return false;
} else {
throw new Meteor.Error('error-invalid-room', 'Invalid room', {
diff --git a/server/methods/loadHistory.js b/server/methods/loadHistory.js
index d0d7fb21e264..76ef737b2eef 100644
--- a/server/methods/loadHistory.js
+++ b/server/methods/loadHistory.js
@@ -1,5 +1,3 @@
-import _ from 'underscore';
-
const hideMessagesOfType = [];
RocketChat.settings.get(/Message_HideType_.+/, function(key, value) {
@@ -43,70 +41,6 @@ Meteor.methods({
return false;
}
- const options = {
- sort: {
- ts: -1
- },
- limit
- };
-
- if (!RocketChat.settings.get('Message_ShowEditedStatus')) {
- options.fields = {
- editedAt: 0
- };
- }
-
- let records;
- if (end != null) {
- records = RocketChat.models.Messages.findVisibleByRoomIdBeforeTimestampNotContainingTypes(rid, end, hideMessagesOfType, options).fetch();
- } else {
- records = RocketChat.models.Messages.findVisibleByRoomIdNotContainingTypes(rid, hideMessagesOfType, options).fetch();
- }
-
- const UI_Use_Real_Name = RocketChat.settings.get('UI_Use_Real_Name') === true;
-
- const messages = records.map((message) => {
- message.starred = _.findWhere(message.starred, {
- _id: fromId
- });
- if (message.u && message.u._id && UI_Use_Real_Name) {
- const user = RocketChat.models.Users.findOneById(message.u._id);
- message.u.name = user && user.name;
- }
- if (message.mentions && message.mentions.length && UI_Use_Real_Name) {
- message.mentions.forEach((mention) => {
- const user = RocketChat.models.Users.findOneById(mention._id);
- mention.name = user && user.name;
- });
- }
- return message;
- });
-
- let unreadNotLoaded = 0;
- let firstUnread;
-
- if (ls != null) {
- const firstMessage = messages[messages.length - 1];
-
- if ((firstMessage != null ? firstMessage.ts : undefined) > ls) {
- delete options.limit;
-
- const unreadMessages = RocketChat.models.Messages.findVisibleByRoomIdBetweenTimestampsNotContainingTypes(rid, ls, firstMessage.ts, hideMessagesOfType, {
- limit: 1,
- sort: {
- ts: 1
- }
- });
-
- firstUnread = unreadMessages.fetch()[0];
- unreadNotLoaded = unreadMessages.count();
- }
- }
-
- return {
- messages,
- firstUnread,
- unreadNotLoaded
- };
+ return RocketChat.loadMessageHistory({ userId: fromId, rid, end, limit, ls });
}
});
diff --git a/server/startup/migrations/v106.js b/server/startup/migrations/v106.js
new file mode 100644
index 000000000000..7508a19901a3
--- /dev/null
+++ b/server/startup/migrations/v106.js
@@ -0,0 +1,46 @@
+import LivechatVisitors from 'meteor/rocketchat:livechat/server/models/LivechatVisitors';
+
+RocketChat.Migrations.add({
+ version: 106,
+ up() {
+ const visitors = Meteor.users.find({ type: 'visitor' });
+ const total = visitors.count();
+ let current = 1;
+
+ console.log('Migrating livechat visitors, this may take a while ...');
+
+ Meteor.setTimeout(() => {
+ visitors.forEach(user => {
+ console.log(`Migrating visitor ${ current++ }/${ total }`);
+
+ const {
+ _id,
+ name,
+ username,
+ deparment,
+ userAgent,
+ ip,
+ host,
+ visitorEmails,
+ phone
+ } = user;
+ LivechatVisitors.insert({
+ _id,
+ name,
+ username,
+ deparment,
+ userAgent,
+ ip,
+ host,
+ visitorEmails,
+ phone,
+ token: user.profile.token
+ });
+
+ Meteor.users.remove({ _id });
+ });
+
+ console.log('Livechat visitors migration finished.');
+ }, 1000);
+ }
+});
diff --git a/server/stream/messages.js b/server/stream/messages.js
index 96afa00f6bc7..71c68bcdfe0d 100644
--- a/server/stream/messages.js
+++ b/server/stream/messages.js
@@ -3,9 +3,9 @@ this.msgStream = msgStream;
msgStream.allowWrite('none');
-msgStream.allowRead(function(eventName) {
+msgStream.allowRead(function(eventName, args) {
try {
- const room = Meteor.call('canAccessRoom', eventName, this.userId);
+ const room = Meteor.call('canAccessRoom', eventName, this.userId, args);
if (!room) {
return false;