fix: 添加rewriteCookieDomain

This commit is contained in:
abearxiong 2025-03-17 02:23:29 +08:00
parent 01503954ad
commit 313f9eb93c
12 changed files with 94 additions and 91 deletions

View File

@ -4,7 +4,6 @@ import fs from 'fs';
import { checkFileExists, createDir } from '../file/index.ts'; import { checkFileExists, createDir } from '../file/index.ts';
import { ProxyInfo } from '../proxy/proxy.ts'; import { ProxyInfo } from '../proxy/proxy.ts';
export const kevisualUrl = 'https://kevisual.xiongxiao.me';
const configDir = createDir(path.join(homedir(), '.config/envision')); const configDir = createDir(path.join(homedir(), '.config/envision'));
export const configPath = path.join(configDir, 'assistant-config.json'); export const configPath = path.join(configDir, 'assistant-config.json');
export const appConfigPath = path.join(configDir, 'assistant-app-config.json'); export const appConfigPath = path.join(configDir, 'assistant-app-config.json');
@ -51,8 +50,8 @@ export const setConfig = (config?: AssistantConfig) => {
if (!config) { if (!config) {
return assistantConfig; return assistantConfig;
} }
assistantConfig = config; assistantConfig = { ...assistantConfig, ...config };
fs.writeFileSync(configPath, JSON.stringify(config, null, 2)); fs.writeFileSync(configPath, JSON.stringify(assistantConfig, null, 2));
return assistantConfig; return assistantConfig;
}; };
type AppConfig = { type AppConfig = {
@ -72,8 +71,10 @@ export const getAppConfig = (): AppConfig => {
}; };
export const setAppConfig = (config: AppConfig) => { export const setAppConfig = (config: AppConfig) => {
fs.writeFileSync(appConfigPath, JSON.stringify(config, null, 2)); const _config = getAppConfig();
return config; const _saveConfig = { ..._config, ...config };
fs.writeFileSync(appConfigPath, JSON.stringify(_saveConfig, null, 2));
return _saveConfig;
}; };
export const addAppConfig = (app: any) => { export const addAppConfig = (app: any) => {

View File

@ -0,0 +1,27 @@
export function rewriteCookieDomain(cookie: string, domainRewrite: string | Record<string, string>) {
if (!domainRewrite) return cookie;
// 解析 Cookie 的属性
const parts = cookie.split(';').map((part) => part.trim());
const nameValue = parts[0];
const attributes = parts.slice(1);
// 查找并替换 Domain 属性
const newAttributes = attributes.map((attr) => {
if (attr.startsWith('Domain=')) {
const originalDomain = attr.slice(7); // 去掉 "Domain="
let newDomain = domainRewrite;
// 如果 domainRewrite 是对象,根据映射关系替换
if (typeof domainRewrite === 'object') {
newDomain = domainRewrite[originalDomain] || originalDomain;
}
return `Domain=${newDomain}`;
}
return attr;
});
// 重新组合 Cookie
return [nameValue, ...newAttributes].join('; ');
}

View File

@ -1,6 +1,6 @@
import http from 'http'; import http from 'http';
import https from 'https'; import https from 'https';
import { rewriteCookieDomain } from '../https/cookie-rewrite.ts';
import { ProxyInfo } from './proxy.ts'; import { ProxyInfo } from './proxy.ts';
export const defaultApiProxy = [ export const defaultApiProxy = [
{ {
@ -29,7 +29,8 @@ export const createApiProxy = (api: string, paths: string[] = ['/api', '/v1', '/
}; };
export const apiProxy = (req: http.IncomingMessage, res: http.ServerResponse, proxyApi: ProxyInfo) => { export const apiProxy = (req: http.IncomingMessage, res: http.ServerResponse, proxyApi: ProxyInfo) => {
const _u = new URL(req.url, `${proxyApi.target}`); const { target } = proxyApi;
const _u = new URL(req.url, `${target}`);
console.log('proxyApi', req.url, _u.href); console.log('proxyApi', req.url, _u.href);
// 设置代理请求的目标 URL 和请求头 // 设置代理请求的目标 URL 和请求头
let header: any = {}; let header: any = {};
@ -40,16 +41,16 @@ export const apiProxy = (req: http.IncomingMessage, res: http.ServerResponse, pr
const headers = Object.keys(req.headers).filter((item) => item && item.toLowerCase() !== 'host'); const headers = Object.keys(req.headers).filter((item) => item && item.toLowerCase() !== 'host');
headers.forEach((item) => { headers.forEach((item) => {
if (item.toLowerCase() === 'origin') { if (item.toLowerCase() === 'origin') {
header.origin = new URL(proxyApi.target).origin; header.origin = new URL(target).origin;
return; return;
} }
if (item.toLowerCase() === 'referer') { if (item.toLowerCase() === 'referer') {
header.referer = new URL(req.url, proxyApi.target).href; header.referer = new URL(req.url, target).href;
return; return;
} }
header[item] = req.headers[item]; header[item] = req.headers[item];
}); });
const options = { const options: http.RequestOptions = {
host: _u.hostname, host: _u.hostname,
path: req.url, path: req.url,
method: req.method, method: req.method,
@ -57,7 +58,7 @@ export const apiProxy = (req: http.IncomingMessage, res: http.ServerResponse, pr
...header, ...header,
}, },
}; };
console.log('options', JSON.stringify(options, null, 2)); // console.log('options', JSON.stringify(options, null, 2));
if (_u.port) { if (_u.port) {
// @ts-ignore // @ts-ignore
options.port = _u.port; options.port = _u.port;
@ -65,6 +66,12 @@ export const apiProxy = (req: http.IncomingMessage, res: http.ServerResponse, pr
const httpProxy = _u.protocol === 'https:' ? https : http; const httpProxy = _u.protocol === 'https:' ? https : http;
// 创建代理请求 // 创建代理请求
const proxyReq = httpProxy.request(options, (proxyRes) => { const proxyReq = httpProxy.request(options, (proxyRes) => {
// Modify the 'set-cookie' headers using rewriteCookieDomain
if (proxyRes.headers['set-cookie']) {
proxyRes.headers['set-cookie'] = proxyRes.headers['set-cookie'].map((cookie) =>
rewriteCookieDomain(cookie, 'localhost')
);
}
// 将代理服务器的响应头和状态码返回给客户端 // 将代理服务器的响应头和状态码返回给客户端
res.writeHead(proxyRes.statusCode, proxyRes.headers); res.writeHead(proxyRes.statusCode, proxyRes.headers);
// 将代理响应流写入客户端响应 // 将代理响应流写入客户端响应

View File

@ -35,7 +35,7 @@ export const fileProxy = (req: http.IncomingMessage, res: http.ServerResponse, p
if (ext === '.html') { if (ext === '.html') {
maxAge = 0; maxAge = 0;
} }
let sendFilePath = filePath.replace(rootPath + '/', ''); let sendFilePath = path.relative(rootPath, filePath);
const file = send(req, sendFilePath, { const file = send(req, sendFilePath, {
root: rootPath, root: rootPath,
maxAge, maxAge,

View File

@ -1,6 +1,12 @@
export type ProxyInfo = { export type ProxyInfo = {
path?: string; path?: string;
/**
*
*/
target?: string; target?: string;
/**
*
*/
type?: 'static' | 'dynamic' | 'minio'; type?: 'static' | 'dynamic' | 'minio';
/** /**
* index.html 访 * index.html 访

View File

@ -1,6 +1,6 @@
{ {
"name": "assistant-center", "name": "assistant-center",
"version": "0.0.1", "version": "0.0.4",
"description": "", "description": "",
"main": "index.js", "main": "index.js",
"app": { "app": {
@ -74,5 +74,6 @@
"tsx": "^4.19.3", "tsx": "^4.19.3",
"typescript": "^5.8.2" "typescript": "^5.8.2"
}, },
"pnpm": {} "pnpm": {},
"packageManager": "pnpm@9.14.4"
} }

View File

@ -12,7 +12,7 @@ app
console.log('httpsConfig', `https://localhost:51015/client/router?path=demo`); console.log('httpsConfig', `https://localhost:51015/client/router?path=demo`);
app.listen(51016, () => { app.listen(51016, () => {
console.log('Router App is running on https://localhost:51015'); console.log('Router App is running on https://localhost:51016');
}); });
app.server.on(proxyRoute); app.server.on(proxyRoute);

View File

@ -1,7 +1,6 @@
import { app } from './index.ts'; import { app } from './index.ts';
import { proxyRoute } from './proxy-route/index.ts'; import { proxyRoute } from './proxy-route/index.ts';
import getPort, { portNumbers } from 'get-port'; import getPort, { portNumbers } from 'get-port';
console.log('httpsConfig', `https://localhost:51015/client/router?path=demo`);
// 检车端口可用性 // 检车端口可用性
const isPortAvailable = await getPort({ port: portNumbers(51015, 52000) }); const isPortAvailable = await getPort({ port: portNumbers(51015, 52000) });
if (!isPortAvailable) { if (!isPortAvailable) {

View File

@ -1,78 +1,20 @@
import path from 'path'; import {
import { homedir } from 'os'; getCacheAssistantConfig,
import fs from 'fs'; setConfig,
import { checkFileExists, createDir } from '../file/index.ts'; getConfig,
getAppConfig,
setAppConfig,
configPath,
appConfigPath,
appDir,
LocalElectronAppUrl,
} from '@kevisual/assistant-module/assistant-config';
export const kevisualUrl = 'https://kevisual.xiongxiao.me'; export const kevisualUrl = process.env.KEVISUAL_URL || 'https://kevisual.xiongxiao.me';
const configDir = createDir(path.join(homedir(), '.config/envision'));
export const configPath = path.join(configDir, 'assistant-config.json');
export const appConfigPath = path.join(configDir, 'assistant-app-config.json');
export const appDir = createDir(path.join(configDir, 'assistant-app/frontend'));
export const LocalElectronAppUrl = 'https://assistant.app/user/tiptap/';
type AssistantConfig = { export { configPath, appConfigPath, appDir, LocalElectronAppUrl };
pageApi?: string; // https://kevisual.silkyai.cn
loadURL?: string; // https://assistant.app/user/tiptap/
proxy?: { user: string; key: string; path: string }[];
};
let assistantConfig: AssistantConfig;
export const getConfig = () => {
try {
if (!checkFileExists(configPath)) {
fs.writeFileSync(configPath, JSON.stringify({ proxy: [] }, null, 2));
return {
loadURL: LocalElectronAppUrl,
pageApi: '',
proxy: [],
};
}
assistantConfig = JSON.parse(fs.readFileSync(configPath, 'utf8'));
return assistantConfig;
} catch (error) {
console.error(error);
return {
loadURL: LocalElectronAppUrl,
pageApi: '',
proxy: [],
};
}
};
export const getCacheAssistantConfig = () => {
if (assistantConfig) {
return assistantConfig;
}
return getConfig();
};
export const setConfig = (config?: AssistantConfig) => { export { getCacheAssistantConfig, setConfig, getConfig, getAppConfig, setAppConfig };
if (!config) {
return assistantConfig;
}
assistantConfig = { ...assistantConfig, ...config };
fs.writeFileSync(configPath, JSON.stringify(assistantConfig, null, 2));
return assistantConfig;
};
type AppConfig = {
list: any[];
};
/**
*
* @returns
*/
export const getAppConfig = (): AppConfig => {
if (!checkFileExists(appConfigPath)) {
return {
list: [],
};
}
return JSON.parse(fs.readFileSync(appConfigPath, 'utf8'));
};
export const setAppConfig = (config: AppConfig) => {
const _config = getAppConfig();
fs.writeFileSync(appConfigPath, JSON.stringify({ ..._config, ...config }, null, 2));
return config;
};
export const addAppConfig = (app: any) => { export const addAppConfig = (app: any) => {
const config = getAppConfig(); const config = getAppConfig();

13
src/modules/parent-msg.ts Normal file
View File

@ -0,0 +1,13 @@
// process.send({
// type: 'fork',
// data: {
// port: isPortAvailable,
// },
// });
export const reload = () => {
process.send({
type: 'reload',
data: {},
});
};

View File

@ -19,7 +19,7 @@ export const proxyRoute = async (req: http.IncomingMessage, res: http.ServerResp
} }
// client, api, v1, serve 开头的拦截 // client, api, v1, serve 开头的拦截
const apiProxyList = assistantConfig?.apiProxyList || []; const apiProxyList = assistantConfig?.apiProxyList || [];
const defaultApiProxy = createApiProxy(assistantConfig?.pageApi || 'https://kevisual.xiongxiao.me'); const defaultApiProxy = createApiProxy(assistantConfig?.pageApi || 'https://kevisual.silkyai.cn');
const apiBackendProxy = [...apiProxyList, ...defaultApiProxy].find((item) => pathname.startsWith(item.path)); const apiBackendProxy = [...apiProxyList, ...defaultApiProxy].find((item) => pathname.startsWith(item.path));
if (apiBackendProxy) { if (apiBackendProxy) {
console.log('apiBackendProxy', apiBackendProxy, req.url); console.log('apiBackendProxy', apiBackendProxy, req.url);
@ -63,6 +63,11 @@ export const proxyRoute = async (req: http.IncomingMessage, res: http.ServerResp
console.log('handle by router 404', req.url); console.log('handle by router 404', req.url);
res.statusCode = 404; res.statusCode = 404;
res.end('Not Found Proxy'); res.end('Not Found Proxy');
// console.log('getCacheAssistantConfig().pageApi', getCacheAssistantConfig().pageApi);
// return apiProxy(req, res, {
// path: url.pathname,
// target: getCacheAssistantConfig().pageApi,
// });
}; };
const localProxyProxyList = [ const localProxyProxyList = [
{ {

View File

@ -1,5 +1,6 @@
import { app } from '@/app.ts'; import { app } from '@/app.ts';
import { getCacheAssistantConfig, setConfig } from '@/modules/config/index.ts'; import { getCacheAssistantConfig, setConfig } from '@/modules/config/index.ts';
import { reload } from '@/modules/parent-msg.ts';
app app
.route({ .route({
@ -19,6 +20,7 @@ app
}) })
.define(async (ctx) => { .define(async (ctx) => {
const { data } = ctx.query; const { data } = ctx.query;
reload();
ctx.body = setConfig(data); ctx.body = setConfig(data);
}) })