fix: prefix view templates to avoid Nunjucks name collisions

Rename all views to activitypub-*.njk to prevent collisions with other
plugins that have dashboard.njk (podroll). Fix all new Date() calls to
use .toISOString() per Indiekit convention. Add try-catch in syndicator
to prevent delivery failures from crashing post creation.
This commit is contained in:
Ricardo
2026-02-18 23:10:35 +01:00
parent b551d82a21
commit deb9cb54a3
16 changed files with 25 additions and 20 deletions

View File

@@ -305,10 +305,15 @@ export default class ActivityPubEndpoint {
if (!self._federationHandler) {
return undefined;
}
return self._federationHandler.deliverToFollowers(
properties,
publication,
);
try {
return await self._federationHandler.deliverToFollowers(
properties,
publication,
);
} catch (error) {
console.error("[ActivityPub] Syndication failed:", error.message);
return undefined;
}
},
};
}

View File

@@ -10,7 +10,7 @@ export function activitiesController(mountPath) {
const collection = application?.collections?.get("ap_activities");
if (!collection) {
return response.render("activities", {
return response.render("activitypub-activities", {
title: response.locals.__("activitypub.activities"),
activities: [],
mountPath,
@@ -30,7 +30,7 @@ export function activitiesController(mountPath) {
const cursor = buildCursor(page, totalPages, mountPath + "/admin/activities");
response.render("activities", {
response.render("activitypub-activities", {
title: response.locals.__("activitypub.activities"),
activities,
mountPath,

View File

@@ -25,7 +25,7 @@ export function dashboardController(mountPath) {
.toArray()
: [];
response.render("dashboard", {
response.render("activitypub-dashboard", {
title: response.locals.__("activitypub.title"),
followerCount,
followingCount,

View File

@@ -10,7 +10,7 @@ export function followersController(mountPath) {
const collection = application?.collections?.get("ap_followers");
if (!collection) {
return response.render("followers", {
return response.render("activitypub-followers", {
title: response.locals.__("activitypub.followers"),
followers: [],
followerCount: 0,
@@ -31,7 +31,7 @@ export function followersController(mountPath) {
const cursor = buildCursor(page, totalPages, mountPath + "/admin/followers");
response.render("followers", {
response.render("activitypub-followers", {
title: response.locals.__("activitypub.followers"),
followers,
followerCount: totalCount,

View File

@@ -10,7 +10,7 @@ export function followingController(mountPath) {
const collection = application?.collections?.get("ap_following");
if (!collection) {
return response.render("following", {
return response.render("activitypub-following", {
title: response.locals.__("activitypub.following"),
following: [],
followingCount: 0,
@@ -31,7 +31,7 @@ export function followingController(mountPath) {
const cursor = buildCursor(page, totalPages, mountPath + "/admin/following");
response.render("following", {
response.render("activitypub-following", {
title: response.locals.__("activitypub.following"),
following,
followingCount: totalCount,

View File

@@ -15,7 +15,7 @@ import {
export function migrateGetController(mountPath) {
return async (request, response, next) => {
try {
response.render("migrate", {
response.render("activitypub-migrate", {
title: response.locals.__("activitypub.migrate"),
mountPath,
result: null,
@@ -91,7 +91,7 @@ export function migratePostController(mountPath, pluginOptions) {
}
}
response.render("migrate", {
response.render("activitypub-migrate", {
title: response.locals.__("activitypub.migrate"),
mountPath,
result,

View File

@@ -221,7 +221,7 @@ export function createFederationHandler(options) {
actorUrl,
objectUrl: activity.object?.id || activity.object,
summary: `Delivered ${activity.type} to ${delivered}/${inboxes.size} inboxes`,
receivedAt: new Date(),
receivedAt: new Date().toISOString(),
...(storeRawActivities ? { raw: activity } : {}),
});

View File

@@ -63,7 +63,7 @@ async function handleFollow(activity, collections, context) {
avatar: profile.icon?.url || "",
inbox: profile.inbox || "",
sharedInbox: profile.endpoints?.sharedInbox || "",
followedAt: new Date(),
followedAt: new Date().toISOString(),
},
},
{ upsert: true },
@@ -286,6 +286,6 @@ async function logActivity(collections, context, record) {
await collections.ap_activities.insertOne({
...rest,
...(context.storeRawActivities ? { raw } : {}),
receivedAt: new Date(),
receivedAt: new Date().toISOString(),
});
}

View File

@@ -32,7 +32,7 @@ export async function getOrCreateKeyPair(collection, actorUrl) {
actorUrl,
publicKeyPem: publicKey,
privateKeyPem: privateKey,
createdAt: new Date(),
createdAt: new Date().toISOString(),
});
return { publicKeyPem: publicKey, privateKeyPem: privateKey };

View File

@@ -121,7 +121,7 @@ export async function bulkImportFollowing(handles, collection) {
name: resolved.name,
inbox: resolved.inbox,
sharedInbox: resolved.sharedInbox,
followedAt: new Date(),
followedAt: new Date().toISOString(),
source: "import",
},
},
@@ -171,7 +171,7 @@ export async function bulkImportFollowers(entries, collection) {
name: actorData.name,
inbox: actorData.inbox,
sharedInbox: actorData.sharedInbox,
followedAt: new Date(),
followedAt: new Date().toISOString(),
pending: true, // Will be confirmed when they re-follow after Move
},
},

View File

@@ -1,6 +1,6 @@
{
"name": "@rmdes/indiekit-endpoint-activitypub",
"version": "0.1.2",
"version": "0.1.3",
"description": "ActivityPub federation endpoint for Indiekit via Fedify. Adds full fediverse support: actor, inbox, outbox, followers, following, syndication, and Mastodon migration.",
"keywords": [
"indiekit",