X-Git-Url: http://these/git/?a=blobdiff_plain;f=src%2Fserver%2Fhandlers%2Fcatch-all-handler.tsx;h=a40136b2c32260a13fcdb6e7437de031959253c3;hb=dd42bc2a3dc75a33d20bb5b2f9dfbbfb7e12b153;hp=bbcb6891809dc7851afbb157b97f69a9b3dc2a53;hpb=d7bd5893d46e349f643ab0f68f751239d601346b;p=lemmy-ui.git diff --git a/src/server/handlers/catch-all-handler.tsx b/src/server/handlers/catch-all-handler.tsx index bbcb689..a40136b 100644 --- a/src/server/handlers/catch-all-handler.tsx +++ b/src/server/handlers/catch-all-handler.tsx @@ -1,17 +1,23 @@ +import { initializeSite, isAuthPath } from "@utils/app"; +import { getHttpBaseInternal } from "@utils/env"; +import { ErrorPageData } from "@utils/types"; +import * as cookie from "cookie"; +import fetch from "cross-fetch"; import type { Request, Response } from "express"; import { StaticRouter, matchPath } from "inferno-router"; import { renderToString } from "inferno-server"; -import IsomorphicCookie from "isomorphic-cookie"; import { GetSite, GetSiteResponse, LemmyHttp } from "lemmy-js-client"; import { App } from "../../shared/components/app/app"; -import { getHttpBaseInternal } from "../../shared/env"; import { InitialFetchRequest, IsoDataOptionalSite, + RouteData, } from "../../shared/interfaces"; import { routes } from "../../shared/routes"; -import { RequestState, wrapClient } from "../../shared/services/HttpService"; -import { ErrorPageData, initializeSite, isAuthPath } from "../../shared/utils"; +import { + FailedRequestState, + wrapClient, +} from "../../shared/services/HttpService"; import { createSsrHtml } from "../utils/create-ssr-html"; import { getErrorPageData } from "../utils/get-error-page-data"; import { setForwardedHeaders } from "../utils/set-forwarded-headers"; @@ -19,12 +25,18 @@ import { setForwardedHeaders } from "../utils/set-forwarded-headers"; export default async (req: Request, res: Response) => { try { const activeRoute = routes.find(route => matchPath(req.path, route)); - let auth: string | undefined = IsomorphicCookie.load("jwt", req); + + let auth = req.headers.cookie + ? cookie.parse(req.headers.cookie).jwt + : undefined; const getSiteForm: GetSite = { auth }; const headers = setForwardedHeaders(req.headers); - const client = wrapClient(new LemmyHttp(getHttpBaseInternal(), headers)); + + const client = wrapClient( + new LemmyHttp(getHttpBaseInternal(), { fetchFunction: fetch, headers }) + ); const { path, url, query } = req; @@ -32,10 +44,11 @@ export default async (req: Request, res: Response) => { // This bypasses errors, so that the client can hit the error on its own, // in order to remove the jwt on the browser. Necessary for wrong jwts let site: GetSiteResponse | undefined = undefined; - const routeData: RequestState[] = []; + let routeData: RouteData = {}; let errorPageData: ErrorPageData | undefined = undefined; let try_site = await client.getSite(getSiteForm); - if (try_site.state === "failed" && try_site.msg == "not_logged_in") { + + if (try_site.state === "failed" && try_site.msg === "not_logged_in") { console.error( "Incorrect JWT token, skipping auth so frontend can remove jwt cookie" ); @@ -56,7 +69,7 @@ export default async (req: Request, res: Response) => { return res.redirect("/setup"); } - if (site) { + if (site && activeRoute?.fetchInitialData) { const initialFetchReq: InitialFetchRequest = { client, auth, @@ -65,26 +78,30 @@ export default async (req: Request, res: Response) => { site, }; - if (activeRoute?.fetchInitialData) { - routeData.push( - ...(await Promise.all([ - ...activeRoute.fetchInitialData(initialFetchReq), - ])) - ); - } + routeData = await activeRoute.fetchInitialData(initialFetchReq); + } + + if (!activeRoute) { + res.status(404); } } else if (try_site.state === "failed") { + res.status(500); errorPageData = getErrorPageData(new Error(try_site.msg), site); } + const error = Object.values(routeData).find( + res => res.state === "failed" && res.msg !== "couldnt_find_object" // TODO: find a better way of handling errors + ) as FailedRequestState | undefined; + // Redirect to the 404 if there's an API error - if (routeData[0] && routeData[0].state === "failed") { - const error = routeData[0].msg; - console.error(error); - if (error === "instance_is_private") { + if (error) { + console.error(error.msg); + + if (error.msg === "instance_is_private") { return res.redirect(`/signup`); } else { - errorPageData = getErrorPageData(new Error(error), site); + res.status(500); + errorPageData = getErrorPageData(new Error(error.msg), site); } } @@ -97,17 +114,18 @@ export default async (req: Request, res: Response) => { const wrapper = ( - + ); const root = renderToString(wrapper); - res.send(await createSsrHtml(root, isoData)); + res.send(await createSsrHtml(root, isoData, res.locals.cspNonce)); } catch (err) { // If an error is caught here, the error page couldn't even be rendered console.error(err); res.statusCode = 500; + return res.send( process.env.NODE_ENV === "development" ? err.message : "Server error" );