Skip to content

Commit

Permalink
Misc cleanup after adding profile posts endpoint (#218)
Browse files Browse the repository at this point in the history
no refs

Misc cleanup after adding profile posts endpoint
  • Loading branch information
mike182uk authored Nov 29, 2024
1 parent f401867 commit 3f7c576
Show file tree
Hide file tree
Showing 4 changed files with 9 additions and 136 deletions.
30 changes: 9 additions & 21 deletions src/api/action/profile/get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
getFollowerCount,
getFollowingCount,
getHandle,
getRecentActivities,
isFollowing,
isHandle,
} from '../../../helpers/activitypub/actor';
Expand All @@ -20,7 +19,6 @@ interface Profile {
followerCount: number;
followingCount: number;
isFollowing: boolean;
posts: any[];
}

export async function profileGetAction(
Expand Down Expand Up @@ -50,7 +48,6 @@ export async function profileGetAction(
followerCount: 0,
followingCount: 0,
isFollowing: false,
posts: [],
};

try {
Expand All @@ -64,28 +61,19 @@ export async function profileGetAction(
result.actor.summary = sanitizeHtml(result.actor.summary);
result.handle = getHandle(actor);

const [
followerCount,
followingCount,
isFollowingResult,
posts,
attachments,
] = await Promise.all([
getFollowerCount(actor),
getFollowingCount(actor),
isFollowing(actor, { db }),
getRecentActivities(actor, {
sanitizeContent: (content: string) => sanitizeHtml(content),
}),
getAttachments(actor, {
sanitizeValue: (value: string) => sanitizeHtml(value),
}),
]);
const [followerCount, followingCount, isFollowingResult, attachments] =
await Promise.all([
getFollowerCount(actor),
getFollowingCount(actor),
isFollowing(actor, { db }),
getAttachments(actor, {
sanitizeValue: (value: string) => sanitizeHtml(value),
}),
]);

result.followerCount = followerCount;
result.followingCount = followingCount;
result.isFollowing = isFollowingResult;
result.posts = posts;
result.actor.attachment = attachments;
} catch (err) {
logger.error('Profile retrieval failed ({handle}): {error}', {
Expand Down
6 changes: 0 additions & 6 deletions src/api/action/search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
getFollowerCount,
getFollowingCount,
getHandle,
getRecentActivities,
isFollowing,
isHandle,
} from '../../helpers/activitypub/actor';
Expand All @@ -21,7 +20,6 @@ interface ProfileSearchResult {
followerCount: number;
followingCount: number;
isFollowing: boolean;
posts: any[];
}

interface SearchResults {
Expand Down Expand Up @@ -70,7 +68,6 @@ export async function searchAction(
followerCount: 0,
followingCount: 0,
isFollowing: false,
posts: [],
};

result.actor = await actor.toJsonLd();
Expand All @@ -83,9 +80,6 @@ export async function searchAction(
result.followerCount = await getFollowerCount(actor);
result.followingCount = await getFollowingCount(actor);
result.isFollowing = await isFollowing(actor, { db });
result.posts = await getRecentActivities(actor, {
sanitizeContent: (content: string) => sanitizeHtml(content),
});

results.profiles.push(result);
}
Expand Down
36 changes: 0 additions & 36 deletions src/helpers/activitypub/actor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,42 +49,6 @@ export function getHandle(actor: Actor): string {
return `@${actor?.preferredUsername || 'unknown'}@${host}`;
}

export async function getRecentActivities(
actor: Actor,
options?: {
sanitizeContent?: (content: string) => string;
},
): Promise<unknown[]> {
const activities: unknown[] = [];
const outbox = await actor.getOutbox();

if (!outbox) {
return [];
}

const firstPage = await outbox.getFirst();

if (!firstPage) {
return [];
}

for await (const activity of firstPage.getItems()) {
const activityJson = (await activity.toJsonLd({
format: 'compact',
})) as { content: string };

if (options?.sanitizeContent) {
activityJson.content = options.sanitizeContent(
activityJson.content,
);
}

activities.push(activityJson);
}

return activities;
}

export async function isFollowing(
actor: Actor,
options: {
Expand Down
73 changes: 0 additions & 73 deletions src/helpers/activitypub/actor.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
getFollowerCount,
getFollowingCount,
getHandle,
getRecentActivities,
isFollowing,
isHandle,
} from './actor';
Expand Down Expand Up @@ -160,78 +159,6 @@ describe('getHandle', () => {
});
});

describe('getRecentActivities', () => {
it('should return an array of recent activities for the actor', async () => {
const activityContent = 'Hello, world!';
const activityToJsonLdMock = vi
.fn()
.mockResolvedValue({ content: activityContent });
const actor = {
getOutbox: vi.fn().mockResolvedValue({
getFirst: vi.fn().mockResolvedValue({
getItems: vi.fn().mockImplementation(async function* () {
yield { toJsonLd: activityToJsonLdMock };
}),
}),
}),
} as unknown as Actor;

expect(await getRecentActivities(actor)).toEqual([
{ content: activityContent },
]);

expect(activityToJsonLdMock).toHaveBeenCalledWith({
format: 'compact',
});
});

it('should return an empty array if the actor outbox is not available', async () => {
const actor = {
getOutbox: vi.fn().mockResolvedValue(null),
} as unknown as Actor;

expect(await getRecentActivities(actor)).toEqual([]);
});

it('should return an empty array if the first page of the actor outbox is not available', async () => {
const actor = {
getOutbox: vi.fn().mockResolvedValue({
getFirst: vi.fn().mockResolvedValue(null),
}),
} as unknown as Actor;

expect(await getRecentActivities(actor)).toEqual([]);
});

it('should sanitize the activity content if a sanitizeContent function is provided', async () => {
const actor = {
getOutbox: vi.fn().mockResolvedValue({
getFirst: vi.fn().mockResolvedValue({
getItems: vi.fn().mockImplementation(async function* () {
yield {
toJsonLd: vi.fn().mockResolvedValue({
content: '<script>alert("XSS")</script>',
}),
};
}),
}),
}),
} as unknown as Actor;

expect(
await getRecentActivities(actor, {
sanitizeContent: (content) =>
content
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;'),
}),
).toEqual([
{ content: '&lt;script&gt;alert(&quot;XSS&quot;)&lt;/script&gt;' },
]);
});
});

describe('isFollowing', () => {
it('should return a boolean indicating if the current user is following the given actor', async () => {
const db = {
Expand Down

0 comments on commit 3f7c576

Please sign in to comment.