Clean up contexts in objects

This commit is contained in:
Bryan Ashby 2023-02-06 18:27:12 -07:00
parent 926f45b917
commit 1b684e2f2b
No known key found for this signature in database
GPG Key ID: C2C1B501E4EFD994
6 changed files with 81 additions and 45 deletions

View File

@ -16,8 +16,8 @@ const { getISOTimestampString } = require('../database');
const _ = require('lodash'); const _ = require('lodash');
module.exports = class Activity extends ActivityPubObject { module.exports = class Activity extends ActivityPubObject {
constructor(obj) { constructor(obj, withContext = ActivityPubObject.DefaultContext) {
super(obj); super(obj, withContext);
} }
static get ActivityTypes() { static get ActivityTypes() {
@ -48,14 +48,17 @@ module.exports = class Activity extends ActivityPubObject {
}); });
} }
static makeCreate(webServer, actor, obj) { static makeCreate(webServer, actor, obj, context) {
const activity = new Activity({ const activity = new Activity(
{
id: Activity.activityObjectId(webServer), id: Activity.activityObjectId(webServer),
to: obj.to, to: obj.to,
type: WellKnownActivity.Create, type: WellKnownActivity.Create,
actor, actor,
object: obj, object: obj,
}); },
context
);
const copy = n => { const copy = n => {
if (obj[n]) { if (obj[n]) {

View File

@ -4,8 +4,8 @@
// ENiGMA½ // ENiGMA½
const { Errors } = require('../enig_error.js'); const { Errors } = require('../enig_error.js');
const UserProps = require('../user_property'); const UserProps = require('../user_property');
const { ActivityStreamsContext, isValidLink, userNameFromSubject } = require('./util');
const Endpoints = require('./endpoint'); const Endpoints = require('./endpoint');
const { userNameFromSubject, isValidLink } = require('./util');
const Log = require('../logger').log; const Log = require('../logger').log;
const { queryWebFinger } = require('../webfinger'); const { queryWebFinger } = require('../webfinger');
const EnigAssert = require('../enigma_assert'); const EnigAssert = require('../enigma_assert');
@ -24,10 +24,17 @@ const paths = require('path');
const ActorCacheTTL = moment.duration(120, 'days'); const ActorCacheTTL = moment.duration(120, 'days');
// default context for Actor's
const DefaultContext = ActivityPubObject.makeContext(['https://w3id.org/security/v1'], {
toot: 'http://joinmastodon.org/ns#',
discoverable: 'toot:discoverable',
manuallyApprovesFollowers: 'as:manuallyApprovesFollowers',
});
// 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 {
constructor(obj) { constructor(obj, withContext = DefaultContext) {
super(obj); super(obj, withContext);
} }
isValid() { isValid() {
@ -90,16 +97,6 @@ module.exports = class Actor extends ActivityPubObject {
}; };
const obj = { const obj = {
'@context': [
ActivityStreamsContext,
'https://w3id.org/security/v1', // :TODO: add support
{
bbsInfo: {
'@id': 'bbs:bbsInfo',
'@type': '@id',
},
},
],
id: userActorId, id: userActorId,
type: 'Person', type: 'Person',
preferredUsername: user.username, preferredUsername: user.username,

View File

@ -1,5 +1,8 @@
const { WellKnownLocations } = require('../servers/content/web'); const { WellKnownLocations } = require('../servers/content/web');
// deps
const { v4: UUIDv4 } = require('uuid');
exports.makeUserUrl = makeUserUrl; exports.makeUserUrl = makeUserUrl;
exports.inbox = inbox; exports.inbox = inbox;
exports.outbox = outbox; exports.outbox = outbox;
@ -9,6 +12,7 @@ exports.actorId = actorId;
exports.profile = profile; exports.profile = profile;
exports.avatar = avatar; exports.avatar = avatar;
exports.sharedInbox = sharedInbox; exports.sharedInbox = sharedInbox;
exports.objectId = objectId;
const ActivityPubUsersPrefix = '/ap/users/'; const ActivityPubUsersPrefix = '/ap/users/';
@ -49,3 +53,9 @@ function avatar(webServer, user, filename) {
function sharedInbox(webServer) { function sharedInbox(webServer) {
return webServer.buildUrl(WellKnownLocations.Internal + '/ap/shared-inbox'); return webServer.buildUrl(WellKnownLocations.Internal + '/ap/shared-inbox');
} }
function objectId(webServer, objectType) {
return webServer.buildUrl(
WellKnownLocations.Internal + `/ap/${UUIDv4()}/${objectType}`
);
}

View File

@ -18,7 +18,7 @@ const APDefaultSummary = '[ActivityPub]';
module.exports = class Note extends ActivityPubObject { module.exports = class Note extends ActivityPubObject {
constructor(obj) { constructor(obj) {
super(obj); super(obj, null); // Note are wrapped
} }
isValid() { isValid() {
@ -127,24 +127,29 @@ module.exports = class Note extends ActivityPubObject {
published: getISOTimestampString(message.modTimestamp), published: getISOTimestampString(message.modTimestamp),
to, to,
attributedTo: fromActor.id, attributedTo: fromActor.id,
summary: message.subject.trim(),
content: messageToHtml(message), content: messageToHtml(message),
source: { source: {
content: message.message, content: message.message,
mediaType: sourceMediaType, mediaType: sourceMediaType,
}, },
sensitive: message.subject.startsWith('[NSFW]'),
}; };
if (replyToNoteId) { if (replyToNoteId) {
obj.inReplyTo = replyToNoteId; obj.inReplyTo = replyToNoteId;
} }
// ignore the subject if it's our default summary value for replies
if (message.subject !== `RE: ${APDefaultSummary}`) {
obj.summary = message.subject;
}
const note = new Note(obj); const note = new Note(obj);
return callback(null, { note, fromUser, remoteActor }); const context = ActivityPubObject.makeContext([], {
sensitive: 'as:sensitive',
});
return callback(null, {
note,
fromUser,
remoteActor,
context,
});
}, },
], ],
(err, noteInfo) => { (err, noteInfo) => {

View File

@ -1,16 +1,32 @@
const { ActivityStreamsContext } = require('./util'); const { ActivityStreamsContext } = require('./util');
const { WellKnownLocations } = require('../servers/content/web'); const Endpoints = require('./endpoint');
// deps // deps
const { isString } = require('lodash'); const { isString, isObject } = require('lodash');
const { v4: UUIDv4 } = require('uuid');
module.exports = class ActivityPubObject { module.exports = class ActivityPubObject {
constructor(obj) { constructor(obj, withContext = [ActivityStreamsContext]) {
this['@context'] = ActivityStreamsContext; if (withContext) {
this.setContext(withContext);
}
Object.assign(this, obj); Object.assign(this, obj);
} }
static get DefaultContext() {
return [ActivityStreamsContext];
}
static makeContext(namespaceUrls, aliases = null) {
const context = [ActivityStreamsContext];
if (Array.isArray(namespaceUrls)) {
context.push(...namespaceUrls);
}
if (isObject(aliases)) {
context.push(aliases);
}
return context;
}
static fromJsonString(s) { static fromJsonString(s) {
let obj; let obj;
try { try {
@ -23,23 +39,27 @@ module.exports = class ActivityPubObject {
} }
isValid() { isValid() {
const nes = s => isString(s) && s.length > 1; const nonEmpty = s => isString(s) && s.length > 1;
// :TODO: Additional validation // :TODO: Additional validation
if ( if (
(this['@context'] === ActivityStreamsContext || (this['@context'] === ActivityStreamsContext ||
this['@context'][0] === ActivityStreamsContext) && this['@context'][0] === ActivityStreamsContext) &&
nes(this.id) && nonEmpty(this.id) &&
nes(this.type) nonEmpty(this.type)
) { ) {
return true; return true;
} }
return false; return false;
} }
static makeObjectId(webServer, suffix) { setContext(context) {
// e.g. http://some.host/_enig/ap/bf81a22e-cb3e-41c8-b114-21f375b61124/activity if (!Array.isArray(context)) {
return webServer.buildUrl( context = [context];
WellKnownLocations.Internal + `/ap/${UUIDv4()}/${suffix}` }
); this['@context'] = context;
}
static makeObjectId(webServer, objectType) {
return Endpoints.objectId(webServer, objectType);
} }
}; };

View File

@ -90,7 +90,7 @@ exports.getModule = class ActivityPubScannerTosser extends MessageScanTossModule
); );
}, },
(noteInfo, deliveryEndpoints, callback) => { (noteInfo, deliveryEndpoints, callback) => {
const { note, fromUser } = noteInfo; const { note, fromUser, context } = noteInfo;
// //
// Update the Note's addressing: // Update the Note's addressing:
@ -127,7 +127,8 @@ exports.getModule = class ActivityPubScannerTosser extends MessageScanTossModule
const activity = Activity.makeCreate( const activity = Activity.makeCreate(
this._webServer(), this._webServer(),
note.attributedTo, note.attributedTo,
note note,
context
); );
let allEndpoints = deliveryEndpoints.sharedInboxes; let allEndpoints = deliveryEndpoints.sharedInboxes;