mirror of
https://github.com/versia-pub/server.git
synced 2025-12-06 16:38:19 +01:00
feat(federation): ✨ Add signatures to all users and objects served
This commit is contained in:
parent
5a52ac005b
commit
d20988afa1
|
|
@ -1,14 +1,17 @@
|
||||||
import { applyConfig, handleZodError } from "@/api";
|
import { applyConfig, handleZodError } from "@/api";
|
||||||
import { errorResponse, jsonResponse, response } from "@/response";
|
import { errorResponse, response } from "@/response";
|
||||||
import type { Hono } from "@hono/hono";
|
import type { Hono } from "@hono/hono";
|
||||||
import { zValidator } from "@hono/zod-validator";
|
import { zValidator } from "@hono/zod-validator";
|
||||||
|
import { SignatureConstructor } from "@lysand-org/federation";
|
||||||
import type { Entity } from "@lysand-org/federation/types";
|
import type { Entity } from "@lysand-org/federation/types";
|
||||||
import { and, eq, inArray, sql } from "drizzle-orm";
|
import { and, eq, inArray, sql } from "drizzle-orm";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { type LikeType, likeToLysand } from "~/classes/functions/like";
|
import { type LikeType, likeToLysand } from "~/classes/functions/like";
|
||||||
import { db } from "~/drizzle/db";
|
import { db } from "~/drizzle/db";
|
||||||
import { Notes } from "~/drizzle/schema";
|
import { Notes } from "~/drizzle/schema";
|
||||||
|
import { config } from "~/packages/config-manager";
|
||||||
import { Note } from "~/packages/database-interface/note";
|
import { Note } from "~/packages/database-interface/note";
|
||||||
|
import { User } from "~/packages/database-interface/user";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
allowedMethods: ["GET"],
|
allowedMethods: ["GET"],
|
||||||
|
|
@ -45,6 +48,7 @@ export default (app: Hono) =>
|
||||||
const { debug } = context.req.valid("query");
|
const { debug } = context.req.valid("query");
|
||||||
|
|
||||||
let foundObject: Note | LikeType | null = null;
|
let foundObject: Note | LikeType | null = null;
|
||||||
|
let foundAuthor: User | null = null;
|
||||||
let apiObject: Entity | null = null;
|
let apiObject: Entity | null = null;
|
||||||
|
|
||||||
foundObject = await Note.fromSql(
|
foundObject = await Note.fromSql(
|
||||||
|
|
@ -54,6 +58,7 @@ export default (app: Hono) =>
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
apiObject = foundObject ? foundObject.toLysand() : null;
|
apiObject = foundObject ? foundObject.toLysand() : null;
|
||||||
|
foundAuthor = foundObject ? foundObject.author : null;
|
||||||
|
|
||||||
if (!foundObject) {
|
if (!foundObject) {
|
||||||
foundObject =
|
foundObject =
|
||||||
|
|
@ -65,6 +70,9 @@ export default (app: Hono) =>
|
||||||
),
|
),
|
||||||
})) ?? null;
|
})) ?? null;
|
||||||
apiObject = foundObject ? likeToLysand(foundObject) : null;
|
apiObject = foundObject ? likeToLysand(foundObject) : null;
|
||||||
|
foundAuthor = foundObject
|
||||||
|
? await User.fromId(foundObject.likerId)
|
||||||
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(foundObject && apiObject)) {
|
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(),
|
||||||
|
});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
import { applyConfig, handleZodError } from "@/api";
|
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 type { Hono } from "@hono/hono";
|
||||||
import { zValidator } from "@hono/zod-validator";
|
import { zValidator } from "@hono/zod-validator";
|
||||||
|
import { SignatureConstructor } from "@lysand-org/federation";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
import { config } from "~/packages/config-manager";
|
||||||
import { User } from "~/packages/database-interface/user";
|
import { User } from "~/packages/database-interface/user";
|
||||||
|
|
||||||
export const meta = applyConfig({
|
export const meta = applyConfig({
|
||||||
|
|
@ -63,6 +65,28 @@ export default (app: Hono) =>
|
||||||
return redirect(user.toApi().url);
|
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(),
|
||||||
|
});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue