summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/auth.tsx26
-rw-r--r--src/db/schema.ts3
-rw-r--r--src/index.tsx19
3 files changed, 33 insertions, 15 deletions
diff --git a/src/auth.tsx b/src/auth.tsx
index ebda74e..eef8b8f 100644
--- a/src/auth.tsx
+++ b/src/auth.tsx
@@ -1,19 +1,35 @@
import { Hono } from "hono";
import * as swa from "@simplewebauthn/server";
import { randomUUID } from "node:crypto";
-import { eq } from "drizzle-orm";
+import { and, eq, gt, sql } from "drizzle-orm";
import { RP_ID, ORIGIN, db } from "./index.js";
import { sessionTable, userTable, webauthnChallenges } from "./db/schema.js";
import { stringify, parse } from "superjson";
-import { setCookie } from "hono/cookie";
-
-let app = new Hono();
+import { getCookie, setCookie } from "hono/cookie";
+import type { Context } from "hono";
export const LoginForm = () => <section class="register-form">
<button hx-post="/auth/register-begin" hx-target="closest .register-form" hx-swap="outerHTML">register</button>
<button hx-post="/auth/login-begin" hx-target="closest .register-form" hx-swap="outerHTML">login</button>
</section>;
+export async function getSession(c: Context) {
+ let sessionId = getCookie(c, "session");
+ if (!sessionId) return null;
+
+ let [result] = await db
+ .select()
+ .from(sessionTable)
+ .innerJoin(userTable, eq(userTable.id, sessionTable.userId))
+ .where(({ sessions: session }) => and(eq(session.uuid, sessionId), gt(session.lastUse, sql`unixepoch() - ${60 * 60 * 24 * 7}`)));
+ if (!result) return null;
+ await db.update(sessionTable).set({ lastUse: sql`unixepoch()` }).where(eq(sessionTable.id, result.sessions.id));
+ return { user: result.users, lastUse: result.sessions.lastUse, uuid: result.sessions.uuid };
+}
+
+let app = new Hono();
+export default app;
+
app.post("/register-begin", async c => {
const username = randomUUID();
let options = await swa.generateRegistrationOptions({
@@ -89,5 +105,3 @@ app.post("/login-finish", async c => {
setCookie(c, "session", uuid);
return c.html(<p>Logged in!</p>);
});
-
-export default app;
diff --git a/src/db/schema.ts b/src/db/schema.ts
index 01b7228..339dfc0 100644
--- a/src/db/schema.ts
+++ b/src/db/schema.ts
@@ -1,4 +1,4 @@
-import { relations } from "drizzle-orm";
+import { relations, sql } from "drizzle-orm";
import { text, sqliteTable, integer } from "drizzle-orm/sqlite-core";
export const groupTable = sqliteTable("groups", {
@@ -17,6 +17,7 @@ export const sessionTable = sqliteTable("sessions", {
id: integer().primaryKey(),
uuid: text().unique().notNull(),
userId: integer("user_id").notNull(),
+ lastUse: integer("last_use", { mode: "timestamp" }).notNull().default(sql`(unixepoch())`),
});
export const sessionRelations = relations(sessionTable, ({ one }) => ({
diff --git a/src/index.tsx b/src/index.tsx
index e029577..5975284 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -3,7 +3,7 @@ import { Hono } from "hono";
import { createClient } from "@libsql/client";
import { drizzle } from "drizzle-orm/libsql";
import { groupTable } from "./db/schema.js";
-import authRouter, { LoginForm } from "./auth.js";
+import authRouter, { getSession, LoginForm } from "./auth.js";
export const RP_ID = "localhost"; // "uneven.0m.nu";
export const ORIGIN = `http://${RP_ID}`;
@@ -38,13 +38,16 @@ app.get("/", c => c.html(
));
let colors = ["red", "green", "blue"];
-app.get("/button", c => c.html(
- <button
- hx-get="/button"
- hx-swap="outerHTML"
- style={{ backgroundColor: colors[Math.floor(Math.random() * colors.length)] }}
- >disco button!</button>
-));
+app.get("/button", async c => {
+ let session = await getSession(c);
+ return c.html(
+ <button
+ hx-get="/button"
+ hx-swap="outerHTML"
+ style={{ backgroundColor: colors[Math.floor(Math.random() * colors.length)] }}
+ >disco button! {session.user.name}</button>
+ );
+});
app.route("/auth", authRouter);