mirror of
https://github.com/versia-pub/server.git
synced 2025-12-06 08:28:19 +01:00
Begin work on refactoring every single route to use new subsystems
This commit is contained in:
parent
3b75f5f0a5
commit
05140f0d6f
18
.vscode/launch.json
vendored
Normal file
18
.vscode/launch.json
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"configurations": [
|
||||
{
|
||||
"type": "node",
|
||||
"name": "vscode-jest-tests.v2.lysand",
|
||||
"request": "launch",
|
||||
"args": [
|
||||
"test",
|
||||
"${jest.testFile}"
|
||||
],
|
||||
"cwd": "/home/jessew/Dev/lysand",
|
||||
"console": "integratedTerminal",
|
||||
"internalConsoleOptions": "neverOpen",
|
||||
"disableOptimisticBPs": true,
|
||||
"program": "/home/jessew/.bun/bin/bun"
|
||||
}
|
||||
]
|
||||
}
|
||||
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
|
|
@ -1,3 +1,5 @@
|
|||
{
|
||||
"typescript.tsdk": "node_modules/typescript/lib"
|
||||
"typescript.tsdk": "node_modules/typescript/lib",
|
||||
"jest.jestCommandLine": "/home/jessew/.bun/bin/bun test",
|
||||
"jest.rootPath": "."
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
* Fuses both and provides a way to retrieve individual values
|
||||
*/
|
||||
|
||||
import { parse, stringify } from "@iarna/toml";
|
||||
/* import { parse, stringify } from "@iarna/toml";
|
||||
import chalk from "chalk";
|
||||
import merge from "merge-deep-ts";
|
||||
|
||||
|
|
@ -23,10 +23,10 @@ const scanConfig = async () => {
|
|||
}
|
||||
|
||||
return parse(await config.text()) as ConfigType;
|
||||
};
|
||||
}; */
|
||||
|
||||
// Creates the internal config with nothing in it if it doesnt exist
|
||||
const scanInternalConfig = async () => {
|
||||
/* const scanInternalConfig = async () => {
|
||||
const config = Bun.file(process.cwd() + "/config/config.internal.toml");
|
||||
|
||||
if (!(await config.exists())) {
|
||||
|
|
@ -397,18 +397,18 @@ export const configDefaults: ConfigType = {
|
|||
max_coeff: 1,
|
||||
},
|
||||
custom_ratelimits: {},
|
||||
};
|
||||
}; */
|
||||
|
||||
export const getConfig = () => {
|
||||
/* export const getConfig = () => {
|
||||
// Deeply merge configDefaults, config and internalConfig
|
||||
return merge([configDefaults, config, internalConfig]) as any as ConfigType;
|
||||
};
|
||||
|
||||
*/
|
||||
/**
|
||||
* Sets the internal config
|
||||
* @param newConfig Any part of ConfigType
|
||||
*/
|
||||
export const setConfig = async (newConfig: Partial<ConfigType>) => {
|
||||
/* export const setConfig = async (newConfig: Partial<ConfigType>) => {
|
||||
const newInternalConfig = merge([
|
||||
internalConfig,
|
||||
newConfig,
|
||||
|
|
@ -421,16 +421,16 @@ export const setConfig = async (newConfig: Partial<ConfigType>) => {
|
|||
newInternalConfig as any
|
||||
)}`
|
||||
);
|
||||
};
|
||||
}; */
|
||||
|
||||
export const getHost = () => {
|
||||
/* export const getHost = () => {
|
||||
const url = new URL(getConfig().http.base_url);
|
||||
|
||||
return url.host;
|
||||
};
|
||||
|
||||
*/
|
||||
// Refresh config every 5 seconds
|
||||
setInterval(() => {
|
||||
/* setInterval(() => {
|
||||
scanConfig()
|
||||
.then(newConfig => {
|
||||
if (newConfig !== config) {
|
||||
|
|
@ -440,6 +440,7 @@ setInterval(() => {
|
|||
.catch(e => {
|
||||
console.error(e);
|
||||
});
|
||||
}, 5000);
|
||||
}, 5000); */
|
||||
|
||||
export { config };
|
||||
/* export { config };
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
import { MatchedRoute } from "bun";
|
||||
import { getConfig, getHost } from "~classes/configmanager";
|
||||
import { xmlResponse } from "@response";
|
||||
import { applyConfig } from "@api";
|
||||
import { apiRoute, applyConfig } from "@api";
|
||||
|
||||
export const meta = applyConfig({
|
||||
allowedMethods: ["GET"],
|
||||
|
|
@ -16,18 +14,13 @@ export const meta = applyConfig({
|
|||
});
|
||||
|
||||
|
||||
/**
|
||||
* Host meta endpoint
|
||||
*/
|
||||
export default async (
|
||||
req: Request,
|
||||
matchedRoute: MatchedRoute
|
||||
): Promise<Response> => {
|
||||
const config = getConfig();
|
||||
export default apiRoute(async (req, matchedRoute, extraData) => {
|
||||
const config = await extraData.configManager.getConfig();
|
||||
|
||||
return xmlResponse(`
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
|
||||
<Link rel="lrdd" template="${config.http.base_url}/.well-known/webfinger?resource={uri}"/>
|
||||
</XRD>
|
||||
</XRD>
|
||||
`);
|
||||
};
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
import { jsonResponse } from "@response";
|
||||
import { MatchedRoute } from "bun";
|
||||
import { getConfig } from "~classes/configmanager";
|
||||
import { applyConfig } from "@api";
|
||||
import { apiRoute, applyConfig } from "@api";
|
||||
|
||||
export const meta = applyConfig({
|
||||
allowedMethods: ["GET"],
|
||||
|
|
@ -15,14 +13,9 @@ export const meta = applyConfig({
|
|||
route: "/.well-known/lysand",
|
||||
});
|
||||
|
||||
/**
|
||||
* Lysand instance metadata endpoint
|
||||
*/
|
||||
export default async (
|
||||
req: Request,
|
||||
matchedRoute: MatchedRoute
|
||||
): Promise<Response> => {
|
||||
const config = getConfig();
|
||||
export default apiRoute(async (req, matchedRoute, extraData) => {
|
||||
const config = await extraData.configManager.getConfig();
|
||||
|
||||
// In the format acct:name@example.com
|
||||
return jsonResponse({
|
||||
type: "ServerMetadata",
|
||||
|
|
@ -47,4 +40,4 @@ export default async (
|
|||
website: "https://lysand.org",
|
||||
// TODO: Add admins, moderators field
|
||||
})
|
||||
};
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
import { MatchedRoute } from "bun";
|
||||
import { getConfig, getHost } from "~classes/configmanager";
|
||||
import { applyConfig } from "@api";
|
||||
import { apiRoute, applyConfig } from "@api";
|
||||
|
||||
export const meta = applyConfig({
|
||||
allowedMethods: ["GET"],
|
||||
|
|
@ -15,14 +13,8 @@ export const meta = applyConfig({
|
|||
});
|
||||
|
||||
|
||||
/**
|
||||
* Redirect to /nodeinfo/2.0
|
||||
*/
|
||||
export default async (
|
||||
req: Request,
|
||||
matchedRoute: MatchedRoute
|
||||
): Promise<Response> => {
|
||||
const config = getConfig();
|
||||
export default apiRoute(async (req, matchedRoute, extraData) => {
|
||||
const config = await extraData.configManager.getConfig();
|
||||
|
||||
return new Response("", {
|
||||
status: 301,
|
||||
|
|
@ -30,4 +22,4 @@ export default async (
|
|||
Location: `${config.http.base_url}/.well-known/nodeinfo/2.0`,
|
||||
},
|
||||
});
|
||||
};
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
import { errorResponse, jsonResponse } from "@response";
|
||||
import { MatchedRoute } from "bun";
|
||||
import { getConfig, getHost } from "~classes/configmanager";
|
||||
import { applyConfig } from "@api";
|
||||
import { apiRoute, applyConfig } from "@api";
|
||||
import { client } from "~database/datasource";
|
||||
|
||||
export const meta = applyConfig({
|
||||
|
|
@ -16,35 +14,30 @@ export const meta = applyConfig({
|
|||
route: "/.well-known/webfinger",
|
||||
});
|
||||
|
||||
/**
|
||||
* ActivityPub WebFinger endpoint
|
||||
*/
|
||||
export default async (
|
||||
req: Request,
|
||||
matchedRoute: MatchedRoute
|
||||
): Promise<Response> => {
|
||||
export default apiRoute(async (req, matchedRoute, extraData) => {
|
||||
// In the format acct:name@example.com
|
||||
const resource = matchedRoute.query.resource;
|
||||
const requestedUser = resource.split("acct:")[1];
|
||||
|
||||
const config = getConfig();
|
||||
|
||||
|
||||
const config = await extraData.configManager.getConfig();
|
||||
const host = new URL(config.http.base_url).hostname;
|
||||
|
||||
// Check if user is a local user
|
||||
if (requestedUser.split("@")[1] !== getHost()) {
|
||||
if (requestedUser.split("@")[1] !== host) {
|
||||
return errorResponse("User is a remote user", 404);
|
||||
}
|
||||
|
||||
|
||||
const user = await client.user.findUnique({
|
||||
where: { username: requestedUser.split("@")[0] },
|
||||
});
|
||||
|
||||
|
||||
if (!user) {
|
||||
return errorResponse("User not found", 404);
|
||||
}
|
||||
|
||||
|
||||
return jsonResponse({
|
||||
subject: `acct:${user.username}@${getHost()}`,
|
||||
|
||||
subject: `acct:${user.username}@${host}`,
|
||||
|
||||
links: [
|
||||
{
|
||||
rel: "self",
|
||||
|
|
@ -63,4 +56,4 @@ export default async (
|
|||
}
|
||||
]
|
||||
})
|
||||
};
|
||||
});
|
||||
|
|
@ -1,12 +1,10 @@
|
|||
import { applyConfig } from "@api";
|
||||
import type { MatchedRoute } from "bun";
|
||||
import { apiRoute, applyConfig } from "@api";
|
||||
import { randomBytes } from "crypto";
|
||||
import { client } from "~database/datasource";
|
||||
import { TokenType } from "~database/entities/Token";
|
||||
import { userRelations } from "~database/entities/User";
|
||||
import type { APIRouteMeta } from "~types/api";
|
||||
|
||||
export const meta: APIRouteMeta = applyConfig({
|
||||
export const meta = applyConfig({
|
||||
allowedMethods: ["POST"],
|
||||
ratelimits: {
|
||||
max: 4,
|
||||
|
|
@ -21,10 +19,10 @@ export const meta: APIRouteMeta = applyConfig({
|
|||
/**
|
||||
* OAuth Code flow
|
||||
*/
|
||||
export default async (
|
||||
req: Request,
|
||||
matchedRoute: MatchedRoute
|
||||
): Promise<Response> => {
|
||||
export default apiRoute<{
|
||||
email: string;
|
||||
password: string;
|
||||
}>(async (req, matchedRoute, extraData) => {
|
||||
const scopes = (matchedRoute.query.scope || "")
|
||||
.replaceAll("+", " ")
|
||||
.split(" ");
|
||||
|
|
@ -32,10 +30,7 @@ export default async (
|
|||
const response_type = matchedRoute.query.response_type;
|
||||
const client_id = matchedRoute.query.client_id;
|
||||
|
||||
const formData = await req.formData();
|
||||
|
||||
const email = formData.get("email")?.toString() || null;
|
||||
const password = formData.get("password")?.toString() || null;
|
||||
const { email, password } = extraData.parsedRequest;
|
||||
|
||||
const redirectToLogin = (error: string) =>
|
||||
Response.redirect(
|
||||
|
|
@ -96,4 +91,4 @@ export default async (
|
|||
|
||||
// Redirect back to application
|
||||
return Response.redirect(`${redirect_uri}?code=${code}`, 302);
|
||||
};
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import { errorResponse } from "@response";
|
||||
import { applyConfig } from "@api";
|
||||
import type { MatchedRoute } from "bun";
|
||||
import { apiRoute, applyConfig } from "@api";
|
||||
|
||||
export const meta = applyConfig({
|
||||
allowedMethods: ["GET"],
|
||||
|
|
@ -14,10 +13,7 @@ export const meta = applyConfig({
|
|||
},
|
||||
});
|
||||
|
||||
export default async (
|
||||
req: Request,
|
||||
matchedRoute: MatchedRoute
|
||||
): Promise<Response> => {
|
||||
export default apiRoute(async (req, matchedRoute) => {
|
||||
// TODO: Add checks for disabled or not email verified accounts
|
||||
|
||||
const id = matchedRoute.params.id;
|
||||
|
|
@ -46,4 +42,4 @@ export default async (
|
|||
"Content-Range": `bytes ${start}-${end}/${file.size}`,
|
||||
},
|
||||
});
|
||||
};
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { applyConfig } from "@api";
|
||||
import { apiRoute, applyConfig } from "@api";
|
||||
import { jsonResponse } from "@response";
|
||||
|
||||
export const meta = applyConfig({
|
||||
|
|
@ -16,8 +16,7 @@ export const meta = applyConfig({
|
|||
/**
|
||||
* ActivityPub nodeinfo 2.0 endpoint
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/require-await
|
||||
export default async (): Promise<Response> => {
|
||||
export default apiRoute(() => {
|
||||
// TODO: Implement this
|
||||
return jsonResponse({
|
||||
version: "2.0",
|
||||
|
|
@ -31,4 +30,4 @@ export default async (): Promise<Response> => {
|
|||
openRegistrations: false,
|
||||
metadata: {},
|
||||
});
|
||||
};
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
import { applyConfig } from "@api";
|
||||
import { getConfig } from "~classes/configmanager";
|
||||
import { apiRoute, applyConfig } from "@api";
|
||||
import { oauthRedirectUri } from "@constants";
|
||||
import type { MatchedRoute } from "bun";
|
||||
import {
|
||||
calculatePKCECodeChallenge,
|
||||
discoveryRequest,
|
||||
|
|
@ -25,11 +23,7 @@ export const meta = applyConfig({
|
|||
/**
|
||||
* Redirects the user to the external OAuth provider
|
||||
*/
|
||||
export default async (
|
||||
req: Request,
|
||||
matchedRoute: MatchedRoute
|
||||
// eslint-disable-next-line @typescript-eslint/require-await
|
||||
): Promise<Response> => {
|
||||
export default apiRoute(async (req, matchedRoute, extraData) => {
|
||||
const redirectToLogin = (error: string) =>
|
||||
Response.redirect(
|
||||
`/oauth/authorize?` +
|
||||
|
|
@ -49,7 +43,7 @@ export default async (
|
|||
return redirectToLogin("Missing client_id");
|
||||
}
|
||||
|
||||
const config = getConfig();
|
||||
const config = await extraData.configManager.getConfig();
|
||||
|
||||
const issuer = config.oidc.providers.find(
|
||||
provider => provider.id === issuerId
|
||||
|
|
@ -98,4 +92,4 @@ export default async (
|
|||
}).toString(),
|
||||
302
|
||||
);
|
||||
};
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
import { applyConfig } from "@api";
|
||||
import { getConfig } from "~classes/configmanager";
|
||||
import { apiRoute, applyConfig } from "@api";
|
||||
import { oauthRedirectUri } from "@constants";
|
||||
import type { MatchedRoute } from "bun";
|
||||
import { randomBytes } from "crypto";
|
||||
import {
|
||||
authorizationCodeGrantRequest,
|
||||
|
|
@ -33,10 +31,7 @@ export const meta = applyConfig({
|
|||
/**
|
||||
* Redirects the user to the external OAuth provider
|
||||
*/
|
||||
export default async (
|
||||
req: Request,
|
||||
matchedRoute: MatchedRoute
|
||||
): Promise<Response> => {
|
||||
export default apiRoute(async (req, matchedRoute, extraData) => {
|
||||
const redirectToLogin = (error: string) =>
|
||||
Response.redirect(
|
||||
`/oauth/authorize?` +
|
||||
|
|
@ -65,7 +60,7 @@ export default async (
|
|||
return redirectToLogin("Invalid flow");
|
||||
}
|
||||
|
||||
const config = getConfig();
|
||||
const config = await extraData.configManager.getConfig();
|
||||
|
||||
const issuer = config.oidc.providers.find(
|
||||
provider => provider.id === issuerParam
|
||||
|
|
@ -192,4 +187,4 @@ export default async (
|
|||
`${flow.application.redirect_uris}?code=${code}`,
|
||||
302
|
||||
);
|
||||
};
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import { applyConfig } from "@api";
|
||||
import { getConfig } from "~classes/configmanager";
|
||||
import { apiRoute, applyConfig } from "@api";
|
||||
import { jsonResponse } from "@response";
|
||||
|
||||
export const meta = applyConfig({
|
||||
|
|
@ -17,9 +16,8 @@ export const meta = applyConfig({
|
|||
/**
|
||||
* Lists available OAuth providers
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/require-await
|
||||
export default async (): Promise<Response> => {
|
||||
const config = getConfig();
|
||||
export default apiRoute(async (req, matchedRoute, extraData) => {
|
||||
const config = await extraData.configManager.getConfig();
|
||||
|
||||
return jsonResponse(
|
||||
config.oidc.providers.map(p => ({
|
||||
|
|
@ -28,4 +26,4 @@ export default async (): Promise<Response> => {
|
|||
id: p.id,
|
||||
}))
|
||||
);
|
||||
};
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import { applyConfig } from "@api";
|
||||
import { parseRequest } from "@request";
|
||||
import { apiRoute, applyConfig } from "@api";
|
||||
import { errorResponse, jsonResponse } from "@response";
|
||||
import { client } from "~database/datasource";
|
||||
|
||||
|
|
@ -18,16 +17,16 @@ export const meta = applyConfig({
|
|||
/**
|
||||
* Allows getting token from OAuth code
|
||||
*/
|
||||
export default async (req: Request): Promise<Response> => {
|
||||
export default apiRoute<{
|
||||
grant_type: string;
|
||||
code: string;
|
||||
redirect_uri: string;
|
||||
client_id: string;
|
||||
client_secret: string;
|
||||
scope: string;
|
||||
}>(async (req, matchedRoute, extraData) => {
|
||||
const { grant_type, code, redirect_uri, client_id, client_secret, scope } =
|
||||
await parseRequest<{
|
||||
grant_type: string;
|
||||
code: string;
|
||||
redirect_uri: string;
|
||||
client_id: string;
|
||||
client_secret: string;
|
||||
scope: string;
|
||||
}>(req);
|
||||
extraData.parsedRequest;
|
||||
|
||||
if (grant_type !== "authorization_code")
|
||||
return errorResponse(
|
||||
|
|
@ -61,4 +60,4 @@ export default async (req: Request): Promise<Response> => {
|
|||
scope: token.scope,
|
||||
created_at: token.created_at,
|
||||
});
|
||||
};
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,8 +1,5 @@
|
|||
/* eslint-disable @typescript-eslint/require-await */
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
import { applyConfig } from "@api";
|
||||
import { apiRoute, applyConfig } from "@api";
|
||||
import { jsonResponse } from "@response";
|
||||
import type { MatchedRoute } from "bun";
|
||||
|
||||
export const meta = applyConfig({
|
||||
allowedMethods: ["GET"],
|
||||
|
|
@ -16,12 +13,6 @@ export const meta = applyConfig({
|
|||
route: "/object/:id",
|
||||
});
|
||||
|
||||
/**
|
||||
* Fetch a user
|
||||
*/
|
||||
export default async (
|
||||
req: Request,
|
||||
matchedRoute: MatchedRoute
|
||||
): Promise<Response> => {
|
||||
export default apiRoute(() => {
|
||||
return jsonResponse({});
|
||||
};
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,10 +1,7 @@
|
|||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
import { applyConfig } from "@api";
|
||||
import { getConfig } from "~classes/configmanager";
|
||||
// TODO: Refactor into smaller packages
|
||||
import { apiRoute, applyConfig } from "@api";
|
||||
import { getBestContentType } from "@content_types";
|
||||
import { errorResponse, jsonResponse } from "@response";
|
||||
import type { MatchedRoute } from "bun";
|
||||
import { client } from "~database/datasource";
|
||||
import { parseEmojis } from "~database/entities/Emoji";
|
||||
import { createLike, deleteLike } from "~database/entities/Like";
|
||||
|
|
@ -39,13 +36,10 @@ export const meta = applyConfig({
|
|||
/**
|
||||
* ActivityPub user inbox endpoint
|
||||
*/
|
||||
export default async (
|
||||
req: Request,
|
||||
matchedRoute: MatchedRoute
|
||||
): Promise<Response> => {
|
||||
export default apiRoute(async (req, matchedRoute, extraData) => {
|
||||
const username = matchedRoute.params.username;
|
||||
|
||||
const config = getConfig();
|
||||
const config = await extraData.configManager.getConfig();
|
||||
|
||||
try {
|
||||
if (
|
||||
|
|
@ -313,7 +307,7 @@ export default async (
|
|||
}
|
||||
|
||||
// Create new reblog
|
||||
const newReblog = await client.status.create({
|
||||
await client.status.create({
|
||||
data: {
|
||||
authorId: author.id,
|
||||
reblogId: rebloggedStatus.id,
|
||||
|
|
@ -405,4 +399,4 @@ export default async (
|
|||
}
|
||||
|
||||
return jsonResponse({});
|
||||
};
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,9 +1,5 @@
|
|||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
import { applyConfig } from "@api";
|
||||
import { getConfig } from "~classes/configmanager";
|
||||
import { apiRoute, applyConfig } from "@api";
|
||||
import { errorResponse, jsonResponse } from "@response";
|
||||
import type { MatchedRoute } from "bun";
|
||||
import { client } from "~database/datasource";
|
||||
import { userRelations, userToLysand } from "~database/entities/User";
|
||||
|
||||
|
|
@ -22,14 +18,9 @@ export const meta = applyConfig({
|
|||
/**
|
||||
* ActivityPub user inbox endpoint
|
||||
*/
|
||||
export default async (
|
||||
req: Request,
|
||||
matchedRoute: MatchedRoute
|
||||
): Promise<Response> => {
|
||||
export default apiRoute(async (req, matchedRoute) => {
|
||||
const uuid = matchedRoute.params.uuid;
|
||||
|
||||
const config = getConfig();
|
||||
|
||||
const user = await client.user.findUnique({
|
||||
where: {
|
||||
id: uuid,
|
||||
|
|
@ -42,4 +33,4 @@ export default async (
|
|||
}
|
||||
|
||||
return jsonResponse(userToLysand(user));
|
||||
};
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
import { jsonResponse } from "@response";
|
||||
import type { MatchedRoute } from "bun";
|
||||
import { getConfig, getHost } from "~classes/configmanager";
|
||||
import { applyConfig } from "@api";
|
||||
import { apiRoute, applyConfig } from "@api";
|
||||
import {
|
||||
statusAndUserRelations,
|
||||
statusToLysand,
|
||||
|
|
@ -23,13 +21,11 @@ export const meta = applyConfig({
|
|||
/**
|
||||
* ActivityPub user outbox endpoint
|
||||
*/
|
||||
export default async (
|
||||
req: Request,
|
||||
matchedRoute: MatchedRoute
|
||||
): Promise<Response> => {
|
||||
export default apiRoute(async (req, matchedRoute, extraData) => {
|
||||
const uuid = matchedRoute.params.uuid;
|
||||
const pageNumber = Number(matchedRoute.query.page) || 1;
|
||||
const config = getConfig();
|
||||
const config = await extraData.configManager.getConfig();
|
||||
const host = new URL(config.http.base_url).hostname;
|
||||
|
||||
const statuses = await client.status.findMany({
|
||||
where: {
|
||||
|
|
@ -53,19 +49,19 @@ export default async (
|
|||
});
|
||||
|
||||
return jsonResponse({
|
||||
first: `${getHost()}/users/${uuid}/outbox?page=1`,
|
||||
last: `${getHost()}/users/${uuid}/outbox?page=1`,
|
||||
first: `${host}/users/${uuid}/outbox?page=1`,
|
||||
last: `${host}/users/${uuid}/outbox?page=1`,
|
||||
total_items: totalStatuses,
|
||||
// Server actor
|
||||
author: `${config.http.base_url}/users/actor`,
|
||||
next:
|
||||
statuses.length === 20
|
||||
? `${getHost()}/users/${uuid}/outbox?page=${pageNumber + 1}`
|
||||
? `${host}/users/${uuid}/outbox?page=${pageNumber + 1}`
|
||||
: undefined,
|
||||
prev:
|
||||
pageNumber > 1
|
||||
? `${getHost()}/users/${uuid}/outbox?page=${pageNumber - 1}`
|
||||
? `${host}/users/${uuid}/outbox?page=${pageNumber - 1}`
|
||||
: undefined,
|
||||
items: statuses.map(s => statusToLysand(s)),
|
||||
});
|
||||
};
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { getConfig } from "~classes/configmanager";
|
||||
import type { RouteHandler } from "~server/api/routes.type";
|
||||
import type { APIRouteMeta } from "~types/api";
|
||||
|
||||
export const applyConfig = (routeMeta: APIRouteMeta) => {
|
||||
|
|
@ -16,3 +17,7 @@ export const applyConfig = (routeMeta: APIRouteMeta) => {
|
|||
|
||||
return newMeta;
|
||||
};
|
||||
|
||||
export const apiRoute = <T>(routeFunction: RouteHandler<T>) => {
|
||||
return routeFunction;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue