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