diff --git a/Common/sources/notificationService.js b/Common/sources/notificationService.js index 67541e9d..1d93356c 100644 --- a/Common/sources/notificationService.js +++ b/Common/sources/notificationService.js @@ -38,6 +38,8 @@ const mailService = require('./mailService'); const cfgEditorDataStorage = config.get('services.CoAuthoring.server.editorDataStorage'); const cfgEditorStatStorage = config.get('services.CoAuthoring.server.editorStatStorage'); +const cfgSmtpServerConfiguration = config.get('email.smtpServerConfiguration'); +const cfgContactDefaults = config.get('email.contactDefaults'); const editorStatStorage = require('./../../DocService/sources/' + (cfgEditorStatStorage || cfgEditorDataStorage)); const editorStat = editorStatStorage.EditorStat ? new editorStatStorage.EditorStat() : new editorStatStorage(); @@ -57,11 +59,11 @@ class MailTransport extends TransportInterface { constructor(ctx) { super(); - const mailServerConfig = ctx.getCfg('email.smtpServerConfiguration'); + const mailServerConfig = ctx.getCfg('email.smtpServerConfiguration', cfgSmtpServerConfiguration); this.host = mailServerConfig.host; this.port = mailServerConfig.port; this.auth = mailServerConfig.auth; - const cfgMailMessageDefaults = ctx.getCfg('email.contactDefaults'); + const cfgMailMessageDefaults = ctx.getCfg('email.contactDefaults', cfgContactDefaults); mailService.createTransporter(ctx, this.host, this.port, this.auth, cfgMailMessageDefaults); } diff --git a/DocService/sources/DocsCoServer.js b/DocService/sources/DocsCoServer.js index 369f5958..ba430cbf 100644 --- a/DocService/sources/DocsCoServer.js +++ b/DocService/sources/DocsCoServer.js @@ -4695,6 +4695,15 @@ exports.shutdown = function (req, res) { } }); }; +/** + * Get active connections array + * @returns {Array} Active connections + */ +function getConnections() { + return connections; +} + +exports.getConnections = getConnections; exports.getEditorConnectionsCount = function (req, res) { const ctx = new operationContext.Context(); let count = 0; diff --git a/DocService/sources/ai/aiProxyHandler.js b/DocService/sources/ai/aiProxyHandler.js index 0b948b74..72779a06 100644 --- a/DocService/sources/ai/aiProxyHandler.js +++ b/DocService/sources/ai/aiProxyHandler.js @@ -353,10 +353,13 @@ async function getPluginSettingsForInterface(ctx) { pluginSettings = undefined; } } - //remove keys from providers - if (pluginSettings && pluginSettings.providers) { + //remove keys from providers - create deep copy to avoid modifying cached config + if (pluginSettings?.providers) { for (const key in pluginSettings.providers) { - pluginSettings.providers[key].key = ''; + if (pluginSettings.providers[key]?.key) { + pluginSettings.providers[key] = JSON.parse(JSON.stringify(pluginSettings.providers[key])); + pluginSettings.providers[key].key = ''; + } } } return pluginSettings; diff --git a/DocService/sources/routes/info.js b/DocService/sources/routes/info.js index fd48cfe9..faa9b67f 100644 --- a/DocService/sources/routes/info.js +++ b/DocService/sources/routes/info.js @@ -54,8 +54,9 @@ function getLicenseNowUtc() { * License info endpoint handler * @param {import('express').Request} req Express request * @param {import('express').Response} res Express response + * @param {Function} getConnections Function to get active connections */ -async function licenseInfo(req, res) { +async function licenseInfo(req, res, getConnections = null) { let isError = false; const serverDate = new Date(); // Security risk of high-precision time @@ -174,7 +175,8 @@ async function licenseInfo(req, res) { const nowUTC = getLicenseNowUtc(); let execRes; execRes = await editorStat.getPresenceUniqueUser(ctx, nowUTC); - output.quota.edit.connectionsCount = await editorStat.getEditorConnectionsCount(ctx, {}); + const connections = getConnections ? getConnections() : null; + output.quota.edit.connectionsCount = await editorStat.getEditorConnectionsCount(ctx, connections); output.quota.edit.usersCount.unique = execRes.length; execRes.forEach(elem => { if (elem.anonym) { @@ -183,7 +185,7 @@ async function licenseInfo(req, res) { }); execRes = await editorStat.getPresenceUniqueViewUser(ctx, nowUTC); - output.quota.view.connectionsCount = await editorStat.getLiveViewerConnectionsCount(ctx, {}); + output.quota.view.connectionsCount = await editorStat.getLiveViewerConnectionsCount(ctx, connections); output.quota.view.usersCount.unique = execRes.length; execRes.forEach(elem => { if (elem.anonym) { @@ -218,24 +220,29 @@ async function licenseInfo(req, res) { isError = true; ctx.logger.error('licenseInfo error %s', err.stack); } finally { - if (!isError) { - res.setHeader('Content-Type', 'application/json'); - res.send(JSON.stringify(output)); - } else { - res.sendStatus(400); + if (!res.headersSent) { + if (!isError) { + res.setHeader('Content-Type', 'application/json'); + res.send(JSON.stringify(output)); + } else { + res.sendStatus(400); + } } } } /** * Create shared Info router + * @param {Function} getConnections Optional function to get active connections * @returns {import('express').Router} Router instance */ -function createInfoRouter() { +function createInfoRouter(getConnections = null) { const router = express.Router(); // License info endpoint with CORS and client IP check - router.get('/info.json', cors(), utils.checkClientIp, licenseInfo); + router.get('/info.json', cors(), utils.checkClientIp, async (req, res) => { + await licenseInfo(req, res, getConnections); + }); return router; } diff --git a/DocService/sources/server.js b/DocService/sources/server.js index d1154530..a5773a20 100644 --- a/DocService/sources/server.js +++ b/DocService/sources/server.js @@ -295,7 +295,7 @@ docsCoServer.install(server, app, () => { converterService.builder(req, res); }); // Shared Info router (provides /info.json) - app.use('/info', infoRouter()); + app.use('/info', infoRouter(docsCoServer.getConnections)); app.put('/internal/cluster/inactive', utils.checkClientIp, docsCoServer.shutdown); app.delete('/internal/cluster/inactive', utils.checkClientIp, docsCoServer.shutdown); app.get('/internal/connections/edit', docsCoServer.getEditorConnectionsCount);