[feat] Authenticate with default U&P
This commit is contained in:
+81
-1
@@ -1,17 +1,45 @@
|
||||
import "dotenv/config";
|
||||
import { drizzle } from "drizzle-orm/libsql";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { createClient } from "@libsql/client";
|
||||
import { SignJWT } from "jose";
|
||||
|
||||
import { Hono } from "@hono/hono";
|
||||
import { commonResponse } from "./utils/response.ts";
|
||||
import { hashPassword, verifyPassword } from "./utils/crypto.ts";
|
||||
import { metasTable } from "./db/schema.ts";
|
||||
|
||||
const client = createClient({
|
||||
url: `file:${process.env.DATABASE_PATH!}`,
|
||||
});
|
||||
const db = drizzle(client);
|
||||
|
||||
const app = new Hono();
|
||||
const JWT_SECRET = crypto.getRandomValues(new Uint8Array(32));
|
||||
|
||||
async function initDefaultUser() {
|
||||
const row = await db
|
||||
.select()
|
||||
.from(metasTable)
|
||||
.where(eq(metasTable.key, "userinfo_username"))
|
||||
.get();
|
||||
if (row) return;
|
||||
|
||||
const usernameHash = await hashPassword("ah");
|
||||
const passwordHash = await hashPassword("123456");
|
||||
|
||||
await db
|
||||
.insert(metasTable)
|
||||
.values([
|
||||
{ key: "userinfo_username", value: usernameHash },
|
||||
{ key: "userinfo_password", value: passwordHash },
|
||||
])
|
||||
.run();
|
||||
console.log("Default user created (username: ah, password: 123456)");
|
||||
}
|
||||
|
||||
await initDefaultUser();
|
||||
|
||||
const app = new Hono();
|
||||
|
||||
app.get("/", (c) => {
|
||||
return commonResponse(c, true, 200, { "hint": "Hello! But nothing here." });
|
||||
@@ -20,6 +48,58 @@ app.get("/ping", (c) => {
|
||||
return commonResponse(c, true, 200, {});
|
||||
});
|
||||
|
||||
app.post("/authenticate", async (c) => {
|
||||
const body = await c.req.json<{ username?: string; password?: string }>();
|
||||
if (!body.username || !body.password) {
|
||||
return commonResponse(
|
||||
c,
|
||||
false,
|
||||
400,
|
||||
{},
|
||||
"Missing username or password",
|
||||
);
|
||||
}
|
||||
|
||||
const storedUsername = await db
|
||||
.select()
|
||||
.from(metasTable)
|
||||
.where(eq(metasTable.key, "userinfo_username"))
|
||||
.get();
|
||||
const storedPassword = await db
|
||||
.select()
|
||||
.from(metasTable)
|
||||
.where(eq(metasTable.key, "userinfo_password"))
|
||||
.get();
|
||||
|
||||
if (!storedUsername?.value || !storedPassword?.value) {
|
||||
return commonResponse(c, false, 500, {}, "User not configured");
|
||||
}
|
||||
|
||||
const usernameValid = await verifyPassword(
|
||||
body.username,
|
||||
storedUsername.value,
|
||||
);
|
||||
if (!usernameValid) {
|
||||
return commonResponse(c, false, 401, {}, "Invalid credentials");
|
||||
}
|
||||
|
||||
const passwordValid = await verifyPassword(
|
||||
body.password,
|
||||
storedPassword.value,
|
||||
);
|
||||
if (!passwordValid) {
|
||||
return commonResponse(c, false, 401, {}, "Invalid credentials");
|
||||
}
|
||||
|
||||
const jwt = await new SignJWT({ username: body.username })
|
||||
.setProtectedHeader({ alg: "HS256" })
|
||||
.setIssuedAt()
|
||||
.setExpirationTime("24h")
|
||||
.sign(JWT_SECRET);
|
||||
|
||||
return commonResponse(c, true, 200, { token: jwt });
|
||||
});
|
||||
|
||||
Deno.serve(app.fetch);
|
||||
|
||||
const handleExit = () => {
|
||||
|
||||
Reference in New Issue
Block a user