adding permissions layer
This commit is contained in:
@@ -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(),
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
};
|
||||||
@@ -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
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -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") {
|
||||||
|
|||||||
Reference in New Issue
Block a user