adding permissions layer

This commit is contained in:
2026-07-07 01:24:14 -05:00
parent 1e43be14bd
commit 1073b794d6
4 changed files with 52 additions and 11 deletions
+21 -5
View File
@@ -10,7 +10,8 @@ import {
unique, unique,
boolean, boolean,
smallint, smallint,
check check,
foreignKey
} from "drizzle-orm/pg-core"; } from "drizzle-orm/pg-core";
import { sql, defineRelations } from "drizzle-orm"; import { sql, defineRelations } from "drizzle-orm";
@@ -42,11 +43,26 @@ export const articles = pgTable("articles", {
date_created: timestamp({ mode: "date", withTimezone: true }).defaultNow().notNull(), date_created: timestamp({ mode: "date", withTimezone: true }).defaultNow().notNull(),
last_edit: timestamp({ mode: "date", withTimezone: true }).defaultNow().notNull(), last_edit: timestamp({ mode: "date", withTimezone: true }).defaultNow().notNull(),
date_published: timestamp({ mode: "date", withTimezone: true }), date_published: timestamp({ mode: "date", withTimezone: true }),
previous_article: uuid(),
next_article: uuid()
}, },
(table) => [{ (table) => [
slugIdx: unique("no_repeat_slugs_per_author") unique("no_repeat_slugs_per_author")
.on(table.author_id, table.slug) .on(table.author_id, table.slug),
}]);
foreignKey({
name: "next_article_ref_id",
columns: [table.next_article],
foreignColumns: [table.id]
}),
foreignKey({
name: "previous_article_ref_id",
columns: [table.previous_article],
foreignColumns: [table.id]
})
]);
export const articleBlocks = pgTable("article_blocks", { export const articleBlocks = pgTable("article_blocks", {
id: uuid().notNull().primaryKey().defaultRandom(), id: uuid().notNull().primaryKey().defaultRandom(),
+17
View File
@@ -0,0 +1,17 @@
import { Request, Response, NextFunction } from "express";
import JsonWebToken from '../types/JsonWebToken.ts';
export enum Permission {
read = 1,
write = 2,
delete = 4
};
export function requirePermissions(permission: number, isOwner: Boolean, requiredPermissions: number): Boolean {
const mask = isOwner ?
Math.floor(permission / 10) :
permission % 10;
return (mask & requiredPermissions) === requiredPermissions;
};
+13 -5
View File
@@ -2,6 +2,7 @@ import { drizzle } from 'drizzle-orm/node-postgres';
import { eq } from 'drizzle-orm'; import { eq } from 'drizzle-orm';
import { articles } from '../db/schema.ts'; import { articles } from '../db/schema.ts';
import express, { Request, Response } from "express"; import express, { Request, Response } from "express";
import { Permission, requirePermissions } from '../helpers/authenticate.ts';
const db = drizzle(process.env.DATABASE_URL!); const db = drizzle(process.env.DATABASE_URL!);
export const articlesRouter = express.Router(); export const articlesRouter = express.Router();
@@ -18,6 +19,17 @@ articlesRouter.get("/getArticle/:articleId", async (req: Request, res: Response)
const resp = await db.select() const resp = await db.select()
.from(articles) .from(articles)
.where(eq(articles.id, parsedId)); .where(eq(articles.id, parsedId));
if (!requirePermissions(
req.jwt.payload.prm,
req.jwt.payload.uid === resp[0].author_id,
Permission.read)) {
res.status(403).json({
error: "Insufficient Permissions"
});
};
res.json(resp); res.json(resp);
}); });
@@ -47,11 +59,7 @@ articlesRouter.put("/updateArticle/:articleId", async (req: Request, res: Respon
const resp = await db.update(articles) const resp = await db.update(articles)
.set({ .set({
name: req.body.name, ...req.body,
author_id: req.body.author_id,
slug: req.body.name.trim().toLowerCase().replace(/\s+/g, '-').replace(/[^\w-]/g, ''),
summary: req.body.summary,
article_status: req.body.article_status,
last_edit: new Date(Date.now()), last_edit: new Date(Date.now()),
date_published: req.body.article_status == "published" ? new Date(Date.now()) : null date_published: req.body.article_status == "published" ? new Date(Date.now()) : null
}) })
+1 -1
View File
@@ -58,7 +58,7 @@ authRouter.post("/signup", async (req: Request, res: Response) => {
display_name: display_name, display_name: display_name,
username: username, username: username,
hashed_password: hashedPassword, hashed_password: hashedPassword,
permissions: 44 permissions: 71
}); });
} catch (err: any) { } catch (err: any) {
if (err.cause.code === "23505") { if (err.cause.code === "23505") {