1
0

improve: the structure of route handlers in backend

This commit is contained in:
alikia2x (寒寒) 2025-11-08 02:29:01 +08:00
parent 19851ec10c
commit 22a450e94f
5 changed files with 109 additions and 92 deletions

View File

@ -0,0 +1,5 @@
import Elysia from "elysia";
import { loginHandler } from "./login";
import { logoutHandler } from "./logout";
export const authHandler = new Elysia().use(loginHandler).use(logoutHandler);

View File

@ -1,8 +1,8 @@
import { Elysia, t } from "elysia";
import { ip } from "elysia-ip";
import { verifyUser, createSession, deactivateSession, getSessionExpirationDate } from "@elysia/lib/auth";
import { verifyUser, createSession, getSessionExpirationDate } from "@elysia/lib/auth";
export const authHandler = new Elysia({ prefix: "/auth" })
export const loginHandler = new Elysia({ prefix: "/auth" })
.use(ip())
.post(
"/session",
@ -56,49 +56,4 @@ export const authHandler = new Elysia({ prefix: "/auth" })
})
}
)
.delete(
"/session",
async ({ set, cookie }) => {
const sessionId = cookie.sessionId?.value;
if (!sessionId) {
set.status = 401;
return { message: "Not authenticated." };
}
await deactivateSession(sessionId as string);
cookie.sessionId.remove();
return { message: "Successfully logged out." };
},
{
response: {
200: t.Object({
message: t.String()
}),
401: t.Object({
message: t.String()
})
}
}
)
.delete(
"/session/:id",
async ({ params }) => {
const sessionId = params.id;
await deactivateSession(sessionId as string);
return { message: "Successfully logged out." };
},
{
response: {
200: t.Object({
message: t.String()
}),
401: t.Object({
message: t.String()
})
}
}
);

View File

@ -0,0 +1,50 @@
import { Elysia, t } from "elysia";
import { deactivateSession } from "@elysia/lib/auth";
export const logoutHandler = new Elysia({ prefix: "/auth" })
.delete(
"/session",
async ({ set, cookie }) => {
const sessionId = cookie.sessionId?.value;
if (!sessionId) {
set.status = 401;
return { message: "Not authenticated." };
}
await deactivateSession(sessionId as string);
cookie.sessionId.remove();
return { message: "Successfully logged out." };
},
{
response: {
200: t.Object({
message: t.String()
}),
401: t.Object({
message: t.String()
})
}
}
)
.delete(
"/session/:id",
async ({ params }) => {
const sessionId = params.id;
await deactivateSession(sessionId as string);
return { message: "Successfully logged out." };
},
{
response: {
200: t.Object({
message: t.String()
}),
401: t.Object({
message: t.String()
})
}
}
);

View File

@ -7,59 +7,18 @@ import { songInfoHandler } from "@elysia/routes/song/info";
import { rootHandler } from "@elysia/routes/root";
import { getVideoMetadataHandler } from "@elysia/routes/video/metadata";
import { closeMileStoneHandler } from "@elysia/routes/song/milestone";
import { authHandler } from "@elysia/routes/auth/session";
import { authHandler } from "@elysia/routes/auth";
import { onAfterHandler } from "./onAfterHandle";
const [host, port] = getBindingInfo();
logStartup(host, port);
const encoder = new TextEncoder();
const app = new Elysia({
serve: {
hostname: host
}
})
.onAfterHandle({ as: "global" }, ({ responseValue, request }) => {
const contentType = request.headers.get("Content-Type") || "";
const accept = request.headers.get("Accept") || "";
const secFetchMode = request.headers.get("Sec-Fetch-Mode");
const requestJson = contentType.includes("application/json");
const isBrowser =
!requestJson && (accept.includes("text/html") || secFetchMode === "navigate");
const responseValueType = typeof responseValue;
const isObject = responseValueType === "object";
if (!isObject) {
const response = {
message: responseValue
};
const text = isBrowser ? JSON.stringify(response, null, 2) : JSON.stringify(response);
return new Response(encoder.encode(text), {
headers: {
"Content-Type": "application/json; charset=utf-8"
}
});
}
const realResponse = responseValue as Record<string, unknown>;
if (realResponse.code) {
const text = isBrowser
? JSON.stringify(realResponse.response, null, 2)
: JSON.stringify(realResponse.response);
return new Response(encoder.encode(text), {
status: realResponse.code as any,
headers: {
"Content-Type": "application/json; charset=utf-8"
}
});
}
const text = isBrowser
? JSON.stringify(realResponse, null, 2)
: JSON.stringify(realResponse);
return new Response(encoder.encode(text), {
headers: {
"Content-Type": "application/json; charset=utf-8"
}
});
})
.use(onAfterHandler)
.use(cors())
.use(openapi())
.use(rootHandler)

View File

@ -0,0 +1,48 @@
import Elysia from "elysia";
const encoder = new TextEncoder();
export const onAfterHandler = new Elysia().onAfterHandle(
{ as: "global" },
({ responseValue, request }) => {
const contentType = request.headers.get("Content-Type") || "";
const accept = request.headers.get("Accept") || "";
const secFetchMode = request.headers.get("Sec-Fetch-Mode");
const requestJson = contentType.includes("application/json");
const isBrowser =
!requestJson && (accept.includes("text/html") || secFetchMode === "navigate");
const responseValueType = typeof responseValue;
const isObject = responseValueType === "object";
if (!isObject) {
const response = {
message: responseValue
};
const text = isBrowser ? JSON.stringify(response, null, 2) : JSON.stringify(response);
return new Response(encoder.encode(text), {
headers: {
"Content-Type": "application/json; charset=utf-8"
}
});
}
const realResponse = responseValue as Record<string, unknown>;
if (realResponse.code) {
const text = isBrowser
? JSON.stringify(realResponse.response, null, 2)
: JSON.stringify(realResponse.response);
return new Response(encoder.encode(text), {
status: realResponse.code as any,
headers: {
"Content-Type": "application/json; charset=utf-8"
}
});
}
const text = isBrowser
? JSON.stringify(realResponse, null, 2)
: JSON.stringify(realResponse);
return new Response(encoder.encode(text), {
headers: {
"Content-Type": "application/json; charset=utf-8"
}
});
}
);