surgio
Version:
查看完整使用文档,前往 [surgio.royli.dev](https://surgio.royli.dev)。
765 lines • 67.5 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const assert_1 = __importDefault(require("assert"));
const axios_1 = __importDefault(require("axios"));
const country_code_emoji_1 = __importDefault(require("country-code-emoji"));
const fs_extra_1 = __importDefault(require("fs-extra"));
const lodash_1 = __importDefault(require("lodash"));
const lru_cache_1 = __importDefault(require("lru-cache"));
const path_1 = __importDefault(require("path"));
const query_string_1 = __importDefault(require("query-string"));
const url_1 = __importDefault(require("url"));
const urlsafe_base64_1 = __importDefault(require("urlsafe-base64"));
const yaml_1 = __importDefault(require("yaml"));
const os_1 = __importDefault(require("os"));
const types_1 = require("../types");
const config_1 = require("./config");
exports.OBFS_UA = 'Mozilla/5.0 (iPhone; CPU iPhone OS 12_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148';
const ConfigCache = new lru_cache_1.default({
maxAge: 10 * 60 * 1000,
});
// istanbul ignore next
exports.resolveRoot = (...args) => path_1.default.join(__dirname, '../../', ...args);
exports.getDownloadUrl = (baseUrl = '/', artifactName) => `${baseUrl}${artifactName}`;
exports.getBlackSSLConfig = async (config) => {
assert_1.default(config.username, 'Lack of BlackSSL username.');
assert_1.default(config.password, 'Lack of BlackSSL password.');
const key = `blackssl_${config.username}`;
async function requestConfigFromBlackSSL(username, password) {
const response = await axios_1.default
.get('https://api.darkssl.com/v1/service/ssl_info', {
params: {
username,
password,
},
timeout: 20000,
proxy: false,
headers: {
'User-Agent': 'GoAgentX/774 CFNetwork/901.1 Darwin/17.6.0 (x86_64)',
},
});
const result = response.data.ssl_nodes.map(item => ({
nodeName: `${country_code_emoji_1.default(item.country_code)}${item.name}`,
type: types_1.NodeTypeEnum.HTTPS,
hostname: item.server,
port: item.port,
username,
password,
}));
ConfigCache.set(key, result);
return result;
}
return ConfigCache.has(key) ?
ConfigCache.get(key) :
await requestConfigFromBlackSSL(config.username, config.password);
};
exports.getShadowsocksJSONConfig = async (config) => {
assert_1.default(config.url, 'Lack of subscription url.');
async function requestConfigFromRemote(url) {
const response = await axios_1.default.get(url, {
proxy: false,
timeout: 20000,
});
const result = response.data.configs.map(item => {
const nodeConfig = {
nodeName: item.remarks,
type: types_1.NodeTypeEnum.Shadowsocks,
hostname: item.server,
port: item.server_port,
method: item.method,
password: item.password,
};
if (typeof config.udpRelay === 'boolean') {
nodeConfig['udp-relay'] = config.udpRelay ? 'true' : 'false';
}
if (item.plugin === 'obfs-local') {
const obfs = item.plugin_opts.match(/obfs=(\w+)/);
const obfsHost = item.plugin_opts.match(/obfs-host=(.+)$/);
if (obfs) {
nodeConfig.obfs = obfs[1];
nodeConfig['obfs-host'] = obfsHost ? obfsHost[1] : 'www.bing.com';
}
}
return nodeConfig;
});
ConfigCache.set(url, result);
return result;
}
return ConfigCache.has(config.url) ?
ConfigCache.get(config.url) :
await requestConfigFromRemote(config.url);
};
exports.getShadowsocksSubscription = async (config) => {
assert_1.default(config.url, 'Lack of subscription url.');
async function requestConfigFromRemote(url) {
const response = await axios_1.default.get(url, {
proxy: false,
timeout: 20000,
responseType: 'text',
});
const configList = exports.fromBase64(response.data).split('\n').filter(item => !!item);
const result = configList.map(item => {
const scheme = url_1.default.parse(item, true);
const userInfo = exports.fromUrlSafeBase64(scheme.auth).split(':');
const pluginInfo = typeof scheme.query.plugin === 'string' ? exports.decodeStringList(scheme.query.plugin.split(';')) : {};
return Object.assign(Object.assign({ type: types_1.NodeTypeEnum.Shadowsocks, nodeName: decodeURIComponent(scheme.hash.replace('#', '')), hostname: scheme.hostname, port: scheme.port, method: userInfo[0], password: userInfo[1] }, (typeof config.udpRelay === 'boolean' ? {
'udp-relay': config.udpRelay ? 'true' : 'false',
} : null)), (pluginInfo['obfs-local'] ? {
obfs: pluginInfo.obfs,
'obfs-host': pluginInfo['obfs-host'],
} : null));
});
ConfigCache.set(url, result);
return result;
}
return ConfigCache.has(config.url) ?
ConfigCache.get(config.url) :
await requestConfigFromRemote(config.url);
};
exports.getShadowsocksrSubscription = async (config) => {
assert_1.default(config.url, 'Lack of subscription url.');
async function requestConfigFromRemote(url) {
const response = await axios_1.default.get(url, {
proxy: false,
timeout: 20000,
responseType: 'text',
});
const configList = exports.fromBase64(response.data).split('\n').filter(item => !!item);
const result = configList.map(item => {
const pair = exports.fromUrlSafeBase64(item.replace('ssr://', '')).split('/');
const basicInfo = pair[0].split(':');
const extras = pair[1] ? url_1.default.parse(pair[1], true) : null;
const nodeName = extras ? exports.fromUrlSafeBase64(extras.query.remarks) : null;
if (!nodeName) {
throw new Error(`${item} doesn\`t contain a remark.`);
}
return {
type: types_1.NodeTypeEnum.Shadowsocksr,
nodeName,
hostname: basicInfo[0],
port: basicInfo[1],
protocol: basicInfo[2],
method: basicInfo[3],
obfs: basicInfo[4],
password: exports.fromUrlSafeBase64(basicInfo[5]),
protoparam: extras ? exports.fromUrlSafeBase64(extras.query.protoparam || '') : '',
obfsparam: extras ? exports.fromUrlSafeBase64(extras.query.obfsparam || '') : '',
};
});
ConfigCache.set(url, result);
return result;
}
return ConfigCache.has(config.url) ?
ConfigCache.get(config.url) :
await requestConfigFromRemote(config.url);
};
exports.getV2rayNSubscription = async (config) => {
assert_1.default(config.url, 'Lack of subscription url.');
async function requestConfigFromRemote(url) {
const response = await axios_1.default.get(url, {
proxy: false,
timeout: 20000,
responseType: 'text',
});
const configList = exports.fromBase64(response.data).split('\n').filter(item => !!item);
const result = configList.map(item => {
const json = JSON.parse(exports.fromBase64(item.replace('vmess://', '')));
if (json.v !== '2') {
throw new Error(`暂不支持该订阅类型:${url}`);
}
return {
nodeName: json.ps,
type: types_1.NodeTypeEnum.Vmess,
hostname: json.add,
port: json.port,
method: 'auto',
uuid: json.id,
alterId: json.aid || '0',
network: json.net,
tls: json.tls === 'tls',
host: json.host || '',
path: json.path || '/',
};
});
ConfigCache.set(url, result);
return result;
}
return ConfigCache.has(config.url) ?
ConfigCache.get(config.url) :
await requestConfigFromRemote(config.url);
};
exports.getSurgeNodes = (list, filter) => {
const result = list
.filter(item => filter ? filter(item) : true)
.map(nodeConfig => {
if (nodeConfig.enable === false) {
return null;
}
switch (nodeConfig.type) {
case types_1.NodeTypeEnum.Shadowsocks: {
const config = nodeConfig;
return ([
config.nodeName,
[
'custom',
config.hostname,
config.port,
config.method,
config.password,
'https://raw.githubusercontent.com/ConnersHua/SSEncrypt/master/SSEncrypt.module',
...exports.pickAndFormatStringList(config, ['udp-relay', 'obfs', 'obfs-host']),
].join(', ')
].join(' = '));
}
case types_1.NodeTypeEnum.HTTPS: {
const config = nodeConfig;
return ([
config.nodeName,
[
'https',
config.hostname,
config.port,
config.username,
config.password,
].join(', ')
].join(' = '));
}
case types_1.NodeTypeEnum.Snell: {
const config = nodeConfig;
return ([
config.nodeName,
[
'snell',
config.hostname,
config.port,
...exports.pickAndFormatStringList(config, ['psk', 'obfs']),
].join(', '),
].join(' = '));
}
case types_1.NodeTypeEnum.Shadowsocksr: {
const config = nodeConfig;
// istanbul ignore next
if (!config.binPath) {
throw new Error('You must specify a binary file path for Shadowsocksr.');
}
const args = [
'-s', config.hostname,
'-p', `${config.port}`,
'-m', config.method,
'-o', config.obfs,
'-O', config.protocol,
'-k', config.password,
'-l', `${config.localPort}`,
'-b', '127.0.0.1',
];
if (config.protoparam) {
args.push('-G', config.protoparam);
}
if (config.obfsparam) {
args.push('-g', config.obfsparam);
}
const configString = [
'external',
`exec = ${JSON.stringify(config.binPath)}`,
...(args).map(arg => `args = ${JSON.stringify(arg)}`),
`local-port = ${config.localPort}`,
`addresses = ${config.hostname}`,
].join(', ');
return ([
config.nodeName,
configString,
].join(' = '));
}
case types_1.NodeTypeEnum.Vmess: {
const config = nodeConfig;
if (nodeConfig.surgeConfig &&
nodeConfig.surgeConfig.v2ray === 'native') {
// Native support for vmess
const configList = [
'vmess',
config.hostname,
config.port,
`username=${config.uuid}`,
];
function getHeader(host, ua = exports.OBFS_UA) {
return [
`Host:${host}`,
`User-Agent:${JSON.stringify(ua)}`,
].join('|');
}
if (config.network === 'ws') {
configList.push('ws=true');
configList.push(`ws-path=${config.path}`);
configList.push('ws-headers=' +
getHeader(config.host || config.hostname));
}
if (config.tls) {
configList.push('tls=true');
}
return ([
config.nodeName,
configList.join(', '),
].join(' = '));
}
else {
// Using external provider
// istanbul ignore next
if (!config.binPath) {
throw new Error('You must specify a binary file path for V2Ray.');
}
const jsonFileName = `v2ray_${config.localPort}_${config.hostname}_${config.port}.json`;
const jsonFilePath = path_1.default.join(exports.ensureConfigFolder(), jsonFileName);
const jsonFile = exports.formatV2rayConfig(config.localPort, nodeConfig);
const args = [
'--config', jsonFilePath.replace(os_1.default.homedir(), '$HOME'),
];
const configString = [
'external',
`exec = ${JSON.stringify(config.binPath)}`,
...(args).map(arg => `args = ${JSON.stringify(arg)}`),
`local-port = ${config.localPort}`,
`addresses = ${config.hostname}`,
].join(', ');
if (process.env.NODE_ENV !== 'test') {
fs_extra_1.default.writeJSONSync(jsonFilePath, jsonFile);
}
return ([
config.nodeName,
configString,
].join(' = '));
}
}
// istanbul ignore next
default:
console.info(`${nodeConfig.type} is not supported, ${nodeConfig.nodeName} will be ignored.`);
return null;
}
})
.filter(item => item !== null);
return result.join('\n');
};
exports.getClashNodes = (list, filter) => {
return list
.filter(item => filter ? filter(item) : true)
.map(nodeConfig => {
if (nodeConfig.enable === false) {
return null;
}
switch (nodeConfig.type) {
case types_1.NodeTypeEnum.Shadowsocks:
return Object.assign({ type: 'ss', cipher: nodeConfig.method, name: nodeConfig.nodeName, password: nodeConfig.password, port: nodeConfig.port, server: nodeConfig.hostname, udp: nodeConfig['udp-relay'] === 'true' }, (nodeConfig.obfs ? {
plugin: 'obfs',
'plugin-opts': {
mode: nodeConfig.obfs,
host: nodeConfig['obfs-host'],
},
} : null));
case types_1.NodeTypeEnum.Vmess:
return Object.assign(Object.assign(Object.assign({ type: 'vmess', cipher: nodeConfig.method, name: nodeConfig.nodeName, server: nodeConfig.hostname, port: nodeConfig.port, uuid: nodeConfig.uuid, alterId: nodeConfig.alterId }, (nodeConfig.network === 'tcp' ? null : {
network: nodeConfig.network,
})), { tls: nodeConfig.tls }), (nodeConfig.network === 'ws' ? {
'ws-path': nodeConfig.path,
'ws-headers': Object.assign({}, (nodeConfig.host ? { Host: nodeConfig.host } : null)),
} : null));
case types_1.NodeTypeEnum.Shadowsocksr:
return {
type: 'ssr',
name: nodeConfig.nodeName,
server: nodeConfig.hostname,
port: nodeConfig.port,
password: nodeConfig.password,
obfs: nodeConfig.obfs,
obfsparam: nodeConfig.obfsparam,
protocol: nodeConfig.protocol,
protocolparam: nodeConfig.protoparam,
cipher: nodeConfig.method,
};
// istanbul ignore next
default:
console.info(`${nodeConfig.type} is not supported yet, ${nodeConfig.nodeName} will be ignored.`);
return null;
}
})
.filter(item => item !== null);
};
// istanbul ignore next
exports.toUrlSafeBase64 = (str) => urlsafe_base64_1.default.encode(Buffer.from(str, 'utf8'));
// istanbul ignore next
exports.fromUrlSafeBase64 = (str) => urlsafe_base64_1.default.decode(str).toString();
// istanbul ignore next
exports.toBase64 = (str) => Buffer.from(str, 'utf8').toString('base64');
// istanbul ignore next
exports.fromBase64 = (str) => Buffer.from(str, 'base64').toString('utf8');
/**
* @see https://github.com/shadowsocks/shadowsocks-org/wiki/SIP002-URI-Scheme
*/
exports.getShadowsocksNodes = (list, groupName = 'Surgio') => {
const result = list
.map(nodeConfig => {
if (nodeConfig.enable === false) {
return null;
}
switch (nodeConfig.type) {
case types_1.NodeTypeEnum.Shadowsocks: {
const config = lodash_1.default.cloneDeep(nodeConfig);
const query = Object.assign(Object.assign({}, (config.obfs ? {
plugin: `${encodeURIComponent(`obfs-local;obfs=${config.obfs};obfs-host=${config['obfs-host']}`)}`,
} : null)), (groupName ? { group: encodeURIComponent(groupName) } : null));
return [
'ss://',
exports.toUrlSafeBase64(`${config.method}:${config.password}`),
'@',
config.hostname,
':',
config.port,
'/?',
query_string_1.default.stringify(query, {
encode: false,
sort: false,
}),
'#',
encodeURIComponent(config.nodeName),
].join('');
}
// istanbul ignore next
default:
console.info(`${nodeConfig.type} is not supported, ${nodeConfig.nodeName} will be ignored.`);
return null;
}
})
.filter(item => item !== null);
return result.join('\n');
};
exports.getShadowsocksrNodes = (list, groupName) => {
const result = list
.map(nodeConfig => {
if (nodeConfig.enable === false) {
return null;
}
switch (nodeConfig.type) {
case types_1.NodeTypeEnum.Shadowsocksr: {
const baseUri = [
nodeConfig.hostname,
nodeConfig.port,
nodeConfig.protocol,
nodeConfig.method,
nodeConfig.obfs,
exports.toUrlSafeBase64(nodeConfig.password),
].join(':');
const query = {
obfsparam: exports.toUrlSafeBase64(nodeConfig.obfsparam),
protoparam: exports.toUrlSafeBase64(nodeConfig.protoparam),
remarks: exports.toUrlSafeBase64(nodeConfig.nodeName),
group: exports.toUrlSafeBase64(groupName),
udpport: 0,
uot: 0,
};
return 'ssr://' + exports.toUrlSafeBase64([
baseUri,
'/?',
query_string_1.default.stringify(query),
].join(''));
}
// istanbul ignore next
default:
console.info(`${nodeConfig.type} is not supported, ${nodeConfig.nodeName} will be ignored.`);
return null;
}
})
.filter(item => item !== null);
return result.join('\n');
};
exports.getV2rayNNodes = (list) => {
const result = list
.map(nodeConfig => {
if (nodeConfig.enable === false) {
return null;
}
switch (nodeConfig.type) {
case types_1.NodeTypeEnum.Vmess: {
const json = {
v: '2',
ps: nodeConfig.nodeName,
add: nodeConfig.hostname,
port: `${nodeConfig.port}`,
id: nodeConfig.uuid,
aid: nodeConfig.alterId,
net: nodeConfig.network,
type: 'none',
host: nodeConfig.host,
path: nodeConfig.path,
tls: nodeConfig.tls ? 'tls' : '',
};
return 'vmess://' + exports.toBase64(JSON.stringify(json));
}
// istanbul ignore next
default:
console.info(`${nodeConfig.type} is not supported, ${nodeConfig.nodeName} will be ignored.`);
return null;
}
})
.filter(item => !!item);
return result.join('\n');
};
exports.getQuantumultNodes = (list, groupName = 'Surgio') => {
function getHeader(host, ua = exports.OBFS_UA) {
return [
`Host:${host}`,
`User-Agent:${ua}`,
].join('[Rr][Nn]');
}
const result = list
.map(nodeConfig => {
if (nodeConfig.enable === false) {
return null;
}
switch (nodeConfig.type) {
case types_1.NodeTypeEnum.Vmess: {
const config = [
'vmess', nodeConfig.hostname, nodeConfig.port,
(nodeConfig.method === 'auto' ? 'chacha20-ietf-poly1305' : nodeConfig.method),
JSON.stringify(nodeConfig.uuid), nodeConfig.alterId,
`group=${groupName}`,
`over-tls=${nodeConfig.tls === true ? 'true' : 'false'}`,
`certificate=1`,
`obfs=${nodeConfig.network}`,
`obfs-path=${JSON.stringify(nodeConfig.path || '/')}`,
`obfs-header=${JSON.stringify(getHeader(nodeConfig.host || nodeConfig.hostname))}`,
].filter(value => !!value).join(',');
return 'vmess://' + exports.toBase64([
nodeConfig.nodeName,
config,
].join(' = '));
}
case types_1.NodeTypeEnum.Shadowsocks: {
return exports.getShadowsocksNodes([nodeConfig], groupName);
}
case types_1.NodeTypeEnum.Shadowsocksr:
return exports.getShadowsocksrNodes([nodeConfig], groupName);
case types_1.NodeTypeEnum.HTTPS: {
const config = [
nodeConfig.nodeName,
[
'http',
`upstream-proxy-address=${nodeConfig.hostname}`,
`upstream-proxy-port=${nodeConfig.port}`,
'upstream-proxy-auth=true',
`upstream-proxy-username=${nodeConfig.username}`,
`upstream-proxy-password=${nodeConfig.password}`,
'over-tls=true',
'certificate=1'
].join(', ')
].join(' = ');
return 'http://' + exports.toBase64(config);
}
// istanbul ignore next
default:
console.info(`${nodeConfig.type} is not supported yet, ${nodeConfig.nodeName} will be ignored.`);
return null;
}
})
.filter(item => !!item);
return result.join('\n');
};
exports.getShadowsocksNodesJSON = (list) => {
const nodes = list
.map(nodeConfig => {
if (nodeConfig.enable === false) {
return null;
}
switch (nodeConfig.type) {
case types_1.NodeTypeEnum.Shadowsocks: {
const useObfs = Boolean(nodeConfig.obfs && nodeConfig['obfs-host']);
return Object.assign({ remarks: nodeConfig.nodeName, server: nodeConfig.hostname, server_port: nodeConfig.port, method: nodeConfig.method, remarks_base64: exports.toUrlSafeBase64(nodeConfig.nodeName), password: nodeConfig.password, tcp_over_udp: false, udp_over_tcp: false, enable: true }, (useObfs ? {
plugin: 'obfs-local',
'plugin-opts': `obfs=${nodeConfig.obfs};obfs-host=${nodeConfig['obfs-host']}`
} : null));
}
// istanbul ignore next
default:
console.info(`${nodeConfig.type} is not supported, ${nodeConfig.nodeName} will be ignored.`);
return null;
}
})
.filter(item => item !== null);
return JSON.stringify(nodes, null, 2);
};
exports.getNodeNames = (list, nodeTypeList = [types_1.NodeTypeEnum.Shadowsocks, types_1.NodeTypeEnum.HTTPS, types_1.NodeTypeEnum.Snell], filter) => {
const nodes = list.filter(item => {
const result = nodeTypeList.includes(item.type) && item.enable !== false;
if (filter) {
return filter(item) && result;
}
return result;
});
return nodes.map(item => item.nodeName).join(', ');
};
exports.getClashNodeNames = (ruleName, ruleType, nodeNameList, nodeTypeList = [types_1.NodeTypeEnum.Shadowsocks], filter) => {
const nodes = nodeNameList.filter(item => {
const result = nodeTypeList.includes(item.type) && item.enable !== false;
if (filter) {
return filter(item) && result;
}
return result;
});
return Object.assign({ type: ruleType, name: ruleName, proxies: nodes.map(item => item.nodeName) }, (ruleType === 'url-test' ? {
url: 'http://www.qualcomm.cn/generate_204',
interval: 1200,
} : null));
};
exports.toYaml = (obj) => yaml_1.default.stringify(obj);
exports.pickAndFormatStringList = (obj, keyList) => {
const result = [];
keyList.forEach(key => {
if (obj.hasOwnProperty(key)) {
result.push(`${key}=${obj[key]}`);
}
});
return result;
};
exports.decodeStringList = (stringList) => {
const result = {};
stringList.forEach(item => {
const pair = item.split('=');
result[pair[0]] = pair[1] || true;
});
return result;
};
exports.loadConfig = (cwd, configPath, override) => {
const absPath = path_1.default.resolve(cwd, configPath);
if (!fs_extra_1.default.existsSync(absPath)) {
throw new Error(`${absPath} cannot be found.`);
}
if (override) {
return Object.assign(Object.assign({}, config_1.normalizeConfig(cwd, require(absPath))), override);
}
return config_1.normalizeConfig(cwd, require(absPath));
};
exports.normalizeClashProxyGroupConfig = (nodeList, customFilters, proxyGroupModifier) => {
const proxyGroup = proxyGroupModifier(nodeList, customFilters);
return proxyGroup.map(item => {
if (item.filter) {
return exports.getClashNodeNames(item.name, item.type, nodeList, [
types_1.NodeTypeEnum.Shadowsocks,
types_1.NodeTypeEnum.Vmess,
], item.filter);
}
else if (item.proxies) {
return item;
}
else {
return exports.getClashNodeNames(item.name, item.type, nodeList, [
types_1.NodeTypeEnum.Shadowsocks,
types_1.NodeTypeEnum.Vmess,
]);
}
});
};
exports.addProxyToSurgeRuleSet = (str, rule) => {
const result = [];
str
.split('\n')
.filter(item => item && item.trim() !== '')
.forEach(item => {
if (!item.startsWith('#') && !item.startsWith('//')) {
const comment = item.split('//');
const line = comment[0].trim().split(',');
if (line.length === 2) {
line.push(rule);
}
else {
line.splice(2, 0, rule);
}
result.push(line.join(',') + (comment[1] ? ` //${comment[1]}` : ''));
}
else {
result.push(item);
}
});
return result.join('\n');
};
exports.loadRemoteSnippetList = (remoteSnippetList) => {
function load(url) {
console.log(`下载远程片段:${url}`);
return axios_1.default.get(url, {
timeout: 20000,
proxy: false,
responseType: 'text',
})
.then(data => data.data)
.catch(err => {
console.error(`远程片段 ${url} 下载失败。`);
throw err;
});
}
return Promise.all(remoteSnippetList.map(item => {
return load(item.url)
.then(res => ({
main: (rule) => exports.addProxyToSurgeRuleSet(res, rule),
name: item.name,
url: item.url,
text: res,
}));
}));
};
exports.ensureConfigFolder = (dir = os_1.default.homedir()) => {
const configDir = path_1.default.join(dir, '.config/surgio');
fs_extra_1.default.mkdirpSync(configDir);
return configDir;
};
exports.formatV2rayConfig = (localPort, nodeConfig) => {
const config = {
log: {
loglevel: 'warning'
},
inbound: {
port: localPort,
listen: '127.0.0.1',
protocol: 'socks',
settings: {
auth: 'noauth',
}
},
outbound: {
protocol: 'vmess',
settings: {
vnext: [
{
address: nodeConfig.hostname,
port: nodeConfig.port,
users: [
{
id: nodeConfig.uuid,
alterId: Number(nodeConfig.alterId),
security: nodeConfig.method,
level: 0,
}
]
}
]
},
streamSettings: {
security: 'none',
},
}
};
if (nodeConfig.tls) {
config.outbound.streamSettings = Object.assign(Object.assign({}, config.outbound.streamSettings), { security: 'tls', tlsSettings: {
serverName: nodeConfig.host || nodeConfig.hostname,
} });
}
if (nodeConfig.network === 'ws') {
config.outbound.streamSettings = Object.assign(Object.assign({}, config.outbound.streamSettings), { network: nodeConfig.network, wsSettings: {
path: nodeConfig.path,
headers: {
Host: nodeConfig.host,
'User-Agent': exports.OBFS_UA,
},
} });
}
return config;
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9saWIvdXRpbHMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxvREFBNEI7QUFDNUIsa0RBQTBCO0FBQzFCLDRFQUFzQztBQUN0Qyx3REFBMEI7QUFDMUIsb0RBQXVCO0FBQ3ZCLDBEQUE0QjtBQUM1QixnREFBd0I7QUFDeEIsZ0VBQXVDO0FBRXZDLDhDQUFzQjtBQUN0QixvRUFBMkM7QUFDM0MsZ0RBQXdCO0FBQ3hCLDRDQUFvQjtBQUVwQixvQ0FnQmtCO0FBQ2xCLHFDQUEyQztBQUU5QixRQUFBLE9BQU8sR0FBRyxpSEFBaUgsQ0FBQztBQUN6SSxNQUFNLFdBQVcsR0FBRyxJQUFJLG1CQUFHLENBQWM7SUFDdkMsTUFBTSxFQUFFLEVBQUUsR0FBRyxFQUFFLEdBQUcsSUFBSTtDQUN2QixDQUFDLENBQUM7QUFFSCx1QkFBdUI7QUFDVixRQUFBLFdBQVcsR0FBRyxDQUFDLEdBQUcsSUFBdUIsRUFBVSxFQUFFLENBQUMsY0FBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsUUFBUSxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUM7QUFFOUYsUUFBQSxjQUFjLEdBQUcsQ0FBQyxVQUFrQixHQUFHLEVBQUUsWUFBb0IsRUFBVSxFQUFFLENBQUMsR0FBRyxPQUFPLEdBQUcsWUFBWSxFQUFFLENBQUM7QUFFdEcsUUFBQSxpQkFBaUIsR0FBRyxLQUFLLEVBQUUsTUFHdkMsRUFBMkMsRUFBRTtJQUM1QyxnQkFBTSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsNEJBQTRCLENBQUMsQ0FBQztJQUN0RCxnQkFBTSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsNEJBQTRCLENBQUMsQ0FBQztJQUV0RCxNQUFNLEdBQUcsR0FBRyxZQUFZLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQztJQUUxQyxLQUFLLFVBQVUseUJBQXlCLENBQUMsUUFBZ0IsRUFBRSxRQUFnQjtRQUN6RSxN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