refactor(server): moved the server files outside the src to improve static files
This commit is contained in:
18
server/services/auth/authService.ts
Normal file
18
server/services/auth/authService.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import {OpenAPIHono} from "@hono/zod-openapi";
|
||||
|
||||
import login from "./routes/login.js";
|
||||
import register from "./routes/register.js";
|
||||
import session from "./routes/session.js";
|
||||
import getAccess from "./routes/getUserRoles.js";
|
||||
import {authMiddleware} from "./middleware/authMiddleware.js";
|
||||
|
||||
const app = new OpenAPIHono();
|
||||
app.route("auth/login", login);
|
||||
app.route("auth/register", register);
|
||||
app.route("auth/session", session);
|
||||
|
||||
// required to login
|
||||
app.use("auth/getuseraccess", authMiddleware);
|
||||
app.route("/auth/getuseraccess", getAccess);
|
||||
|
||||
export default app;
|
||||
15
server/services/auth/controllers/getUserAccess.ts
Normal file
15
server/services/auth/controllers/getUserAccess.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
pass over a users uuid and return all modules they have permission too.
|
||||
in the login route we attach it to user under roles.
|
||||
*/
|
||||
|
||||
import {eq} from "drizzle-orm";
|
||||
import {db} from "../../../../database/dbclient.js";
|
||||
import {userRoles} from "../../../../database/schema/userRoles.js";
|
||||
|
||||
export const roleCheck = async (user_id: any) => {
|
||||
// get the user roles by the user_id
|
||||
const roles = await db.select().from(userRoles).where(eq(userRoles.user_id, user_id));
|
||||
|
||||
return roles;
|
||||
};
|
||||
55
server/services/auth/controllers/login.ts
Normal file
55
server/services/auth/controllers/login.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
import jwt from "jsonwebtoken";
|
||||
import {db} from "../../../../database/dbclient.js";
|
||||
import {users} from "../../../../database/schema/users.js";
|
||||
import {eq, sql} from "drizzle-orm";
|
||||
import {checkPassword} from "../utils/checkPassword.js";
|
||||
import {roleCheck} from "./getUserAccess.js";
|
||||
|
||||
/**
|
||||
* Authenticate a user and return a JWT.
|
||||
*/
|
||||
const {sign, verify} = jwt;
|
||||
|
||||
export async function login(
|
||||
username: string,
|
||||
password: string
|
||||
): Promise<{token: string; user: {user_id: string; username: string}}> {
|
||||
const user = await db.select().from(users).where(eq(users.username, username));
|
||||
|
||||
//console.log(user);
|
||||
if (user.length === 0) {
|
||||
throw new Error("Invalid or Missing user");
|
||||
}
|
||||
// check the password
|
||||
const checkedPass = await checkPassword(password, user[0]?.password);
|
||||
//console.log(checkedPass);
|
||||
if (!checkedPass) {
|
||||
throw new Error("Invalid Password");
|
||||
}
|
||||
|
||||
// Create a JWT
|
||||
const secret: string = process.env.JWT_SECRET!;
|
||||
const expiresIn = Number(process.env.JWT_EXPIRES!) || 60;
|
||||
|
||||
// get the user roles
|
||||
const roles = await roleCheck(user[0].user_id);
|
||||
const userData = {
|
||||
user_id: user[0].user_id,
|
||||
username: user[0].username,
|
||||
email: user[0].email,
|
||||
roles: roles || null,
|
||||
role: user[0].role || null, // this should be removed onces full migration to v2 is completed
|
||||
};
|
||||
|
||||
// update the user last login
|
||||
// try {
|
||||
// db.update(users)
|
||||
// .set({lastLogin: sql`NOW()`})
|
||||
// .where(eq(users.user_id, user[0].user_id));
|
||||
// } catch (e) {
|
||||
// console.log(e);
|
||||
// }
|
||||
const token = sign({user: userData}, secret, {expiresIn: expiresIn * 60});
|
||||
|
||||
return {token, user: userData};
|
||||
}
|
||||
8
server/services/auth/controllers/logout.ts
Normal file
8
server/services/auth/controllers/logout.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Logout (clear the token).
|
||||
* This is a placeholder function since JWTs are stateless.
|
||||
* In a real app, you might want to implement token blacklisting.
|
||||
*/
|
||||
export function logout(): {message: string} {
|
||||
return {message: "Logout successful"};
|
||||
}
|
||||
1
server/services/auth/controllers/register.ts
Normal file
1
server/services/auth/controllers/register.ts
Normal file
@@ -0,0 +1 @@
|
||||
export const registerUser = async () => {};
|
||||
17
server/services/auth/controllers/verifyToken.ts
Normal file
17
server/services/auth/controllers/verifyToken.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import {sign, verify} from "jsonwebtoken";
|
||||
|
||||
/**
|
||||
* Verify a JWT and return the decoded payload.
|
||||
*/
|
||||
|
||||
const secret: string = process.env.JWT_SECRET! || "bnghsjhsd";
|
||||
const expiresIn: string = process.env.JWT_EXPIRES! || "1h";
|
||||
|
||||
export function verifyToken(token: string): {userId: number} {
|
||||
try {
|
||||
const payload = verify(token, secret) as {userId: number};
|
||||
return payload;
|
||||
} catch (err) {
|
||||
throw new Error("Invalid token");
|
||||
}
|
||||
}
|
||||
45
server/services/auth/middleware/authMiddleware.ts
Normal file
45
server/services/auth/middleware/authMiddleware.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import {type MiddlewareHandler} from "hono";
|
||||
import jwt from "jsonwebtoken";
|
||||
|
||||
const {sign, verify} = jwt;
|
||||
|
||||
export const authMiddleware: MiddlewareHandler = async (c, next) => {
|
||||
const authHeader = c.req.header("Authorization");
|
||||
|
||||
if (!authHeader || !authHeader.startsWith("Bearer ")) {
|
||||
return c.json({error: "Unauthorized"}, 401);
|
||||
}
|
||||
|
||||
const token = authHeader.split(" ")[1];
|
||||
|
||||
try {
|
||||
const decoded = verify(token, process.env.JWT_SECRET!, {ignoreExpiration: false}) as {
|
||||
userId: number;
|
||||
exp: number;
|
||||
};
|
||||
|
||||
const currentTime = Math.floor(Date.now() / 1000); // Get current timestamp
|
||||
const timeLeft = decoded.exp - currentTime;
|
||||
|
||||
// If the token has less than REFRESH_THRESHOLD seconds left, refresh it
|
||||
let newToken = null;
|
||||
|
||||
if (timeLeft < parseInt(process.env.REFRESH_THRESHOLD!)) {
|
||||
newToken = sign({userId: decoded.userId}, process.env.JWT_SECRET!, {
|
||||
expiresIn: parseInt(process.env.EXPIRATION_TIME!),
|
||||
});
|
||||
c.res.headers.set("Authorization", `Bearer ${newToken}`);
|
||||
}
|
||||
|
||||
c.set("user", {id: decoded.userId});
|
||||
await next();
|
||||
|
||||
// If a new token was generated, send it in response headers
|
||||
if (newToken) {
|
||||
console.log("token was refreshed");
|
||||
c.res.headers.set("X-Refreshed-Token", newToken);
|
||||
}
|
||||
} catch (err) {
|
||||
return c.json({error: "Invalid token"}, 401);
|
||||
}
|
||||
};
|
||||
31
server/services/auth/routes/getUserRoles.ts
Normal file
31
server/services/auth/routes/getUserRoles.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import {z, createRoute, OpenAPIHono} from "@hono/zod-openapi";
|
||||
import {apiHit} from "../../../globalUtils/apiHits.js";
|
||||
|
||||
const app = new OpenAPIHono();
|
||||
|
||||
const responseSchema = z.object({
|
||||
message: z.string().optional().openapi({example: "User Created"}),
|
||||
});
|
||||
|
||||
app.openapi(
|
||||
createRoute({
|
||||
tags: ["Auth"],
|
||||
summary: "Returns the useraccess table",
|
||||
method: "get",
|
||||
path: "/",
|
||||
|
||||
responses: {
|
||||
200: {
|
||||
content: {"application/json": {schema: responseSchema}},
|
||||
description: "Retrieve the user",
|
||||
},
|
||||
},
|
||||
}),
|
||||
async (c) => {
|
||||
// apit hit
|
||||
apiHit(c, {endpoint: "api/auth/register"});
|
||||
return c.json({message: "UserRoles coming over"});
|
||||
}
|
||||
);
|
||||
|
||||
export default app;
|
||||
90
server/services/auth/routes/login.ts
Normal file
90
server/services/auth/routes/login.ts
Normal file
@@ -0,0 +1,90 @@
|
||||
import {z, createRoute, OpenAPIHono} from "@hono/zod-openapi";
|
||||
import {login} from "../controllers/login.js";
|
||||
|
||||
const app = new OpenAPIHono();
|
||||
|
||||
const UserSchema = z
|
||||
.object({
|
||||
username: z.string().optional().openapi({example: "smith002"}),
|
||||
//email: z.string().optional().openapi({example: "s.smith@example.com"}),
|
||||
password: z.string().openapi({example: "password123"}),
|
||||
})
|
||||
.openapi("User");
|
||||
|
||||
const route = createRoute({
|
||||
tags: ["Auth"],
|
||||
summary: "Login as user",
|
||||
description: "Login as a user to get a JWT token",
|
||||
method: "post",
|
||||
path: "/",
|
||||
request: {
|
||||
body: {
|
||||
content: {
|
||||
"application/json": {schema: UserSchema},
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: {
|
||||
200: {
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: z.object({
|
||||
success: z.boolean().openapi({example: true}),
|
||||
message: z.string().openapi({example: "Logged in"}),
|
||||
}),
|
||||
},
|
||||
},
|
||||
description: "Response message",
|
||||
},
|
||||
|
||||
400: {
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: z.object({
|
||||
success: z.boolean().openapi({example: false}),
|
||||
message: z.string().openapi({example: "Username and password required"}),
|
||||
}),
|
||||
},
|
||||
},
|
||||
description: "Bad request",
|
||||
},
|
||||
401: {
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: z.object({
|
||||
success: z.boolean().openapi({example: false}),
|
||||
message: z.string().openapi({example: "Username and password required"}),
|
||||
}),
|
||||
},
|
||||
},
|
||||
description: "Bad request",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
app.openapi(route, async (c) => {
|
||||
const {username, password, email} = await c.req.json();
|
||||
|
||||
if (!username || !password) {
|
||||
return c.json(
|
||||
{
|
||||
success: false,
|
||||
message: "Username and password are required",
|
||||
},
|
||||
400
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
const {token, user} = await login(username.toLowerCase(), password);
|
||||
|
||||
// Set the JWT as an HTTP-only cookie
|
||||
//c.header("Set-Cookie", `auth_token=${token}; HttpOnly; Secure; Path=/; SameSite=None; Max-Age=3600`);
|
||||
|
||||
return c.json({success: true, message: "Login successful", user, token}, 200);
|
||||
} catch (err) {
|
||||
return c.json({success: false, message: "Incorrect Credentials"}, 401);
|
||||
}
|
||||
});
|
||||
|
||||
export default app;
|
||||
121
server/services/auth/routes/register.ts
Normal file
121
server/services/auth/routes/register.ts
Normal file
@@ -0,0 +1,121 @@
|
||||
import {z, createRoute, OpenAPIHono} from "@hono/zod-openapi";
|
||||
import {db} from "../../../../database/dbclient.js";
|
||||
import {users} from "../../../../database/schema/users.js";
|
||||
import {apiHit} from "../../../globalUtils/apiHits.js";
|
||||
import {createPassword} from "../utils/createPassword.js";
|
||||
import {eq} from "drizzle-orm";
|
||||
|
||||
const app = new OpenAPIHono();
|
||||
|
||||
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!"}),
|
||||
});
|
||||
|
||||
type User = z.infer<typeof UserSchema>;
|
||||
|
||||
const responseSchema = z.object({
|
||||
message: z.string().optional().openapi({example: "User Created"}),
|
||||
});
|
||||
|
||||
app.openapi(
|
||||
createRoute({
|
||||
tags: ["Auth"],
|
||||
summary: "Register a new user",
|
||||
method: "post",
|
||||
path: "/",
|
||||
request: {
|
||||
body: {
|
||||
content: {
|
||||
"application/json": {schema: UserSchema},
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: {
|
||||
200: {
|
||||
content: {"application/json": {schema: responseSchema}},
|
||||
description: "Retrieve the user",
|
||||
},
|
||||
400: {
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: z.object({
|
||||
success: z.boolean().openapi({example: false}),
|
||||
message: z.string().openapi({example: "Invalid credentials passed"}),
|
||||
}),
|
||||
},
|
||||
},
|
||||
description: "Retrieve the user",
|
||||
},
|
||||
},
|
||||
}),
|
||||
async (c) => {
|
||||
// apit hit
|
||||
apiHit(c, {endpoint: "api/auth/register"});
|
||||
let {username, email, password} = await c.req.json();
|
||||
|
||||
if (!username || !email || !password) {
|
||||
return c.json({success: false, message: "Credentials missing"}, 400);
|
||||
}
|
||||
|
||||
// some usernames that should be ignored
|
||||
const badActors = ["admin", "root"];
|
||||
if (badActors.includes(username)) {
|
||||
return c.json(
|
||||
{
|
||||
success: false,
|
||||
message: `${username} is not a valid name to be registerd please try again`,
|
||||
},
|
||||
400
|
||||
);
|
||||
}
|
||||
|
||||
// make sure the user dose not already exist in the system
|
||||
const userCheck = await db.select().from(users).where(eq(users.username, username));
|
||||
|
||||
if (userCheck.length === 1) {
|
||||
return c.json(
|
||||
{
|
||||
success: false,
|
||||
message: `${username} already exists please login or reset password, if you feel this is an error please contact your admin.`,
|
||||
},
|
||||
400
|
||||
);
|
||||
}
|
||||
|
||||
// make sure we only send over a username that is all lowercase
|
||||
username = username.toLowerCase();
|
||||
|
||||
// get the good kinda password
|
||||
password = await createPassword(password);
|
||||
|
||||
try {
|
||||
const user = await db
|
||||
.insert(users)
|
||||
.values({username, email, password})
|
||||
.returning({user: users.username, email: users.email});
|
||||
|
||||
return c.json({message: "User Registered", user}, 200);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
return c.json(
|
||||
{
|
||||
success: false,
|
||||
message: `${username} already exists please login or reset password, if you feel this is an error please contact your admin.`,
|
||||
},
|
||||
400
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
export default app;
|
||||
99
server/services/auth/routes/session.ts
Normal file
99
server/services/auth/routes/session.ts
Normal file
@@ -0,0 +1,99 @@
|
||||
import {z, createRoute, OpenAPIHono} from "@hono/zod-openapi";
|
||||
import {verify} from "hono/jwt";
|
||||
|
||||
const session = new OpenAPIHono();
|
||||
const tags = ["Auth"];
|
||||
const JWT_SECRET = process.env.JWT_SECRET!;
|
||||
|
||||
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!"}),
|
||||
});
|
||||
|
||||
session.openapi(
|
||||
createRoute({
|
||||
tags,
|
||||
summary: "Checks a user session based on there token",
|
||||
description: "Can post there via Authentiaction header or cookies",
|
||||
method: "get",
|
||||
path: "/",
|
||||
// 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) => {
|
||||
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!);
|
||||
return c.json({data: {token: token, user: payload.user}}, 200);
|
||||
} catch (error) {}
|
||||
return c.json({data: {token: "tsfds"}}, 200);
|
||||
}
|
||||
);
|
||||
|
||||
// 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;
|
||||
16
server/services/auth/utils/checkPassword.ts
Normal file
16
server/services/auth/utils/checkPassword.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import bcrypt from "bcrypt";
|
||||
|
||||
export const checkPassword = async (currentPassword: string, dbPassword: string) => {
|
||||
let decyptPass = "";
|
||||
try {
|
||||
decyptPass = atob(dbPassword);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
// encypt password
|
||||
const pass: string | undefined = process.env.SECRET;
|
||||
|
||||
const checked = bcrypt.compareSync(pass + currentPassword, decyptPass);
|
||||
|
||||
return checked;
|
||||
};
|
||||
17
server/services/auth/utils/createPassword.ts
Normal file
17
server/services/auth/utils/createPassword.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import bcrypt from "bcrypt";
|
||||
|
||||
export const createPassword = async (password: string) => {
|
||||
// encypt password
|
||||
let pass: string | undefined = process.env.SECRET;
|
||||
let salt: string | undefined = process.env.SALTING;
|
||||
|
||||
if (!pass || !salt) {
|
||||
pass = "error";
|
||||
} else {
|
||||
pass = bcrypt.hashSync(pass + password, parseInt(salt));
|
||||
|
||||
pass = btoa(pass);
|
||||
}
|
||||
|
||||
return pass;
|
||||
};
|
||||
52
server/services/general/route/apiHits.ts
Normal file
52
server/services/general/route/apiHits.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
import {z, createRoute, OpenAPIHono} from "@hono/zod-openapi";
|
||||
|
||||
const app = new OpenAPIHono();
|
||||
|
||||
// Define the request body schema
|
||||
const requestSchema = z.object({
|
||||
ip: z.string().optional(),
|
||||
endpoint: z.string().optional(),
|
||||
action: z.string().optional(),
|
||||
stats: z.string().optional(),
|
||||
});
|
||||
|
||||
// Define the response schema
|
||||
const responseSchema = z.object({
|
||||
message: z.string(),
|
||||
});
|
||||
|
||||
app.openapi(
|
||||
createRoute({
|
||||
tags: ["api"],
|
||||
summary: "Tracks the API posts and how often",
|
||||
method: "post",
|
||||
path: "/hits",
|
||||
request: {
|
||||
body: {
|
||||
content: {
|
||||
"application/json": {schema: requestSchema},
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: {
|
||||
200: {
|
||||
content: {
|
||||
"application/json": {schema: responseSchema},
|
||||
},
|
||||
description: "Response message",
|
||||
},
|
||||
},
|
||||
}),
|
||||
async (c) => {
|
||||
const data = await c.req.json();
|
||||
|
||||
//apiHit(data);
|
||||
|
||||
// Return response with the received data
|
||||
return c.json({
|
||||
message: `Received name: ${data.name}, arrayData: ${data.arrayData}`,
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
export default app;
|
||||
79
server/services/general/route/scalar.ts
Normal file
79
server/services/general/route/scalar.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
import {OpenAPIHono} from "@hono/zod-openapi";
|
||||
import {apiReference} from "@scalar/hono-api-reference";
|
||||
|
||||
const app = new OpenAPIHono();
|
||||
|
||||
app.get(
|
||||
"/docs",
|
||||
apiReference({
|
||||
theme: "kepler",
|
||||
layout: "classic",
|
||||
defaultHttpClient: {targetKey: "node", clientKey: "axios"},
|
||||
pageTitle: "Lst API Reference",
|
||||
hiddenClients: [
|
||||
"libcurl",
|
||||
"clj_http",
|
||||
"httpclient",
|
||||
"restsharp",
|
||||
"native",
|
||||
"http1.1",
|
||||
"asynchttp",
|
||||
"nethttp",
|
||||
"okhttp",
|
||||
"unirest",
|
||||
"xhr",
|
||||
"fetch",
|
||||
"jquery",
|
||||
"okhttp",
|
||||
"native",
|
||||
"request",
|
||||
"unirest",
|
||||
"nsurlsession",
|
||||
"cohttp",
|
||||
"curl",
|
||||
"guzzle",
|
||||
"http1",
|
||||
"http2",
|
||||
"webrequest",
|
||||
"restmethod",
|
||||
"python3",
|
||||
"requests",
|
||||
"httr",
|
||||
"native",
|
||||
"curl",
|
||||
"httpie",
|
||||
"wget",
|
||||
"nsurlsession",
|
||||
"undici",
|
||||
],
|
||||
spec: {
|
||||
url: "/api/ref",
|
||||
},
|
||||
baseServerURL: "https://scalar.com",
|
||||
servers: [
|
||||
{
|
||||
url: `http://usday1vms006:${process.env.SERVER_PORT}`,
|
||||
description: "Production",
|
||||
},
|
||||
{
|
||||
url: `http://localhost:${process.env.SERVER_PORT}`,
|
||||
description: "dev server",
|
||||
},
|
||||
],
|
||||
// authentication: {
|
||||
// preferredSecurityScheme: {'bearerAuth'},
|
||||
// },
|
||||
|
||||
// metaData: {
|
||||
// title: "Page title",
|
||||
// description: "My page page",
|
||||
// ogDescription: "Still about my my page",
|
||||
// ogTitle: "Page title",
|
||||
// ogImage: "https://example.com/image.png",
|
||||
// twitterCard: "summary_large_image",
|
||||
// // Add more...
|
||||
// },
|
||||
})
|
||||
);
|
||||
|
||||
export default app;
|
||||
19
server/services/ocme/ocmeService.ts
Normal file
19
server/services/ocme/ocmeService.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import type {Context} from "hono";
|
||||
|
||||
export const ocmeService = async (c: Context) => {
|
||||
const url = new URL(c.req.url);
|
||||
|
||||
const ocmeUrl = `http://localhost:${process.env.OCME_PORT}${url.pathname.replace("/ocme", "")}`;
|
||||
|
||||
console.log(ocmeUrl);
|
||||
const ocmeResponse = await fetch(ocmeUrl, {
|
||||
method: c.req.method,
|
||||
headers: c.req.raw.headers,
|
||||
body: c.req.method !== "GET" && c.req.method !== "HEAD" ? await c.req.text() : undefined,
|
||||
});
|
||||
|
||||
return new Response(ocmeResponse.body, {
|
||||
status: ocmeResponse.status,
|
||||
headers: ocmeResponse.headers,
|
||||
});
|
||||
};
|
||||
66
server/services/server/route/modules.ts
Normal file
66
server/services/server/route/modules.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
import {z, createRoute, OpenAPIHono} from "@hono/zod-openapi";
|
||||
import {modules} from "../../../../database/schema/modules.js";
|
||||
import {db} from "../../../../database/dbclient.js";
|
||||
import {eq} from "drizzle-orm";
|
||||
|
||||
// Define the request body schema
|
||||
const requestSchema = z.object({
|
||||
ip: z.string().optional(),
|
||||
endpoint: z.string().optional(),
|
||||
action: z.string().optional(),
|
||||
stats: z.string().optional(),
|
||||
});
|
||||
|
||||
// Define the response schema
|
||||
const responseSchema = z.object({
|
||||
message: z.string().optional(),
|
||||
module_id: z.string().openapi({example: "6c922c6c-7de3-4ec4-acb0-f068abdc"}).optional(),
|
||||
name: z.string().openapi({example: "Production"}).optional(),
|
||||
active: z.boolean().openapi({example: true}).optional(),
|
||||
roles: z.string().openapi({example: `["viewer","technician"]`}).optional(),
|
||||
});
|
||||
|
||||
const app = new OpenAPIHono();
|
||||
|
||||
app.openapi(
|
||||
createRoute({
|
||||
tags: ["server"],
|
||||
summary: "Returns all modules in the server",
|
||||
method: "get",
|
||||
path: "/",
|
||||
responses: {
|
||||
200: {
|
||||
content: {
|
||||
"application/json": {schema: responseSchema},
|
||||
},
|
||||
description: "Response message",
|
||||
},
|
||||
},
|
||||
}),
|
||||
async (c) => {
|
||||
//console.log("system modules");
|
||||
let module: any = [];
|
||||
try {
|
||||
module = await db.select().from(modules).where(eq(modules.active, true));
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
module = [];
|
||||
}
|
||||
|
||||
// parse the roles
|
||||
const updateModules = module.map((m: any) => {
|
||||
if (m.roles) {
|
||||
return {...m, roles: JSON.parse(m?.roles)};
|
||||
}
|
||||
return m;
|
||||
}); //JSON.parse(module[0]?.roles);
|
||||
|
||||
// Return response with the received data
|
||||
return c.json({
|
||||
message: `All active modules`,
|
||||
data: updateModules,
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
export default app;
|
||||
7
server/services/server/systemServer.ts
Normal file
7
server/services/server/systemServer.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import {OpenAPIHono} from "@hono/zod-openapi";
|
||||
|
||||
import modules from "./route/modules.js";
|
||||
|
||||
const app = new OpenAPIHono().route("server/modules", modules);
|
||||
|
||||
export default app;
|
||||
Reference in New Issue
Block a user