mirror of
https://github.com/khairul169/home-lab.git
synced 2026-10-02 17:13:57 +07:00
feat: add authentication
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
import { Hono } from "hono";
|
||||
import auth from "./auth";
|
||||
import system from "./system";
|
||||
import _process from "./process";
|
||||
import { authMiddleware } from "../lib/jwt";
|
||||
|
||||
const routes = new Hono()
|
||||
.route("/auth", auth)
|
||||
.use(authMiddleware)
|
||||
.route("/system", system)
|
||||
.route("/process", _process);
|
||||
|
||||
export type AppType = typeof routes;
|
||||
|
||||
export default routes;
|
||||
@@ -0,0 +1,34 @@
|
||||
import { zValidator } from "@hono/zod-validator";
|
||||
import { Hono } from "hono";
|
||||
import { HTTPException } from "hono/http-exception";
|
||||
import { z } from "zod";
|
||||
import { generateToken } from "../lib/jwt";
|
||||
import { nanoid } from "nanoid";
|
||||
|
||||
const loginSchema = z.object({
|
||||
username: z.string().min(1),
|
||||
password: z.string().min(1),
|
||||
});
|
||||
type LoginSchema = z.infer<typeof loginSchema>;
|
||||
|
||||
const route = new Hono().post(
|
||||
"/login",
|
||||
zValidator("json", loginSchema),
|
||||
async (c) => {
|
||||
const input: LoginSchema = await c.req.json();
|
||||
const { AUTH_USERNAME, AUTH_PASSWORD } = process.env;
|
||||
|
||||
if (input.username !== AUTH_USERNAME || input.password !== AUTH_PASSWORD) {
|
||||
throw new HTTPException(400, {
|
||||
message: "Username or password is invalid!",
|
||||
});
|
||||
}
|
||||
|
||||
const data = { sessionId: nanoid() };
|
||||
const token = await generateToken(data);
|
||||
|
||||
return c.json({ token, ...data });
|
||||
}
|
||||
);
|
||||
|
||||
export default route;
|
||||
@@ -0,0 +1,51 @@
|
||||
import { Hono } from "hono";
|
||||
import si from "systeminformation";
|
||||
import { formatBytes } from "../lib/utils";
|
||||
import { zValidator } from "@hono/zod-validator";
|
||||
import { z } from "zod";
|
||||
|
||||
const route = new Hono().get(
|
||||
"/",
|
||||
zValidator(
|
||||
"query",
|
||||
z
|
||||
.object({ sort: z.enum(["cpu", "mem"]), limit: z.coerce.number() })
|
||||
.partial()
|
||||
.optional()
|
||||
),
|
||||
async (c) => {
|
||||
const memTotal = (await si.mem()).total;
|
||||
const sort = c.req.query("sort") || "mem";
|
||||
const limit = parseInt(c.req.query("limit") || "") || 10;
|
||||
|
||||
let processList = (await si.processes()).list;
|
||||
|
||||
if (sort) {
|
||||
switch (sort) {
|
||||
case "cpu":
|
||||
processList = processList.sort((a, b) => b.cpu - a.cpu);
|
||||
break;
|
||||
case "mem":
|
||||
processList = processList.sort((a, b) => b.mem - a.mem);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const list = processList
|
||||
.map((p) => ({
|
||||
name: p.name,
|
||||
cmd: [p.name, p.params].filter(Boolean).join(" "),
|
||||
cpu: p.cpu,
|
||||
cpuPercent: p.cpu.toFixed(1) + "%",
|
||||
mem: p.mem,
|
||||
memUsage: formatBytes((p.mem / 100) * memTotal),
|
||||
path: p.path,
|
||||
user: p.user,
|
||||
}))
|
||||
.slice(0, limit);
|
||||
|
||||
return c.json({ list });
|
||||
}
|
||||
);
|
||||
|
||||
export default route;
|
||||
@@ -0,0 +1,48 @@
|
||||
import { Hono } from "hono";
|
||||
import si from "systeminformation";
|
||||
import { formatBytes, secondsToTime } from "../lib/utils";
|
||||
|
||||
const route = new Hono().get("/", async (c) => {
|
||||
const date = new Date().toISOString();
|
||||
const uptime = secondsToTime(si.time().uptime || 0);
|
||||
const system = await si.system();
|
||||
|
||||
const cpuSpeed = await si.cpuCurrentSpeed();
|
||||
const cpuTemp = await si.cpuTemperature();
|
||||
const cpuLoad = await si.currentLoad();
|
||||
const mem = await si.mem();
|
||||
|
||||
const perf = {
|
||||
cpu: {
|
||||
load: cpuLoad.currentLoad,
|
||||
speed: cpuSpeed.avg,
|
||||
temp: cpuTemp.main,
|
||||
},
|
||||
mem: {
|
||||
total: formatBytes(mem.total),
|
||||
percent: (mem.active / mem.total) * 100,
|
||||
used: formatBytes(mem.active),
|
||||
free: formatBytes(mem.total - mem.active),
|
||||
},
|
||||
};
|
||||
|
||||
const fsMounts = await si.fsSize();
|
||||
const storage = fsMounts
|
||||
.filter(
|
||||
(i) =>
|
||||
i.size > 32 * 1024 * 1024 * 1024 &&
|
||||
!i.mount.startsWith("/var/lib/docker")
|
||||
)
|
||||
.map((i) => ({
|
||||
type: i.type,
|
||||
mount: i.mount,
|
||||
used: formatBytes(i.used),
|
||||
percent: (i.used / i.size) * 100,
|
||||
total: formatBytes(i.size),
|
||||
free: formatBytes(i.available),
|
||||
}));
|
||||
|
||||
return c.json({ uptime, date, system, perf, storage });
|
||||
});
|
||||
|
||||
export default route;
|
||||
Reference in New Issue
Block a user