[web] add config option for custom maintenance message (#27618)

GitOrigin-RevId: e01eebecce780af6e9e3f8b82321cb7776d414e2
This commit is contained in:
Jakob Ackermann
2025-08-12 11:01:25 +02:00
committed by Copybot
parent e7d8bf8aec
commit e4b42705c3
4 changed files with 53 additions and 4 deletions

View File

@@ -188,6 +188,8 @@ const settings = {
// Add https:// protocol prefix if not set (Allow plain-text http:// for Server Pro/CE).
(process.env.OVERLEAF_STATUS_PAGE_URL.startsWith('http://') || process.env.OVERLEAF_STATUS_PAGE_URL.startsWith('https://')) ? process.env.OVERLEAF_STATUS_PAGE_URL : `https://${process.env.OVERLEAF_STATUS_PAGE_URL}`
: undefined,
maintenanceMessage: process.env.OVERLEAF_MAINTENANCE_MESSAGE,
maintenanceMessageHTML: process.env.OVERLEAF_MAINTENANCE_MESSAGE_HTML,
// The name this is used to describe your Overleaf Community Edition Installation
appName: process.env.OVERLEAF_APP_NAME || 'Overleaf Community Edition',

View File

@@ -144,9 +144,12 @@ module.exports = HttpErrorHandler = {
} else {
res.status(503)
}
let message = `${Settings.appName} is currently down for maintenance.`
if (Settings.statusPageUrl) {
message += ` Please check ${Settings.statusPageUrl} for updates.`
let message = Settings.maintenanceMessage
if (!message) {
message = `${Settings.appName} is currently down for maintenance.`
if (Settings.statusPageUrl) {
message += ` Please check ${Settings.statusPageUrl} for updates.`
}
}
switch (req.accepts(['html', 'json'])) {
case 'html':

View File

@@ -8,7 +8,11 @@ block content
.page-header
h1 Maintenance
p
if settings.statusPageUrl
if settings.maintenanceMessageHTML
| !{settings.maintenanceMessageHTML}
else if settings.maintenanceMessage
| #{settings.maintenanceMessage}
else if settings.statusPageUrl
| #{settings.appName} is currently down for maintenance.
| Please check our #[a(href=settings.statusPageUrl target='_blank') status page]
| for updates.

View File

@@ -15,6 +15,11 @@ import Settings from '@overleaf/settings'
import request from './helpers/request.js'
describe('siteIsOpen', function () {
afterEach(function () {
delete Settings.maintenanceMessage
delete Settings.maintenanceMessageHTML
})
describe('when siteIsOpen is default (true)', function () {
it('should get page', function (done) {
return request.get('/login', (error, response, body) => {
@@ -41,6 +46,29 @@ describe('siteIsOpen', function () {
})
})
it('should return a custom message on maintenance page', function (done) {
const message = `Hello world (${Math.random()})`
Settings.maintenanceMessage = message
request.get('/login', (error, response, body) => {
response.statusCode.should.equal(503)
body.should.contain(message)
done()
})
})
it('should return a custom HTML message on maintenance page', function (done) {
const message = `Hello world (${Math.random()})`
const messageHTML = `<p style="color: ghostwhite">Hello world (${Math.random()})</p>`
Settings.maintenanceMessage = message
Settings.maintenanceMessageHTML = messageHTML
request.get('/login', (error, response, body) => {
response.statusCode.should.equal(503)
body.should.not.contain(message)
body.should.contain(messageHTML)
done()
})
})
it('should return a plain text message for a json request', function (done) {
request.get('/some/route', { json: true }, (error, response, body) => {
response.statusCode.should.equal(503)
@@ -50,6 +78,18 @@ describe('siteIsOpen', function () {
})
})
it('should return a custom message for a json request', function (done) {
const message = `Hello world (${Math.random()})`
const messageHTML = `<p style="color: ghostwhite">Hello world (${Math.random()})</p>`
Settings.maintenanceMessage = message
Settings.maintenanceMessageHTML = messageHTML
request.get('/some/route', { json: true }, (error, response, body) => {
response.statusCode.should.equal(503)
body.message.should.equal(message)
done()
})
})
it('should return a 200 on / for load balancer health checks', function (done) {
request.get('/', (error, response, body) => {
response.statusCode.should.equal(200)