import serialize from 'serialize-javascript'; import express from 'express'; import { StaticRouter } from 'inferno-router'; import { renderToString } from 'inferno-server'; import { matchPath } from 'inferno-router'; import path from 'path'; import { App } from '../shared/components/app'; import { ILemmyConfig, InitialFetchRequest, IsoData, } from '../shared/interfaces'; import { routes } from '../shared/routes'; import IsomorphicCookie from 'isomorphic-cookie'; import { GetSite, LemmyHttp } from 'lemmy-js-client'; import process from 'process'; import { Helmet } from 'inferno-helmet'; import { initializeSite } from '../shared/initialize'; import { httpUri } from '../shared/env'; import { IncomingHttpHeaders } from 'http'; import { setOptionalAuth } from '../shared/utils'; const server = express(); const port = 1234; server.use(express.json()); server.use(express.urlencoded({ extended: false })); server.use('/static', express.static(path.resolve('./dist'))); // server.use(cookieParser()); server.get('/*', async (req, res) => { const activeRoute = routes.find(route => matchPath(req.path, route)) || {}; const context = {} as any; let auth: string = IsomorphicCookie.load('jwt', req); let getSiteForm: GetSite = {}; setOptionalAuth(getSiteForm, auth); let promises: Promise[] = []; let headers = setForwardedHeaders(req.headers); let initialFetchReq: InitialFetchRequest = { client: new LemmyHttp(httpUri, headers), auth, path: req.path, }; // Get site data first let site = await initialFetchReq.client.getSite(getSiteForm); initializeSite(site); if (activeRoute.fetchInitialData) { promises.push(...activeRoute.fetchInitialData(initialFetchReq)); } let routeData = await Promise.all(promises); // Redirect to the 404 if there's an API error if (routeData[0] && routeData[0].error) { let errCode = routeData[0].error; return res.redirect(`/404?err=${errCode}`); } let acceptLang = req.headers['accept-language'] ? req.headers['accept-language'].split(',')[0] : 'en'; let lang = site.my_user ? site.my_user.lang == 'browser' ? acceptLang : 'en' : acceptLang; let isoData: IsoData = { path: req.path, site_res: site, routeData, lang, }; const wrapper = ( ); if (context.url) { return res.redirect(context.url); } const cspHtml = ( ); const root = renderToString(wrapper); const cspStr = process.env.LEMMY_EXTERNAL_HOST ? renderToString(cspHtml) : ''; const helmet = Helmet.renderStatic(); const config: ILemmyConfig = { wsHost: process.env.LEMMY_WS_HOST }; res.send(` ${helmet.title.toString()} ${helmet.meta.toString()} ${cspStr} ${helmet.link.toString()}
${root}
`); }); server.listen(port, () => { console.log(`http://localhost:${port}`); }); function setForwardedHeaders( headers: IncomingHttpHeaders ): { [key: string]: string } { let out = { host: headers.host, }; if (headers['x-real-ip']) { out['x-real-ip'] = headers['x-real-ip']; } if (headers['x-forwarded-for']) { out['x-forwarded-for'] = headers['x-forwarded-for']; } return out; } process.on('SIGINT', () => { console.info('Interrupted'); process.exit(0); });