mirror of
https://github.com/versia-pub/server.git
synced 2026-03-13 05:49:16 +01:00
refactor(federation): 🔥 Remove old code and simplify federation requests
This commit is contained in:
parent
ad9ed2598c
commit
2f823317c2
18 changed files with 182 additions and 302 deletions
|
|
@ -1,27 +0,0 @@
|
|||
import { emojiValidatorWithColons } from "@/api";
|
||||
import { type InferSelectModel, inArray } from "drizzle-orm";
|
||||
import { Emojis, type Instances } from "~/drizzle/schema";
|
||||
import { Emoji } from "~/packages/database-interface/emoji";
|
||||
|
||||
export type EmojiWithInstance = InferSelectModel<typeof Emojis> & {
|
||||
instance: InferSelectModel<typeof Instances> | null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Used for parsing emojis from local text
|
||||
* @param text The text to parse
|
||||
* @returns An array of emojis
|
||||
*/
|
||||
export const parseEmojis = async (text: string): Promise<Emoji[]> => {
|
||||
const matches = text.match(emojiValidatorWithColons);
|
||||
if (!matches || matches.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return Emoji.manyFromSql(
|
||||
inArray(
|
||||
Emojis.shortcode,
|
||||
matches.map((match) => match.replace(/:/g, "")),
|
||||
),
|
||||
);
|
||||
};
|
||||
|
|
@ -1,65 +1,10 @@
|
|||
import { debugRequest } from "@/api";
|
||||
import { getLogger } from "@logtape/logtape";
|
||||
import { SignatureConstructor } from "@lysand-org/federation";
|
||||
import type { Entity, Undo } from "@lysand-org/federation/types";
|
||||
import type { Undo } from "@lysand-org/federation/types";
|
||||
import { config } from "config-manager";
|
||||
import type { User } from "~/packages/database-interface/user";
|
||||
|
||||
export const localObjectUri = (id: string) =>
|
||||
new URL(`/objects/${id}`, config.http.base_url).toString();
|
||||
|
||||
export const objectToInboxRequest = async (
|
||||
object: Entity,
|
||||
author: User,
|
||||
userToSendTo: User,
|
||||
): Promise<Request> => {
|
||||
if (userToSendTo.isLocal() || !userToSendTo.data.endpoints?.inbox) {
|
||||
throw new Error("UserToSendTo has no inbox or is a local user");
|
||||
}
|
||||
|
||||
if (author.isRemote()) {
|
||||
throw new Error("Author is a remote user");
|
||||
}
|
||||
|
||||
const privateKey = await crypto.subtle.importKey(
|
||||
"pkcs8",
|
||||
Buffer.from(author.data.privateKey ?? "", "base64"),
|
||||
"Ed25519",
|
||||
false,
|
||||
["sign"],
|
||||
);
|
||||
|
||||
const ctor = new SignatureConstructor(privateKey, author.getUri());
|
||||
|
||||
const userInbox = new URL(userToSendTo.data.endpoints?.inbox ?? "");
|
||||
|
||||
const request = new Request(userInbox, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Origin: new URL(config.http.base_url).host,
|
||||
},
|
||||
body: JSON.stringify(object),
|
||||
});
|
||||
|
||||
const { request: signed, signedString } = await ctor.sign(request);
|
||||
|
||||
if (config.debug.federation) {
|
||||
// Debug request
|
||||
await debugRequest(signed);
|
||||
|
||||
const logger = getLogger("federation");
|
||||
|
||||
// Log public key
|
||||
logger.debug`Sender public key: ${author.data.publicKey}`;
|
||||
|
||||
// Log signed string
|
||||
logger.debug`Signed string:\n${signedString}`;
|
||||
}
|
||||
|
||||
return signed;
|
||||
};
|
||||
|
||||
export const undoFederationRequest = (undoer: User, uri: string): Undo => {
|
||||
const id = crypto.randomUUID();
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,6 @@
|
|||
import { mentionValidator } from "@/api";
|
||||
import { sanitizeHtml, sanitizeHtmlInline } from "@/sanitization";
|
||||
import markdownItTaskLists from "@hackmd/markdown-it-task-lists";
|
||||
import { getLogger } from "@logtape/logtape";
|
||||
import {
|
||||
FederationRequester,
|
||||
SignatureConstructor,
|
||||
} from "@lysand-org/federation";
|
||||
import type { ContentFormat } from "@lysand-org/federation/types";
|
||||
import { config } from "config-manager";
|
||||
import {
|
||||
|
|
@ -37,11 +32,9 @@ import {
|
|||
type Notes,
|
||||
Users,
|
||||
} from "~/drizzle/schema";
|
||||
import type { Note } from "~/packages/database-interface/note";
|
||||
import type { EmojiWithInstance } from "~/packages/database-interface/emoji";
|
||||
import { User } from "~/packages/database-interface/user";
|
||||
import type { Application } from "./application";
|
||||
import type { EmojiWithInstance } from "./emoji";
|
||||
import { objectToInboxRequest } from "./federation";
|
||||
import {
|
||||
type UserWithInstance,
|
||||
type UserWithRelations,
|
||||
|
|
@ -316,11 +309,7 @@ export const parseTextMentions = async (
|
|||
|
||||
// Attempt to resolve mentions that were not found
|
||||
for (const person of notFoundRemoteUsers) {
|
||||
const signatureConstructor = await SignatureConstructor.fromStringKey(
|
||||
author.data.privateKey ?? "",
|
||||
author.getUri(),
|
||||
);
|
||||
const manager = new FederationRequester(signatureConstructor);
|
||||
const manager = await author.getFederationRequester();
|
||||
|
||||
const uri = await User.webFinger(
|
||||
manager,
|
||||
|
|
@ -451,26 +440,3 @@ export const getMarkdownRenderer = () => {
|
|||
|
||||
return renderer;
|
||||
};
|
||||
|
||||
export const federateNote = async (note: Note) => {
|
||||
for (const user of await note.getUsersToFederateTo()) {
|
||||
// TODO: Add queue system
|
||||
const request = await objectToInboxRequest(
|
||||
note.toLysand(),
|
||||
note.author,
|
||||
user,
|
||||
);
|
||||
|
||||
// Send request
|
||||
const response = await fetch(request, {
|
||||
proxy: config.http.proxy.address,
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const logger = getLogger("federation");
|
||||
|
||||
logger.debug`${await response.text()}`;
|
||||
logger.error`Failed to federate status ${note.data.id} to ${user.getUri()}`;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,7 +1,3 @@
|
|||
/**
|
||||
* Old code that needs to be rewritten
|
||||
*/
|
||||
import { getLogger } from "@logtape/logtape";
|
||||
import type {
|
||||
Follow,
|
||||
FollowAccept,
|
||||
|
|
@ -19,10 +15,9 @@ import {
|
|||
Tokens,
|
||||
type Users,
|
||||
} from "~/drizzle/schema";
|
||||
import type { EmojiWithInstance } from "~/packages/database-interface/emoji";
|
||||
import { User } from "~/packages/database-interface/user";
|
||||
import type { Application } from "./application";
|
||||
import type { EmojiWithInstance } from "./emoji";
|
||||
import { objectToInboxRequest } from "./federation";
|
||||
import {
|
||||
type Relationship,
|
||||
checkForBidirectionalRelationships,
|
||||
|
|
@ -168,25 +163,12 @@ export const followRequestUser = async (
|
|||
}
|
||||
|
||||
if (isRemote) {
|
||||
// Federate
|
||||
// TODO: Make database job
|
||||
const request = await objectToInboxRequest(
|
||||
const { ok } = await follower.federateToUser(
|
||||
followRequestToLysand(follower, followee),
|
||||
follower,
|
||||
followee,
|
||||
);
|
||||
|
||||
// Send request
|
||||
const response = await fetch(request, {
|
||||
proxy: config.http.proxy.address,
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const logger = getLogger("federation");
|
||||
|
||||
logger.debug`${await response.text()}`;
|
||||
logger.error`Failed to federate follow request from ${follower.id} to ${followee.getUri()}`;
|
||||
|
||||
if (!ok) {
|
||||
await db
|
||||
.update(Relationships)
|
||||
.set({
|
||||
|
|
@ -217,45 +199,17 @@ export const followRequestUser = async (
|
|||
};
|
||||
|
||||
export const sendFollowAccept = async (follower: User, followee: User) => {
|
||||
// TODO: Make database job
|
||||
const request = await objectToInboxRequest(
|
||||
await follower.federateToUser(
|
||||
followAcceptToLysand(follower, followee),
|
||||
followee,
|
||||
follower,
|
||||
);
|
||||
|
||||
// Send request
|
||||
const response = await fetch(request, {
|
||||
proxy: config.http.proxy.address,
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const logger = getLogger("federation");
|
||||
|
||||
logger.debug`${await response.text()}`;
|
||||
logger.error`Failed to federate follow accept from ${followee.id} to ${follower.getUri()}`;
|
||||
}
|
||||
};
|
||||
|
||||
export const sendFollowReject = async (follower: User, followee: User) => {
|
||||
// TODO: Make database job
|
||||
const request = await objectToInboxRequest(
|
||||
await follower.federateToUser(
|
||||
followRejectToLysand(follower, followee),
|
||||
followee,
|
||||
follower,
|
||||
);
|
||||
|
||||
// Send request
|
||||
const response = await fetch(request, {
|
||||
proxy: config.http.proxy.address,
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const logger = getLogger("federation");
|
||||
|
||||
logger.debug`${await response.text()}`;
|
||||
logger.error`Failed to federate follow reject from ${followee.id} to ${follower.getUri()}`;
|
||||
}
|
||||
};
|
||||
|
||||
export const transformOutputToUserWithRelations = (
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue