Fix up message header for public AP, Undo following, some bugs around following local Actors...

This commit is contained in:
Bryan Ashby 2023-02-24 22:54:19 -07:00
parent 5b08d21966
commit a205445dd1
No known key found for this signature in database
GPG Key ID: C2C1B501E4EFD994
6 changed files with 75 additions and 28 deletions

View File

@ -176,6 +176,10 @@ module.exports = class Actor extends ActivityPubObject {
} }
}; };
if (!id) {
return cb(Errors.Invalid('Invalid Actor ID'));
}
Actor._fromCache(id, (err, actor, subject, needsRefresh) => { Actor._fromCache(id, (err, actor, subject, needsRefresh) => {
if (!err) { if (!err) {
// cache hit // cache hit

View File

@ -20,18 +20,19 @@ function sendFollowRequest(fromUser, toActor, webServer, cb) {
// We always add to the following collection; // We always add to the following collection;
// We expect an async follow up request to our server of // We expect an async follow up request to our server of
// Accept or Reject but it's not guaranteed // Accept or Reject but it's not guaranteed
const followRequest = new ActivityPubObject({
id: ActivityPubObject.makeObjectId(webServer, 'follow'),
type: WellKnownActivity.Follow,
actor: fromActorId,
object: toActor.id,
});
toActor._followRequest = followRequest;
Collection.addFollowing(fromUser, toActor, webServer, true, err => { Collection.addFollowing(fromUser, toActor, webServer, true, err => {
if (err) { if (err) {
return cb(err); return cb(err);
} }
const followRequest = new ActivityPubObject({
id: ActivityPubObject.makeObjectId(webServer, 'follow'),
type: WellKnownActivity.Follow,
actor: fromActorId,
object: toActor.id,
});
return followRequest.sendTo(toActor.inbox, fromUser, webServer, cb); return followRequest.sendTo(toActor.inbox, fromUser, webServer, cb);
}); });
} }
@ -46,19 +47,37 @@ function sendUnfollowRequest(fromUser, toActor, webServer, cb) {
); );
} }
// Always remove from the local collection, notify the remote server // Fetch previously saved 'Follow'; We're going to Undo it &
Collection.removeOwnedById(Collections.Following, fromUser, toActor.inbox, err => { // need a copy.
if (err) { Collection.ownedObjectByNameAndId(
return cb(err); Collections.Following,
fromUser,
toActor.id,
(err, followedActor) => {
if (err) {
return cb(err);
}
// Always remove from the local collection, notify the remote server
Collection.removeOwnedById(
Collections.Following,
fromUser,
toActor.id,
err => {
if (err) {
return cb(err);
}
const undoRequest = new ActivityPubObject({
id: ActivityPubObject.makeObjectId(webServer, 'undo'),
type: WellKnownActivity.Undo,
actor: fromActorId,
object: followedActor._followRequest,
});
return undoRequest.sendTo(toActor.inbox, fromUser, webServer, cb);
}
);
} }
);
const undoRequest = new ActivityPubObject({
id: ActivityPubObject.makeObjectId(webServer, 'undo'),
type: WellKnownActivity.Undo,
actor: fromActorId,
object: toActor.id,
});
return undoRequest.sendTo(toActor.inbox, fromUser, webServer, cb);
});
} }

View File

@ -17,6 +17,7 @@ const { encode, decode } = require('html-entities');
const { isString } = require('lodash'); const { isString } = require('lodash');
const { stripHtml } = require('string-strip-html'); const { stripHtml } = require('string-strip-html');
exports.getActorId = o => o.actor?.id || o.actor;
exports.parseTimestampOrNow = parseTimestampOrNow; exports.parseTimestampOrNow = parseTimestampOrNow;
exports.isValidLink = isValidLink; exports.isValidLink = isValidLink;
exports.userFromActorId = userFromActorId; exports.userFromActorId = userFromActorId;

View File

@ -37,7 +37,7 @@ const moment = require('moment');
const fse = require('fs-extra'); const fse = require('fs-extra');
const fs = require('graceful-fs'); const fs = require('graceful-fs');
const paths = require('path'); const paths = require('path');
const sanatizeFilename = require('sanitize-filename'); const sanitizeFilename = require('sanitize-filename');
const { ErrorReasons } = require('./enig_error.js'); const { ErrorReasons } = require('./enig_error.js');
exports.moduleInfo = { exports.moduleInfo = {
@ -350,7 +350,7 @@ exports.FullScreenEditorModule =
return { return {
// :TODO: ensure we show real names for form/to if they are enforced in the area // :TODO: ensure we show real names for form/to if they are enforced in the area
fromUserName: this.message.fromUserName, fromUserName: this.message.fromUserName,
toUserName: this.message.toUserName, toUserName: this._viewModeToField(),
// :TODO: // :TODO:
//fromRealName //fromRealName
//toRealName //toRealName
@ -1108,6 +1108,24 @@ exports.FullScreenEditorModule =
this.setViewText('header', id, text); this.setViewText('header', id, text);
} }
_viewModeToField() {
// Imported messages may have no explicit 'to' on various public forums
if (this.message.toUserName) {
return this.message.toUserName;
}
const toRemoteUser = _.get(this.message, 'meta.System.remote_to_user');
if (toRemoteUser) {
return toRemoteUser;
}
if (this.message.isPublic()) {
return '(Public)';
}
this.menuConfig.config.remoteUserNotAvail || 'N/A';
}
initHeaderViewMode() { initHeaderViewMode() {
// Only set header text for from view if it is on the form // Only set header text for from view if it is on the form
if ( if (
@ -1115,7 +1133,7 @@ exports.FullScreenEditorModule =
) { ) {
this.setHeaderText(MciViewIds.header.from, this.message.fromUserName); this.setHeaderText(MciViewIds.header.from, this.message.fromUserName);
} }
this.setHeaderText(MciViewIds.header.to, this.message.toUserName); this.setHeaderText(MciViewIds.header.to, this._viewModeToField());
this.setHeaderText(MciViewIds.header.subject, this.message.subject); this.setHeaderText(MciViewIds.header.subject, this.message.subject);
this.setHeaderText( this.setHeaderText(
@ -1199,7 +1217,7 @@ exports.FullScreenEditorModule =
const outputFileName = paths.join( const outputFileName = paths.join(
sysTempDownloadDir, sysTempDownloadDir,
sanatizeFilename( sanitizeFilename(
`(${msgInfo.messageId}) ${ `(${msgInfo.messageId}) ${
msgInfo.subject msgInfo.subject
}_(${this.message.modTimestamp.format('YYYY-MM-DD')}).txt` }_(${this.message.modTimestamp.format('YYYY-MM-DD')}).txt`

View File

@ -91,6 +91,10 @@ module.exports = class Message {
return Message.isPrivateAreaTag(this.areaTag); return Message.isPrivateAreaTag(this.areaTag);
} }
isPublic() {
return !this.isPrivate();
}
isFromRemoteUser() { isFromRemoteUser() {
return null !== this.getRemoteFromUser(); return null !== this.getRemoteFromUser();
} }

View File

@ -3,6 +3,7 @@ const {
userFromActorId, userFromActorId,
getUserProfileTemplatedBody, getUserProfileTemplatedBody,
DefaultProfileTemplate, DefaultProfileTemplate,
getActorId,
} = require('../../../activitypub/util'); } = require('../../../activitypub/util');
const Endpoints = require('../../../activitypub/endpoint'); const Endpoints = require('../../../activitypub/endpoint');
const { const {
@ -257,7 +258,7 @@ exports.getModule = class ActivityPubWebHandler extends WebHandlerModule {
} }
// Fetch and validate the signature of the remote Actor // Fetch and validate the signature of the remote Actor
Actor.fromId(activity.actor, (err, remoteActor) => { Actor.fromId(getActorId(activity), (err, remoteActor) => {
if (err) { if (err) {
return this.webServer.internalServerError(resp, err); return this.webServer.internalServerError(resp, err);
} }
@ -318,7 +319,7 @@ exports.getModule = class ActivityPubWebHandler extends WebHandlerModule {
activity activity
); );
} else { } else {
this.log.warn(`Unsupported Undo for type "${type}`); this.log.warn(`Unsupported Undo for type "${type}"`);
} }
} }
break; break;
@ -920,7 +921,7 @@ exports.getModule = class ActivityPubWebHandler extends WebHandlerModule {
const accept = Activity.makeAccept( const accept = Activity.makeAccept(
this.webServer, this.webServer,
localActor, localActor.id,
requestActivity requestActivity
); );