mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-26 08:36:12 +01:00
refactor: move mockProfile and mockPost to separate mocks.js
This commit is contained in:
@@ -14,7 +14,7 @@ const ActivityPub = module.exports;
|
|||||||
|
|
||||||
ActivityPub.helpers = require('./helpers');
|
ActivityPub.helpers = require('./helpers');
|
||||||
ActivityPub.inbox = require('./inbox');
|
ActivityPub.inbox = require('./inbox');
|
||||||
ActivityPub.notes = require('./notes');
|
ActivityPub.mocks = require('./mocks');
|
||||||
|
|
||||||
ActivityPub.getActor = async (uid, input) => {
|
ActivityPub.getActor = async (uid, input) => {
|
||||||
// Can be a webfinger id, uri, or object, handle as appropriate
|
// Can be a webfinger id, uri, or object, handle as appropriate
|
||||||
@@ -56,66 +56,6 @@ ActivityPub.getActor = async (uid, input) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// todo: move to mocks.js
|
|
||||||
ActivityPub.mockProfile = async (actors, callerUid = 0) => {
|
|
||||||
// Accepts an array containing actor objects (the output of getActor()), or uris
|
|
||||||
let single = false;
|
|
||||||
if (!Array.isArray(actors)) {
|
|
||||||
single = true;
|
|
||||||
actors = [actors];
|
|
||||||
}
|
|
||||||
|
|
||||||
const profiles = (await Promise.all(actors.map(async (actor) => {
|
|
||||||
// convert uri to actor object
|
|
||||||
if (typeof actor === 'string' && ActivityPub.helpers.isUri(actor)) {
|
|
||||||
actor = await ActivityPub.getActor(callerUid, actor);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!actor) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const uid = actor.id;
|
|
||||||
const { preferredUsername, published, icon, image, name, summary, hostname, followerCount, followingCount } = actor;
|
|
||||||
const isFollowing = await db.isSortedSetMember(`followingRemote:${callerUid}`, uid);
|
|
||||||
|
|
||||||
let picture;
|
|
||||||
if (icon) {
|
|
||||||
picture = typeof icon === 'string' ? icon : icon.url;
|
|
||||||
}
|
|
||||||
const iconBackgrounds = await user.getIconBackgrounds();
|
|
||||||
let bgColor = Array.prototype.reduce.call(preferredUsername, (cur, next) => cur + next.charCodeAt(), 0);
|
|
||||||
bgColor = iconBackgrounds[bgColor % iconBackgrounds.length];
|
|
||||||
|
|
||||||
const payload = {
|
|
||||||
uid,
|
|
||||||
username: `${preferredUsername}@${hostname}`,
|
|
||||||
userslug: `${preferredUsername}@${hostname}`,
|
|
||||||
displayname: name,
|
|
||||||
fullname: name,
|
|
||||||
joindate: new Date(published).getTime(),
|
|
||||||
picture,
|
|
||||||
'icon:text': (preferredUsername[0] || '').toUpperCase(),
|
|
||||||
'icon:bgColor': bgColor,
|
|
||||||
uploadedpicture: undefined,
|
|
||||||
'cover:url': !image || typeof image === 'string' ? image : image.url,
|
|
||||||
'cover:position': '50% 50%',
|
|
||||||
aboutme: summary,
|
|
||||||
aboutmeParsed: summary,
|
|
||||||
|
|
||||||
isFollowing,
|
|
||||||
counts: {
|
|
||||||
following: followingCount,
|
|
||||||
followers: followerCount,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
return payload;
|
|
||||||
}))).filter(Boolean);
|
|
||||||
|
|
||||||
return single ? profiles.pop() : profiles;
|
|
||||||
};
|
|
||||||
|
|
||||||
ActivityPub.resolveInboxes = async (uid, ids) => await Promise.all(ids.map(async (id) => {
|
ActivityPub.resolveInboxes = async (uid, ids) => await Promise.all(ids.map(async (id) => {
|
||||||
const actor = await ActivityPub.getActor(uid, id);
|
const actor = await ActivityPub.getActor(uid, id);
|
||||||
return actor.inbox;
|
return actor.inbox;
|
||||||
|
|||||||
128
src/activitypub/mocks.js
Normal file
128
src/activitypub/mocks.js
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const winston = require('winston');
|
||||||
|
|
||||||
|
const db = require('../database');
|
||||||
|
const user = require('../user');
|
||||||
|
|
||||||
|
const activitypub = module.parent.exports;
|
||||||
|
const Mocks = module.exports;
|
||||||
|
|
||||||
|
Mocks.profile = async (actors, callerUid = 0) => {
|
||||||
|
// Accepts an array containing actor objects (the output of getActor()), or uris
|
||||||
|
let single = false;
|
||||||
|
if (!Array.isArray(actors)) {
|
||||||
|
single = true;
|
||||||
|
actors = [actors];
|
||||||
|
}
|
||||||
|
|
||||||
|
const profiles = (await Promise.all(actors.map(async (actor) => {
|
||||||
|
// convert uri to actor object
|
||||||
|
if (typeof actor === 'string' && activitypub.helpers.isUri(actor)) {
|
||||||
|
actor = await activitypub.getActor(callerUid, actor);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!actor) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uid = actor.id;
|
||||||
|
const { preferredUsername, published, icon, image, name, summary, hostname, followerCount, followingCount } = actor;
|
||||||
|
const isFollowing = await db.isSortedSetMember(`followingRemote:${callerUid}`, uid);
|
||||||
|
|
||||||
|
let picture;
|
||||||
|
if (icon) {
|
||||||
|
picture = typeof icon === 'string' ? icon : icon.url;
|
||||||
|
}
|
||||||
|
const iconBackgrounds = await user.getIconBackgrounds();
|
||||||
|
let bgColor = Array.prototype.reduce.call(preferredUsername, (cur, next) => cur + next.charCodeAt(), 0);
|
||||||
|
bgColor = iconBackgrounds[bgColor % iconBackgrounds.length];
|
||||||
|
|
||||||
|
const payload = {
|
||||||
|
uid,
|
||||||
|
username: `${preferredUsername}@${hostname}`,
|
||||||
|
userslug: `${preferredUsername}@${hostname}`,
|
||||||
|
displayname: name,
|
||||||
|
fullname: name,
|
||||||
|
joindate: new Date(published).getTime(),
|
||||||
|
picture,
|
||||||
|
'icon:text': (preferredUsername[0] || '').toUpperCase(),
|
||||||
|
'icon:bgColor': bgColor,
|
||||||
|
uploadedpicture: undefined,
|
||||||
|
'cover:url': !image || typeof image === 'string' ? image : image.url,
|
||||||
|
'cover:position': '50% 50%',
|
||||||
|
aboutme: summary,
|
||||||
|
aboutmeParsed: summary,
|
||||||
|
|
||||||
|
isFollowing,
|
||||||
|
counts: {
|
||||||
|
following: followingCount,
|
||||||
|
followers: followerCount,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
return payload;
|
||||||
|
}))).filter(Boolean);
|
||||||
|
|
||||||
|
return single ? profiles.pop() : profiles;
|
||||||
|
};
|
||||||
|
|
||||||
|
Mocks.post = async (objects) => {
|
||||||
|
const postCache = require('../posts/cache');
|
||||||
|
|
||||||
|
let single = false;
|
||||||
|
if (!Array.isArray(objects)) {
|
||||||
|
single = true;
|
||||||
|
objects = [objects];
|
||||||
|
}
|
||||||
|
|
||||||
|
const posts = (await Promise.all(objects.map(async (object) => {
|
||||||
|
if (object.type !== 'Note') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const {
|
||||||
|
id: pid,
|
||||||
|
published,
|
||||||
|
updated,
|
||||||
|
attributedTo: uid,
|
||||||
|
// conversation,
|
||||||
|
content,
|
||||||
|
sourceContent,
|
||||||
|
inReplyTo: toPid,
|
||||||
|
} = object;
|
||||||
|
|
||||||
|
const timestamp = new Date(published);
|
||||||
|
let edited = new Date(updated);
|
||||||
|
edited = Number.isNaN(edited.valueOf()) ? 0 : edited;
|
||||||
|
|
||||||
|
// If no source content, then `content` is pre-parsed and should be HTML, so cache it
|
||||||
|
if (!sourceContent) {
|
||||||
|
winston.verbose(`[activitypub/mockPost] pid ${pid} already has pre-parsed HTML content, adding to post cache...`);
|
||||||
|
postCache.set(pid, content);
|
||||||
|
}
|
||||||
|
|
||||||
|
const payload = {
|
||||||
|
uid,
|
||||||
|
pid,
|
||||||
|
timestamp: timestamp.getTime(),
|
||||||
|
timestampISO: timestamp.toISOString(),
|
||||||
|
content: sourceContent || content,
|
||||||
|
toPid,
|
||||||
|
|
||||||
|
edited,
|
||||||
|
editor: edited ? uid : undefined,
|
||||||
|
editedISO: edited ? edited.toISOString() : '',
|
||||||
|
|
||||||
|
deleted: 0,
|
||||||
|
deleterUid: 0,
|
||||||
|
replies: 0, // todo
|
||||||
|
bookmarks: 0,
|
||||||
|
votes: 0, // todo
|
||||||
|
};
|
||||||
|
|
||||||
|
return payload;
|
||||||
|
}))).filter(Boolean);
|
||||||
|
|
||||||
|
return single ? posts.pop() : posts;
|
||||||
|
};
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
const winston = require('winston');
|
|
||||||
|
|
||||||
const db = require('../database');
|
|
||||||
|
|
||||||
const activitypub = module.parent.exports;
|
|
||||||
const Notes = module.exports;
|
|
||||||
|
|
||||||
Notes.get = async (uid, id) => {
|
|
||||||
try {
|
|
||||||
const object = await activitypub.get(uid, id);
|
|
||||||
return await Notes.mockPost(object);
|
|
||||||
} catch (e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// todo: move to mocks.js
|
|
||||||
Notes.mockPost = async (objects) => {
|
|
||||||
const postCache = require('../posts/cache');
|
|
||||||
|
|
||||||
let single = false;
|
|
||||||
if (!Array.isArray(objects)) {
|
|
||||||
single = true;
|
|
||||||
objects = [objects];
|
|
||||||
}
|
|
||||||
|
|
||||||
const posts = (await Promise.all(objects.map(async (object) => {
|
|
||||||
if (object.type !== 'Note') {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const {
|
|
||||||
id: pid,
|
|
||||||
published,
|
|
||||||
updated,
|
|
||||||
attributedTo: uid,
|
|
||||||
// conversation,
|
|
||||||
content,
|
|
||||||
sourceContent,
|
|
||||||
inReplyTo: toPid,
|
|
||||||
} = object;
|
|
||||||
|
|
||||||
const timestamp = new Date(published);
|
|
||||||
let edited = new Date(updated);
|
|
||||||
edited = Number.isNaN(edited.valueOf()) ? 0 : edited;
|
|
||||||
|
|
||||||
// If no source content, then `content` is pre-parsed and should be HTML, so cache it
|
|
||||||
if (!sourceContent) {
|
|
||||||
winston.verbose(`[activitypub/mockPost] pid ${pid} already has pre-parsed HTML content, adding to post cache...`);
|
|
||||||
postCache.set(pid, content);
|
|
||||||
}
|
|
||||||
|
|
||||||
const payload = {
|
|
||||||
uid,
|
|
||||||
pid,
|
|
||||||
timestamp: timestamp.getTime(),
|
|
||||||
timestampISO: timestamp.toISOString(),
|
|
||||||
content: sourceContent || content,
|
|
||||||
toPid,
|
|
||||||
|
|
||||||
edited,
|
|
||||||
editor: edited ? uid : undefined,
|
|
||||||
editedISO: edited ? edited.toISOString() : '',
|
|
||||||
|
|
||||||
deleted: 0,
|
|
||||||
deleterUid: 0,
|
|
||||||
replies: 0, // todo
|
|
||||||
bookmarks: 0,
|
|
||||||
votes: 0, // todo
|
|
||||||
};
|
|
||||||
|
|
||||||
return payload;
|
|
||||||
}))).filter(Boolean);
|
|
||||||
|
|
||||||
return single ? posts.pop() : posts;
|
|
||||||
};
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const { getActor, mockProfile, get } = require('../../activitypub');
|
const { getActor, mocks, get } = require('../../activitypub');
|
||||||
const helpers = require('../helpers');
|
const helpers = require('../helpers');
|
||||||
const pagination = require('../../pagination');
|
const pagination = require('../../pagination');
|
||||||
|
|
||||||
@@ -13,7 +13,7 @@ controller.get = async function (req, res, next) {
|
|||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
|
|
||||||
const payload = await mockProfile(actor, req.uid);
|
const payload = await mocks.profile(actor, req.uid);
|
||||||
res.render('account/profile', payload);
|
res.render('account/profile', payload);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -26,13 +26,13 @@ controller.getFollow = async function (tpl, name, req, res) {
|
|||||||
const page = parseInt(req.query.page, 10) || 1;
|
const page = parseInt(req.query.page, 10) || 1;
|
||||||
|
|
||||||
const payload = {
|
const payload = {
|
||||||
...await mockProfile(actor, req.uid),
|
...await mocks.profile(actor, req.uid),
|
||||||
};
|
};
|
||||||
payload.title = `[[pages:${tpl}, ${username}]]`;
|
payload.title = `[[pages:${tpl}, ${username}]]`;
|
||||||
|
|
||||||
const collection = await get(req.uid, `${actor[name]}?page=${page}`);
|
const collection = await get(req.uid, `${actor[name]}?page=${page}`);
|
||||||
const resultsPerPage = collection.orderedItems.length;
|
const resultsPerPage = collection.orderedItems.length;
|
||||||
payload.users = await mockProfile(collection.orderedItems, req.uid);
|
payload.users = await mocks.profile(collection.orderedItems, req.uid);
|
||||||
|
|
||||||
const count = name === 'following' ? followingCount : followerCount;
|
const count = name === 'following' ? followingCount : followerCount;
|
||||||
const pageCount = Math.ceil(count / resultsPerPage);
|
const pageCount = Math.ceil(count / resultsPerPage);
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ module.exports = function (User) {
|
|||||||
|
|
||||||
const users = [
|
const users = [
|
||||||
...await db.getObjectsFields(uniqueUids.map(uid => `user:${uid}`), fields),
|
...await db.getObjectsFields(uniqueUids.map(uid => `user:${uid}`), fields),
|
||||||
...await activitypub.mockProfile(remoteIds, 0, fields),
|
...await activitypub.mocks.profile(remoteIds, 0, fields),
|
||||||
];
|
];
|
||||||
const result = await plugins.hooks.fire('filter:user.getFields', {
|
const result = await plugins.hooks.fire('filter:user.getFields', {
|
||||||
uids: uniqueUids,
|
uids: uniqueUids,
|
||||||
|
|||||||
Reference in New Issue
Block a user