Convert server and router files to ES modules

GitOrigin-RevId: dab330dd89afb156db6586d8c28b146216548477
This commit is contained in:
andrew rumble 2024-09-25 17:16:48 +01:00 committed by Copybot
parent e128e8ea32
commit 5a5995f43c
3 changed files with 134 additions and 138 deletions

View file

@ -13,7 +13,7 @@ import https from 'node:https'
import * as Serializers from './app/src/infrastructure/LoggerSerializers.js'
import Server from './app/src/infrastructure/Server.js'
import Server from './app/src/infrastructure/Server.mjs'
import QueueWorkers from './app/src/infrastructure/QueueWorkers.js'
import mongodb from './app/src/infrastructure/mongodb.js'
import mongoose from './app/src/infrastructure/Mongoose.js'

View file

@ -1,49 +1,46 @@
const Path = require('path')
const express = require('express')
const Settings = require('@overleaf/settings')
const logger = require('@overleaf/logger')
const metrics = require('@overleaf/metrics')
const Validation = require('./Validation')
const csp = require('./CSP')
const Router = require('../router')
const helmet = require('helmet')
const UserSessionsRedis = require('../Features/User/UserSessionsRedis')
const Csrf = require('./Csrf')
const HttpPermissionsPolicyMiddleware = require('./HttpPermissionsPolicy')
import express from 'express'
import Settings from '@overleaf/settings'
import logger from '@overleaf/logger'
import metrics from '@overleaf/metrics'
import Validation from './Validation.js'
import csp from './CSP.js'
import Router from '../router.mjs'
import helmet from 'helmet'
import UserSessionsRedis from '../Features/User/UserSessionsRedis.js'
import Csrf from './Csrf.js'
import HttpPermissionsPolicyMiddleware from './HttpPermissionsPolicy.js'
import SessionAutostartMiddleware from './SessionAutostartMiddleware.js'
import AnalyticsManager from '../Features/Analytics/AnalyticsManager.js'
import session from 'express-session'
import CookieMetrics from './CookieMetrics.js'
import CustomSessionStore from './CustomSessionStore.js'
import bodyParser from './BodyParserWrapper.js'
import methodOverride from 'method-override'
import cookieParser from 'cookie-parser'
import bearerTokenMiddleware from 'express-bearer-token'
import passport from 'passport'
import { Strategy as LocalStrategy } from 'passport-local'
import ReferalConnect from '../Features/Referal/ReferalConnect.js'
import RedirectManager from './RedirectManager.js'
import translations from './Translations.js'
import Views from './Views.js'
import Features from './Features.js'
import ErrorController from '../Features/Errors/ErrorController.js'
import HttpErrorHandler from '../Features/Errors/HttpErrorHandler.js'
import UserSessionsManager from '../Features/User/UserSessionsManager.js'
import AuthenticationController from '../Features/Authentication/AuthenticationController.js'
import SessionManager from '../Features/Authentication/SessionManager.js'
import { hasAdminAccess } from '../Features/Helpers/AdminAuthorizationHelper.js'
import Modules from './Modules.js'
import expressLocals from './ExpressLocals.js'
import noCache from 'nocache'
import os from 'os'
import http from 'http'
import { fileURLToPath } from 'url'
const sessionsRedisClient = UserSessionsRedis.client()
const SessionAutostartMiddleware = require('./SessionAutostartMiddleware')
const AnalyticsManager = require('../Features/Analytics/AnalyticsManager')
const session = require('express-session')
const CookieMetrics = require('./CookieMetrics')
const CustomSessionStore = require('./CustomSessionStore')
const bodyParser = require('./BodyParserWrapper')
const methodOverride = require('method-override')
const cookieParser = require('cookie-parser')
const bearerTokenMiddleware = require('express-bearer-token')
const passport = require('passport')
const LocalStrategy = require('passport-local').Strategy
const oneDayInMilliseconds = 86400000
const ReferalConnect = require('../Features/Referal/ReferalConnect')
const RedirectManager = require('./RedirectManager')
const translations = require('./Translations')
const Views = require('./Views')
const Features = require('./Features')
const ErrorController = require('../Features/Errors/ErrorController')
const HttpErrorHandler = require('../Features/Errors/HttpErrorHandler')
const UserSessionsManager = require('../Features/User/UserSessionsManager')
const AuthenticationController = require('../Features/Authentication/AuthenticationController')
const SessionManager = require('../Features/Authentication/SessionManager')
const {
hasAdminAccess,
} = require('../Features/Helpers/AdminAuthorizationHelper')
const Modules = require('./Modules')
const expressLocals = require('./ExpressLocals')
const STATIC_CACHE_AGE = Settings.cacheStaticAssets
? oneDayInMilliseconds * 365
@ -67,7 +64,7 @@ if (Settings.behindProxy) {
* X-Original-Forwarded-For. Express expects all proxy IPs to be in a comma
* separated list in X-Forwarded-For.
*/
app.use(function getForwardedForHeader(req, res, next) {
app.use((req, res, next) => {
if (
req.headers['x-original-forwarded-for'] &&
req.headers['x-forwarded-for']
@ -92,7 +89,7 @@ const ORIGINAL_REQ_IP = Object.getOwnPropertyDescriptor(
Object.defineProperty(app.request, 'ip', {
configurable: true,
enumerable: true,
get: function ipWithCache() {
get() {
const ip = ORIGINAL_REQ_IP.call(this)
// Shadow the prototype level getter with a property on the instance.
// Any future access on `req.ip` will get served by the instance property.
@ -100,7 +97,8 @@ Object.defineProperty(app.request, 'ip', {
return ip
},
})
app.use(function ignoreAbortedConnections(req, res, next) {
app.use((req, res, next) => {
if (req.destroyed) {
// Request has been aborted already.
return
@ -114,20 +112,21 @@ app.use(function ignoreAbortedConnections(req, res, next) {
})
if (Settings.exposeHostname) {
const HOSTNAME = require('os').hostname()
app.use(function exposeHostname(req, res, next) {
const HOSTNAME = os.hostname()
app.use((req, res, next) => {
res.setHeader('X-Served-By', HOSTNAME)
next()
})
}
webRouter.use(
express.static(Path.join(__dirname, '/../../../public'), {
express.static(fileURLToPath(new URL('../../../public', import.meta.url)), {
maxAge: STATIC_CACHE_AGE,
setHeaders: csp.removeCSPHeaders,
})
)
app.set('views', Path.join(__dirname, '/../../views'))
app.set('views', fileURLToPath(new URL('../../views', import.meta.url)))
app.set('view engine', 'pug')
if (Settings.enabledServices.includes('web')) {
@ -144,7 +143,7 @@ if (Settings.enabledServices.includes('web')) {
app.use(metrics.http.monitor(logger))
Modules.applyMiddleware(app, 'appMiddleware')
await Modules.applyMiddleware(app, 'appMiddleware')
app.use(bodyParser.urlencoded({ extended: true, limit: '2mb' }))
app.use(bodyParser.json({ limit: Settings.max_json_request_size }))
app.use(methodOverride())
@ -160,7 +159,6 @@ if (Settings.useHttpPermissionsPolicy) {
Settings.httpPermissions
)
logger.debug('adding permissions policy config', Settings.httpPermissions)
webRouter.use(httpPermissionsPolicy.middleware)
}
@ -179,7 +177,7 @@ const sessionSecrets = [
webRouter.use(cookieParser(sessionSecrets))
webRouter.use(CookieMetrics.middleware)
SessionAutostartMiddleware.applyInitialMiddleware(webRouter)
Modules.applyMiddleware(webRouter, 'sessionMiddleware', {
await Modules.applyMiddleware(webRouter, 'sessionMiddleware', {
store: sessionStore,
})
webRouter.use(
@ -199,6 +197,7 @@ webRouter.use(
rolling: Settings.cookieRollingSession === true,
})
)
if (Features.hasFeature('saas')) {
webRouter.use(AnalyticsManager.analyticsIdMiddleware)
}
@ -220,13 +219,13 @@ passport.use(
passport.serializeUser(AuthenticationController.serializeUser)
passport.deserializeUser(AuthenticationController.deserializeUser)
Modules.hooks.fire('passportSetup', passport, function (err) {
Modules.hooks.fire('passportSetup', passport, err => {
if (err != null) {
logger.err({ err }, 'error setting up passport in modules')
}
})
Modules.applyNonCsrfRouter(webRouter, privateApiRouter, publicApiRouter)
await Modules.applyNonCsrfRouter(webRouter, privateApiRouter, publicApiRouter)
webRouter.csrf = new Csrf()
webRouter.use(webRouter.csrf.middleware)
@ -235,7 +234,7 @@ webRouter.use(translations.setLangBasedOnDomainMiddleware)
if (Settings.cookieRollingSession) {
// Measure expiry from last request, not last login
webRouter.use(function touchSession(req, res, next) {
webRouter.use((req, res, next) => {
if (!req.session.noSessionCallback) {
req.session.touch()
if (SessionManager.isUserLoggedIn(req.session)) {
@ -255,7 +254,6 @@ if (Settings.cookieRollingSession) {
webRouter.use(ReferalConnect.use)
expressLocals(webRouter, privateApiRouter, publicApiRouter)
webRouter.use(SessionAutostartMiddleware.invokeCallbackMiddleware)
webRouter.use(function checkIfSiteClosed(req, res, next) {
@ -281,8 +279,8 @@ webRouter.use(function checkIfEditorClosed(req, res, next) {
webRouter.use(AuthenticationController.validateAdmin)
// add security headers using Helmet
const noCacheMiddleware = require('nocache')()
webRouter.use(function addNoCacheHeader(req, res, next) {
const noCacheMiddleware = noCache()
webRouter.use((req, res, next) => {
const isProjectPage = /^\/project\/[a-f0-9]{24}$/.test(req.path)
if (isProjectPage) {
// always set no-cache headers on a project page, as it could be an anonymous token viewer
@ -319,6 +317,7 @@ webRouter.use(function addNoCacheHeader(req, res, next) {
// allow other responses (anonymous users, except for project pages) to be cached
return next()
})
webRouter.use(
helmet({
// note that more headers are added by default
@ -346,22 +345,21 @@ if (Settings.csp && Settings.csp.enabled) {
}
logger.debug('creating HTTP server'.yellow)
const server = require('http').createServer(app)
const server = http.createServer(app)
// provide settings for separate web and api processes
if (Settings.enabledServices.includes('api')) {
logger.debug('providing api router')
logger.debug({}, 'providing api router')
app.use(privateApiRouter)
app.use(Validation.errorMiddleware)
app.use(ErrorController.handleApiError)
}
if (Settings.enabledServices.includes('web')) {
logger.debug('providing web router')
logger.debug({}, 'providing web router')
app.use(publicApiRouter) // public API goes with web router for public access
app.use(Validation.errorMiddleware)
app.use(ErrorController.handleApiError)
app.use(webRouter)
app.use(Validation.errorMiddleware)
app.use(ErrorController.handleError)
@ -370,9 +368,6 @@ if (Settings.enabledServices.includes('web')) {
metrics.injectMetricsRoute(webRouter)
metrics.injectMetricsRoute(privateApiRouter)
Router.initialize(webRouter, privateApiRouter, publicApiRouter)
await Router.initialize(webRouter, privateApiRouter, publicApiRouter)
module.exports = {
app,
server,
}
export default { app, server }

View file

@ -1,76 +1,77 @@
const AdminController = require('./Features/ServerAdmin/AdminController')
const ErrorController = require('./Features/Errors/ErrorController')
const ProjectController = require('./Features/Project/ProjectController')
const ProjectApiController = require('./Features/Project/ProjectApiController')
const ProjectListController = require('./Features/Project/ProjectListController')
const SpellingController = require('./Features/Spelling/SpellingController')
const EditorRouter = require('./Features/Editor/EditorRouter')
const Settings = require('@overleaf/settings')
const TpdsController = require('./Features/ThirdPartyDataStore/TpdsController')
const SubscriptionRouter = require('./Features/Subscription/SubscriptionRouter')
const UploadsRouter = require('./Features/Uploads/UploadsRouter')
const metrics = require('@overleaf/metrics')
const ReferalController = require('./Features/Referal/ReferalController')
const AuthenticationController = require('./Features/Authentication/AuthenticationController')
const PermissionsController = require('./Features/Authorization/PermissionsController')
const SessionManager = require('./Features/Authentication/SessionManager')
const TagsController = require('./Features/Tags/TagsController')
const NotificationsController = require('./Features/Notifications/NotificationsController')
const CollaboratorsRouter = require('./Features/Collaborators/CollaboratorsRouter')
const UserInfoController = require('./Features/User/UserInfoController')
const UserController = require('./Features/User/UserController')
const UserEmailsController = require('./Features/User/UserEmailsController')
const UserPagesController = require('./Features/User/UserPagesController')
const TutorialController = require('./Features/Tutorial/TutorialController')
const DocumentController = require('./Features/Documents/DocumentController')
const CompileManager = require('./Features/Compile/CompileManager')
const CompileController = require('./Features/Compile/CompileController')
const ClsiCookieManager = require('./Features/Compile/ClsiCookieManager')(
Settings.apis.clsi != null ? Settings.apis.clsi.backendGroupName : undefined
)
const HealthCheckController = require('./Features/HealthCheck/HealthCheckController')
const ProjectDownloadsController = require('./Features/Downloads/ProjectDownloadsController')
const FileStoreController = require('./Features/FileStore/FileStoreController')
const DocumentUpdaterController = require('./Features/DocumentUpdater/DocumentUpdaterController')
const HistoryController = require('./Features/History/HistoryController')
const ExportsController = require('./Features/Exports/ExportsController')
const PasswordResetRouter = require('./Features/PasswordReset/PasswordResetRouter')
const StaticPagesRouter = require('./Features/StaticPages/StaticPagesRouter')
const ChatController = require('./Features/Chat/ChatController')
const Modules = require('./infrastructure/Modules')
const {
import AdminController from './Features/ServerAdmin/AdminController.js'
import ErrorController from './Features/Errors/ErrorController.js'
import Features from './infrastructure/Features.js'
import ProjectController from './Features/Project/ProjectController.js'
import ProjectApiController from './Features/Project/ProjectApiController.js'
import ProjectListController from './Features/Project/ProjectListController.js'
import SpellingController from './Features/Spelling/SpellingController.js'
import EditorRouter from './Features/Editor/EditorRouter.js'
import Settings from '@overleaf/settings'
import TpdsController from './Features/ThirdPartyDataStore/TpdsController.js'
import SubscriptionRouter from './Features/Subscription/SubscriptionRouter.js'
import UploadsRouter from './Features/Uploads/UploadsRouter.js'
import metrics from '@overleaf/metrics'
import ReferalController from './Features/Referal/ReferalController.js'
import AuthenticationController from './Features/Authentication/AuthenticationController.js'
import PermissionsController from './Features/Authorization/PermissionsController.js'
import SessionManager from './Features/Authentication/SessionManager.js'
import TagsController from './Features/Tags/TagsController.js'
import NotificationsController from './Features/Notifications/NotificationsController.js'
import CollaboratorsRouter from './Features/Collaborators/CollaboratorsRouter.js'
import UserInfoController from './Features/User/UserInfoController.js'
import UserController from './Features/User/UserController.js'
import UserEmailsController from './Features/User/UserEmailsController.js'
import UserPagesController from './Features/User/UserPagesController.js'
import TutorialController from './Features/Tutorial/TutorialController.js'
import DocumentController from './Features/Documents/DocumentController.js'
import CompileManager from './Features/Compile/CompileManager.js'
import CompileController from './Features/Compile/CompileController.js'
import ClsiCookieManagerFactory from './Features/Compile/ClsiCookieManager.js'
import HealthCheckController from './Features/HealthCheck/HealthCheckController.js'
import ProjectDownloadsController from './Features/Downloads/ProjectDownloadsController.js'
import FileStoreController from './Features/FileStore/FileStoreController.js'
import DocumentUpdaterController from './Features/DocumentUpdater/DocumentUpdaterController.js'
import HistoryController from './Features/History/HistoryController.js'
import ExportsController from './Features/Exports/ExportsController.js'
import PasswordResetRouter from './Features/PasswordReset/PasswordResetRouter.js'
import StaticPagesRouter from './Features/StaticPages/StaticPagesRouter.js'
import ChatController from './Features/Chat/ChatController.js'
import Modules from './infrastructure/Modules.js'
import {
RateLimiter,
openProjectRateLimiter,
overleafLoginRateLimiter,
} = require('./infrastructure/RateLimiter')
const RateLimiterMiddleware = require('./Features/Security/RateLimiterMiddleware')
const InactiveProjectController = require('./Features/InactiveData/InactiveProjectController')
const ContactRouter = require('./Features/Contacts/ContactRouter')
const ReferencesController = require('./Features/References/ReferencesController')
const AuthorizationMiddleware = require('./Features/Authorization/AuthorizationMiddleware')
const BetaProgramController = require('./Features/BetaProgram/BetaProgramController')
const AnalyticsRouter = require('./Features/Analytics/AnalyticsRouter')
const MetaController = require('./Features/Metadata/MetaController')
const TokenAccessController = require('./Features/TokenAccess/TokenAccessController')
const TokenAccessRouter = require('./Features/TokenAccess/TokenAccessRouter')
const Features = require('./infrastructure/Features')
const LinkedFilesRouter = require('./Features/LinkedFiles/LinkedFilesRouter')
const TemplatesRouter = require('./Features/Templates/TemplatesRouter')
const UserMembershipRouter = require('./Features/UserMembership/UserMembershipRouter')
const SystemMessageController = require('./Features/SystemMessages/SystemMessageController')
const AnalyticsRegistrationSourceMiddleware = require('./Features/Analytics/AnalyticsRegistrationSourceMiddleware')
const AnalyticsUTMTrackingMiddleware = require('./Features/Analytics/AnalyticsUTMTrackingMiddleware')
const CaptchaMiddleware = require('./Features/Captcha/CaptchaMiddleware')
const { Joi, validate } = require('./infrastructure/Validation')
const {
} from './infrastructure/RateLimiter.js'
import RateLimiterMiddleware from './Features/Security/RateLimiterMiddleware.js'
import InactiveProjectController from './Features/InactiveData/InactiveProjectController.js'
import ContactRouter from './Features/Contacts/ContactRouter.js'
import ReferencesController from './Features/References/ReferencesController.js'
import AuthorizationMiddleware from './Features/Authorization/AuthorizationMiddleware.js'
import BetaProgramController from './Features/BetaProgram/BetaProgramController.js'
import AnalyticsRouter from './Features/Analytics/AnalyticsRouter.js'
import MetaController from './Features/Metadata/MetaController.js'
import TokenAccessController from './Features/TokenAccess/TokenAccessController.js'
import TokenAccessRouter from './Features/TokenAccess/TokenAccessRouter.js'
import LinkedFilesRouter from './Features/LinkedFiles/LinkedFilesRouter.js'
import TemplatesRouter from './Features/Templates/TemplatesRouter.js'
import UserMembershipRouter from './Features/UserMembership/UserMembershipRouter.js'
import SystemMessageController from './Features/SystemMessages/SystemMessageController.js'
import AnalyticsRegistrationSourceMiddleware from './Features/Analytics/AnalyticsRegistrationSourceMiddleware.js'
import AnalyticsUTMTrackingMiddleware from './Features/Analytics/AnalyticsUTMTrackingMiddleware.js'
import CaptchaMiddleware from './Features/Captcha/CaptchaMiddleware.js'
import { Joi, validate } from './infrastructure/Validation.js'
import {
renderUnsupportedBrowserPage,
unsupportedBrowserMiddleware,
} = require('./infrastructure/UnsupportedBrowserMiddleware')
} from './infrastructure/UnsupportedBrowserMiddleware.js'
const logger = require('@overleaf/logger')
const _ = require('lodash')
const { plainTextResponse } = require('./infrastructure/Response')
const PublicAccessLevels = require('./Features/Authorization/PublicAccessLevels')
import logger from '@overleaf/logger'
import _ from 'lodash'
import { plainTextResponse } from './infrastructure/Response.js'
import PublicAccessLevels from './Features/Authorization/PublicAccessLevels.js'
const ClsiCookieManager = ClsiCookieManagerFactory(
Settings.apis.clsi != null ? Settings.apis.clsi.backendGroupName : undefined
)
const rateLimiters = {
addEmail: new RateLimiter('add-email', {
@ -212,7 +213,7 @@ const rateLimiters = {
}),
}
function initialize(webRouter, privateApiRouter, publicApiRouter) {
async function initialize(webRouter, privateApiRouter, publicApiRouter) {
webRouter.use(unsupportedBrowserMiddleware)
if (!Settings.allowPublicAccess) {
@ -291,7 +292,7 @@ function initialize(webRouter, privateApiRouter, publicApiRouter) {
UserMembershipRouter.apply(webRouter)
TokenAccessRouter.apply(webRouter)
Modules.applyRouter(webRouter, privateApiRouter, publicApiRouter)
await Modules.applyRouter(webRouter, privateApiRouter, publicApiRouter)
if (Settings.enableSubscriptions) {
webRouter.get(
@ -1377,4 +1378,4 @@ function initialize(webRouter, privateApiRouter, publicApiRouter) {
webRouter.get('*', ErrorController.notFound)
}
module.exports = { initialize, rateLimiters }
export default { initialize, rateLimiters }