The communications platform that puts data protection first.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
Rocket.Chat/packages/rocketchat-lib/server/functions/Notifications.js

183 lines
5.5 KiB

import { Meteor } from 'meteor/meteor';
class RoomStreamer extends Meteor.Streamer {
_publish(publication, eventName, options) {
super._publish(publication, eventName, options);
const uid = Meteor.userId();
if (/rooms-changed/.test(eventName)) {
const roomEvent = (...args) => {
RocketChat.Notifications.notifyUserInThisInstance(uid, 'rooms-changed', ...args);
};
const rooms = RocketChat.models.Subscriptions.find({ 'u._id': uid }, { fields: { rid: 1 } }).fetch();
rooms.forEach(({ rid }) => {
this.on(rid, roomEvent);
});
const userEvent = (clientAction, { rid }) => {
switch (clientAction) {
case 'inserted':
rooms.push({ rid });
this.on(rid, roomEvent);
break;
case 'removed':
this.removeListener(rid, roomEvent);
break;
}
};
this.on(uid, userEvent);
publication.onStop(() => {
this.removeListener(uid, userEvent);
rooms.forEach(({ rid }) => this.removeListener(rid, roomEvent));
});
}
}
}
RocketChat.Notifications = new class {
constructor() {
this.debug = false;
this.streamAll = new Meteor.Streamer('notify-all');
this.streamLogged = new Meteor.Streamer('notify-logged');
this.streamRoom = new Meteor.Streamer('notify-room');
this.streamRoomUsers = new Meteor.Streamer('notify-room-users');
this.streamUser = new RoomStreamer('notify-user');
this.streamAll.allowWrite('none');
this.streamLogged.allowWrite('none');
this.streamRoom.allowWrite('none');
this.streamRoomUsers.allowWrite(function(eventName, ...args) {
const [roomId, e] = eventName.split('/');
// const user = Meteor.users.findOne(this.userId, {
// fields: {
// username: 1
// }
// });
if (RocketChat.models.Subscriptions.findOneByRoomIdAndUserId(roomId, this.userId) != null) {
const subscriptions = RocketChat.models.Subscriptions.findByRoomIdAndNotUserId(roomId, this.userId).fetch();
subscriptions.forEach((subscription) => RocketChat.Notifications.notifyUser(subscription.u._id, e, ...args));
}
return false;
});
this.streamUser.allowWrite('logged');
this.streamAll.allowRead('all');
this.streamLogged.allowRead('logged');
this.streamRoom.allowRead(function(eventName, extraData) {
const [roomId] = eventName.split('/');
const room = RocketChat.models.Rooms.findOneById(roomId);
if (!room) {
console.warn(`Invalid streamRoom eventName: "${ eventName }"`);
return false;
}
if (room.t === 'l' && extraData && extraData.token && room.v.token === extraData.token) {
return true;
}
if (this.userId == null) {
return false;
}
const subscription = RocketChat.models.Subscriptions.findOneByRoomIdAndUserId(roomId, this.userId, { fields: { _id: 1 } });
return subscription != null;
});
this.streamRoomUsers.allowRead('none');
this.streamUser.allowRead(function(eventName) {
const [userId] = eventName.split('/');
return (this.userId != null) && this.userId === userId;
});
}
notifyAll(eventName, ...args) {
if (this.debug === true) {
console.log('notifyAll', [eventName, ...args]);
}
args.unshift(eventName);
return this.streamAll.emit.apply(this.streamAll, args);
}
notifyLogged(eventName, ...args) {
if (this.debug === true) {
console.log('notifyLogged', [eventName, ...args]);
}
args.unshift(eventName);
return this.streamLogged.emit.apply(this.streamLogged, args);
}
notifyRoom(room, eventName, ...args) {
if (this.debug === true) {
console.log('notifyRoom', [room, eventName, ...args]);
}
args.unshift(`${ room }/${ eventName }`);
return this.streamRoom.emit.apply(this.streamRoom, args);
}
notifyUser(userId, eventName, ...args) {
if (this.debug === true) {
console.log('notifyUser', [userId, eventName, ...args]);
}
args.unshift(`${ userId }/${ eventName }`);
return this.streamUser.emit.apply(this.streamUser, args);
}
notifyAllInThisInstance(eventName, ...args) {
if (this.debug === true) {
console.log('notifyAll', [eventName, ...args]);
}
args.unshift(eventName);
return this.streamAll.emitWithoutBroadcast.apply(this.streamAll, args);
}
notifyLoggedInThisInstance(eventName, ...args) {
if (this.debug === true) {
console.log('notifyLogged', [eventName, ...args]);
}
args.unshift(eventName);
return this.streamLogged.emitWithoutBroadcast.apply(this.streamLogged, args);
}
notifyRoomInThisInstance(room, eventName, ...args) {
if (this.debug === true) {
console.log('notifyRoomAndBroadcast', [room, eventName, ...args]);
}
args.unshift(`${ room }/${ eventName }`);
return this.streamRoom.emitWithoutBroadcast.apply(this.streamRoom, args);
}
notifyUserInThisInstance(userId, eventName, ...args) {
if (this.debug === true) {
console.log('notifyUserAndBroadcast', [userId, eventName, ...args]);
}
args.unshift(`${ userId }/${ eventName }`);
return this.streamUser.emitWithoutBroadcast.apply(this.streamUser, args);
}
};
RocketChat.Notifications.streamRoom.allowWrite(function(eventName, username, typing, extraData) {
const [roomId, e] = eventName.split('/');
if (e === 'webrtc') {
return true;
}
if (e === 'typing') {
const key = RocketChat.settings.get('UI_Use_Real_Name') ? 'name' : 'username';
// 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: {
[key]: 1,
},
});
if (!user) {
return false;
}
return user[key] === username;
}
return false;
});