Loading backend/example.env +0 −4 Original line number Diff line number Diff line Loading @@ -7,10 +7,6 @@ PORT=3000 OIDC_ISSUER=http://localhost:3000 # redirect routes to this host # used by some alternate packager, like vite CLIENT_HOST=http://localhost:5173 # Lemmy Polyfill LEMMY_HOST= LEMMY_USER= Loading backend/src/lib/express.ts +91 −33 Original line number Diff line number Diff line Loading @@ -34,51 +34,109 @@ app.use( secure: process.env.NODE_ENV === "production" && !process.env.USE_INSECURE, sameSite: "lax", httpOnly: false, }, // TODO: do not use memory store }) ); app.use("/interaction/:uid", async (req, res, next) => { const interactionMiddleware = ( req: express.Request, resp: express.Response ) => { return new Promise< | { type: "continue" } | { type: "redirect"; to: string } | { type: "error"; error: "session_lost" } | { type: "error"; error: "unknown" } >(async (res) => { const interaction = await oidc.Interaction.find(req.params.uid); if (interaction?.prompt.name === "login") { if (typeof req.session.user === "undefined") { res.redirect("/login?return=" + encodeURIComponent(req.originalUrl)); res({ type: "redirect", to: "/login?return=" + encodeURIComponent("/interaction/" + req.params.uid), }); } else { try { const returnTo = await oidc.interactionResult(req, res, { const returnTo = await oidc.interactionResult(req, resp, { login: { accountId: req.session.user.sub }, }); req.session.destroy(() => { res.redirect(returnTo); res({ type: "redirect", to: returnTo }); }); } catch (e) { console.error("Error while in interaction middleware", e); req.session.destroy(() => { if (e instanceof OIDC_Errors.SessionNotFound) { res.send("<h1>session lost</h1>try logging in again"); res({ type: "error", error: "session_lost" }); } else { res.send("<h1>unknown error</h1> try logging in again"); res({ type: "error", error: "unknown" }); } }); } } return; } else { res({ type: "continue" }); } next(); }); }; if (process.env.CLIENT_HOST) { app.get(["/interaction*", "/login"], (req, res) => { const url = new URL(req.originalUrl, process.env.CLIENT_HOST!); res.redirect(url.toString()); if (process.env.NODE_ENV === "development") { // expose the internals of the interaction middleware for the vite dev server to access app.post("/_dev/interaction/:uid", async (req, res) => { const middleware = await interactionMiddleware(req, res); switch (middleware.type) { case "redirect": res.redirect(middleware.to); break; case "error": switch (middleware.error) { case "session_lost": res.send("<h1>session lost</h1><p>Try login again</p>"); break; case "unknown": res.send("<h1>unknown error</h1>"); break; } break; case "continue": default: res.end(); break; } }); } app.use("/interaction/:uid", async (req, res, next) => { const middleware = await interactionMiddleware(req, res); switch (middleware.type) { case "redirect": res.redirect(middleware.to); break; case "error": switch (middleware.error) { case "session_lost": res.send("<h1>session lost</h1><p>Try login again</p>"); break; case "unknown": res.send("<h1>unknown error</h1>"); break; } break; case "continue": default: next(); break; } }); if (process.env.SERVE_FRONTEND) { const indexFile = path.join(process.env.SERVE_FRONTEND, "index.html"); Loading frontend/example.env +1 −1 Original line number Diff line number Diff line # Development Use # Specify the backend url # VITE_APP_ROOT=http://localhost:3000 No newline at end of file # DEV_BACKEND_HOST=http://localhost:3000 No newline at end of file frontend/src/Logout/Logout.tsx +2 −2 Original line number Diff line number Diff line Loading @@ -17,7 +17,7 @@ export const LogoutPage = () => { >(); useEffect(() => { fetch(import.meta.env.VITE_APP_ROOT + "/api/v1/whoami", { fetch("/api/v1/whoami", { credentials: "include", }) .then((a) => a.json()) Loading @@ -33,7 +33,7 @@ export const LogoutPage = () => { const doLogout = () => { setLoading(true); fetch(import.meta.env.VITE_APP_ROOT + "/api/v1/logout", { fetch("/api/v1/logout", { method: "POST", credentials: "include", }) Loading frontend/src/env.d.ts 0 → 100644 +10 −0 Original line number Diff line number Diff line declare global { namespace NodeJS { interface ProcessEnv { NODE_ENV: "development" | "production"; DEV_BACKEND_HOST?: string; } } } export {}; Loading
backend/example.env +0 −4 Original line number Diff line number Diff line Loading @@ -7,10 +7,6 @@ PORT=3000 OIDC_ISSUER=http://localhost:3000 # redirect routes to this host # used by some alternate packager, like vite CLIENT_HOST=http://localhost:5173 # Lemmy Polyfill LEMMY_HOST= LEMMY_USER= Loading
backend/src/lib/express.ts +91 −33 Original line number Diff line number Diff line Loading @@ -34,51 +34,109 @@ app.use( secure: process.env.NODE_ENV === "production" && !process.env.USE_INSECURE, sameSite: "lax", httpOnly: false, }, // TODO: do not use memory store }) ); app.use("/interaction/:uid", async (req, res, next) => { const interactionMiddleware = ( req: express.Request, resp: express.Response ) => { return new Promise< | { type: "continue" } | { type: "redirect"; to: string } | { type: "error"; error: "session_lost" } | { type: "error"; error: "unknown" } >(async (res) => { const interaction = await oidc.Interaction.find(req.params.uid); if (interaction?.prompt.name === "login") { if (typeof req.session.user === "undefined") { res.redirect("/login?return=" + encodeURIComponent(req.originalUrl)); res({ type: "redirect", to: "/login?return=" + encodeURIComponent("/interaction/" + req.params.uid), }); } else { try { const returnTo = await oidc.interactionResult(req, res, { const returnTo = await oidc.interactionResult(req, resp, { login: { accountId: req.session.user.sub }, }); req.session.destroy(() => { res.redirect(returnTo); res({ type: "redirect", to: returnTo }); }); } catch (e) { console.error("Error while in interaction middleware", e); req.session.destroy(() => { if (e instanceof OIDC_Errors.SessionNotFound) { res.send("<h1>session lost</h1>try logging in again"); res({ type: "error", error: "session_lost" }); } else { res.send("<h1>unknown error</h1> try logging in again"); res({ type: "error", error: "unknown" }); } }); } } return; } else { res({ type: "continue" }); } next(); }); }; if (process.env.CLIENT_HOST) { app.get(["/interaction*", "/login"], (req, res) => { const url = new URL(req.originalUrl, process.env.CLIENT_HOST!); res.redirect(url.toString()); if (process.env.NODE_ENV === "development") { // expose the internals of the interaction middleware for the vite dev server to access app.post("/_dev/interaction/:uid", async (req, res) => { const middleware = await interactionMiddleware(req, res); switch (middleware.type) { case "redirect": res.redirect(middleware.to); break; case "error": switch (middleware.error) { case "session_lost": res.send("<h1>session lost</h1><p>Try login again</p>"); break; case "unknown": res.send("<h1>unknown error</h1>"); break; } break; case "continue": default: res.end(); break; } }); } app.use("/interaction/:uid", async (req, res, next) => { const middleware = await interactionMiddleware(req, res); switch (middleware.type) { case "redirect": res.redirect(middleware.to); break; case "error": switch (middleware.error) { case "session_lost": res.send("<h1>session lost</h1><p>Try login again</p>"); break; case "unknown": res.send("<h1>unknown error</h1>"); break; } break; case "continue": default: next(); break; } }); if (process.env.SERVE_FRONTEND) { const indexFile = path.join(process.env.SERVE_FRONTEND, "index.html"); Loading
frontend/example.env +1 −1 Original line number Diff line number Diff line # Development Use # Specify the backend url # VITE_APP_ROOT=http://localhost:3000 No newline at end of file # DEV_BACKEND_HOST=http://localhost:3000 No newline at end of file
frontend/src/Logout/Logout.tsx +2 −2 Original line number Diff line number Diff line Loading @@ -17,7 +17,7 @@ export const LogoutPage = () => { >(); useEffect(() => { fetch(import.meta.env.VITE_APP_ROOT + "/api/v1/whoami", { fetch("/api/v1/whoami", { credentials: "include", }) .then((a) => a.json()) Loading @@ -33,7 +33,7 @@ export const LogoutPage = () => { const doLogout = () => { setLoading(true); fetch(import.meta.env.VITE_APP_ROOT + "/api/v1/logout", { fetch("/api/v1/logout", { method: "POST", credentials: "include", }) Loading
frontend/src/env.d.ts 0 → 100644 +10 −0 Original line number Diff line number Diff line declare global { namespace NodeJS { interface ProcessEnv { NODE_ENV: "development" | "production"; DEV_BACKEND_HOST?: string; } } } export {};