mirror of
https://github.com/ONLYOFFICE/server.git
synced 2026-02-10 18:05:07 +08:00
Merge pull request 'fix/admin-panel-bugs-2' (#71) from fix/admin-panel-bugs-2 into release/v9.1.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/server/pulls/71
This commit is contained in:
@ -6,7 +6,7 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta name="description" content="Document Server Admin Panel" />
|
||||
<title>ONLIOFFICE Admin</title>
|
||||
<title>ONLYOFFICE Admin</title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
|
||||
@ -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 () => {
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -13,6 +13,9 @@
|
||||
width: 100%;
|
||||
max-width: 500px;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.title {
|
||||
|
||||
12
AdminPanel/server/sources/jwtSecret.js
Normal file
12
AdminPanel/server/sources/jwtSecret.js
Normal file
@ -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;
|
||||
@ -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
|
||||
|
||||
@ -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) => {
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
{
|
||||
"adminPanel": {
|
||||
"secret": "secret",
|
||||
"port": 9000
|
||||
},
|
||||
"statsd": {
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
Reference in New Issue
Block a user