generated from tailored/router-template
fix: 添加rewriteCookieDomain
This commit is contained in:
parent
01503954ad
commit
313f9eb93c
@ -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 = {
|
||||||
@ -71,9 +70,11 @@ export const getAppConfig = (): AppConfig => {
|
|||||||
return JSON.parse(fs.readFileSync(appConfigPath, 'utf8'));
|
return JSON.parse(fs.readFileSync(appConfigPath, 'utf8'));
|
||||||
};
|
};
|
||||||
|
|
||||||
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) => {
|
||||||
|
27
assistant-module/src/https/cookie-rewrite.ts
Normal file
27
assistant-module/src/https/cookie-rewrite.ts
Normal 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('; ');
|
||||||
|
}
|
@ -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);
|
||||||
// 将代理响应流写入客户端响应
|
// 将代理响应流写入客户端响应
|
||||||
|
@ -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,
|
||||||
|
@ -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, 设置了首要文件,如果文件不存在,则访问首要文件
|
||||||
|
@ -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"
|
||||||
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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) {
|
||||||
|
@ -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
13
src/modules/parent-msg.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
// process.send({
|
||||||
|
// type: 'fork',
|
||||||
|
// data: {
|
||||||
|
// port: isPortAvailable,
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
|
||||||
|
export const reload = () => {
|
||||||
|
process.send({
|
||||||
|
type: 'reload',
|
||||||
|
data: {},
|
||||||
|
});
|
||||||
|
};
|
@ -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 = [
|
||||||
{
|
{
|
||||||
|
@ -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);
|
||||||
})
|
})
|
||||||
|
Loading…
x
Reference in New Issue
Block a user