Skip to content
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/db/db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,21 @@ PRAGMA user_version = 1;`);
}

const dbVersion = (db.query("PRAGMA user_version").get() as { user_version?: number }).user_version;

// existing migration: add status column to file_names
if (dbVersion === 0) {
db.exec("ALTER TABLE file_names ADD COLUMN status TEXT DEFAULT 'not started';");
db.exec("PRAGMA user_version = 1;");
console.log("Updated database to version 1.");
}

const userColumns = db.query("PRAGMA table_info(users)").all() as { name: string }[];
const hasRoleColumn = userColumns.some((col) => col.name === "role");
if (!hasRoleColumn) {
db.exec("ALTER TABLE users ADD COLUMN role TEXT NOT NULL DEFAULT 'user';");
console.log("Added 'role' column to users table.");
}

// enable WAL mode
db.exec("PRAGMA journal_mode = WAL;");

Expand Down
1 change: 1 addition & 0 deletions src/db/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,5 @@ export class User {
id!: number;
email!: string;
password!: string;
role!: string; // 'admin' | 'user'
}
30 changes: 27 additions & 3 deletions src/pages/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,22 @@ export const root = new Elysia().use(userService).get(
}

// validate jwt
let user: ({ id: string } & JWTPayloadSpec) | false = false;
let user: ({ id: string; role: string } & JWTPayloadSpec) | false = false;

if (ALLOW_UNAUTHENTICATED) {
const newUserId = String(
UNAUTHENTICATED_USER_SHARING
? 0
: randomInt(2 ** 24, Math.min(2 ** 48 + 2 ** 24 - 1, Number.MAX_SAFE_INTEGER)),
);

const accessToken = await jwt.sign({
id: newUserId,
role: "user",
});

user = { id: newUserId };
user = { id: newUserId, role: "user" };

if (!auth) {
return {
message: "No auth cookie, perhaps your browser is blocking cookies.",
Expand All @@ -57,7 +61,24 @@ export const root = new Elysia().use(userService).get(
sameSite: "strict",
});
} else if (auth?.value) {
user = await jwt.verify(auth.value);
const verified = await jwt.verify(auth.value);

// If verification fails, keep user as false
if (verified === false) {
user = false;
} else {
// Ensure role is present (defensive, for older tokens)
const verifiedUser = verified as { id?: string; role?: string } & JWTPayloadSpec;

if (!verifiedUser.id) {
user = false;
} else if (!verifiedUser.role) {
// fallback: treat as normal user if role missing
user = { ...verifiedUser, id: verifiedUser.id, role: "user" };
} else {
user = verifiedUser as { id: string; role: string } & JWTPayloadSpec;
}
}

if (
user !== false &&
Expand All @@ -73,6 +94,9 @@ export const root = new Elysia().use(userService).get(
}
return redirect(`${WEBROOT}/login`, 302);
}

// Optional: if you want DB to be the source of truth for role, uncomment below:
// user = { ...user, role: existingUser.role ?? "user" };
}
}

Expand Down
Loading