diff --git a/AdminPanel/client/public/index.html b/AdminPanel/client/public/index.html
index 9ae0a010..8352f721 100644
--- a/AdminPanel/client/public/index.html
+++ b/AdminPanel/client/public/index.html
@@ -6,7 +6,7 @@
-
ONLIOFFICE Admin
+ ONLYOFFICE Admin
diff --git a/AdminPanel/client/src/api/index.js b/AdminPanel/client/src/api/index.js
index e9867873..1cddad45 100644
--- a/AdminPanel/client/src/api/index.js
+++ b/AdminPanel/client/src/api/index.js
@@ -62,9 +62,12 @@ export const updateConfiguration = async configData => {
export const fetchCurrentUser = async () => {
const response = await safeFetch(`${BACKEND_URL}${API_BASE_PATH}/me`, {credentials: 'include'});
- if (response.status === 401) throw new Error('Unauthorized');
if (!response.ok) throw new Error('Failed to fetch current user');
- return response.json();
+ const data = await response.json();
+ if (data && data.authorized === false) {
+ throw new Error('Unauthorized');
+ }
+ return data;
};
export const checkSetupRequired = async () => {
diff --git a/AdminPanel/client/src/pages/AiIntegration/hooks/useAiPlugin.js b/AdminPanel/client/src/pages/AiIntegration/hooks/useAiPlugin.js
index a25e9104..88d11f3c 100644
--- a/AdminPanel/client/src/pages/AiIntegration/hooks/useAiPlugin.js
+++ b/AdminPanel/client/src/pages/AiIntegration/hooks/useAiPlugin.js
@@ -29,7 +29,6 @@ const useAiPlugin = statisticsData => {
}
initAISettings(iframeId, sdkVersion);
- console.log('AI Settings initialized with version:', sdkVersion);
},
[statisticsData]
);
@@ -50,7 +49,6 @@ const useAiPlugin = statisticsData => {
return () => {
localStorage.removeItem('onlyoffice_ai_actions_key');
localStorage.removeItem('onlyoffice_ai_plugin_storage_key');
- console.log('AI configuration cleared from localStorage');
};
}, [config?.aiSettings]);
@@ -62,7 +60,6 @@ const useAiPlugin = statisticsData => {
* @param {Object} config - Window configuration
*/
const handleShowWindow = (iframeId, config) => {
- console.log('showPluginWindow', iframeId, config);
setPluginWindows(current => {
// Avoid duplicate windows with same iframeId
const filtered = current.filter(w => w.iframeId !== iframeId);
@@ -118,9 +115,6 @@ const useAiPlugin = statisticsData => {
// Save configuration using Redux action
dispatch(saveConfig(configToSave));
- console.log('AI configuration saved successfully', updatedAiSettings);
- } else {
- console.log('No AI configuration found in localStorage');
}
} catch (error) {
console.error('Error saving AI configuration:', error);
diff --git a/AdminPanel/client/src/pages/RequestFiltering/RequestFiltering.js b/AdminPanel/client/src/pages/RequestFiltering/RequestFiltering.js
index f9313aad..f9050987 100644
--- a/AdminPanel/client/src/pages/RequestFiltering/RequestFiltering.js
+++ b/AdminPanel/client/src/pages/RequestFiltering/RequestFiltering.js
@@ -23,8 +23,8 @@ function RequestFiltering() {
// Configuration paths
const CONFIG_PATHS = {
- allowPrivateIPAddress: 'request-filtering-agent.allowPrivateIPAddress',
- allowMetaIPAddress: 'request-filtering-agent.allowMetaIPAddress'
+ allowPrivateIPAddress: 'services.CoAuthoring.request-filtering-agent.allowPrivateIPAddress',
+ allowMetaIPAddress: 'services.CoAuthoring.request-filtering-agent.allowMetaIPAddress'
};
const hasInitialized = useRef(false);
diff --git a/AdminPanel/client/src/pages/Setup/styles.module.css b/AdminPanel/client/src/pages/Setup/styles.module.css
index 28e51e59..0faf996e 100644
--- a/AdminPanel/client/src/pages/Setup/styles.module.css
+++ b/AdminPanel/client/src/pages/Setup/styles.module.css
@@ -13,6 +13,9 @@
width: 100%;
max-width: 500px;
text-align: center;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
}
.title {
diff --git a/AdminPanel/server/sources/jwtSecret.js b/AdminPanel/server/sources/jwtSecret.js
new file mode 100644
index 00000000..9cf09be2
--- /dev/null
+++ b/AdminPanel/server/sources/jwtSecret.js
@@ -0,0 +1,12 @@
+'use strict';
+
+const crypto = require('crypto');
+
+//todo Need common secret in case of cluster deployment
+// const config = require('config');
+// const adminPanelJwtSecret = config.get('adminPanel.secret');
+
+// Generate random JWT secret once for cluster deployment
+const adminPanelJwtSecret = crypto.randomBytes(64).toString('hex');
+
+module.exports = adminPanelJwtSecret;
diff --git a/AdminPanel/server/sources/middleware/auth.js b/AdminPanel/server/sources/middleware/auth.js
index b34a30af..4104511b 100644
--- a/AdminPanel/server/sources/middleware/auth.js
+++ b/AdminPanel/server/sources/middleware/auth.js
@@ -1,10 +1,8 @@
'use strict';
-const config = require('config');
const jwt = require('jsonwebtoken');
const operationContext = require('../../../../Common/sources/operationContext');
-
-const adminPanelJwtSecret = config.get('adminPanel.secret');
+const adminPanelJwtSecret = require('../jwtSecret');
/**
* JWT Authentication Middleware
diff --git a/AdminPanel/server/sources/routes/adminpanel/router.js b/AdminPanel/server/sources/routes/adminpanel/router.js
index bbdffa8b..4f0d1410 100644
--- a/AdminPanel/server/sources/routes/adminpanel/router.js
+++ b/AdminPanel/server/sources/routes/adminpanel/router.js
@@ -1,13 +1,11 @@
'use strict';
-const config = require('config');
const express = require('express');
const jwt = require('jsonwebtoken');
const cookieParser = require('cookie-parser');
const operationContext = require('../../../../../Common/sources/operationContext');
const passwordManager = require('../../passwordManager');
const bootstrap = require('../../bootstrap');
-
-const adminPanelJwtSecret = config.get('adminPanel.secret');
+const adminPanelJwtSecret = require('../../jwtSecret');
const router = express.Router();
@@ -170,8 +168,17 @@ router.post('/change-password', requireAuth, async (req, res) => {
}
});
-router.get('/me', requireAuth, (req, res) => {
- res.json(req.user);
+router.get('/me', (req, res) => {
+ try {
+ const token = req.cookies?.accessToken;
+ if (!token) {
+ return res.json({authorized: false});
+ }
+ const decoded = jwt.verify(token, adminPanelJwtSecret);
+ return res.json({authorized: true, ...decoded});
+ } catch {
+ return res.json({authorized: false});
+ }
});
router.post('/login', async (req, res) => {
diff --git a/Common/config/default.json b/Common/config/default.json
index bbc483b8..31526446 100644
--- a/Common/config/default.json
+++ b/Common/config/default.json
@@ -1,6 +1,5 @@
{
"adminPanel": {
- "secret": "secret",
"port": 9000
},
"statsd": {
diff --git a/Common/config/schemas/config.schema.json b/Common/config/schemas/config.schema.json
index 2edb94f6..fd1295db 100644
--- a/Common/config/schemas/config.schema.json
+++ b/Common/config/schemas/config.schema.json
@@ -87,6 +87,21 @@
"sessionabsolute": {"type": "string", "x-scope": ["admin", "tenant"]}
}
},
+ "request-filtering-agent": {
+ "type": "object",
+ "additionalProperties": false,
+ "x-scope": ["admin", "tenant"],
+ "properties": {
+ "allowPrivateIPAddress": {
+ "type": "boolean",
+ "description": "Whether to allow requests from private IP addresses"
+ },
+ "allowMetaIPAddress": {
+ "type": "boolean",
+ "description": "Whether to allow requests from meta IP addresses"
+ }
+ }
+ },
"autoAssembly": {
"type": "object",
"additionalProperties": false,
@@ -165,21 +180,6 @@
}
}
},
- "request-filtering-agent": {
- "type": "object",
- "additionalProperties": false,
- "x-scope": ["admin", "tenant"],
- "properties": {
- "allowPrivateIPAddress": {
- "type": "boolean",
- "description": "Whether to allow requests from private IP addresses"
- },
- "allowMetaIPAddress": {
- "type": "boolean",
- "description": "Whether to allow requests from meta IP addresses"
- }
- }
- },
"FileConverter": {
"type": "object",
"additionalProperties": false,
diff --git a/DocService/sources/canvasservice.js b/DocService/sources/canvasservice.js
index 71ce3e42..5a1815fe 100644
--- a/DocService/sources/canvasservice.js
+++ b/DocService/sources/canvasservice.js
@@ -303,6 +303,28 @@ async function getOutputData(ctx, cmd, outputData, key, optConn, optAdditionalOu
//this status has no handler
break;
case commonDefines.FileStatus.WaitQueue:
+ {
+ const timeout = await utils.getConvertionTimeout(ctx);
+ console.log(timeout);
+ console.log(statusInfo);
+ console.log(Date.now() - statusInfo * 60000);
+ console.log(Date.now() - statusInfo * 60000 > timeout);
+ if (Date.now() - statusInfo * 60000 > timeout) {
+ ctx.logger.warn('WaitQueue expired');
+ const updateMask = new taskResult.TaskResultData();
+ updateMask.tenant = ctx.tenant;
+ updateMask.key = key;
+ updateMask.status = status;
+ updateMask.statusInfo = statusInfo;
+ const updateTask = new taskResult.TaskResultData();
+ updateTask.status = commonDefines.FileStatus.None;
+ updateTask.statusInfo = constants.NO_ERROR;
+ const updateIfRes = await taskResult.updateIf(ctx, updateTask, updateMask);
+ if (updateIfRes.affectedRows > 0) {
+ status = commonDefines.FileStatus.None;
+ }
+ }
+ }
//task in the queue. response will be after convertion
break;
default:
@@ -514,7 +536,7 @@ function* commandOpen(ctx, conn, cmd, outputData, opt_upsertRes, opt_bIsRestore)
const task = new taskResult.TaskResultData();
task.status = commonDefines.FileStatus.WaitQueue;
- task.statusInfo = constants.NO_ERROR;
+ task.statusInfo = Math.floor(Date.now() / 60000); //minutes
const updateIfRes = yield taskResult.updateIf(ctx, task, updateMask);
if (updateIfRes.affectedRows > 0) {
@@ -570,7 +592,7 @@ function* commandReopen(ctx, conn, cmd, outputData) {
const task = new taskResult.TaskResultData();
task.status = commonDefines.FileStatus.WaitQueue;
- task.statusInfo = constants.NO_ERROR;
+ task.statusInfo = Math.floor(Date.now() / 60000); //minutes
const upsertRes = yield taskResult.updateIf(ctx, task, updateMask);
if (upsertRes.affectedRows > 0) {
diff --git a/DocService/sources/converterservice.js b/DocService/sources/converterservice.js
index 54b2b02c..385273d3 100644
--- a/DocService/sources/converterservice.js
+++ b/DocService/sources/converterservice.js
@@ -137,7 +137,7 @@ function* convertByCmd(ctx, cmd, async, opt_fileTo, opt_taskExist, opt_priority,
task.tenant = ctx.tenant;
task.key = docId;
task.status = commonDefines.FileStatus.WaitQueue;
- task.statusInfo = constants.NO_ERROR;
+ task.statusInfo = Math.floor(Date.now() / 60000); //minutes
const upsertRes = yield taskResult.upsert(ctx, task);
bCreate = upsertRes.isInsert;
diff --git a/DocService/sources/taskresult.js b/DocService/sources/taskresult.js
index 46f84a4c..22c75a35 100644
--- a/DocService/sources/taskresult.js
+++ b/DocService/sources/taskresult.js
@@ -297,6 +297,7 @@ function* addRandomKeyTask(ctx, key, opt_prefix, opt_size) {
task.tenant = ctx.tenant;
task.key = key;
task.status = commonDefines.FileStatus.WaitQueue;
+ task.statusInfo = Math.floor(Date.now() / 60000); //minutes
//nTryCount so as not to freeze if there are really problems with the DB
let nTryCount = RANDOM_KEY_MAX;
let addRes = null;