]> Untitled Git - lemmy-ui.git/blobdiff - src/server/handlers/catch-all-handler.tsx
ES-Lint tweak (#2001)
[lemmy-ui.git] / src / server / handlers / catch-all-handler.tsx
index bbcb6891809dc7851afbb157b97f69a9b3dc2a53..a40136b2c32260a13fcdb6e7437de031959253c3 100644 (file)
@@ -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<any>[] = [];
+    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 = (
       <StaticRouter location={url} context={isoData}>
-        <App />
+        <App user={site?.my_user} />
       </StaticRouter>
     );
 
     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"
     );