diff --git a/keyserver/src/keyserver.js b/keyserver/src/keyserver.js --- a/keyserver/src/keyserver.js +++ b/keyserver/src/keyserver.js @@ -62,7 +62,8 @@ initENSCache(), ]); - const keyserverBaseRoutePath = getKeyserverURLFacts()?.baseRoutePath; + const keyserverURLFacts = getKeyserverURLFacts(); + const keyserverBaseRoutePath = keyserverURLFacts?.baseRoutePath; const landingBaseRoutePath = getLandingURLFacts()?.baseRoutePath; const webAppURLFacts = getWebAppURLFacts(); const webAppBaseRoutePath = webAppURLFacts?.baseRoutePath; @@ -145,14 +146,18 @@ server.use(express.json({ limit: '250mb' })); server.use(cookieParser()); - const setupAppRouter = router => { - if (areEndpointMetricsEnabled) { - router.use(logEndpointMetrics); - } - router.use('/images', express.static('images')); - router.use('/fonts', express.static('fonts')); - router.use('/misc', express.static('misc')); - router.use( + // Note - the order of router declarations matters. On prod we have + // keyserverBaseRoutePath configured to '/', which means it's a catch-all. + // If we call server.use on keyserverRouter first, it will catch all + // requests and prevent webAppRouter and landingRouter from working + // correctly. So we make sure that keyserverRouter goes last + + server.get('/invite/:secret', inviteResponder); + + if (landingBaseRoutePath) { + const landingRouter = express.Router(); + landingRouter.get('/invite/:secret', inviteResponder); + landingRouter.use( '/.well-known', express.static( '.well-known', @@ -163,92 +168,98 @@ }, ), ); - router.use( + landingRouter.use('/images', express.static('images')); + landingRouter.use('/fonts', express.static('fonts')); + landingRouter.use( + '/compiled', + express.static('landing_compiled', compiledFolderOptions), + ); + landingRouter.use('/', express.static('landing_icons')); + landingRouter.post('/subscribe_email', emailSubscriptionResponder); + landingRouter.get('*', landingHandler); + server.use(landingBaseRoutePath, landingRouter); + } + + if (webAppBaseRoutePath) { + const webAppRouter = express.Router(); + webAppRouter.use('/images', express.static('images')); + webAppRouter.use('/fonts', express.static('fonts')); + webAppRouter.use('/misc', express.static('misc')); + webAppRouter.use( + '/.well-known', + express.static( + '.well-known', + // Necessary for apple-app-site-association file + { + setHeaders: res => + res.setHeader('Content-Type', 'application/json'), + }, + ), + ); + webAppRouter.use( '/compiled', express.static('app_compiled', compiledFolderOptions), ); - router.use('/', express.static('icons')); + webAppRouter.use('/', express.static('icons')); + + webAppRouter.get('/invite/:secret', inviteResponder); + + webAppRouter.get('/worker/:worker', webWorkerResponder); + + if (keyserverURLFacts) { + webAppRouter.get( + '/upload/:uploadID/:secret', + (req: $Request, res: $Response) => { + const { uploadID, secret } = req.params; + const url = `${keyserverURLFacts.baseDomain}${keyserverURLFacts.basePath}upload/${uploadID}/${secret}`; + res.redirect(url); + }, + ); + } + + webAppRouter.get('*', htmlHandler(websiteResponder)); + + server.use(webAppBaseRoutePath, webAppRouter); + } + + if (keyserverBaseRoutePath) { + const keyserverRouter = express.Router(); + if (areEndpointMetricsEnabled) { + keyserverRouter.use(logEndpointMetrics); + } + if (keyserverCorsOptions) { + keyserverRouter.use(cors(keyserverCorsOptions)); + } for (const endpoint in jsonEndpoints) { // $FlowFixMe Flow thinks endpoint is string const responder = jsonEndpoints[endpoint]; const expectCookieInvalidation = endpoint === 'log_out'; - router.post( + keyserverRouter.post( `/${endpoint}`, jsonHandler(responder, expectCookieInvalidation), ); } - router.get( + keyserverRouter.get( '/download_error_report/:reportID', downloadHandler(errorReportDownloadResponder), ); - router.get( + keyserverRouter.get( '/upload/:uploadID/:secret', downloadHandler(uploadDownloadResponder), ); - router.get('/invite/:secret', inviteResponder); - // $FlowFixMe express-ws has side effects that can't be typed - router.ws('/ws', onConnection); - router.get('/worker/:worker', webWorkerResponder); - router.get('*', htmlHandler(websiteResponder)); + keyserverRouter.ws('/ws', onConnection); - router.post( + keyserverRouter.post( '/upload_multimedia', multerProcessor, uploadHandler(multimediaUploadResponder), ); - }; - - // Note - the order of router declarations matters. On prod we have - // squadCalBaseRoutePath configured to '/', which means it's a catch-all. If - // we call server.use on squadCalRouter first, it will catch all requests - // and prevent commAppRouter and landingRouter from working correctly. So we - // make sure that squadCalRouter goes last - - server.get('/invite/:secret', inviteResponder); - if (landingBaseRoutePath) { - const landingRouter = express.Router(); - landingRouter.get('/invite/:secret', inviteResponder); - landingRouter.use( - '/.well-known', - express.static( - '.well-known', - // Necessary for apple-app-site-association file - { - setHeaders: res => - res.setHeader('Content-Type', 'application/json'), - }, - ), - ); - landingRouter.use('/images', express.static('images')); - landingRouter.use('/fonts', express.static('fonts')); - landingRouter.use( - '/compiled', - express.static('landing_compiled', compiledFolderOptions), - ); - landingRouter.use('/', express.static('landing_icons')); - landingRouter.post('/subscribe_email', emailSubscriptionResponder); - landingRouter.get('*', landingHandler); - server.use(landingBaseRoutePath, landingRouter); - } - - if (webAppBaseRoutePath) { - const commAppRouter = express.Router(); - setupAppRouter(commAppRouter); - server.use(webAppBaseRoutePath, commAppRouter); - } - - if (keyserverBaseRoutePath) { - const squadCalRouter = express.Router(); - if (keyserverCorsOptions) { - squadCalRouter.use(cors(keyserverCorsOptions)); - } - setupAppRouter(squadCalRouter); - server.use(keyserverBaseRoutePath, squadCalRouter); + server.use(keyserverBaseRoutePath, keyserverRouter); } if (isDev && webAppURLFacts) {