Files
overleaf-cep/services/web/app/src/Features/ServerAdmin/AdminController.mjs
Maria Florencia Besteiro Gonzalez a76f0ee9f4 Merge pull request #31247 from overleaf/revert-31216-revert-30418-mfb-improve-handling-of-debug-copies-of-user-projects
Revert "Revert "Add isDebugCopyOf property to project, add Debug tag to debug project.""

GitOrigin-RevId: 2ed41ec4504ccd8b6ec9cb1d23a9d217079d4347
2026-02-04 09:06:44 +00:00

115 lines
3.4 KiB
JavaScript

import logger from '@overleaf/logger'
import http from 'node:http'
import https from 'node:https'
import Settings from '@overleaf/settings'
import TpdsUpdateSender from '../ThirdPartyDataStore/TpdsUpdateSender.mjs'
import TpdsProjectFlusher from '../ThirdPartyDataStore/TpdsProjectFlusher.mjs'
import EditorRealTimeController from '../Editor/EditorRealTimeController.mjs'
import SystemMessageManager from '../SystemMessages/SystemMessageManager.mjs'
import ProjectGetter from '../Project/ProjectGetter.mjs'
import Modules from '../../infrastructure/Modules.mjs'
import Features from '../../infrastructure/Features.mjs'
import { expressify } from '@overleaf/promise-utils'
const AdminController = {
_sendDisconnectAllUsersMessage: delay => {
return EditorRealTimeController.emitToAll(
'forceDisconnect',
'Sorry, we are performing a quick update to the editor and need to close it down. Please refresh the page to continue.',
delay
)
},
index: expressify(async (req, res, next) => {
let url
const openSockets = {}
for (url in http.globalAgent.sockets) {
openSockets[`http://${url}`] = http.globalAgent.sockets[url].map(
socket => socket._httpMessage.path
)
}
for (url in https.globalAgent.sockets) {
openSockets[`https://${url}`] = https.globalAgent.sockets[url].map(
socket => socket._httpMessage.path
)
}
const systemMessages =
await SystemMessageManager.promises.getMessagesFromDB()
const privilegesMatrixResults = await Modules.promises.hooks.fire(
'getPrivilegesMatrix'
)
const privilegesMatrix = privilegesMatrixResults[0] || null
const toRender = {
title: 'System Admin',
openSockets,
systemMessages,
privilegesMatrix,
}
if (Features.hasFeature('saas')) {
const debugProjects = await ProjectGetter.promises.findAllDebugProjects(
'name lastUpdated owner_ref'
)
toRender.debugProjects = debugProjects
}
res.render('admin/index', toRender)
}),
disconnectAllUsers: (req, res) => {
logger.warn('disconecting everyone')
const delay = (req.query && req.query.delay) > 0 ? req.query.delay : 10
AdminController._sendDisconnectAllUsersMessage(delay)
res.redirect('/admin#open-close-editor')
},
openEditor(req, res) {
logger.warn('opening editor')
Settings.editorIsOpen = true
res.redirect('/admin#open-close-editor')
},
closeEditor(req, res) {
logger.warn('closing editor')
Settings.editorIsOpen = req.body.isOpen
res.redirect('/admin#open-close-editor')
},
flushProjectToTpds(req, res, next) {
TpdsProjectFlusher.flushProjectToTpds(req.body.project_id, error => {
if (error) {
return next(error)
}
res.sendStatus(200)
})
},
pollDropboxForUser(req, res) {
const { user_id: userId } = req.body
TpdsUpdateSender.pollDropboxForUser(userId, () => res.sendStatus(200))
},
createMessage(req, res, next) {
SystemMessageManager.createMessage(req.body.content, function (error) {
if (error) {
return next(error)
}
res.redirect('/admin#system-messages')
})
},
clearMessages(req, res, next) {
SystemMessageManager.clearMessages(function (error) {
if (error) {
return next(error)
}
res.redirect('/admin#system-messages')
})
},
}
export default AdminController