mirror of
https://github.com/versia-pub/server.git
synced 2026-03-13 05:49:16 +01:00
chore(federation): 👽 Finish initial Versia Working Draft 4 update
This commit is contained in:
parent
c3fa867e74
commit
42e198ca0e
14 changed files with 90 additions and 115 deletions
|
|
@ -1,4 +1,4 @@
|
|||
import { emojiValidatorWithColons } from "@/api";
|
||||
import { emojiValidatorWithColons, emojiValidatorWithIdentifiers } from "@/api";
|
||||
import { proxyUrl } from "@/response";
|
||||
import type { Emoji as ApiEmoji } from "@lysand-org/client/types";
|
||||
import type { CustomEmojiExtension } from "@versia/federation/types";
|
||||
|
|
@ -191,7 +191,7 @@ export class Emoji extends BaseInterface<typeof Emojis, EmojiWithInstance> {
|
|||
|
||||
public toVersia(): CustomEmojiExtension["emojis"][0] {
|
||||
return {
|
||||
name: this.data.shortcode,
|
||||
name: `:${this.data.shortcode}:`,
|
||||
url: {
|
||||
[this.data.contentType]: {
|
||||
content: this.data.url,
|
||||
|
|
@ -206,8 +206,17 @@ export class Emoji extends BaseInterface<typeof Emojis, EmojiWithInstance> {
|
|||
emoji: CustomEmojiExtension["emojis"][0],
|
||||
instanceId: string | null,
|
||||
): Promise<Emoji> {
|
||||
// Extracts the shortcode from the emoji name (e.g. :shortcode: -> shortcode)
|
||||
const shortcode = [
|
||||
...emoji.name.matchAll(emojiValidatorWithIdentifiers),
|
||||
][0].groups.shortcode;
|
||||
|
||||
if (!shortcode) {
|
||||
throw new Error("Could not extract shortcode from emoji name");
|
||||
}
|
||||
|
||||
return Emoji.insert({
|
||||
shortcode: emoji.name,
|
||||
shortcode,
|
||||
url: Object.entries(emoji.url)[0][1].content,
|
||||
alt: Object.entries(emoji.url)[0][1].description || undefined,
|
||||
contentType: Object.keys(emoji.url)[0],
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ export class Instance extends BaseInterface<typeof Instances> {
|
|||
const wellKnownUrl = new URL("/.well-known/versia", origin);
|
||||
const logger = getLogger("federation");
|
||||
|
||||
const requester = await User.getServerActor().getFederationRequester();
|
||||
const requester = await User.getFederationRequester();
|
||||
|
||||
try {
|
||||
const { ok, raw, data } = await requester
|
||||
|
|
@ -195,7 +195,7 @@ export class Instance extends BaseInterface<typeof Instances> {
|
|||
// Go to endpoint, then follow the links to the actual metadata
|
||||
|
||||
const logger = getLogger("federation");
|
||||
const requester = await User.getServerActor().getFederationRequester();
|
||||
const requester = await User.getFederationRequester();
|
||||
|
||||
try {
|
||||
const {
|
||||
|
|
|
|||
|
|
@ -602,8 +602,7 @@ export class Note extends BaseInterface<typeof Notes, StatusWithRelations> {
|
|||
throw new Error(`Invalid URI to parse ${uri}`);
|
||||
}
|
||||
|
||||
const requester =
|
||||
await User.getServerActor().getFederationRequester();
|
||||
const requester = await User.getFederationRequester();
|
||||
|
||||
const { data } = await requester.get(uri, {
|
||||
// @ts-expect-error Bun extension
|
||||
|
|
@ -636,7 +635,7 @@ export class Note extends BaseInterface<typeof Notes, StatusWithRelations> {
|
|||
const emojis: Emoji[] = [];
|
||||
const logger = getLogger("federation");
|
||||
|
||||
for (const emoji of note.extensions?.["org.lysand:custom_emojis"]
|
||||
for (const emoji of note.extensions?.["pub.versia:custom_emojis"]
|
||||
?.emojis ?? []) {
|
||||
const resolvedEmoji = await Emoji.fetchFromRemote(emoji).catch(
|
||||
(e) => {
|
||||
|
|
@ -948,7 +947,7 @@ export class Note extends BaseInterface<typeof Notes, StatusWithRelations> {
|
|||
// TODO: Refactor as part of groups
|
||||
group: status.visibility === "public" ? "public" : "followers",
|
||||
extensions: {
|
||||
"org.lysand:custom_emojis": {
|
||||
"pub.versia:custom_emojis": {
|
||||
emojis: status.emojis.map((emoji) =>
|
||||
new Emoji(emoji).toVersia(),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -135,56 +135,6 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
|
|||
);
|
||||
}
|
||||
|
||||
static getServerActor(): User {
|
||||
return new User({
|
||||
id: "00000000-0000-0000-0000-000000000000",
|
||||
username: "actor",
|
||||
avatar: "",
|
||||
createdAt: "2024-01-01T00:00:00.000Z",
|
||||
displayName: "Server Actor",
|
||||
note: "This is a system actor used for server-to-server communication. It is not a real user.",
|
||||
updatedAt: "2024-01-01T00:00:00.000Z",
|
||||
instanceId: null,
|
||||
publicKey: config.instance.keys.public,
|
||||
source: {
|
||||
fields: [],
|
||||
language: null,
|
||||
note: "",
|
||||
privacy: "public",
|
||||
sensitive: false,
|
||||
},
|
||||
fields: [],
|
||||
isAdmin: false,
|
||||
isBot: false,
|
||||
isLocked: false,
|
||||
isDiscoverable: false,
|
||||
endpoints: {
|
||||
dislikes: "",
|
||||
featured: "",
|
||||
likes: "",
|
||||
followers: "",
|
||||
following: "",
|
||||
inbox: "",
|
||||
outbox: "",
|
||||
},
|
||||
disableAutomoderation: false,
|
||||
email: "",
|
||||
emailVerificationToken: "",
|
||||
emojis: [],
|
||||
followerCount: 0,
|
||||
followingCount: 0,
|
||||
header: "",
|
||||
instance: null,
|
||||
password: "",
|
||||
passwordResetToken: "",
|
||||
privateKey: config.instance.keys.private,
|
||||
roles: [],
|
||||
sanctions: [],
|
||||
statusCount: 0,
|
||||
uri: "/users/actor",
|
||||
});
|
||||
}
|
||||
|
||||
static getUri(id: string, uri: string | null, baseUrl: string) {
|
||||
return uri || new URL(`/users/${id}`, baseUrl).toString();
|
||||
}
|
||||
|
|
@ -433,7 +383,7 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
|
|||
uri: string,
|
||||
instance: Instance,
|
||||
): Promise<User> {
|
||||
const requester = await User.getServerActor().getFederationRequester();
|
||||
const requester = await User.getFederationRequester();
|
||||
const { data: json } = await requester.get<Partial<VersiaUser>>(uri, {
|
||||
// @ts-expect-error Bun extension
|
||||
proxy: config.http.proxy.address,
|
||||
|
|
@ -749,6 +699,20 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
|
|||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to get the appropriate Versia SDK requester with the instance's private key
|
||||
*
|
||||
* @returns The requester
|
||||
*/
|
||||
static async getFederationRequester(): Promise<FederationRequester> {
|
||||
const signatureConstructor = await SignatureConstructor.fromStringKey(
|
||||
config.instance.keys.private,
|
||||
config.http.base_url,
|
||||
);
|
||||
|
||||
return new FederationRequester(signatureConstructor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to get the appropriate Versia SDK requester with this user's private key
|
||||
*
|
||||
|
|
@ -947,6 +911,7 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
|
|||
).toString(),
|
||||
indexable: false,
|
||||
username: user.username,
|
||||
manually_approves_followers: this.data.isLocked,
|
||||
avatar: urlToContentFormat(this.getAvatarUrl(config)) ?? undefined,
|
||||
header: urlToContentFormat(this.getHeaderUrl(config)) ?? undefined,
|
||||
display_name: user.displayName,
|
||||
|
|
@ -960,7 +925,7 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
|
|||
algorithm: "ed25519",
|
||||
},
|
||||
extensions: {
|
||||
"org.lysand:custom_emojis": {
|
||||
"pub.versia:custom_emojis": {
|
||||
emojis: user.emojis.map((emoji) =>
|
||||
new Emoji(emoji).toVersia(),
|
||||
),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue