Mirror of https://github.com/roostorg/coop github.com/roostorg/coop
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 54 lines 2.7 kB view raw
1import express from 'express'; 2 3import makeApiApp from './api.js'; 4import { type Dependencies } from './iocContainer/index.js'; 5 6export default async function makeWWWServer(deps: Dependencies) { 7 const { app: apiApp, shutdown } = await makeApiApp(deps); 8 const app = express(); 9 10 // Traffic is routed to our app via: NLB -> ALB -> Express. The 11 // NLB terminates TLS, so the NLB -> ALB request is over HTTP. As a 12 // result, when the ALB hits express, it sets the `x-forwarded-proto` header 13 // to `http`. This causes express to think the request is insecure, which 14 // cause express-session to refuse to send a session cookie (since we mark our 15 // session cookies with the `Secure` flag, which is designed to prevent both 16 // server and client from sending the cookie in plaintext over HTTP). 17 // express-session intentionally does not have a way to force it to skip the 18 // secure check and unconditionally send the session cookie (see 19 // https://github.com/expressjs/session/issues/785), so we have two options: 20 // 21 // 1. Override `req.secure` to always return true, so express-session thinks 22 // the request is secure. 23 // 24 // 2. Actually have the request hit the ALB over HTTPS, which involves either 25 // having the NLB re-encrypt the traffic on the way to the ALB, or having 26 // the NLB re-encrypt it and pass that through. 27 // 28 // Option 2 is more complex, so we go with option 1 for now. However, the risk 29 // with option 1 is that different code/middleware will check different things 30 // to determine whether the request is secure, and those checks disagreeing 31 // could lead to subtle bugs. So, we limit that risk by patching as many 32 // things as possible (i.e, also `req.protocol` and `x-forwarded-proto`); we 33 // don't deal with the `Forwarded` header since that's more complicated and 34 // less widely supported, so less likely to be checked by middleware. 35 // 36 // Note: forcing the ALB to set `x-forwarded-proto` to `https` is not an 37 // option, as AWS doesn't support that. 38 app.set('trust proxy', true); 39 app.use((req, _res, next) => { 40 // Define our overrides as getter properties to be consistent with their 41 // definition in express, just in case. 42 Object.defineProperty(req, 'secure', { get: () => true }); 43 Object.defineProperty(req, 'protocol', { get: () => 'https' }); 44 // NB: we overwrite the x-forwarded-proto, rather than append to it with a 45 // comma, because x-forwarded-proto is a non-standardized header with no spec, 46 // and it's not clear if appending is actually kosher/universally supported. 47 req.headers['x-forwarded-proto'] = 'https'; 48 next(); 49 }); 50 51 app.use('/api/v1', apiApp); 52 53 return { app, shutdown }; 54}