mirror of
https://github.com/ONLYOFFICE/server.git
synced 2026-04-07 14:04:35 +08:00
[feature] Add 'aiSettings.proxy' to support routing AI requests via proxy
This commit is contained in:
@ -17,6 +17,7 @@
|
|||||||
"allowedCorsOrigins": [
|
"allowedCorsOrigins": [
|
||||||
"https://onlyoffice.github.io", "https://onlyoffice-plugins.github.io"
|
"https://onlyoffice.github.io", "https://onlyoffice-plugins.github.io"
|
||||||
],
|
],
|
||||||
|
"proxy": "",
|
||||||
"pluginDir" : "../branding/info/ai"
|
"pluginDir" : "../branding/info/ai"
|
||||||
},
|
},
|
||||||
"log": {
|
"log": {
|
||||||
|
|||||||
@ -38,6 +38,7 @@ const config = require('config');
|
|||||||
const utils = require('./../../../Common/sources/utils');
|
const utils = require('./../../../Common/sources/utils');
|
||||||
const operationContext = require('./../../../Common/sources/operationContext');
|
const operationContext = require('./../../../Common/sources/operationContext');
|
||||||
const commonDefines = require('./../../../Common/sources/commondefines');
|
const commonDefines = require('./../../../Common/sources/commondefines');
|
||||||
|
const tenantManager = require('./../../../Common/sources/tenantManager');
|
||||||
const docsCoServer = require('./../DocsCoServer');
|
const docsCoServer = require('./../DocsCoServer');
|
||||||
const statsDClient = require('./../../../Common/sources/statsdclient');
|
const statsDClient = require('./../../../Common/sources/statsdclient');
|
||||||
|
|
||||||
@ -45,8 +46,12 @@ const statsDClient = require('./../../../Common/sources/statsdclient');
|
|||||||
const aiEngine = require('./aiEngineWrapper');
|
const aiEngine = require('./aiEngineWrapper');
|
||||||
|
|
||||||
const cfgAiApiAllowedOrigins = config.get('aiSettings.allowedCorsOrigins');
|
const cfgAiApiAllowedOrigins = config.get('aiSettings.allowedCorsOrigins');
|
||||||
|
const cfgAiApiProxy = config.get('aiSettings.proxy');
|
||||||
const cfgAiApiTimeout = config.get('aiSettings.timeout');
|
const cfgAiApiTimeout = config.get('aiSettings.timeout');
|
||||||
const cfgTokenEnableBrowser = config.get('services.CoAuthoring.token.enable.browser');
|
const cfgTokenEnableBrowser = config.get('services.CoAuthoring.token.enable.browser');
|
||||||
|
const cfgTokenEnableOutbox = config.get('services.CoAuthoring.token.enable.request.outbox');
|
||||||
|
const cfgTokenOutboxHeader = config.get('services.CoAuthoring.token.outbox.header');
|
||||||
|
const cfgTokenOutboxPrefix = config.get('services.CoAuthoring.token.outbox.prefix');
|
||||||
const cfgAiSettings = config.get('aiSettings');
|
const cfgAiSettings = config.get('aiSettings');
|
||||||
|
|
||||||
const AI = aiEngine.AI;
|
const AI = aiEngine.AI;
|
||||||
@ -160,12 +165,15 @@ async function proxyRequest(req, res) {
|
|||||||
const tenTokenEnableBrowser = ctx.getCfg('services.CoAuthoring.token.enable.browser', cfgTokenEnableBrowser);
|
const tenTokenEnableBrowser = ctx.getCfg('services.CoAuthoring.token.enable.browser', cfgTokenEnableBrowser);
|
||||||
const tenAiApiTimeout = ctx.getCfg('aiSettings.timeout', cfgAiApiTimeout);
|
const tenAiApiTimeout = ctx.getCfg('aiSettings.timeout', cfgAiApiTimeout);
|
||||||
const tenAiApi = ctx.getCfg('aiSettings', cfgAiSettings);
|
const tenAiApi = ctx.getCfg('aiSettings', cfgAiSettings);
|
||||||
|
const tenAiApiProxy = ctx.getCfg('aiSettings.proxy', cfgAiApiProxy);
|
||||||
|
|
||||||
// 1. Handle CORS preflight (OPTIONS) requests if necessary
|
// 1. Handle CORS preflight (OPTIONS) requests if necessary
|
||||||
if (handleCorsHeaders(req, res, ctx) === true) {
|
if (handleCorsHeaders(req, res, ctx) === true) {
|
||||||
return; // OPTIONS request handled, stop further processing
|
return; // OPTIONS request handled, stop further processing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let docId = '';
|
||||||
|
let userId = '';
|
||||||
if (tenTokenEnableBrowser) {
|
if (tenTokenEnableBrowser) {
|
||||||
let checkJwtRes = await docsCoServer.checkJwtHeader(ctx, req, 'Authorization', 'Bearer ', commonDefines.c_oAscSecretType.Session);
|
let checkJwtRes = await docsCoServer.checkJwtHeader(ctx, req, 'Authorization', 'Bearer ', commonDefines.c_oAscSecretType.Session);
|
||||||
if (!checkJwtRes || checkJwtRes.err) {
|
if (!checkJwtRes || checkJwtRes.err) {
|
||||||
@ -177,6 +185,11 @@ async function proxyRequest(req, res) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
|
} else {
|
||||||
|
userId = checkJwtRes?.decoded?.editorConfig?.user?.id;
|
||||||
|
docId = checkJwtRes?.decoded?.document?.key;
|
||||||
|
ctx.setDocId(docId);
|
||||||
|
ctx.setUserId(userId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,6 +241,34 @@ async function proxyRequest(req, res) {
|
|||||||
// Merge key in headers
|
// Merge key in headers
|
||||||
const headers = { ...body.headers, ...providerHeaders };
|
const headers = { ...body.headers, ...providerHeaders };
|
||||||
|
|
||||||
|
// use proxy instead of direct request
|
||||||
|
if (tenAiApiProxy) {
|
||||||
|
const tenTokenEnableOutbox = ctx.getCfg('services.CoAuthoring.token.enable.request.outbox', cfgTokenEnableOutbox);
|
||||||
|
if (tenTokenEnableOutbox) {
|
||||||
|
const tenTokenOutboxHeader = ctx.getCfg('services.CoAuthoring.token.outbox.header', cfgTokenOutboxHeader);
|
||||||
|
const tenTokenOutboxPrefix = ctx.getCfg('services.CoAuthoring.token.outbox.prefix', cfgTokenOutboxPrefix);
|
||||||
|
let [licenseInfo] = await tenantManager.getTenantLicense(ctx);
|
||||||
|
|
||||||
|
let dataObject = {
|
||||||
|
key: docId,
|
||||||
|
user: userId,
|
||||||
|
customer_id: licenseInfo.customerId
|
||||||
|
}
|
||||||
|
|
||||||
|
let secret = await tenantManager.getTenantSecret(ctx, commonDefines.c_oAscSecretType.Outbox);
|
||||||
|
let auth = utils.fillJwtForRequest(ctx, dataObject, secret, false);
|
||||||
|
headers[tenTokenOutboxHeader] = tenTokenOutboxPrefix + auth;
|
||||||
|
}
|
||||||
|
// Replace protocol, host and port in URI with proxy URL
|
||||||
|
const proxyUrl = new URL(tenAiApiProxy);
|
||||||
|
const targetUrl = new URL(uri);
|
||||||
|
targetUrl.protocol = proxyUrl.protocol;
|
||||||
|
targetUrl.host = proxyUrl.host;
|
||||||
|
targetUrl.port = proxyUrl.port || targetUrl.port;
|
||||||
|
uri = targetUrl.toString();
|
||||||
|
ctx.logger.debug(`proxyRequest: Updated URI to use proxy host: ${tenAiApiProxy}`);
|
||||||
|
}
|
||||||
|
|
||||||
// Configure timeout options for the request
|
// Configure timeout options for the request
|
||||||
const timeoutOptions = {
|
const timeoutOptions = {
|
||||||
connectionAndInactivity: tenAiApiTimeout,
|
connectionAndInactivity: tenAiApiTimeout,
|
||||||
@ -245,7 +286,7 @@ async function proxyRequest(req, res) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Log the sanitized request parameters
|
// Log the sanitized request parameters
|
||||||
ctx.logger.debug(`Proxying request: %j`, requestParams);
|
ctx.logger.debug(`proxyRequest request: %j`, requestParams);
|
||||||
|
|
||||||
// Use utils.httpRequest to make the request
|
// Use utils.httpRequest to make the request
|
||||||
const result = await utils.httpRequest(
|
const result = await utils.httpRequest(
|
||||||
|
|||||||
Reference in New Issue
Block a user