better blogid handling

This commit is contained in:
Jordi Enric
2025-12-11 11:46:41 +01:00
parent 37498516bd
commit f38b2e550e
2 changed files with 55 additions and 23 deletions
@@ -0,0 +1,21 @@
export const isValidBlogId = (blogId: string | undefined): blogId is string => {
if (!blogId) {
return false;
}
const trimmed = blogId.trim();
if (trimmed === "") {
return false;
}
if (trimmed.toLowerCase() === "undefined") {
return false;
}
if (trimmed.toLowerCase() === "null") {
return false;
}
return true;
};
+34 -23
View File
@@ -15,6 +15,7 @@ import { PublicApiResponse } from "./public-api.types";
import { Post, PostWithContent } from "@zenblog/types";
import { throwError } from "./public-api.errors";
import { trackApiUsage } from "lib/axiom";
import { isValidBlogId } from "./public-api.validation";
const app = new Hono()
.basePath("/api/public")
@@ -23,25 +24,23 @@ const app = new Hono()
.use("*", async (ctx, next) => {
// middleware doesnt get the blogId param
// so we need to get it from the url
const blogId = ctx.req.url.split("/")[6];
const rawBlogId = ctx.req.url.split("/")[6];
if (!blogId) {
await next();
return;
if (isValidBlogId(rawBlogId)) {
const blogId: string = rawBlogId;
trackApiUsage({
blogId,
event: "api-usage",
timestamp: new Date().toISOString(),
path: ctx.req.url,
});
}
trackApiUsage({
blogId,
event: "api-usage",
timestamp: new Date().toISOString(),
path: ctx.req.url,
});
await next();
});
app.get(posts.path, async (c) => {
const blogId = c.req.param("blogId");
const rawBlogId = c.req.param("blogId");
const offset = parseInt(c.req.query("offset") || "0");
const limit = parseInt(c.req.query("limit") || "30");
const categoryFilter = c.req.query("category");
@@ -49,10 +48,12 @@ app.get(posts.path, async (c) => {
const authorFilter = c.req.query("author");
const supabase = createClient();
if (!blogId) {
if (!isValidBlogId(rawBlogId)) {
return throwError(c, "MISSING_BLOG_ID");
}
const blogId: string = rawBlogId;
let postsQuery = supabase
.from("posts_v10")
.select(
@@ -141,14 +142,16 @@ app.get(posts.path, async (c) => {
});
app.get(postBySlug.path, async (c) => {
const blogId = c.req.param("blogId");
const rawBlogId = c.req.param("blogId");
const slug = c.req.param("slug");
const supabase = createClient();
if (!blogId || !slug) {
if (!isValidBlogId(rawBlogId) || !slug?.trim()) {
return throwError(c, "MISSING_BLOG_ID_OR_SLUG");
}
const blogId: string = rawBlogId;
const { data: post, error } = await supabase
.from("posts_v10")
.select(
@@ -212,15 +215,17 @@ app.get(postBySlug.path, async (c) => {
});
app.get(categories.path, async (c) => {
const blogId = c.req.param("blogId");
const rawBlogId = c.req.param("blogId");
const offset = parseInt(c.req.query("offset") || "0");
const limit = parseInt(c.req.query("limit") || "30");
const supabase = createClient();
if (!blogId) {
if (!isValidBlogId(rawBlogId)) {
return throwError(c, "MISSING_BLOG_ID");
}
const blogId: string = rawBlogId;
const {
data: categories,
error,
@@ -246,15 +251,17 @@ app.get(categories.path, async (c) => {
});
app.get(tags.path, async (c) => {
const blogId = c.req.param("blogId");
const rawBlogId = c.req.param("blogId");
const offset = parseInt(c.req.query("offset") || "0");
const limit = parseInt(c.req.query("limit") || "30");
const supabase = createClient();
if (!blogId) {
if (!isValidBlogId(rawBlogId)) {
return throwError(c, "MISSING_BLOG_ID");
}
const blogId: string = rawBlogId;
const {
data: tags,
error,
@@ -280,15 +287,17 @@ app.get(tags.path, async (c) => {
});
app.get(authors.path, async (c) => {
const blogId = c.req.param("blogId");
const rawBlogId = c.req.param("blogId");
const offset = parseInt(c.req.query("offset") || "0");
const limit = parseInt(c.req.query("limit") || "30");
const supabase = createClient();
if (!blogId) {
if (!isValidBlogId(rawBlogId)) {
return throwError(c, "MISSING_BLOG_ID");
}
const blogId: string = rawBlogId;
const {
data: authors,
error,
@@ -314,14 +323,16 @@ app.get(authors.path, async (c) => {
});
app.get(authorBySlug.path, async (c) => {
const blogId = c.req.param("blogId");
const rawBlogId = c.req.param("blogId");
const slug = c.req.param("slug");
const supabase = createClient();
if (!blogId || !slug) {
if (!isValidBlogId(rawBlogId) || !slug?.trim()) {
return throwError(c, "MISSING_BLOG_ID_OR_SLUG");
}
const blogId: string = rawBlogId;
const { data: author, error } = await supabase
.from("authors")
.select("name, slug, image_url, twitter, website, bio")