diff --git a/handlers/naddr.ts b/handlers/naddr.ts index 4f708d6..3295702 100644 --- a/handlers/naddr.ts +++ b/handlers/naddr.ts @@ -2,6 +2,7 @@ import { Context } from "@oak/oak"; import { nip19 } from "@nostr/tools"; import { log } from "../log.ts"; import { lookupUsernameByPubkey } from "../ldap.ts"; +import notFoundHandler from "../handlers/not-found.ts"; const naddrHandler = async function (ctx: Context) { const naddr = ctx.params.path; @@ -13,13 +14,11 @@ const naddrHandler = async function (ctx: Context) { if (username && r.data.identifier) { ctx.response.redirect(`/@${username}/${r.data.identifier}`); } else { - ctx.response.status = 404; - ctx.response.body = "Not Found"; + notFoundHandler(ctx); } } catch (e) { log(e, "yellow"); - ctx.response.status = 404; - ctx.response.body = "Not Found"; + notFoundHandler(ctx); } }; diff --git a/handlers/not-found.ts b/handlers/not-found.ts new file mode 100644 index 0000000..46524bd --- /dev/null +++ b/handlers/not-found.ts @@ -0,0 +1,10 @@ +import { Context } from "@oak/oak"; +import { errorPageHtml } from "../html.ts"; + +const notFoundHandler = function (ctx: Context) { + const html = errorPageHtml(404, "Not found"); + ctx.response.body = html; + ctx.response.status = 404; +}; + +export default notFoundHandler; diff --git a/handlers/nprofile.ts b/handlers/nprofile.ts index 15bc048..250ce21 100644 --- a/handlers/nprofile.ts +++ b/handlers/nprofile.ts @@ -2,6 +2,7 @@ import { Context } from "@oak/oak"; import { nip19 } from "@nostr/tools"; import { log } from "../log.ts"; import { lookupUsernameByPubkey } from "../ldap.ts"; +import notFoundHandler from "../handlers/not-found.ts"; const nprofileHandler = async function (ctx: Context) { const nprofile = ctx.params.path; @@ -13,13 +14,11 @@ const nprofileHandler = async function (ctx: Context) { if (username) { ctx.response.redirect(`/@${username}`); } else { - ctx.response.status = 404; - ctx.response.body = "Not Found"; + notFoundHandler(ctx); } } catch (e) { log(e, "yellow"); - ctx.response.status = 404; - ctx.response.body = "Not Found"; + notFoundHandler(ctx); } }; diff --git a/handlers/npub.ts b/handlers/npub.ts index 69ebd77..48ce9d7 100644 --- a/handlers/npub.ts +++ b/handlers/npub.ts @@ -2,6 +2,7 @@ import { Context } from "@oak/oak"; import { nip19 } from "@nostr/tools"; import { log } from "../log.ts"; import { lookupUsernameByPubkey } from "../ldap.ts"; +import notFoundHandler from "../handlers/not-found.ts"; const npubHandler = async function (ctx: Context) { const npub = ctx.params.path; @@ -13,13 +14,11 @@ const npubHandler = async function (ctx: Context) { if (username) { ctx.response.redirect(`/@${username}`); } else { - ctx.response.status = 404; - ctx.response.body = "Not Found"; + notFoundHandler(ctx); } } catch (e) { log(e, "yellow"); - ctx.response.status = 404; - ctx.response.body = "Not Found"; + notFoundHandler(ctx); } }; diff --git a/handlers/user-atom-feed.ts b/handlers/user-atom-feed.ts index 77073b1..c1e317a 100644 --- a/handlers/user-atom-feed.ts +++ b/handlers/user-atom-feed.ts @@ -5,14 +5,14 @@ import { fetchArticlesByAuthor, fetchProfileEvent } from "../nostr.ts"; import { profileAtomFeed } from "../feeds.ts"; import Article from "../models/article.ts"; import Profile from "../models/profile.ts"; +import notFoundHandler from "../handlers/not-found.ts"; const userAtomFeedHandler = async function (ctx: Context) { const username = ctx.params.user.replace(/^(@|~)/, ""); const pubkey = await lookupPubkeyByUsername(username); if (!pubkey) { - ctx.response.status = 404; - ctx.response.body = "Not Found"; + notFoundHandler(ctx); return; } @@ -33,8 +33,7 @@ const userAtomFeedHandler = async function (ctx: Context) { } } catch (e) { log(e, "yellow"); - ctx.response.status = 404; - ctx.response.body = "Not Found"; + notFoundHandler(ctx); } }; diff --git a/handlers/user-event.ts b/handlers/user-event.ts index d4cb7d1..4c37314 100644 --- a/handlers/user-event.ts +++ b/handlers/user-event.ts @@ -5,6 +5,7 @@ import { fetchProfileEvent, fetchReplaceableEvent } from "../nostr.ts"; import Article from "../models/article.ts"; import Profile from "../models/profile.ts"; import { articleHtml } from "../html.ts"; +import notFoundHandler from "../handlers/not-found.ts"; const userEventHandler = async function (ctx: Context) { const username = ctx.params.user.replace(/^(@|~)/, ""); @@ -12,8 +13,7 @@ const userEventHandler = async function (ctx: Context) { const pubkey = await lookupPubkeyByUsername(username); if (!pubkey) { - ctx.response.status = 404; - ctx.response.body = "Not Found"; + notFoundHandler(ctx); return; } @@ -31,13 +31,11 @@ const userEventHandler = async function (ctx: Context) { ctx.response.body = html; } else { - ctx.response.status = 404; - ctx.response.body = "Not Found"; + notFoundHandler(ctx); } } catch (e) { log(e, "yellow"); - ctx.response.status = 404; - ctx.response.body = "Not Found"; + notFoundHandler(ctx); } }; diff --git a/handlers/user-profile.ts b/handlers/user-profile.ts index 732d720..92a436f 100644 --- a/handlers/user-profile.ts +++ b/handlers/user-profile.ts @@ -5,14 +5,14 @@ import { fetchArticlesByAuthor, fetchProfileEvent } from "../nostr.ts"; import Article from "../models/article.ts"; import Profile from "../models/profile.ts"; import { profilePageHtml } from "../html.ts"; +import notFoundHandler from "../handlers/not-found.ts"; const userProfileHandler = async function (ctx: Context) { const username = ctx.params.path.replace(/^(@|~)/, ""); const pubkey = await lookupPubkeyByUsername(username); if (!pubkey) { - ctx.response.status = 404; - ctx.response.body = "Not Found"; + notFoundHandler(ctx); return; } @@ -27,13 +27,11 @@ const userProfileHandler = async function (ctx: Context) { ctx.response.body = html; } else { - ctx.response.status = 404; - ctx.response.body = "Not Found"; + notFoundHandler(ctx); } } catch (e) { log(e, "yellow"); - ctx.response.status = 404; - ctx.response.body = "Not Found"; + notFoundHandler(ctx); } }; diff --git a/html.ts b/html.ts index 6af1b78..1c1633a 100644 --- a/html.ts +++ b/html.ts @@ -2,7 +2,13 @@ import { localizeDate } from "./dates.ts"; import Article from "./models/article.ts"; import Profile from "./models/profile.ts"; -function htmlLayout(title: string, body: string, profile: Profile): string { +function htmlLayout(title: string, body: string, profile?: Profile): string { + let feedLinksHtml = ""; + if (profile) { + feedLinksHtml = + ``; + } + return ` @@ -11,7 +17,7 @@ function htmlLayout(title: string, body: string, profile: Profile): string { ${title} - + ${feedLinksHtml} @@ -22,6 +28,16 @@ function htmlLayout(title: string, body: string, profile: Profile): string { `; } +export function errorPageHtml(statusCode: number, title: string): string { + const body = ` +
+

${statusCode} - ${title}

+
+ `; + + return htmlLayout(title, body); +} + export function articleHtml(article: Article, profile: Profile): string { const publishedAtFormatted = localizeDate(article.publishedAt); diff --git a/server.ts b/server.ts index e3605eb..73914b9 100644 --- a/server.ts +++ b/server.ts @@ -6,6 +6,7 @@ import npubHandler from "./handlers/npub.ts"; import userProfileHandler from "./handlers/user-profile.ts"; import userEventHandler from "./handlers/user-event.ts"; import userAtomFeedHandler from "./handlers/user-atom-feed.ts"; +import notFoundHandler from "./handlers/not-found.ts"; const router = new Router(); @@ -21,8 +22,7 @@ router.get("/:path", async (ctx: ctx) => { } else if (path.startsWith("@") || path.startsWith("~")) { await userProfileHandler(ctx); } else { - ctx.response.status = 404; - ctx.response.body = "Not Found"; + notFoundHandler(ctx); } }); @@ -35,8 +35,7 @@ router.get("/:user/:kind.atom", async (ctx: ctx) => { ) { await userAtomFeedHandler(ctx); } else { - ctx.response.status = 404; - ctx.response.body = "Not Found"; + notFoundHandler(ctx); } }); @@ -46,8 +45,7 @@ router.get("/:user/:identifier", async (ctx: ctx) => { if (user.startsWith("@") || user.startsWith("~")) { await userEventHandler(ctx); } else { - ctx.response.status = 404; - ctx.response.body = "Not Found"; + notFoundHandler(ctx); } }); @@ -59,8 +57,7 @@ router.get("/assets/:path*", async (ctx) => { root: `${Deno.cwd()}/assets`, }); } catch (_e) { - ctx.response.status = 404; - ctx.response.body = "Not Found"; + notFoundHandler(ctx); } });