Skip to content

Commit

Permalink
feat: 支持导出 Quantumult 的 HTTPS, Shadowsocksr 节点
Browse files Browse the repository at this point in the history
  • Loading branch information
geekdada committed Aug 27, 2019
1 parent 53466f2 commit dd728e0
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 8 deletions.
1 change: 0 additions & 1 deletion lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,6 @@ export interface ShadowsocksrNodeConfig extends SimpleNodeConfig {
readonly password: string;
readonly obfsparam: string;
readonly protoparam: string;
readonly group: string;
}

export interface VmessNodeConfig extends SimpleNodeConfig {
Expand Down
22 changes: 22 additions & 0 deletions lib/utils/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -462,10 +462,32 @@ test('getQuantumultNodes', t => {
host: '',
uuid: '1386f85e-657b-4d6e-9d56-78badb75e1fd',
},
{
type: NodeTypeEnum.Shadowsocksr,
nodeName: '🇭🇰HK',
hostname: 'hk.example.com',
port: 10000,
method: 'chacha20-ietf',
password: 'password',
obfs: 'tls1.2_ticket_auth',
obfsparam: 'music.163.com',
protocol: 'auth_aes128_md5',
protoparam: '',
},
{
type: NodeTypeEnum.HTTPS,
nodeName: 'test',
hostname: 'a.com',
port: 443,
username: 'snsms',
password: 'nndndnd',
}
])
.split('\n');

t.is(schemeList[0], 'vmess://5rWL6K+VIDEgPSB2bWVzcywxLjEuMS4xLDgwODAsY2hhY2hhMjAtaWV0Zi1wb2x5MTMwNSwiMTM4NmY4NWUtNjU3Yi00ZDZlLTlkNTYtNzhiYWRiNzVlMWZkIiw2NCxncm91cD1TdXJnaW8sb3Zlci10bHM9ZmFsc2UsY2VydGlmaWNhdGU9MSxvYmZzPXdzLG9iZnMtcGF0aD0iLyIsb2Jmcy1oZWFkZXI9Ikhvc3Q6ZXhhbXBsZS5jb21bUnJdW05uXVVzZXItQWdlbnQ6TW96aWxsYS81LjAgKGlQaG9uZTsgQ1BVIGlQaG9uZSBPUyAxMl8zXzEgbGlrZSBNYWMgT1MgWCkgQXBwbGVXZWJLaXQvNjA1LjEuMTUgKEtIVE1MLCBsaWtlIEdlY2tvKSBNb2JpbGUvMTVFMTQ4Ig==');
t.is(schemeList[1], 'vmess://5rWL6K+VIDIgPSB2bWVzcywxLjEuMS4xLDgwODAsY2hhY2hhMjAtaWV0Zi1wb2x5MTMwNSwiMTM4NmY4NWUtNjU3Yi00ZDZlLTlkNTYtNzhiYWRiNzVlMWZkIiw2NCxncm91cD1TdXJnaW8sb3Zlci10bHM9ZmFsc2UsY2VydGlmaWNhdGU9MSxvYmZzPXRjcCxvYmZzLXBhdGg9Ii8iLG9iZnMtaGVhZGVyPSJIb3N0OjEuMS4xLjFbUnJdW05uXVVzZXItQWdlbnQ6TW96aWxsYS81LjAgKGlQaG9uZTsgQ1BVIGlQaG9uZSBPUyAxMl8zXzEgbGlrZSBNYWMgT1MgWCkgQXBwbGVXZWJLaXQvNjA1LjEuMTUgKEtIVE1MLCBsaWtlIEdlY2tvKSBNb2JpbGUvMTVFMTQ4Ig==');
t.is(schemeList[2], 'vmess://5rWL6K+VIDMgPSB2bWVzcywxLjEuMS4xLDgwODAsY2hhY2hhMjAtaWV0Zi1wb2x5MTMwNSwiMTM4NmY4NWUtNjU3Yi00ZDZlLTlkNTYtNzhiYWRiNzVlMWZkIiw2NCxncm91cD1TdXJnaW8sb3Zlci10bHM9ZmFsc2UsY2VydGlmaWNhdGU9MSxvYmZzPXdzLG9iZnMtcGF0aD0iLyIsb2Jmcy1oZWFkZXI9Ikhvc3Q6MS4xLjEuMVtScl1bTm5dVXNlci1BZ2VudDpNb3ppbGxhLzUuMCAoaVBob25lOyBDUFUgaVBob25lIE9TIDEyXzNfMSBsaWtlIE1hYyBPUyBYKSBBcHBsZVdlYktpdC82MDUuMS4xNSAoS0hUTUwsIGxpa2UgR2Vja28pIE1vYmlsZS8xNUUxNDgi');
t.is(schemeList[3], 'ssr://aGsuZXhhbXBsZS5jb206MTAwMDA6YXV0aF9hZXMxMjhfbWQ1OmNoYWNoYTIwLWlldGY6dGxzMS4yX3RpY2tldF9hdXRoOmNHRnpjM2R2Y21RLz9ncm91cD1VM1Z5WjJsdiZvYmZzcGFyYW09YlhWemFXTXVNVFl6TG1OdmJRJnByb3RvcGFyYW09JnJlbWFya3M9OEotSHJmQ2ZoN0JJU3cmdWRwcG9ydD0wJnVvdD0w');
t.is(schemeList[4], 'http://dGVzdCA9IGh0dHAsIHVwc3RyZWFtLXByb3h5LWFkZHJlc3M9YS5jb20sIHVwc3RyZWFtLXByb3h5LXBvcnQ9NDQzLCB1cHN0cmVhbS1wcm94eS1hdXRoPXRydWUsIHVwc3RyZWFtLXByb3h5LXVzZXJuYW1lPXNuc21zLCB1cHN0cmVhbS1wcm94eS1wYXNzd29yZD1ubmRuZG5kLCBvdmVyLXRscz10cnVlLCBjZXJ0aWZpY2F0ZT0x');
});
35 changes: 28 additions & 7 deletions lib/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -314,8 +314,8 @@ export const getShadowsocksNodes = (
} = {
...(config.obfs ? {
plugin: `${encodeURIComponent(`obfs-local;obfs=${config.obfs};obfs-host=${config['obfs-host']}`)}`,
} : {}),
...(groupName ? { group: encodeURIComponent(groupName) } : {}),
} : null),
...(groupName ? { group: encodeURIComponent(groupName) } : null),
};

return [
Expand Down Expand Up @@ -344,7 +344,7 @@ export const getShadowsocksNodes = (
return result.join('\n');
};

export const getShadowsocksrNodes = (list: ReadonlyArray<ShadowsocksrNodeConfig>): string => {
export const getShadowsocksrNodes = (list: ReadonlyArray<ShadowsocksrNodeConfig>, groupName: string): string => {
const result: ReadonlyArray<string> = list
.map(nodeConfig => {
if (nodeConfig.enable === false) { return null; }
Expand All @@ -363,7 +363,7 @@ export const getShadowsocksrNodes = (list: ReadonlyArray<ShadowsocksrNodeConfig>
obfsparam: toUrlSafeBase64(nodeConfig.obfsparam),
protoparam: toUrlSafeBase64(nodeConfig.protoparam),
remarks: toUrlSafeBase64(nodeConfig.nodeName),
group: toUrlSafeBase64(nodeConfig.group),
group: toUrlSafeBase64(groupName),
udpport: 0,
uot: 0,
};
Expand Down Expand Up @@ -418,7 +418,7 @@ export const getV2rayNNodes = (list: ReadonlyArray<VmessNodeConfig>): string =>
};

export const getQuantumultNodes = (
list: ReadonlyArray<ShadowsocksNodeConfig | VmessNodeConfig>,
list: ReadonlyArray<ShadowsocksNodeConfig|VmessNodeConfig|ShadowsocksrNodeConfig|HttpsNodeConfig>,
groupName: string = 'Surgio'
): string => {
function getHeader(
Expand Down Expand Up @@ -459,6 +459,27 @@ export const getQuantumultNodes = (
return getShadowsocksNodes([nodeConfig], groupName);
}

case NodeTypeEnum.Shadowsocksr:
return getShadowsocksrNodes([nodeConfig], groupName);

case 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://' + toBase64(config);
}

default:
return null;
}
Expand Down Expand Up @@ -489,7 +510,7 @@ export const getShadowsocksNodesJSON = (list: ReadonlyArray<ShadowsocksNodeConfi
...(useObfs ? {
plugin: 'obfs-local',
'plugin-opts': `obfs=${nodeConfig.obfs};obfs-host=${nodeConfig['obfs-host']}`
} : {})
} : null)
};
}

Expand Down Expand Up @@ -550,7 +571,7 @@ export const getClashNodeNames = (
...(ruleType === 'url-test' ? {
url: 'http://www.gstatic.com/generate_204',
interval: 1200,
} : {}),
} : null),
};
};

Expand Down

0 comments on commit dd728e0

Please sign in to comment.