feat: support remote "Video" type objects in note assertion, #13120

- handle array attributedTo (plus per-object actor assertion instead of batched)
- explicit "Video" type handling to automatically save URL as post attachment
- handle array url property
This commit is contained in:
Julian Lam
2025-02-26 13:55:39 -05:00
parent bad0a4c2d2
commit 95f2c4edb5
3 changed files with 44 additions and 5 deletions

View File

@@ -37,7 +37,7 @@ ActivityPub._constants = Object.freeze({
'application/ld+json; profile="https://www.w3.org/ns/activitystreams"',
],
acceptedPostTypes: [
'Note', 'Page', 'Article', 'Question',
'Note', 'Page', 'Article', 'Question', 'Video',
],
acceptableActorTypes: new Set(['Application', 'Group', 'Organization', 'Person', 'Service']),
requiredActorProps: ['inbox', 'outbox'],

View File

@@ -153,9 +153,6 @@ Mocks.post = async (objects) => {
objects = [objects];
}
const actorIds = new Set(objects.map(object => object.attributedTo).filter(Boolean));
await activitypub.actors.assert(Array.from(actorIds));
const posts = await Promise.all(objects.map(async (object) => {
if (
!activitypub._constants.acceptedPostTypes.includes(object.type) ||
@@ -170,13 +167,30 @@ Mocks.post = async (objects) => {
attributedTo: uid,
inReplyTo: toPid,
published, updated, name, content, source,
to, cc, audience, attachment, tag, image,
type, to, cc, audience, attachment, tag, image,
} = object;
if (Array.isArray(uid)) { // Handle array attributedTo
uid = uid.reduce((valid, cur) => {
if (typeof cur === 'string') {
valid.push(cur);
} else if (typeof cur === 'object') {
if (cur.type === 'Person' && cur.id) {
valid.push(cur.id);
}
}
return valid;
}, []);
uid = uid.shift(); // take first valid uid
await activitypub.actors.assert(uid);
}
const resolved = await activitypub.helpers.resolveLocalId(toPid);
if (resolved.type === 'post') {
toPid = resolved.id;
}
const timestamp = new Date(published).getTime();
let edited = new Date(updated);
edited = Number.isNaN(edited.valueOf()) ? undefined : edited;
@@ -215,6 +229,30 @@ Mocks.post = async (objects) => {
}
}
if (url) { // Handle url array
if (Array.isArray(url)) {
url = url.reduce((valid, cur) => {
if (typeof cur === 'string') {
valid.push(cur);
} else if (typeof cur === 'object') {
if (cur.type === 'Link' && cur.href) {
if (!cur.mediaType || (cur.mediaType && cur.mediaType === 'text/html')) {
valid.push(cur.href);
}
}
}
return valid;
}, []);
url = url.shift(); // take first valid url
}
}
if (type === 'Video') {
attachment = attachment || [];
attachment.push({ url });
}
const payload = {
uid,
pid,

View File

@@ -137,6 +137,7 @@ middleware.resolveObjects = async function (req, res, next) {
next();
};
// todo: deprecate... this should be handled in actor and note assertion methods instead, or perhaps via helper fn
middleware.normalize = async function (req, res, next) {
// Normalizes the received data structure
const { body } = req;