Files
lst/lstV2/server/services/auth/routes/session.ts

162 lines
4.6 KiB
TypeScript

import { createRoute, OpenAPIHono, z } from "@hono/zod-openapi";
import axios from "axios";
import { verify } from "hono/jwt";
import jwt from "jsonwebtoken";
import { authMiddleware } from "../middleware/authMiddleware.js";
const session = new OpenAPIHono();
const expiresIn = Number(process.env.JWT_EXPIRES!) || 60;
const secret: string = process.env.JWT_SECRET!;
const { sign } = jwt;
const UserSchema = z.object({
username: z
.string()
.regex(/^[a-zA-Z0-9_]{3,30}$/)
.openapi({ example: "smith034" }),
email: z.string().email().openapi({ example: "smith@example.com" }),
password: z
.string()
.min(6, { message: "Passwords must be longer than 3 characters" })
.regex(/[A-Z]/, {
message: "Password must contain at least one uppercase letter",
})
.regex(/[\W_]/, {
message: "Password must contain at least one special character",
})
.openapi({ example: "Password1!" }),
});
const activeSessions: Record<string, { lastSeen: number; expiresAt: number }> =
{};
const SESSION_TIMEOUT_MS = 60 * 60 * 1000; // 1 hour
session.openapi(
createRoute({
tags: ["Auth"],
summary: "Checks a user session based on there token",
description: "Can post there via Authentiaction header or cookies",
method: "get",
path: "/session",
middleware: authMiddleware,
// request: {
// body: {
// content: {
// "application/json": {schema: UserSchema},
// },
// },
// },
responses: {
200: {
content: {
"application/json": {
schema: z.object({
data: z.object({
token: z.string().openapi({
example: "sdkjhgsldkvhdakl;jvhs;adkjfhvds.kvnsad;ovhads",
}),
// user: z.object({
// user_id: z.string().openapi({example: "04316c86-f086-4cc6-b3d4-cca164a26f3f"}),
// username: z.string().openapi({example: "smith"}),
// email: z.string().openapi({example: "smith@example.com"}).optional(),
// }),
}),
}),
},
},
description: "Login successful",
},
401: {
content: {
"application/json": {
schema: z.object({
message: z.string().openapi({ example: "Unathenticated" }),
}),
},
},
description: "Error of why you were not logged in.",
},
},
}),
async (c: any) => {
const cookieHeader = c.req.header("Cookie");
if (!cookieHeader) return c.json({ error: "Unauthorized" }, 401);
const res = await axios.get(`${process.env.LST_BASE_URL}/api/user/me`, {
headers: { Cookie: cookieHeader },
withCredentials: true,
});
if (res.status === 401) return c.json({ error: "Unauthorized" }, 401);
const user = res.data.user;
// ── record session heartbeat ───────────────────────────────────────────
activeSessions[user.id] = {
lastSeen: Date.now(),
expiresAt: Date.now() + SESSION_TIMEOUT_MS,
};
// clean up stale sessions in the background
for (const [key, sess] of Object.entries(activeSessions)) {
if (Date.now() > sess.expiresAt) delete activeSessions[key];
}
const setCookie =
res.headers &&
((res.headers["set-cookie"] || res.headers["Set-Cookie"]) as
| string[]
| undefined);
if (setCookie) c.header("Set-Cookie", setCookie);
return c.json(
{ data: { token: res.data.token, user: res.data.user } },
200,
);
// const authHeader = c.req.header("Authorization");
// if (authHeader?.includes("Basic")) {
// return c.json(
// { message: "You are a Basic user! Please login to get a token" },
// 401
// );
// }
// if (!authHeader) {
// return c.json({ message: "Unauthorized" }, 401);
// }
// const token = authHeader?.split("Bearer ")[1] || "";
// try {
// const payload = await verify(token, process.env.JWT_SECRET!);
// // If it's valid, return a new token
// const newToken = sign({ user: payload.user }, secret, {
// expiresIn: expiresIn * 60,
// });
// return c.json({ data: { token: newToken, user: payload.user } }, 200);
// } catch (error) {
// return c.json({ message: "Unauthorized" }, 401);
// }
},
);
// const token = authHeader?.split("Bearer ")[1] || "";
// try {
// const payload = await verify(token, process.env.JWT_SECRET!);
// //console.log(payload);
// //return c.json({data: {token, user: payload.user}}, 200);
// return c.json({message: "something"});
// } catch (err) {
// return c.json({error: "Invalid or expired token"}, 401);
// }
// });
export default session;