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/endpoints/requestFromLatest.js

61 lines
1.9 KiB

import { EJSON } from 'meteor/ejson';
import { API } from '../../../api/server';
import { logger } from '../lib/logger';
import { FederationRoomEvents } from '../../../models/server';
import { decryptIfNeeded } from '../lib/crypt';
import { isFederationEnabled } from '../lib/isFederationEnabled';
import { dispatchEvents } from '../handler';
API.v1.addRoute('federation.events.requestFromLatest', { authRequired: false }, {
async post() {
if (!isFederationEnabled()) {
return API.v1.failure('Federation not enabled');
}
//
// Decrypt the payload if needed
let payload;
try {
payload = decryptIfNeeded(this.request, this.bodyParams);
} catch (err) {
return API.v1.failure('Could not decrypt payload');
}
const { fromDomain, contextType, contextQuery, latestEventIds } = EJSON.fromJSONValue(payload);
logger.server.debug(`federation.events.requestFromLatest => contextType=${ contextType } contextQuery=${ JSON.stringify(contextQuery, null, 2) } latestEventIds=${ latestEventIds.join(', ') }`);
let EventsModel;
// Define the model for the context
switch (contextType) {
case 'room':
EventsModel = FederationRoomEvents;
break;
}
let missingEvents = [];
if (latestEventIds.length) {
// Get the oldest event from the latestEventIds
const oldestEvent = EventsModel.findOne({ _id: { $in: latestEventIds } }, { $sort: { timestamp: 1 } });
if (!oldestEvent) {
return;
}
// Get all the missing events on this context, after the oldest one
missingEvents = EventsModel.find({ _id: { $nin: latestEventIds }, context: contextQuery, timestamp: { $gte: oldestEvent.timestamp } }, { sort: { timestamp: 1 } }).fetch();
} else {
// If there are no latest events, send all of them
missingEvents = EventsModel.find({ context: contextQuery }, { sort: { timestamp: 1 } }).fetch();
}
// Dispatch all the events, on the same request
dispatchEvents([fromDomain], missingEvents);
return API.v1.success();
},
});