diff --git a/src/db/posts.ts b/src/db/posts.ts index 85f2d32..aa6a5bd 100644 --- a/src/db/posts.ts +++ b/src/db/posts.ts @@ -93,4 +93,26 @@ export async function get_post(post: number | string): Promise { const [result] = await db.select().from(schema.posts).where(eq(post_attr, post)); if (!result) throw new PostNotFoundError(); return result; +} + +/** + * Verifies a user owns a post. Errors with `PostNotFoundError` if not. + * @param {number} user_id User's ID. + * @param {number | string} post Post's ID or UUID. + * @returns {Promise} Post. + */ +export async function assert_post_owner(user_id: number, post: number | string): Promise { + let post_attr = (typeof post === "string") ? schema.posts.uuid : schema.posts.id; + const [result] = await db + .select({ post: schema.posts }) + .from(schema.posts) + .innerJoin(schema.blogs, eq(schema.posts.blog_id, schema.blogs.id)) + .where( + and( + eq(post_attr, post), + eq(schema.blogs.user_id, user_id) + ) + ); + if (!result) throw new PostNotFoundError(); + return result.post; } \ No newline at end of file diff --git a/src/routes/write.ts b/src/routes/write.ts index 03e1114..05e0515 100644 --- a/src/routes/write.ts +++ b/src/routes/write.ts @@ -1,6 +1,6 @@ import Hono from "@/lib/hono"; import { session_auth } from "@/middleware/authenticated"; -import { get_post } from '@/db/posts'; +import { assert_post_owner, get_post } from '@/db/posts'; import { PostNotFoundError } from '@/lib/errors'; import { create_post } from '@/db/posts'; import { get_blog } from '@/db/blogs'; @@ -8,6 +8,7 @@ import { post_template } from "@/lib/post_template"; import eta from "@/lib/eta"; import { UUID_REGEX } from "@/lib/constants"; import type { Blog, Post } from "@/lib/types"; +import { users } from "@/db/schema/schema"; const write = new Hono(); @@ -26,19 +27,17 @@ write.post(`/new/:blog{${UUID_REGEX.source}}`, async (c) => { }); write.get(`/:uuid{${UUID_REGEX.source}}`, async (c) => { - let [uuid, post] = [c.req.param('uuid'), {} as Post]; + let [uuid, post, user] = [c.req.param('uuid'), {} as Post, c.get('user')]; try { - post = await get_post(uuid); + post = await assert_post_owner(user.id!, uuid); + return eta(c, "editor", { post }); } catch (e) { if (e instanceof PostNotFoundError) return c.notFound(); console.error(e); - } finally { - if (!post) return c.notFound(); - return eta(c, "editor", { post }); } }).post(async (c) => { let uuid = c.req.param('uuid'); - + }) export default write; \ No newline at end of file