tunli 0.0.21 → 0.0.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -10,6 +10,7 @@ import {renewProxyUrlRegistration, requestNewProxyUrl} from "#lib/Flow/proxyUrl"
|
|
|
10
10
|
import {getCurrentIp} from "#lib/Flow/getCurrentIp";
|
|
11
11
|
import {arrayUnique} from "#src/utils/arrayFunctions";
|
|
12
12
|
import {initDashboard} from "#src/cli-app/Dashboard";
|
|
13
|
+
import {proxy} from "#lib/Proxy";
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* @callback httpCommandExec
|
|
@@ -94,9 +95,15 @@ const exec = (configRef, cmd, program) => {
|
|
|
94
95
|
protocol: options.protocol
|
|
95
96
|
}
|
|
96
97
|
|
|
98
|
+
const useDashboard = process.env.DASHBOARD !== 'off'
|
|
99
|
+
|
|
97
100
|
const client = new TunnelClient(clientOptions)
|
|
98
|
-
const dashboard = initDashboard(client, clientOptions, config)
|
|
101
|
+
const dashboard = useDashboard ? initDashboard(client, clientOptions, config) : null
|
|
99
102
|
await client.init(dashboard)
|
|
103
|
+
|
|
104
|
+
if (!useDashboard) {
|
|
105
|
+
console.log(clientOptions)
|
|
106
|
+
}
|
|
100
107
|
}
|
|
101
108
|
}
|
|
102
109
|
/**
|
package/src/lib/Proxy.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import {ConfigManager} from "#src/config/ConfigManager";
|
|
2
|
+
import {TunnelClient} from "#src/tunnel-client/TunnelClient";
|
|
3
|
+
import {renewProxyUrlRegistration} from "#lib/Flow/proxyUrl";
|
|
4
|
+
|
|
5
|
+
const prepareOptions = async (options) => {
|
|
6
|
+
|
|
7
|
+
options ??= {}
|
|
8
|
+
const localConf = ConfigManager.loadLocalOnly()
|
|
9
|
+
const globalConf = ConfigManager.loadGlobalOnly()
|
|
10
|
+
|
|
11
|
+
const authToken = globalConf.authToken
|
|
12
|
+
|
|
13
|
+
let preparedOptions = {authToken, ...localConf.dump(), ...options}
|
|
14
|
+
|
|
15
|
+
preparedOptions.server = await renewProxyUrlRegistration(preparedOptions.proxyURL, preparedOptions.authToken)
|
|
16
|
+
preparedOptions.denyCidr ??= []
|
|
17
|
+
preparedOptions.allowCidr ??= []
|
|
18
|
+
|
|
19
|
+
console.log(preparedOptions)
|
|
20
|
+
|
|
21
|
+
return preparedOptions
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
*
|
|
26
|
+
* @param {tunliProxyOptions} options
|
|
27
|
+
*/
|
|
28
|
+
export const proxy = async (options) => {
|
|
29
|
+
|
|
30
|
+
options = await prepareOptions(options)
|
|
31
|
+
const client = new TunnelClient(options)
|
|
32
|
+
|
|
33
|
+
await client.init()
|
|
34
|
+
console.log('INIT')
|
|
35
|
+
return options
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const tunli = {
|
|
39
|
+
proxy
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export default tunli
|
|
@@ -109,11 +109,15 @@ export const forwardTunnelRequestToProxyTarget = (req, eventEmitter, options) =>
|
|
|
109
109
|
setupErrorHandlers(tunnelRequest, localReq)
|
|
110
110
|
|
|
111
111
|
const onLocalResponse = (localRes) => {
|
|
112
|
+
|
|
112
113
|
localReq.off('error', onLocalError)
|
|
114
|
+
|
|
113
115
|
if (isWebSocket && localRes.upgrade) {
|
|
114
116
|
return
|
|
115
117
|
}
|
|
116
118
|
|
|
119
|
+
if (!isWebSocket) rewriteResponse(localRes, options)
|
|
120
|
+
|
|
117
121
|
const tunnelResponse = new TunnelResponse({
|
|
118
122
|
responseId: req.requestId,
|
|
119
123
|
socket: req.tunnelSocket,
|
|
@@ -175,3 +179,51 @@ export const forwardTunnelRequestToProxyTarget = (req, eventEmitter, options) =>
|
|
|
175
179
|
localReq.on('upgrade', onUpgrade)
|
|
176
180
|
}
|
|
177
181
|
}
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* @param {Response<IncomingMessage>} localRes
|
|
186
|
+
* @param {tunnelClientOptions} options
|
|
187
|
+
*/
|
|
188
|
+
const rewriteResponse = (localRes, options) => {
|
|
189
|
+
|
|
190
|
+
options.proxyURL ??= options.server
|
|
191
|
+
|
|
192
|
+
const hostSearch = options.origin ?? options.host
|
|
193
|
+
const {protocol: protocolReplace, hostname: hostReplace} = new URL(options.proxyURL)
|
|
194
|
+
const baseURL = new URL(`${options.protocol}://${hostSearch}:${options.port}`).toString()
|
|
195
|
+
|
|
196
|
+
if (localRes.statusCode === 301) {
|
|
197
|
+
delete localRes.headers.location
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
let location = localRes.headers.location
|
|
201
|
+
let setCookie = localRes.headers['set-cookie']
|
|
202
|
+
|
|
203
|
+
if (!setCookie || !Array.isArray(setCookie)) {
|
|
204
|
+
setCookie = null
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if (location) {
|
|
208
|
+
location = new URL(location, baseURL).toString()
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if (location && location.charAt(0) !== '/' && location.startsWith(baseURL)) {
|
|
212
|
+
localRes.headers.location = location.replace(baseURL, options.proxyURL)
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if (setCookie) {
|
|
216
|
+
localRes.headers['set-cookie'] = setCookie.map(cookie => {
|
|
217
|
+
return updateCookieDomain(cookie, hostReplace) // TODO MOVE THIS PART TO SERVER
|
|
218
|
+
})
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
function extractDomainFromCookieString(cookie) {
|
|
223
|
+
const domainMatch = cookie.match(/Domain=([^;]+)/);
|
|
224
|
+
return domainMatch ? domainMatch[1] : null;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
function updateCookieDomain(cookie, newDomain) {
|
|
228
|
+
return cookie.replace(/Domain=[^;]+/, `Domain=${newDomain}`);
|
|
229
|
+
}
|
|
@@ -94,6 +94,10 @@ export class TunnelClient extends EventEmitter {
|
|
|
94
94
|
setInterval(ping, 5000)
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
+
/**
|
|
98
|
+
* @param [dashboard]
|
|
99
|
+
* @return {Promise<TunnelClient>}
|
|
100
|
+
*/
|
|
97
101
|
async init(dashboard) {
|
|
98
102
|
|
|
99
103
|
const params = await this.#createParameters(dashboard)
|
|
@@ -108,7 +112,7 @@ export class TunnelClient extends EventEmitter {
|
|
|
108
112
|
const webSocketCapturePath = await securedHttpClient(options.authToken).get('/capture_path')
|
|
109
113
|
|
|
110
114
|
if (webSocketCapturePath.error) {
|
|
111
|
-
dashboard
|
|
115
|
+
dashboard?.destroy()
|
|
112
116
|
if (webSocketCapturePath.error?.message === 'Request failed with status code 401') {
|
|
113
117
|
console.error('missing authorization, check your registration and try again')
|
|
114
118
|
} else {
|