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/app/federation/server/hooks/afterCreateRoom.js

99 lines
3.0 KiB

import { logger } from '../lib/logger';
import { FederationRoomEvents, Subscriptions, Users } from '../../../models/server';
import { normalizers } from '../normalizers';
import { deleteRoom } from '../../../lib/server/functions';
import { getFederationDomain } from '../lib/getFederationDomain';
import { dispatchEvents } from '../handler';
import { checkRoomType, checkRoomDomainsLength } from '../functions/helpers';
export async function doAfterCreateRoom(room, users, subscriptions) {
const normalizedUsers = [];
//
// Add user events
//
const addUserEvents = [];
for (const user of users) {
/* eslint-disable no-await-in-loop */
const subscription = subscriptions[user._id];
const normalizedSourceUser = normalizers.normalizeUser(user);
const normalizedSourceSubscription = normalizers.normalizeSubscription(subscription);
normalizedUsers.push(normalizedSourceUser);
const addUserEvent = await FederationRoomEvents.createAddUserEvent(getFederationDomain(), room._id, normalizedSourceUser, normalizedSourceSubscription);
addUserEvents.push(addUserEvent);
/* eslint-enable no-await-in-loop */
}
//
// Genesis
//
// Normalize room
const normalizedRoom = normalizers.normalizeRoom(room, normalizedUsers);
// Check if the number of domains is allowed
if (!checkRoomDomainsLength(normalizedRoom.federation.domains)) {
throw new Error('Cannot federate rooms with more than 10 domains');
}
// Ensure a genesis event for this room
const genesisEvent = await FederationRoomEvents.createGenesisEvent(getFederationDomain(), normalizedRoom);
// Dispatch the events
dispatchEvents(normalizedRoom.federation.domains, [genesisEvent, ...addUserEvents]);
}
async function afterCreateRoom(roomOwner, room) {
// If the room is federated, ignore
if (room.federation) { return roomOwner; }
// Find all subscriptions of this room
let subscriptions = Subscriptions.findByRoomIdWhenUsernameExists(room._id).fetch();
subscriptions = subscriptions.reduce((acc, s) => {
acc[s.u._id] = s;
return acc;
}, {});
// Get all user ids
const userIds = Object.keys(subscriptions);
// Load all the users
const users = Users.findUsersWithUsernameByIds(userIds).fetch();
// Check if there is a federated user on this room
const hasFederatedUser = users.find((u) => u.username.indexOf('@') !== -1);
// If there are not federated users on this room, ignore it
if (!hasFederatedUser) { return roomOwner; }
try {
// If the room is not on the allowed types, ignore
if (!checkRoomType(room)) {
throw new Error('Channels cannot be federated');
}
logger.client.debug(() => `afterCreateRoom => roomOwner=${ JSON.stringify(roomOwner, null, 2) } room=${ JSON.stringify(room, null, 2) }`);
await doAfterCreateRoom(room, users, subscriptions);
} catch (err) {
deleteRoom(room._id);
logger.client.error('afterCreateRoom => Could not create federated room:', err);
}
return room;
}
export const definition = {
hook: 'afterCreateRoom',
callback: (roomOwner, room) => Promise.await(afterCreateRoom(roomOwner, room)),
id: 'federation-after-create-room',
};