Fix shared inbox delivery for private + public

This commit is contained in:
Bryan Ashby 2023-02-05 14:43:46 -07:00
parent 41cd0f7f33
commit 36ebda5269
No known key found for this signature in database
GPG Key ID: C2C1B501E4EFD994
2 changed files with 27 additions and 7 deletions

View File

@ -28,7 +28,7 @@ const { getISOTimestampString } = require('../database.js');
const moment = require('moment'); const moment = require('moment');
const paths = require('path'); const paths = require('path');
const ActorCacheTTL = moment.duration(1, 'day'); const ActorCacheTTL = moment.duration(120, 'days');
// https://www.w3.org/TR/activitypub/#actor-objects // https://www.w3.org/TR/activitypub/#actor-objects
module.exports = class Actor extends ActivityPubObject { module.exports = class Actor extends ActivityPubObject {

View File

@ -13,7 +13,7 @@ const Collection = require('./collection');
const async = require('async'); const async = require('async');
const { isString, isObject, truncate } = require('lodash'); const { isString, isObject, truncate } = require('lodash');
const APMessageIdNamespace = '307bc7b3-3735-4573-9a20-e3f9eaac29c5'; const PublicMessageIdNamespace = 'a26ae389-5dfb-4b24-a58e-5472085c8e42';
const APDefaultSummary = '[ActivityPub]'; const APDefaultSummary = '[ActivityPub]';
module.exports = class Note extends ActivityPubObject { module.exports = class Note extends ActivityPubObject {
@ -154,10 +154,26 @@ module.exports = class Note extends ActivityPubObject {
return cb(Errors.MissingParam('Missing one or more required options!')); return cb(Errors.MissingParam('Missing one or more required options!'));
} }
// stable ID based on Note ID const isPrivate = isObject(options.toUser);
const message = new Message({
uuid: UUIDv5(this.id, APMessageIdNamespace), //
}); // Message UUIDs are unique in the message database;
// However, we may need to deliver a particular message to:
// - #Public / sharedInbox
// - 1:N private user inboxes
//
// In both cases, the UUID is stable. That is, the same ID
// will equal the same UUID as to prevent dupes.
//
const makeMessageUuid = () => {
if (isPrivate) {
// UUID specific to the target user
const url = `${this.id}/${options.toUser.userId}`;
return UUIDv5(url, UUIDv5.URL);
} else {
return UUIDv5(this.id, PublicMessageIdNamespace);
}
};
// Fetch the remote actor info to get their user info // Fetch the remote actor info to get their user info
Actor.fromId(this.attributedTo, (err, attributedToActor, fromActorSubject) => { Actor.fromId(this.attributedTo, (err, attributedToActor, fromActorSubject) => {
@ -165,13 +181,17 @@ module.exports = class Note extends ActivityPubObject {
return cb(err); return cb(err);
} }
const message = new Message({
uuid: makeMessageUuid(),
});
message.fromUserName = fromActorSubject || this.attributedTo; message.fromUserName = fromActorSubject || this.attributedTo;
// //
// Note's can be addressed to 1:N users, but a Message is a 1:1 // Note's can be addressed to 1:N users, but a Message is a 1:1
// relationship. This method requires the mapping up front via options // relationship. This method requires the mapping up front via options
// //
if (isObject(options.toUser)) { if (isPrivate) {
message.toUserName = options.toUser.username; message.toUserName = options.toUser.username;
message.meta.System[Message.SystemMetaNames.LocalToUserID] = message.meta.System[Message.SystemMetaNames.LocalToUserID] =
options.toUser.userId; options.toUser.userId;