feat(federation): Add signatures to all users and objects served

This commit is contained in:
Jesse Wierzbinski 2024-07-24 23:42:00 +02:00
parent 5a52ac005b
commit d20988afa1
No known key found for this signature in database
2 changed files with 60 additions and 4 deletions

View file

@ -1,14 +1,17 @@
import { applyConfig, handleZodError } from "@/api";
import { errorResponse, jsonResponse, response } from "@/response";
import { errorResponse, response } from "@/response";
import type { Hono } from "@hono/hono";
import { zValidator } from "@hono/zod-validator";
import { SignatureConstructor } from "@lysand-org/federation";
import type { Entity } from "@lysand-org/federation/types";
import { and, eq, inArray, sql } from "drizzle-orm";
import { z } from "zod";
import { type LikeType, likeToLysand } from "~/classes/functions/like";
import { db } from "~/drizzle/db";
import { Notes } from "~/drizzle/schema";
import { config } from "~/packages/config-manager";
import { Note } from "~/packages/database-interface/note";
import { User } from "~/packages/database-interface/user";
export const meta = applyConfig({
allowedMethods: ["GET"],
@ -45,6 +48,7 @@ export default (app: Hono) =>
const { debug } = context.req.valid("query");
let foundObject: Note | LikeType | null = null;
let foundAuthor: User | null = null;
let apiObject: Entity | null = null;
foundObject = await Note.fromSql(
@ -54,6 +58,7 @@ export default (app: Hono) =>
),
);
apiObject = foundObject ? foundObject.toLysand() : null;
foundAuthor = foundObject ? foundObject.author : null;
if (!foundObject) {
foundObject =
@ -65,6 +70,9 @@ export default (app: Hono) =>
),
})) ?? null;
apiObject = foundObject ? likeToLysand(foundObject) : null;
foundAuthor = foundObject
? await User.fromId(foundObject.likerId)
: null;
}
if (!(foundObject && apiObject)) {
@ -77,6 +85,30 @@ export default (app: Hono) =>
});
}
return jsonResponse(apiObject);
const objectString = JSON.stringify(apiObject);
// If base_url uses https and request uses http, rewrite request to use https
// This fixes reverse proxy errors
const reqUrl = new URL(context.req.url);
if (
new URL(config.http.base_url).protocol === "https:" &&
reqUrl.protocol === "http:"
) {
reqUrl.protocol = "https:";
}
const author = foundAuthor ?? User.getServerActor();
const { headers } = await (
await SignatureConstructor.fromStringKey(
author.data.privateKey ?? "",
author.getUri(),
)
).sign("POST", reqUrl, objectString);
return response(objectString, 200, {
"Content-Type": "application/json",
...headers.toJSON(),
});
},
);

View file

@ -1,8 +1,10 @@
import { applyConfig, handleZodError } from "@/api";
import { errorResponse, jsonResponse, redirect, response } from "@/response";
import { errorResponse, redirect, response } from "@/response";
import type { Hono } from "@hono/hono";
import { zValidator } from "@hono/zod-validator";
import { SignatureConstructor } from "@lysand-org/federation";
import { z } from "zod";
import { config } from "~/packages/config-manager";
import { User } from "~/packages/database-interface/user";
export const meta = applyConfig({
@ -63,6 +65,28 @@ export default (app: Hono) =>
return redirect(user.toApi().url);
}
return jsonResponse(user.toLysand());
const userString = JSON.stringify(user.toLysand());
// If base_url uses https and request uses http, rewrite request to use https
// This fixes reverse proxy errors
const reqUrl = new URL(context.req.url);
if (
new URL(config.http.base_url).protocol === "https:" &&
reqUrl.protocol === "http:"
) {
reqUrl.protocol = "https:";
}
const { headers } = await (
await SignatureConstructor.fromStringKey(
user.data.privateKey ?? "",
user.getUri(),
)
).sign("POST", reqUrl, userString);
return response(userString, 200, {
"Content-Type": "application/json",
...headers.toJSON(),
});
},
);