Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
mike182uk committed Sep 16, 2024
1 parent 46ef68e commit 3a3e987
Show file tree
Hide file tree
Showing 15 changed files with 784 additions and 258 deletions.
17 changes: 17 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// @ts-check

// See https://typescript-eslint.io/getting-started/

import eslint from '@eslint/js';
import tseslint from 'typescript-eslint';

export default tseslint.config(
eslint.configs.recommended,
...tseslint.configs.recommended,
...tseslint.configs.stylistic,
{
rules: {
'@typescript-eslint/no-explicit-any': ['warn'],
},
},
);
8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,28 @@
"test:integration": "c8 --src src --all --reporter text --reporter cobertura mocha -r tsx './src/**/*.integration.test.ts'",
"test:code": "c8 --src src --all --reporter text --reporter cobertura mocha -r tsx './src/**/*.test.ts'",
"test:all": "yarn test:types && yarn test:code",
"lint:code": "eslint *.js lib/ --ext .js --cache",
"lint:code": "eslint src/**/*.ts",
"lint": "yarn lint:code"
},
"files": [
"src"
],
"devDependencies": {
"@cucumber/cucumber": "10.8.0",
"@eslint/js": "9.10.0",
"@types/eslint__js": "8.42.3",
"@types/mocha": "10.0.7",
"@types/node": "20.12.12",
"@types/sanitize-html": "^2.11.0",
"@types/sanitize-html": "2.11.0",
"@types/sinon": "17.0.3",
"@types/uuid": "10.0.0",
"c8": "10.1.2",
"eslint": "9.10.0",
"mocha": "10.5.2",
"sinon": "18.0.0",
"tsx": "4.11.0",
"typescript": "5.4.5",
"typescript-eslint": "8.5.0",
"wiremock-captain": "3.3.1"
},
"dependencies": {
Expand Down
18 changes: 6 additions & 12 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,11 @@ import { serve } from '@hono/node-server';
import {
Article,
Accept,
Object as ActivityPubObject,
createFederation,
Follow,
KvKey,
KvStore,
MemoryKvStore,
Create,
Note,
Application,
Group,
Organization,
Service,
Update,
Announce,
Context,
Expand Down Expand Up @@ -68,10 +61,10 @@ await configure({
loggers: [{ category: 'fedify', sinks: ['console'], level: 'debug' }],
});

export type ContextData = {
export interface ContextData {
db: KvStore;
globaldb: KvStore;
};
}

const fedifyKv = await KnexKvStore.create(client, 'key_value');

Expand Down Expand Up @@ -198,10 +191,11 @@ fedify.setObjectDispatcher(

/** Hono */

export type HonoContextVariables = {
export interface HonoContextVariables {
db: KvStore;
globaldb: KvStore;
};
[key: string]: unknown;
}

const app = new Hono<{ Variables: HonoContextVariables }>();

Expand Down Expand Up @@ -270,7 +264,7 @@ app.use(async (ctx, next) => {

/** Custom API routes */

app.get('/ping', (ctx) => {
app.get('/ping', () => {
return new Response('', {
status: 200
});
Expand Down
47 changes: 22 additions & 25 deletions src/dispatchers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import {
Announce,
isActor,
Actor,
Object as APObject,
Recipient,
Like,
Undo,
Expand Down Expand Up @@ -55,7 +54,11 @@ export async function handleFollow(
if (!follow.id) {
return;
}
const parsed = (ctx as any).parseUri(follow.objectId);
if (!follow.objectId) {
console.log('Follow missing objectId - exit');
return;
}
const parsed = ctx.parseUri(follow.objectId);
if (parsed?.type !== 'actor') {
// TODO Log
return;
Expand All @@ -66,7 +69,7 @@ export async function handleFollow(
}

const currentFollowers = await ctx.data.db.get<string[]>(['followers']) ?? [];
let shouldRecordFollower = currentFollowers.includes(sender.id.href) === false;
const shouldRecordFollower = currentFollowers.includes(sender.id.href) === false;

// Add follow activity to inbox
const followJson = await follow.toJsonLd();
Expand Down Expand Up @@ -106,12 +109,13 @@ export async function handleAccept(
accept: Accept,
) {
console.log('Handling Accept');
const parsed = (ctx as any).parseUri(accept.objectId);
console.log(parsed);
if (false && parsed?.type !== 'follow') {
console.log('Not accepting a follow - exit');
if (!accept.objectId) {
console.log('Accept missing objectId - exit');
return;
}
const parsed = ctx.parseUri(accept.objectId);
console.log(parsed);

if (!accept.id) {
console.log('Accept missing id - exit');
return;
Expand All @@ -138,14 +142,15 @@ export async function handleCreate(
create: Create,
) {
console.log('Handling Create');
const parsed = (ctx as any).parseUri(create.objectId);
console.log(parsed);
if (false && parsed?.type !== 'article') {
console.log('Not accepting a follow - exit');
if (!create.objectId) {
console.log('Create missing objectId - exit');
return;
}
const parsed = ctx.parseUri(create.objectId);
console.log(parsed);

if (!create.id) {
console.log('Accept missing id - exit');
console.log('Create missing id - exit');
return;
}

Expand Down Expand Up @@ -188,7 +193,7 @@ export async function handleAnnounce(

// Lookup announced object - If not found in globalDb, perform network lookup
let object = null;
let existing = await ctx.data.globaldb.get([announce.objectId.href]) ?? null;
const existing = await ctx.data.globaldb.get([announce.objectId.href]) ?? null;

if (!existing) {
console.log('Object not found in globalDb, performing network lookup');
Expand Down Expand Up @@ -257,7 +262,7 @@ export async function handleLike(

// Lookup liked object - If not found in globalDb, perform network lookup
let object = null;
let existing = await ctx.data.globaldb.get([like.objectId.href]) ?? null;
const existing = await ctx.data.globaldb.get([like.objectId.href]) ?? null;

if (!existing) {
console.log('Object not found in globalDb, performing network lookup');
Expand Down Expand Up @@ -314,7 +319,6 @@ function convertJsonLdToRecipient(result: any): Recipient {

export async function followersDispatcher(
ctx: Context<ContextData>,
handle: string,
) {
console.log('Followers Dispatcher');
let items: Recipient[] = [];
Expand All @@ -336,20 +340,18 @@ export async function followersDispatcher(

export async function followersCounter(
ctx: RequestContext<ContextData>,
handle: string,
) {
const results = (await ctx.data.db.get<string[]>(['followers'])) || [];
return results.length;
}

export async function followingDispatcher(
ctx: RequestContext<ContextData>,
handle: string,
) {
console.log('Following Dispatcher');
const results = (await ctx.data.db.get<string[]>(['following'])) || [];
console.log(results);
let items: Person[] = [];
const items: Person[] = [];
for (const result of results) {
try {
const thing = await lookupActor(ctx, result);
Expand All @@ -367,7 +369,6 @@ export async function followingDispatcher(

export async function followingCounter(
ctx: RequestContext<ContextData>,
handle: string,
) {
const results = (await ctx.data.db.get<string[]>(['following'])) || [];
return results.length;
Expand All @@ -380,13 +381,12 @@ function filterOutboxActivityUris (activityUris: string[]) {

export async function outboxDispatcher(
ctx: RequestContext<ContextData>,
handle: string,
) {
console.log('Outbox Dispatcher');
const results = filterOutboxActivityUris((await ctx.data.db.get<string[]>(['outbox'])) || []);
console.log(results);

let items: Activity[] = [];
const items: Activity[] = [];
for (const result of results) {
try {
const thing = await ctx.data.globaldb.get([result]);
Expand All @@ -403,7 +403,6 @@ export async function outboxDispatcher(

export async function outboxCounter(
ctx: RequestContext<ContextData>,
handle: string,
) {
const results = (await ctx.data.db.get<string[]>(['outbox'])) || [];

Expand All @@ -412,13 +411,12 @@ export async function outboxCounter(

export async function likedDispatcher(
ctx: RequestContext<ContextData>,
handle: string,
) {
console.log('Liked Dispatcher');
const results = (await ctx.data.db.get<string[]>(['liked'])) || [];
console.log(results);

let items: Like[] = [];
const items: Like[] = [];
for (const result of results) {
try {
const thing = await ctx.data.globaldb.get([result]);
Expand All @@ -435,7 +433,6 @@ export async function likedDispatcher(

export async function likedCounter(
ctx: RequestContext<ContextData>,
handle: string,
) {
const results = (await ctx.data.db.get<string[]>(['liked'])) || [];

Expand Down
23 changes: 2 additions & 21 deletions src/dispatchers.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,7 @@ import assert from 'assert';
import sinon from 'sinon';
import {
actorDispatcher,
keypairDispatcher,
handleFollow,
inboxErrorHandler,
handleAccept,
handleCreate,
followersDispatcher,
followersCounter,
followingDispatcher,
followingCounter,
outboxDispatcher,
outboxCounter,
articleDispatcher,
noteDispatcher,
followDispatcher,
acceptDispatcher,
createDispatcher,
} from './dispatchers';
import { Activity, RequestContext } from '@fedify/fedify';
import { ACTOR_DEFAULT_HANDLE } from './constants';
Expand All @@ -34,8 +19,6 @@ describe('dispatchers', function () {
assert.equal(actual, expected);
});
});
describe('keypairDispatcher', function () {});
describe('handleFollow', function () {});

describe('outboxDispatcher', function () {
const outboxActivities: Record<string, any> = {
Expand Down Expand Up @@ -102,10 +85,8 @@ describe('dispatchers', function () {
assert.equal(result.items.length, 2);
assert.equal(result.items[0] instanceof Activity, true);
assert.equal(result.items[1] instanceof Activity, true);
// @ts-ignore: We know that this is the correct type because of the above assertions
assert.equal(result.items[0].id.toString(), 'https://example.com/announce/456');
// @ts-ignore: We know that this is the correct type because of the above assertions
assert.equal(result.items[1].id.toString(), 'https://example.com/create/123');
assert.equal(result.items[0].id?.toString(), 'https://example.com/announce/456');
assert.equal(result.items[1].id?.toString(), 'https://example.com/create/123');
});
});
});
2 changes: 1 addition & 1 deletion src/ghost.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
ACTOR_DEFAULT_SUMMARY
} from './constants';

type SiteSettings = {
export interface SiteSettings {
site: {
description: string;
icon: string;
Expand Down
15 changes: 6 additions & 9 deletions src/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
Actor,
PUBLIC_COLLECTION
} from '@fedify/fedify';
import { Context, Next } from 'hono';
import { Context } from 'hono';
import sanitizeHtml from 'sanitize-html';
import { v4 as uuidv4 } from 'uuid';
import { addToList, removeFromList } from './kv-helpers';
Expand All @@ -24,14 +24,14 @@ import { Temporal } from '@js-temporal/polyfill';
import { createHash } from 'node:crypto';
import { lookupActor } from 'lookup-helpers';

type StoredThing = {
export interface StoredThing {
id: string;
object: string | {
id: string;
content: string;
[key: string]: any;
[key: string]: unknown;
};
[key: string]: any;
[key: string]: unknown;
}

import z from 'zod';
Expand Down Expand Up @@ -247,7 +247,6 @@ const PostPublishedWebhookSchema = z.object({

export async function postPublishedWebhook(
ctx: Context<{ Variables: HonoContextVariables }>,
next: Next,
) {
// TODO: Validate webhook with secret
const data = PostPublishedWebhookSchema.parse(
Expand Down Expand Up @@ -299,7 +298,6 @@ export async function postPublishedWebhook(

export async function siteChangedWebhook(
ctx: Context<{ Variables: HonoContextVariables }>,
next: Next,
) {
try {
// Retrieve site settings from Ghost
Expand Down Expand Up @@ -377,15 +375,14 @@ export async function siteChangedWebhook(

export async function inboxHandler(
ctx: Context<{ Variables: HonoContextVariables }>,
next: Next,
) {
const liked = (await ctx.get('db').get<string[]>(['liked'])) || [];
const results = (await ctx.get('db').get<string[]>(['inbox'])) || [];
const apCtx = fedify.createContext(ctx.req.raw as Request, {
db: ctx.get('db'),
globaldb: ctx.get('globaldb'),
});
let items: unknown[] = [];
const items: unknown[] = [];
for (const result of results) {
try {
const db = ctx.get('globaldb');
Expand All @@ -412,7 +409,7 @@ export async function inboxHandler(
});
}

let objectId: string = '';
let objectId = '';
if (typeof thing.object === 'string') {
objectId = thing.object;
} else if (typeof thing.object.id === 'string') {
Expand Down
Loading

0 comments on commit 3a3e987

Please sign in to comment.