bdy 1.22.84 → 1.22.85-beta

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.
@@ -46,283 +46,18 @@ const http_1 = __importStar(require("./http"));
46
46
  const http2_1 = __importDefault(require("./server/http2"));
47
47
  const http1_1 = __importDefault(require("./server/http1"));
48
48
  const log_1 = __importDefault(require("./http/log"));
49
+ const auth_1 = __importDefault(require("./http/auth"));
50
+ const config_1 = __importDefault(require("./config"));
49
51
  const format_1 = __importDefault(require("../format"));
50
- const node_crypto_1 = __importDefault(require("node:crypto"));
51
- const node_zlib_1 = __importDefault(require("node:zlib"));
52
52
  const texts_1 = require("../texts");
53
53
  const dns_1 = __importDefault(require("./dns"));
54
54
  const tunnel_1 = require("../types/tunnel");
55
- const CIPHER_ALG = 'aes-256-cbc';
56
- const CIPHER_IV = Buffer.alloc(16).fill(0);
57
- const COOKIE_NAME = 'jwt_token';
58
- const ISSUERS = {
59
- 'https://stage-oidc.buddyusercontent.com': `-----BEGIN CERTIFICATE-----
60
- MIIEwDCCAqgCFBDp9Im/iI4hjQTeypaLQbZZZs45MA0GCSqGSIb3DQEBCwUAMBYx
61
- FDASBgNVBAMMC2J1ZGR5LndvcmtzMCAXDTIzMDIxNjA4MTMyOFoYDzIwNTMwMjA4
62
- MDgxMzI4WjAhMR8wHQYDVQQDDBYqLmJ1ZGR5dXNlcmNvbnRlbnQuY29tMIICIjAN
63
- BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvMDTFG4ha//vRxUb/AJpnubUi4Er
64
- z2TLxCNZBdHPwIqWvygvMHUmTySxMU+a05D/6yHnQiaqnXI0y7nh/ZYmkTqHs985
65
- 3hr5gN/kLmcujo3YtUIm93ZbPHsmaBSlvBSzS1sI8GFE2pqePTo3e/qSWtV6aQBI
66
- 0MTEAMKo3JokOft/9cMbdv212eo1Z7vkHvzO0IyAJ15fm4pX/to+2Xap2aG0M78K
67
- zVgtYdbJAmhstsGBaYxSr15PeDE0OkirevjRXPcGfyjV501tubGk18CH/hUBO3CB
68
- QOiAH2q1w8Istxus5xibpWYFHoPJiuZ1BryHHV4vnzkDS2RJ3tE+dXHAfIHIN2q0
69
- AjyDir0KZPOHLxOr17JsZuAfboVgLcZpmFWnm7hfZ6GfRt77ih9IFNi0doMbHmPx
70
- 9B436oaFTXXQdDdMiFSDel1DyKqe+BBiGyqfg9Dvw6Qk+pS0b6q+e/XZYwG9q8K6
71
- 6r1A+TribcAp0bl6O5XxFRdllEwbY9vbyoRX/bB0aKzhAkoP3Cuh4oss0ueiSwZC
72
- 5NUIGSdHMioGjhIGLNj7hv4pZfwr5cxkwPwO43Vv25qVej+AJJwdlRNXS2MSjTQg
73
- Z/sVVOXsgJHTDyP7ke388rqsgXjdoacoJkTXUdl0652wkRPl9UQ4InVfyNw24MVc
74
- 9ksePMYUIyW7rI8CAwEAATANBgkqhkiG9w0BAQsFAAOCAgEAa8I0iJ8155ihutvw
75
- 1HEqhWbQokANxCdJ3zfdu6guTjrG9HxD7kuloB3ZyVVQsLdZlZoFfZnpMKtnFK1v
76
- deDtEoayPiUI6DHURtxFHWOYM/VWJd41s3nIoilApBdESpNI6RQvb7JIXuXCDndc
77
- pvuZ6U0zMnWTVFK7MVrbxqRDMO/mCTJUKIqNLmGo+6YYfhWy8y3HHdnC86CFUy+T
78
- IaMuDEuqd3HvpqljgXM8o5cTCYawnQA2PKA36XiJoc+9A00EuVQw0ILQbw3aYaIX
79
- /PNiq3CCyt1YIjal+zSNMxNnmNEW7H5+arxbT+I8oWDZUR+KyeZJYRjuZGzqfRGt
80
- hAzRj7HKN0bU4Y97a7GyWaxzMtbunWnl8U+1TsM/9cfNgjKZxMopZCb1n/TfUDMo
81
- /67xEjDS2B/LcGOWDUEExLXaxCoLtVwk7co+Z4FXmiMDmoJmrE6lbGcMD1Ys+6Td
82
- el3K5ll/6obgUFZsUMPP6xV2+nFz+LThueWphs1+7s0eD3xanVijSHXS8HF87yvE
83
- eiq+rBRq7FE0Eqen6spTWFpjrmdBxY5Ti0z14KKXHGJStrpC5KquegwBIj0w/wNY
84
- O6+HPN73rzfhtkO+A0tAG7el3XtqI0fOXiD1xot84neFJV6/qxyvnRUamJjKCgK2
85
- X1wqKx71Z3gigILDphu5m3d0RRU=
86
- -----END CERTIFICATE-----`,
87
- 'https://stageeu-oidc.buddyusercontent.com': `-----BEGIN CERTIFICATE-----
88
- MIIEwDCCAqgCFBDp9Im/iI4hjQTeypaLQbZZZs45MA0GCSqGSIb3DQEBCwUAMBYx
89
- FDASBgNVBAMMC2J1ZGR5LndvcmtzMCAXDTIzMDIxNjA4MTMyOFoYDzIwNTMwMjA4
90
- MDgxMzI4WjAhMR8wHQYDVQQDDBYqLmJ1ZGR5dXNlcmNvbnRlbnQuY29tMIICIjAN
91
- BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvMDTFG4ha//vRxUb/AJpnubUi4Er
92
- z2TLxCNZBdHPwIqWvygvMHUmTySxMU+a05D/6yHnQiaqnXI0y7nh/ZYmkTqHs985
93
- 3hr5gN/kLmcujo3YtUIm93ZbPHsmaBSlvBSzS1sI8GFE2pqePTo3e/qSWtV6aQBI
94
- 0MTEAMKo3JokOft/9cMbdv212eo1Z7vkHvzO0IyAJ15fm4pX/to+2Xap2aG0M78K
95
- zVgtYdbJAmhstsGBaYxSr15PeDE0OkirevjRXPcGfyjV501tubGk18CH/hUBO3CB
96
- QOiAH2q1w8Istxus5xibpWYFHoPJiuZ1BryHHV4vnzkDS2RJ3tE+dXHAfIHIN2q0
97
- AjyDir0KZPOHLxOr17JsZuAfboVgLcZpmFWnm7hfZ6GfRt77ih9IFNi0doMbHmPx
98
- 9B436oaFTXXQdDdMiFSDel1DyKqe+BBiGyqfg9Dvw6Qk+pS0b6q+e/XZYwG9q8K6
99
- 6r1A+TribcAp0bl6O5XxFRdllEwbY9vbyoRX/bB0aKzhAkoP3Cuh4oss0ueiSwZC
100
- 5NUIGSdHMioGjhIGLNj7hv4pZfwr5cxkwPwO43Vv25qVej+AJJwdlRNXS2MSjTQg
101
- Z/sVVOXsgJHTDyP7ke388rqsgXjdoacoJkTXUdl0652wkRPl9UQ4InVfyNw24MVc
102
- 9ksePMYUIyW7rI8CAwEAATANBgkqhkiG9w0BAQsFAAOCAgEAa8I0iJ8155ihutvw
103
- 1HEqhWbQokANxCdJ3zfdu6guTjrG9HxD7kuloB3ZyVVQsLdZlZoFfZnpMKtnFK1v
104
- deDtEoayPiUI6DHURtxFHWOYM/VWJd41s3nIoilApBdESpNI6RQvb7JIXuXCDndc
105
- pvuZ6U0zMnWTVFK7MVrbxqRDMO/mCTJUKIqNLmGo+6YYfhWy8y3HHdnC86CFUy+T
106
- IaMuDEuqd3HvpqljgXM8o5cTCYawnQA2PKA36XiJoc+9A00EuVQw0ILQbw3aYaIX
107
- /PNiq3CCyt1YIjal+zSNMxNnmNEW7H5+arxbT+I8oWDZUR+KyeZJYRjuZGzqfRGt
108
- hAzRj7HKN0bU4Y97a7GyWaxzMtbunWnl8U+1TsM/9cfNgjKZxMopZCb1n/TfUDMo
109
- /67xEjDS2B/LcGOWDUEExLXaxCoLtVwk7co+Z4FXmiMDmoJmrE6lbGcMD1Ys+6Td
110
- el3K5ll/6obgUFZsUMPP6xV2+nFz+LThueWphs1+7s0eD3xanVijSHXS8HF87yvE
111
- eiq+rBRq7FE0Eqen6spTWFpjrmdBxY5Ti0z14KKXHGJStrpC5KquegwBIj0w/wNY
112
- O6+HPN73rzfhtkO+A0tAG7el3XtqI0fOXiD1xot84neFJV6/qxyvnRUamJjKCgK2
113
- X1wqKx71Z3gigILDphu5m3d0RRU=
114
- -----END CERTIFICATE-----`,
115
- 'https://oidc.buddyusercontent.com': `-----BEGIN CERTIFICATE-----
116
- MIIEwDCCAqgCFCIRhplNpTZLH9WdAbZus4xHHjPXMA0GCSqGSIb3DQEBCwUAMBYx
117
- FDASBgNVBAMMC2J1ZGR5LndvcmtzMCAXDTIzMDIxNjA4MTM1M1oYDzIwNTMwMjA4
118
- MDgxMzUzWjAhMR8wHQYDVQQDDBYqLmJ1ZGR5dXNlcmNvbnRlbnQuY29tMIICIjAN
119
- BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAuA5ulo8uVKsxLcgIDn3DtnoMdyJv
120
- BHHl68b1p+SAb4OEN4SlEdl33jy2LMNwr0SS6Mh7VT9tkCUAxDpmImTdsd59qhqu
121
- 5oxCnE5slx5/RmV0/RgCZRjy0phmPIImsMAvBsFY6+c+fPZfxJGs+uWtXXRS1IgI
122
- LO0BXSqIF2UIst+R787vynmI6UFPaD7bKaJkM79RPanjqvma+y8VvJU2isqz3bjS
123
- T32842iGlwnkwzz4SfOIiVgKT8HhnZsD5YmtTMPYYghgWj1HtMxOTJ/qEuXiLWfg
124
- TzqPI6Z2usnUb2lJl/EtEHILLyU4hfYr113nO3VIG6iLZahRttbelqujfWbQXS0w
125
- nAGn0e4RD5OzG+bu/y4yYBoQ2kRGtFpIH4nXOw43PhKo0rALAllrpQi4p26KYqWk
126
- r27BuOoZWmB2nkVm2v7vnDa6e2CpwXMaLpIFDANeSoK8Tr+RaHCp1JNMI7zYVejN
127
- C9bOKL35/Q0gsxWW3BdLL/EtTrwZKGlJtovkBQdFkEmiNnK8tc4BLKDmtYFsf8HZ
128
- I0jYHwVD90DP9lMJG/VFZl2xUBHKq7UjX/CLgRPc1S5QiqeHFh0kWVilcrVauaTT
129
- nAX2cG41lxGSH/60zxtOAYqKIdEvvQdHVl3S1AHemENl/ngh9kt2oU5+1Csb/+jG
130
- zrE5dI3ipDCUNHMCAwEAATANBgkqhkiG9w0BAQsFAAOCAgEAuZCIfMcexrKHEcQM
131
- otb6PXrCEOdiVq+vQuVAQCMfC9MyGcufxLY9+QhuPSVhsyZ1ffZufF6oT+HlQY4z
132
- 5E5CE7kTw1q9Gpu4RHEtlg7ALvpAy+Hfi2sAJy6r6Tqa5hEoi/8qQFgqTn5ooFr2
133
- SkjK72dx3YkgRsV9P7O9TlteLgwd6POLmrbibvcGB9CiPSL/SmItT2vpASUxow0a
134
- JiyrbBgPQFaKPocfJJ917Zur1bigdUoCK+S0vq5tOFWrm3HXDIiz5+aB5/cW9/3W
135
- AXghWYdAStJH9xTIWA7dk8V4SPJjjQWhyG+GxM+oE999K4iPTOpGMjLfG/ZiLKLg
136
- 1Z3gO3wNP2BrhotrAxVRcynvm6552nzDos9ybiq1VPbiz8qLYThNTu/tlw2JbCXw
137
- PWaM1jh8B2v5Q4NhRKnl3Zz03RtNHwAUYzZLahe47/ADb5/XC86H46NRLHZB3QIO
138
- wXYcTFrCskkdoGEZwiiqUchYjvWKb9++WHkPGGBaLhAlaCZNTgGXyt8OYJSRwIfT
139
- YbGYXuZMGUV3U63WZm3fOpHflQPkC9bzmK9MgFshhUlB0xk1vC1dkC2I5jOGJqa0
140
- 3yZghw2R+f5zGZd7TusSmm7Kk8i6mCssRG8B3R8p+6a6GQFeWtqQcUV/dcJVs9sx
141
- ZbFKWzfs9+m8Y04W4PmzZM2ZAN8=
142
- -----END CERTIFICATE-----`,
143
- 'https://eu-oidc.buddyusercontent.com': `-----BEGIN CERTIFICATE-----
144
- MIIEwDCCAqgCFCIRhplNpTZLH9WdAbZus4xHHjPXMA0GCSqGSIb3DQEBCwUAMBYx
145
- FDASBgNVBAMMC2J1ZGR5LndvcmtzMCAXDTIzMDIxNjA4MTM1M1oYDzIwNTMwMjA4
146
- MDgxMzUzWjAhMR8wHQYDVQQDDBYqLmJ1ZGR5dXNlcmNvbnRlbnQuY29tMIICIjAN
147
- BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAuA5ulo8uVKsxLcgIDn3DtnoMdyJv
148
- BHHl68b1p+SAb4OEN4SlEdl33jy2LMNwr0SS6Mh7VT9tkCUAxDpmImTdsd59qhqu
149
- 5oxCnE5slx5/RmV0/RgCZRjy0phmPIImsMAvBsFY6+c+fPZfxJGs+uWtXXRS1IgI
150
- LO0BXSqIF2UIst+R787vynmI6UFPaD7bKaJkM79RPanjqvma+y8VvJU2isqz3bjS
151
- T32842iGlwnkwzz4SfOIiVgKT8HhnZsD5YmtTMPYYghgWj1HtMxOTJ/qEuXiLWfg
152
- TzqPI6Z2usnUb2lJl/EtEHILLyU4hfYr113nO3VIG6iLZahRttbelqujfWbQXS0w
153
- nAGn0e4RD5OzG+bu/y4yYBoQ2kRGtFpIH4nXOw43PhKo0rALAllrpQi4p26KYqWk
154
- r27BuOoZWmB2nkVm2v7vnDa6e2CpwXMaLpIFDANeSoK8Tr+RaHCp1JNMI7zYVejN
155
- C9bOKL35/Q0gsxWW3BdLL/EtTrwZKGlJtovkBQdFkEmiNnK8tc4BLKDmtYFsf8HZ
156
- I0jYHwVD90DP9lMJG/VFZl2xUBHKq7UjX/CLgRPc1S5QiqeHFh0kWVilcrVauaTT
157
- nAX2cG41lxGSH/60zxtOAYqKIdEvvQdHVl3S1AHemENl/ngh9kt2oU5+1Csb/+jG
158
- zrE5dI3ipDCUNHMCAwEAATANBgkqhkiG9w0BAQsFAAOCAgEAuZCIfMcexrKHEcQM
159
- otb6PXrCEOdiVq+vQuVAQCMfC9MyGcufxLY9+QhuPSVhsyZ1ffZufF6oT+HlQY4z
160
- 5E5CE7kTw1q9Gpu4RHEtlg7ALvpAy+Hfi2sAJy6r6Tqa5hEoi/8qQFgqTn5ooFr2
161
- SkjK72dx3YkgRsV9P7O9TlteLgwd6POLmrbibvcGB9CiPSL/SmItT2vpASUxow0a
162
- JiyrbBgPQFaKPocfJJ917Zur1bigdUoCK+S0vq5tOFWrm3HXDIiz5+aB5/cW9/3W
163
- AXghWYdAStJH9xTIWA7dk8V4SPJjjQWhyG+GxM+oE999K4iPTOpGMjLfG/ZiLKLg
164
- 1Z3gO3wNP2BrhotrAxVRcynvm6552nzDos9ybiq1VPbiz8qLYThNTu/tlw2JbCXw
165
- PWaM1jh8B2v5Q4NhRKnl3Zz03RtNHwAUYzZLahe47/ADb5/XC86H46NRLHZB3QIO
166
- wXYcTFrCskkdoGEZwiiqUchYjvWKb9++WHkPGGBaLhAlaCZNTgGXyt8OYJSRwIfT
167
- YbGYXuZMGUV3U63WZm3fOpHflQPkC9bzmK9MgFshhUlB0xk1vC1dkC2I5jOGJqa0
168
- 3yZghw2R+f5zGZd7TusSmm7Kk8i6mCssRG8B3R8p+6a6GQFeWtqQcUV/dcJVs9sx
169
- ZbFKWzfs9+m8Y04W4PmzZM2ZAN8=
170
- -----END CERTIFICATE-----`,
171
- 'https://as-oidc.buddyusercontent.com': `-----BEGIN CERTIFICATE-----
172
- MIIEwDCCAqgCFCIRhplNpTZLH9WdAbZus4xHHjPXMA0GCSqGSIb3DQEBCwUAMBYx
173
- FDASBgNVBAMMC2J1ZGR5LndvcmtzMCAXDTIzMDIxNjA4MTM1M1oYDzIwNTMwMjA4
174
- MDgxMzUzWjAhMR8wHQYDVQQDDBYqLmJ1ZGR5dXNlcmNvbnRlbnQuY29tMIICIjAN
175
- BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAuA5ulo8uVKsxLcgIDn3DtnoMdyJv
176
- BHHl68b1p+SAb4OEN4SlEdl33jy2LMNwr0SS6Mh7VT9tkCUAxDpmImTdsd59qhqu
177
- 5oxCnE5slx5/RmV0/RgCZRjy0phmPIImsMAvBsFY6+c+fPZfxJGs+uWtXXRS1IgI
178
- LO0BXSqIF2UIst+R787vynmI6UFPaD7bKaJkM79RPanjqvma+y8VvJU2isqz3bjS
179
- T32842iGlwnkwzz4SfOIiVgKT8HhnZsD5YmtTMPYYghgWj1HtMxOTJ/qEuXiLWfg
180
- TzqPI6Z2usnUb2lJl/EtEHILLyU4hfYr113nO3VIG6iLZahRttbelqujfWbQXS0w
181
- nAGn0e4RD5OzG+bu/y4yYBoQ2kRGtFpIH4nXOw43PhKo0rALAllrpQi4p26KYqWk
182
- r27BuOoZWmB2nkVm2v7vnDa6e2CpwXMaLpIFDANeSoK8Tr+RaHCp1JNMI7zYVejN
183
- C9bOKL35/Q0gsxWW3BdLL/EtTrwZKGlJtovkBQdFkEmiNnK8tc4BLKDmtYFsf8HZ
184
- I0jYHwVD90DP9lMJG/VFZl2xUBHKq7UjX/CLgRPc1S5QiqeHFh0kWVilcrVauaTT
185
- nAX2cG41lxGSH/60zxtOAYqKIdEvvQdHVl3S1AHemENl/ngh9kt2oU5+1Csb/+jG
186
- zrE5dI3ipDCUNHMCAwEAATANBgkqhkiG9w0BAQsFAAOCAgEAuZCIfMcexrKHEcQM
187
- otb6PXrCEOdiVq+vQuVAQCMfC9MyGcufxLY9+QhuPSVhsyZ1ffZufF6oT+HlQY4z
188
- 5E5CE7kTw1q9Gpu4RHEtlg7ALvpAy+Hfi2sAJy6r6Tqa5hEoi/8qQFgqTn5ooFr2
189
- SkjK72dx3YkgRsV9P7O9TlteLgwd6POLmrbibvcGB9CiPSL/SmItT2vpASUxow0a
190
- JiyrbBgPQFaKPocfJJ917Zur1bigdUoCK+S0vq5tOFWrm3HXDIiz5+aB5/cW9/3W
191
- AXghWYdAStJH9xTIWA7dk8V4SPJjjQWhyG+GxM+oE999K4iPTOpGMjLfG/ZiLKLg
192
- 1Z3gO3wNP2BrhotrAxVRcynvm6552nzDos9ybiq1VPbiz8qLYThNTu/tlw2JbCXw
193
- PWaM1jh8B2v5Q4NhRKnl3Zz03RtNHwAUYzZLahe47/ADb5/XC86H46NRLHZB3QIO
194
- wXYcTFrCskkdoGEZwiiqUchYjvWKb9++WHkPGGBaLhAlaCZNTgGXyt8OYJSRwIfT
195
- YbGYXuZMGUV3U63WZm3fOpHflQPkC9bzmK9MgFshhUlB0xk1vC1dkC2I5jOGJqa0
196
- 3yZghw2R+f5zGZd7TusSmm7Kk8i6mCssRG8B3R8p+6a6GQFeWtqQcUV/dcJVs9sx
197
- ZbFKWzfs9+m8Y04W4PmzZM2ZAN8=
198
- -----END CERTIFICATE-----`,
199
- 'https://master-oidc.buddyusercontent.com': `-----BEGIN CERTIFICATE-----
200
- MIIEwDCCAqgCFBDp9Im/iI4hjQTeypaLQbZZZs47MA0GCSqGSIb3DQEBCwUAMBYx
201
- FDASBgNVBAMMC2J1ZGR5LndvcmtzMCAXDTIzMDIxNjA4MTM0NVoYDzIwNTMwMjA4
202
- MDgxMzQ1WjAhMR8wHQYDVQQDDBYqLmJ1ZGR5dXNlcmNvbnRlbnQuY29tMIICIjAN
203
- BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAyHdEa5QrqJVIAESbgkIMw/pPAJ1R
204
- kIlin/BQBn43YmcIpw/uFSPol9M5S9WkVMESWhM+wk3V+byiAULOm7FQ5N1AqRMa
205
- msxmuFenDJQEtEZ/Ca/HQXSOqwUG0TTIE5OZxuJy0SlEIjNPE56cJhp/ojOkvhXn
206
- mdPtjPI8sslF4CXAHW8qTa/N9L66ro5WMEVba/XGzdySOSN3z8ycr1583ZVXPK7x
207
- nvo/LrskdbPIjNz8firGp2OBsM0qeINmTUBLFVkWRj4PGgcCGRd1bV4C085obtep
208
- 0Cg/xZen3TQmoAFFsGVSO/3FP/lNv598HrzyHQKN/d2pl1d06NUl7mM7SLdHCbvi
209
- 3zVe1Ntr01QJuQGo3Uv9v4D6j1urzN25ghSfjOzjmTJjpGIwHfKJlVy674laq7mT
210
- KBnkpwmOgvbPSaaYQ8ik72PuLb73IWkxIaQ4Hr0pqUw00CDLO9p1gcz/biktxhxj
211
- d48SzS0tQXQMTSKZYWWzfh+Q5rCwVKozzyHPHSJuLxetrtxEcnt5OQFqKu3bcCwI
212
- xoFLpl5BQjBTrvigOO2ElQxGz2+N7W9zu5VLOl0nCw5MQwN9KXyVHVEYYbC3Mmnq
213
- RSuudH/25SuYMaEkIUoQa7vgJmwPJ4uWVSExO9fnOmA0L0GM+1WbU3BgEp3FUVSw
214
- x4QPC1swwlhkVkkCAwEAATANBgkqhkiG9w0BAQsFAAOCAgEApZEjwNCxWHxuAMwE
215
- jvlEouPs+yZsaxxIC44kKuwNacvk5pV4lC4w59pDTlZghgQwGvT7YlU0GfNrZbJi
216
- 2mREXH2DQt2GPv0roFYJGfT+tranbmmozJXdohSqllcM6Ev2f5I5Y7AkZePX3vAE
217
- aY0CJzBq9WTnfEjZCOcrkuI4hSccZ53R2DMm3IU2SBfwJlY5HwFLOokwUOgbVMCN
218
- O5szeNqGgdJjeNGwzCN3u0GwnKNhbvz02FsL+LSe2Mj9K5y5B950DIK6Nuj79nbj
219
- 48uYcplsLBB7g1977QlTBnUVASy859Uajydla6RREw6ZPESVkZHXXJ7+2ek+vnnt
220
- 5RHcbfnR+79MaKfUyVrtHmqtr5osvjhPQ9m9cmQG9UzoidKbxbYm6b6HbNRL5v79
221
- YNO/12X5pH5h5lc5iFc/0S5NQuOq1OT7lzZNcE0H87rvIvThW0U/X4KVqYj7XY90
222
- z2U1X+SDiq8ldzXtUYIJnl9J4v+I+u9iyJqYHYBBjj3Wn1NTzuE3ZDEBiwguuVUN
223
- aKEbQvoT3Eh8nNw3v/BVThjTpa+pMWlI6XpMi9rcN8/edLgaCbMaO059KJTwx4hq
224
- gUkjwZKhdE4s4pAn1BF644kkVdx2FXzdtmTfYWx1Rnsp1T0sxlzgMWltMd8wAuzS
225
- 5cMq3aQmM1PRT/Q2XYwq7FhiiUg=
226
- -----END CERTIFICATE-----`,
227
- 'https://sls-oidc.buddyusercontent.com': `-----BEGIN CERTIFICATE-----
228
- MIIEwDCCAqgCFBDp9Im/iI4hjQTeypaLQbZZZs45MA0GCSqGSIb3DQEBCwUAMBYx
229
- FDASBgNVBAMMC2J1ZGR5LndvcmtzMCAXDTIzMDIxNjA4MTMyOFoYDzIwNTMwMjA4
230
- MDgxMzI4WjAhMR8wHQYDVQQDDBYqLmJ1ZGR5dXNlcmNvbnRlbnQuY29tMIICIjAN
231
- BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvMDTFG4ha//vRxUb/AJpnubUi4Er
232
- z2TLxCNZBdHPwIqWvygvMHUmTySxMU+a05D/6yHnQiaqnXI0y7nh/ZYmkTqHs985
233
- 3hr5gN/kLmcujo3YtUIm93ZbPHsmaBSlvBSzS1sI8GFE2pqePTo3e/qSWtV6aQBI
234
- 0MTEAMKo3JokOft/9cMbdv212eo1Z7vkHvzO0IyAJ15fm4pX/to+2Xap2aG0M78K
235
- zVgtYdbJAmhstsGBaYxSr15PeDE0OkirevjRXPcGfyjV501tubGk18CH/hUBO3CB
236
- QOiAH2q1w8Istxus5xibpWYFHoPJiuZ1BryHHV4vnzkDS2RJ3tE+dXHAfIHIN2q0
237
- AjyDir0KZPOHLxOr17JsZuAfboVgLcZpmFWnm7hfZ6GfRt77ih9IFNi0doMbHmPx
238
- 9B436oaFTXXQdDdMiFSDel1DyKqe+BBiGyqfg9Dvw6Qk+pS0b6q+e/XZYwG9q8K6
239
- 6r1A+TribcAp0bl6O5XxFRdllEwbY9vbyoRX/bB0aKzhAkoP3Cuh4oss0ueiSwZC
240
- 5NUIGSdHMioGjhIGLNj7hv4pZfwr5cxkwPwO43Vv25qVej+AJJwdlRNXS2MSjTQg
241
- Z/sVVOXsgJHTDyP7ke388rqsgXjdoacoJkTXUdl0652wkRPl9UQ4InVfyNw24MVc
242
- 9ksePMYUIyW7rI8CAwEAATANBgkqhkiG9w0BAQsFAAOCAgEAa8I0iJ8155ihutvw
243
- 1HEqhWbQokANxCdJ3zfdu6guTjrG9HxD7kuloB3ZyVVQsLdZlZoFfZnpMKtnFK1v
244
- deDtEoayPiUI6DHURtxFHWOYM/VWJd41s3nIoilApBdESpNI6RQvb7JIXuXCDndc
245
- pvuZ6U0zMnWTVFK7MVrbxqRDMO/mCTJUKIqNLmGo+6YYfhWy8y3HHdnC86CFUy+T
246
- IaMuDEuqd3HvpqljgXM8o5cTCYawnQA2PKA36XiJoc+9A00EuVQw0ILQbw3aYaIX
247
- /PNiq3CCyt1YIjal+zSNMxNnmNEW7H5+arxbT+I8oWDZUR+KyeZJYRjuZGzqfRGt
248
- hAzRj7HKN0bU4Y97a7GyWaxzMtbunWnl8U+1TsM/9cfNgjKZxMopZCb1n/TfUDMo
249
- /67xEjDS2B/LcGOWDUEExLXaxCoLtVwk7co+Z4FXmiMDmoJmrE6lbGcMD1Ys+6Td
250
- el3K5ll/6obgUFZsUMPP6xV2+nFz+LThueWphs1+7s0eD3xanVijSHXS8HF87yvE
251
- eiq+rBRq7FE0Eqen6spTWFpjrmdBxY5Ti0z14KKXHGJStrpC5KquegwBIj0w/wNY
252
- O6+HPN73rzfhtkO+A0tAG7el3XtqI0fOXiD1xot84neFJV6/qxyvnRUamJjKCgK2
253
- X1wqKx71Z3gigILDphu5m3d0RRU=
254
- -----END CERTIFICATE-----`,
255
- '*': `-----BEGIN CERTIFICATE-----
256
- MIIEwDCCAqgCFBDp9Im/iI4hjQTeypaLQbZZZs45MA0GCSqGSIb3DQEBCwUAMBYx
257
- FDASBgNVBAMMC2J1ZGR5LndvcmtzMCAXDTIzMDIxNjA4MTMyOFoYDzIwNTMwMjA4
258
- MDgxMzI4WjAhMR8wHQYDVQQDDBYqLmJ1ZGR5dXNlcmNvbnRlbnQuY29tMIICIjAN
259
- BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvMDTFG4ha//vRxUb/AJpnubUi4Er
260
- z2TLxCNZBdHPwIqWvygvMHUmTySxMU+a05D/6yHnQiaqnXI0y7nh/ZYmkTqHs985
261
- 3hr5gN/kLmcujo3YtUIm93ZbPHsmaBSlvBSzS1sI8GFE2pqePTo3e/qSWtV6aQBI
262
- 0MTEAMKo3JokOft/9cMbdv212eo1Z7vkHvzO0IyAJ15fm4pX/to+2Xap2aG0M78K
263
- zVgtYdbJAmhstsGBaYxSr15PeDE0OkirevjRXPcGfyjV501tubGk18CH/hUBO3CB
264
- QOiAH2q1w8Istxus5xibpWYFHoPJiuZ1BryHHV4vnzkDS2RJ3tE+dXHAfIHIN2q0
265
- AjyDir0KZPOHLxOr17JsZuAfboVgLcZpmFWnm7hfZ6GfRt77ih9IFNi0doMbHmPx
266
- 9B436oaFTXXQdDdMiFSDel1DyKqe+BBiGyqfg9Dvw6Qk+pS0b6q+e/XZYwG9q8K6
267
- 6r1A+TribcAp0bl6O5XxFRdllEwbY9vbyoRX/bB0aKzhAkoP3Cuh4oss0ueiSwZC
268
- 5NUIGSdHMioGjhIGLNj7hv4pZfwr5cxkwPwO43Vv25qVej+AJJwdlRNXS2MSjTQg
269
- Z/sVVOXsgJHTDyP7ke388rqsgXjdoacoJkTXUdl0652wkRPl9UQ4InVfyNw24MVc
270
- 9ksePMYUIyW7rI8CAwEAATANBgkqhkiG9w0BAQsFAAOCAgEAa8I0iJ8155ihutvw
271
- 1HEqhWbQokANxCdJ3zfdu6guTjrG9HxD7kuloB3ZyVVQsLdZlZoFfZnpMKtnFK1v
272
- deDtEoayPiUI6DHURtxFHWOYM/VWJd41s3nIoilApBdESpNI6RQvb7JIXuXCDndc
273
- pvuZ6U0zMnWTVFK7MVrbxqRDMO/mCTJUKIqNLmGo+6YYfhWy8y3HHdnC86CFUy+T
274
- IaMuDEuqd3HvpqljgXM8o5cTCYawnQA2PKA36XiJoc+9A00EuVQw0ILQbw3aYaIX
275
- /PNiq3CCyt1YIjal+zSNMxNnmNEW7H5+arxbT+I8oWDZUR+KyeZJYRjuZGzqfRGt
276
- hAzRj7HKN0bU4Y97a7GyWaxzMtbunWnl8U+1TsM/9cfNgjKZxMopZCb1n/TfUDMo
277
- /67xEjDS2B/LcGOWDUEExLXaxCoLtVwk7co+Z4FXmiMDmoJmrE6lbGcMD1Ys+6Td
278
- el3K5ll/6obgUFZsUMPP6xV2+nFz+LThueWphs1+7s0eD3xanVijSHXS8HF87yvE
279
- eiq+rBRq7FE0Eqen6spTWFpjrmdBxY5Ti0z14KKXHGJStrpC5KquegwBIj0w/wNY
280
- O6+HPN73rzfhtkO+A0tAG7el3XtqI0fOXiD1xot84neFJV6/qxyvnRUamJjKCgK2
281
- X1wqKx71Z3gigILDphu5m3d0RRU=
282
- -----END CERTIFICATE-----`,
283
- };
284
55
  class Tunnel extends events_1.default {
285
56
  agent;
286
57
  id;
287
- cipherKey;
288
58
  sshHostKey;
289
- type;
290
- region;
291
- target;
292
- whitelist;
293
- domain;
294
- subdomain;
295
- name;
296
- timeout;
297
- useragents;
298
- headers;
299
- responseHeaders;
300
- terminate;
301
- key;
302
- cert;
303
- ca;
304
- host;
305
- login;
306
- password;
307
- authType;
308
- serve;
309
- circuitBreaker;
310
- log;
311
- verify;
312
- compression;
313
- http2;
314
- sshIp;
315
- sshId;
316
- sshPort;
317
- sshUser;
318
- sshPassword;
319
- sshForwardPort;
320
- sshClientUser;
321
- sshClientPassword;
322
- targetProto;
323
- targetHost;
324
- targetPort;
325
- targetAuth;
59
+ config;
60
+ auth;
326
61
  totalConnections;
327
62
  status;
328
63
  connections;
@@ -337,128 +72,129 @@ class Tunnel extends events_1.default {
337
72
  sshServer;
338
73
  ssh;
339
74
  started;
340
- httpAuthClient;
341
- constructor({ agent, id, type, target, region, timeout, domain, name, subdomain, whitelist, tlsSettings, httpSettings, sshSettings, sshHostKey, }) {
75
+ constructor({ agent, id, sshHostKey, ...options }) {
342
76
  super();
343
- this.httpAuthClient = {};
344
77
  if (!sshHostKey)
345
78
  sshHostKey = require('../sshKeygen').createSshHostKey();
346
79
  this.agent = agent;
347
80
  this.id = id;
348
- this.cipherKey = node_crypto_1.default
349
- .createHash('sha512')
350
- .update(this.id)
351
- .digest('hex')
352
- .substring(0, 32);
353
81
  this.sshHostKey = sshHostKey;
354
- this.create({
355
- type,
356
- target,
357
- region,
358
- timeout,
359
- domain,
360
- subdomain,
361
- name,
362
- whitelist,
363
- tlsSettings,
364
- httpSettings,
365
- sshSettings,
366
- });
82
+ this.auth = new auth_1.default(this);
83
+ this.config = new config_1.default(options);
84
+ this.resetState();
367
85
  }
368
- create({ type, target, region, timeout, domain, subdomain, name, whitelist, tlsSettings, httpSettings, sshSettings, }) {
369
- this.type = type;
370
- this.region = region;
371
- this.target = target;
372
- this.whitelist = whitelist || [];
373
- this.domain = domain;
374
- this.subdomain = subdomain;
375
- this.name = name;
376
- this.timeout = timeout || utils_1.DEFAULT_TIMEOUT;
377
- this.useragents = [];
378
- this.headers = [];
379
- this.responseHeaders = [];
380
- if (tlsSettings) {
381
- this.terminate = tlsSettings.terminate;
382
- this.key = tlsSettings.key;
383
- this.cert = tlsSettings.cert;
384
- this.ca = tlsSettings.ca;
385
- }
386
- if (httpSettings) {
387
- this.host = httpSettings.host;
388
- if (httpSettings.authType) {
389
- this.authType = httpSettings.authType;
390
- if (this.authType === tunnel_1.TUNNEL_HTTP_AUTH_TYPE.BASIC) {
391
- this.login = httpSettings.login || '';
392
- this.password = httpSettings.password || '';
393
- }
394
- }
395
- else if (httpSettings.login || httpSettings.password) {
396
- this.authType = tunnel_1.TUNNEL_HTTP_AUTH_TYPE.BASIC;
397
- this.login = httpSettings.login || '';
398
- this.password = httpSettings.password || '';
399
- }
400
- else {
401
- this.authType = tunnel_1.TUNNEL_HTTP_AUTH_TYPE.NONE;
402
- }
403
- this.ca = httpSettings.ca;
404
- this.serve = httpSettings.serve;
405
- this.useragents = httpSettings.userAgents || [];
406
- this.headers = httpSettings.headers || [];
407
- this.responseHeaders = httpSettings.responseHeaders || [];
408
- this.circuitBreaker = httpSettings.circuitBreaker;
409
- this.log = httpSettings.log;
410
- this.verify = httpSettings.verify;
411
- this.compression = httpSettings.compression;
412
- this.http2 = httpSettings.http2;
413
- }
414
- if (sshSettings) {
415
- this.sshIp = sshSettings.ip;
416
- this.sshId = sshSettings.sshId;
417
- this.sshPort = sshSettings.port;
418
- this.sshUser = sshSettings.user;
419
- this.sshPassword = sshSettings.password;
420
- this.sshForwardPort = sshSettings.forwardPort;
421
- this.sshClientUser = sshSettings.clientUser;
422
- this.sshClientPassword = sshSettings.clientPassword;
423
- }
424
- this.targetProto = 'http';
425
- this.targetHost = 'localhost';
426
- this.targetPort = 80;
427
- this.targetAuth = null;
428
- if (this.type === tunnel_1.TUNNEL_TYPE.HTTP) {
429
- let m = this.target.match(utils_1.TARGET_ONLY_PORT_REGEX);
430
- if (m) {
431
- this.targetPort = parseInt(m[0], 10);
432
- }
433
- else {
434
- m = this.target.match(utils_1.TARGET_HTTP_REGEX);
435
- if (m) {
436
- if (m[2])
437
- this.targetProto = m[2];
438
- if (m[6])
439
- this.targetPort = parseInt(m[6], 10);
440
- else if (this.targetProto === 'https')
441
- this.targetPort = 443;
442
- if (m[4])
443
- this.targetHost = m[4];
444
- if (m[3])
445
- this.targetAuth = m[3].replace(/@$/, '');
446
- }
447
- }
448
- }
449
- else if (this.type === tunnel_1.TUNNEL_TYPE.SSH) {
450
- this.targetHost = 'localhost';
451
- this.targetProto = 'ssh://';
452
- this.targetPort = 22;
453
- }
454
- else {
455
- const m = this.target.match(utils_1.TARGET_TCP_TLS_REGEX);
456
- if (m) {
457
- this.targetPort = parseInt(m[3], 10);
458
- if (m[2])
459
- this.targetHost = m[2];
460
- }
461
- }
86
+ get type() {
87
+ return this.config.type;
88
+ }
89
+ get region() {
90
+ return this.config.region;
91
+ }
92
+ get target() {
93
+ return this.config.target;
94
+ }
95
+ get whitelist() {
96
+ return this.config.whitelist;
97
+ }
98
+ get domain() {
99
+ return this.config.domain;
100
+ }
101
+ get subdomain() {
102
+ return this.config.subdomain;
103
+ }
104
+ get name() {
105
+ return this.config.name;
106
+ }
107
+ get timeout() {
108
+ return this.config.timeout;
109
+ }
110
+ get useragents() {
111
+ return this.config.useragents;
112
+ }
113
+ get headers() {
114
+ return this.config.headers;
115
+ }
116
+ get responseHeaders() {
117
+ return this.config.responseHeaders;
118
+ }
119
+ get terminate() {
120
+ return this.config.terminate;
121
+ }
122
+ get key() {
123
+ return this.config.key;
124
+ }
125
+ get cert() {
126
+ return this.config.cert;
127
+ }
128
+ get ca() {
129
+ return this.config.ca;
130
+ }
131
+ get host() {
132
+ return this.config.host;
133
+ }
134
+ get login() {
135
+ return this.config.login;
136
+ }
137
+ get password() {
138
+ return this.config.password;
139
+ }
140
+ get authType() {
141
+ return this.config.authType;
142
+ }
143
+ get serve() {
144
+ return this.config.serve;
145
+ }
146
+ get circuitBreaker() {
147
+ return this.config.circuitBreaker;
148
+ }
149
+ get log() {
150
+ return this.config.log;
151
+ }
152
+ get verify() {
153
+ return this.config.verify;
154
+ }
155
+ get compression() {
156
+ return this.config.compression;
157
+ }
158
+ get http2() {
159
+ return this.config.http2;
160
+ }
161
+ get sshIp() {
162
+ return this.config.sshIp;
163
+ }
164
+ get sshId() {
165
+ return this.config.sshId;
166
+ }
167
+ get sshPort() {
168
+ return this.config.sshPort;
169
+ }
170
+ get sshUser() {
171
+ return this.config.sshUser;
172
+ }
173
+ get sshPassword() {
174
+ return this.config.sshPassword;
175
+ }
176
+ get sshForwardPort() {
177
+ return this.config.sshForwardPort;
178
+ }
179
+ get sshClientUser() {
180
+ return this.config.sshClientUser;
181
+ }
182
+ get sshClientPassword() {
183
+ return this.config.sshClientPassword;
184
+ }
185
+ get targetProto() {
186
+ return this.config.targetProto;
187
+ }
188
+ get targetHost() {
189
+ return this.config.targetHost;
190
+ }
191
+ get targetPort() {
192
+ return this.config.targetPort;
193
+ }
194
+ get targetAuth() {
195
+ return this.config.targetAuth;
196
+ }
197
+ resetState() {
462
198
  this.connections = {};
463
199
  this.totalConnections = 0;
464
200
  this.status = tunnel_1.TUNNEL_STATUS.CLOSED;
@@ -474,134 +210,16 @@ class Tunnel extends events_1.default {
474
210
  this.ssh = null;
475
211
  this.started = false;
476
212
  }
477
- recreate({ type, target, region, timeout, domain, subdomain, name, whitelist, tlsSettings, httpSettings, sshSettings, }) {
213
+ recreate(options) {
478
214
  const started = this.started;
479
215
  this.stop(false);
480
- this.create({
481
- type,
482
- target,
483
- region,
484
- timeout,
485
- domain,
486
- subdomain,
487
- name,
488
- whitelist,
489
- tlsSettings,
490
- httpSettings,
491
- sshSettings,
492
- });
216
+ this.config = new config_1.default(options);
217
+ this.resetState();
493
218
  if (started)
494
219
  this.start();
495
220
  }
496
221
  hasChanged(data) {
497
- const tunnel = new Tunnel({
498
- ...data,
499
- sshHostKey: this.sshHostKey,
500
- });
501
- const diff = (field, a, b) => {
502
- logger_1.default.debug(`Tunnel '${this.id}' hasChanged: ${field} (running=${JSON.stringify(a)} incoming=${JSON.stringify(b)})`);
503
- return true;
504
- };
505
- if (this.type !== tunnel.type)
506
- return diff('type', this.type, tunnel.type);
507
- if (this.target !== tunnel.target)
508
- return diff('target', this.target, tunnel.target);
509
- if (this.region !== tunnel.region)
510
- return diff('region', this.region, tunnel.region);
511
- if (this.timeout !== tunnel.timeout)
512
- return diff('timeout', this.timeout, tunnel.timeout);
513
- if (this.domain !== tunnel.domain)
514
- return diff('domain', this.domain, tunnel.domain);
515
- if (this.subdomain !== tunnel.subdomain)
516
- return diff('subdomain', this.subdomain, tunnel.subdomain);
517
- if (this.terminate !== tunnel.terminate)
518
- return diff('terminate', this.terminate, tunnel.terminate);
519
- if (this.key !== tunnel.key)
520
- return diff('key', this.key, tunnel.key);
521
- if (this.cert !== tunnel.cert)
522
- return diff('cert', this.cert, tunnel.cert);
523
- if (this.ca !== tunnel.ca)
524
- return diff('ca', this.ca, tunnel.ca);
525
- if (this.host !== tunnel.host)
526
- return diff('host', this.host, tunnel.host);
527
- if (this.login !== tunnel.login)
528
- return diff('login', this.login, tunnel.login);
529
- if (this.password !== tunnel.password)
530
- return diff('password', this.password, tunnel.password);
531
- if (this.serve !== tunnel.serve)
532
- return diff('serve', this.serve, tunnel.serve);
533
- if (this.circuitBreaker !== tunnel.circuitBreaker)
534
- return diff('circuitBreaker', this.circuitBreaker, tunnel.circuitBreaker);
535
- if (this.log !== tunnel.log)
536
- return diff('log', this.log, tunnel.log);
537
- if (this.verify !== tunnel.verify)
538
- return diff('verify', this.verify, tunnel.verify);
539
- if (this.http2 !== tunnel.http2)
540
- return diff('http2', this.http2, tunnel.http2);
541
- if (this.compression !== tunnel.compression)
542
- return diff('compression', this.compression, tunnel.compression);
543
- if (this.sshIp !== tunnel.sshIp)
544
- return diff('sshIp', this.sshIp, tunnel.sshIp);
545
- if (this.sshId !== tunnel.sshId)
546
- return diff('sshId', this.sshId, tunnel.sshId);
547
- if (this.sshPort !== tunnel.sshPort)
548
- return diff('sshPort', this.sshPort, tunnel.sshPort);
549
- if (this.sshUser !== tunnel.sshUser)
550
- return diff('sshUser', this.sshUser, tunnel.sshUser);
551
- if (this.sshPassword !== tunnel.sshPassword)
552
- return diff('sshPassword', this.sshPassword, tunnel.sshPassword);
553
- if (this.sshForwardPort !== tunnel.sshForwardPort)
554
- return diff('sshForwardPort', this.sshForwardPort, tunnel.sshForwardPort);
555
- if (this.sshClientPassword !== tunnel.sshClientPassword)
556
- return diff('sshClientPassword', this.sshClientPassword, tunnel.sshClientPassword);
557
- if (this.sshClientUser !== tunnel.sshClientUser)
558
- return diff('sshClientUser', this.sshClientUser, tunnel.sshClientUser);
559
- if (this.whitelist?.length !== tunnel.whitelist?.length)
560
- return diff('whitelist.length', this.whitelist, tunnel.whitelist);
561
- if (this.whitelist && tunnel.whitelist) {
562
- this.whitelist.sort();
563
- tunnel.whitelist.sort();
564
- for (let i = 0; i < this.whitelist.length; i += 1) {
565
- if (this.whitelist[i] !== tunnel.whitelist[i])
566
- return diff('whitelist', this.whitelist, tunnel.whitelist);
567
- }
568
- }
569
- if (this.useragents?.length !== tunnel.useragents?.length)
570
- return diff('useragents.length', this.useragents, tunnel.useragents);
571
- if (this.useragents && tunnel.useragents) {
572
- this.useragents.sort();
573
- tunnel.useragents.sort();
574
- for (let i = 0; i < this.useragents.length; i += 1) {
575
- if (this.useragents[i] !== tunnel.useragents[i])
576
- return diff('useragents', this.useragents, tunnel.useragents);
577
- }
578
- }
579
- const sortHeaders = (a, b) => a.name.localeCompare(b.name);
580
- if (this.headers?.length !== tunnel.headers?.length)
581
- return diff('headers.length', this.headers, tunnel.headers);
582
- if (this.headers && tunnel.headers) {
583
- this.headers.sort(sortHeaders);
584
- tunnel.headers.sort(sortHeaders);
585
- for (let i = 0; i < this.headers.length; i += 1) {
586
- const thisH = this.headers[i];
587
- const tunnelH = tunnel.headers[i];
588
- if (thisH.name !== tunnelH.name || thisH.value !== tunnelH.value)
589
- return diff('headers', this.headers, tunnel.headers);
590
- }
591
- }
592
- if (this.responseHeaders?.length !== tunnel.responseHeaders?.length)
593
- return diff('responseHeaders.length', this.responseHeaders, tunnel.responseHeaders);
594
- if (this.responseHeaders && tunnel.responseHeaders) {
595
- this.responseHeaders.sort(sortHeaders);
596
- tunnel.responseHeaders.sort(sortHeaders);
597
- for (let i = 0; i < this.responseHeaders.length; i += 1) {
598
- const thisRH = this.responseHeaders[i];
599
- const tunnelRH = tunnel.responseHeaders[i];
600
- if (thisRH.name !== tunnelRH.name || thisRH.value !== tunnelRH.value)
601
- return diff('responseHeaders', this.responseHeaders, tunnel.responseHeaders);
602
- }
603
- }
604
- return false;
222
+ return this.config.changed(new config_1.default(data), this.id);
605
223
  }
606
224
  async sshConnected() {
607
225
  try {
@@ -631,7 +249,7 @@ class Tunnel extends events_1.default {
631
249
  if (!this.totalConnections)
632
250
  this.totalConnections = 0;
633
251
  this.totalConnections += 1;
634
- const tcp = new tcp_1.default(this.targetHost || '', this.targetPort || 0, stream);
252
+ const tcp = new tcp_1.default(this.targetHost, this.targetPort, stream);
635
253
  if (!this.connections)
636
254
  this.connections = {};
637
255
  this.connections[tcp.id] = tcp;
@@ -663,319 +281,13 @@ class Tunnel extends events_1.default {
663
281
  }
664
282
  this.emit(tunnel_1.TUNNEL_EVENT.HTTP_CLOSED, this);
665
283
  }
666
- async httpBasicAuth(req, res) {
667
- if (this.authType === tunnel_1.TUNNEL_HTTP_AUTH_TYPE.BASIC) {
668
- const user = require('basic-auth')(req);
669
- if (user && user.name === this.login && user.pass === this.password) {
670
- // tunnel consumed the credentials; don't leak them to the target
671
- delete req.headers.authorization;
672
- return true;
673
- }
674
- const authorized = await this._checkHttpPat(req, res, false);
675
- if (authorized) {
676
- // tunnel consumed the credentials; don't leak them to the target
677
- delete req.headers.authorization;
678
- return true;
679
- }
680
- logger_1.default.debug(texts_1.LOG_TUNNEL_HTTP_WRON_AUTH);
681
- this.httpEndFast(req, res, 401, 'Unauthorised', {
682
- 'WWW-Authenticate': 'Basic real="Buddy"',
683
- });
684
- return false;
685
- }
686
- return true;
687
- }
688
- async _checkHttpPat(req, res, setCookie) {
689
- const user = require('basic-auth')(req);
690
- if (!user || !user.name || !user.pass)
691
- return false;
692
- const client = this._getHttpAuthClient();
693
- let ipAddress;
694
- if (req.httpVersion === '2.0') {
695
- ipAddress = req.socket.stream ? req.socket.stream.remoteAddress : '::1';
696
- }
697
- else {
698
- ipAddress = req.socket.remoteAddress;
699
- }
700
- try {
701
- const { statusCode, body } = await client.request({
702
- path: `/tunnel/auth/pat`,
703
- method: 'POST',
704
- headers: {
705
- 'content-type': 'application/json',
706
- },
707
- body: JSON.stringify({
708
- id: this.id,
709
- agentId: this.agent.id,
710
- login: user.name,
711
- password: user.pass,
712
- ipAddress,
713
- }),
714
- });
715
- if (statusCode !== 200) {
716
- await body.dump();
717
- return false;
718
- }
719
- const result = (await body.json());
720
- if (!result.success)
721
- return false;
722
- if (setCookie)
723
- this._httpSetAuthCookie(res, result.token);
724
- return true;
725
- }
726
- catch {
727
- return false;
728
- }
729
- }
730
- _getHttpAuthClient() {
731
- const host = this.agent.host;
732
- if (!this.httpAuthClient[host]) {
733
- const { Pool: UndiciPool } = require('undici');
734
- this.httpAuthClient[host] = new UndiciPool(host, {
735
- connect: {
736
- rejectUnauthorized: false,
737
- },
738
- });
739
- }
740
- return this.httpAuthClient[host];
741
- }
742
- async _httpExchangeAuthCode(code, verifier) {
743
- const client = this._getHttpAuthClient();
744
- try {
745
- const r = await client.request({
746
- path: `/external-api/auth/token?grant_type=authorization_code`,
747
- method: 'POST',
748
- headers: {
749
- 'content-type': 'application/json',
750
- },
751
- body: JSON.stringify({
752
- code,
753
- verifier,
754
- }),
755
- });
756
- const o = (await r.body.json());
757
- if (o.accessToken) {
758
- return o.accessToken;
759
- }
760
- }
761
- catch {
762
- // do nothing
763
- }
764
- return '';
765
- }
766
- async _httpParseAuthToken(token) {
767
- return new Promise((resolve, reject) => {
768
- const msg = 'Invalid authorization token';
769
- if (!token) {
770
- reject(new Error(msg));
771
- return;
772
- }
773
- const data = require('jsonwebtoken').decode(token);
774
- if (!data || !data.iss) {
775
- reject(new Error(msg));
776
- return;
777
- }
778
- let cert;
779
- if (ISSUERS[data.iss])
780
- cert = ISSUERS[data.iss];
781
- else
782
- cert = ISSUERS['*'];
783
- require('jsonwebtoken').verify(token, cert, {
784
- complete: true,
785
- issuer: data.iss,
786
- }, (err, data) => {
787
- if (err || !data) {
788
- reject(new Error(msg));
789
- return;
790
- }
791
- const payload = data.payload;
792
- if (!payload.tunnelId ||
793
- !payload.userId ||
794
- payload.aud !== 'tunnels' ||
795
- payload.sub !== 'tunnel_read') {
796
- reject(new Error(msg));
797
- return;
798
- }
799
- resolve({
800
- tunnelId: payload.tunnelId,
801
- userId: payload.userId,
802
- token,
803
- });
804
- });
805
- });
806
- }
807
- _httpSetAuthCookie(res, token) {
808
- res.setHeader('set-cookie', require('cookie').serialize(COOKIE_NAME, token, {
809
- maxAge: 3600,
810
- path: '/',
811
- secure: true,
812
- httpOnly: true,
813
- sameSite: 'lax',
814
- }));
815
- }
816
- _checkHttpAuthTokenRedirect(req, res, code, state, accessToken, url) {
817
- if ((code || accessToken) && state && url) {
818
- const u2 = new URL(url);
819
- const currentHost = req.headers['x-forwarded-host'] || req.headers.host || req.headers[':authority'] || '';
820
- const currentUrl = `https://${currentHost}`;
821
- const originalUrl = `https://${u2.host}`;
822
- if (currentUrl !== originalUrl) {
823
- let newUrl = `${originalUrl}?state=${encodeURIComponent(state)}`;
824
- if (code)
825
- newUrl += `&code=${encodeURIComponent(code)}`;
826
- else if (accessToken)
827
- newUrl += `&access_token=${encodeURIComponent(accessToken)}`;
828
- this.httpEndFast(req, res, 302, 'Found', {
829
- location: newUrl,
830
- });
831
- return true;
832
- }
833
- }
834
- return false;
835
- }
836
- async _checkHttpAuthToken(code, verifier, token, req, res) {
837
- let fromCookie = false;
838
- if (code && verifier && !token) {
839
- token = await this._httpExchangeAuthCode(code, verifier);
840
- }
841
- if (!token) {
842
- const cookies = require('cookie').parse(req.headers.cookie || '');
843
- token = cookies[COOKIE_NAME] || '';
844
- fromCookie = true;
845
- }
846
- if (!token) {
847
- return false;
848
- }
849
- try {
850
- const data = await this._httpParseAuthToken(token);
851
- if (data.tunnelId !== this.id) {
852
- return false;
853
- }
854
- if (!data.userId) {
855
- return false;
856
- }
857
- if (fromCookie) {
858
- return true;
859
- }
860
- this._httpSetAuthCookie(res, token);
861
- return true;
862
- }
863
- catch {
864
- return false;
865
- }
866
- }
867
- _httpEncryptState(url, verifier) {
868
- try {
869
- const cipher = node_crypto_1.default.createCipheriv(CIPHER_ALG, Buffer.from(this.cipherKey), Buffer.from(CIPHER_IV));
870
- const compressed = node_zlib_1.default.deflateRawSync(JSON.stringify({ url, verifier }));
871
- const enc = Buffer.concat([cipher.update(compressed), cipher.final()]);
872
- return enc.toString('base64url');
873
- }
874
- catch {
875
- // do nothing
876
- }
877
- return '';
878
- }
879
- _httpDecryptState(state) {
880
- let url = null;
881
- let verifier = null;
882
- if (state) {
883
- try {
884
- const decipher = node_crypto_1.default.createDecipheriv(CIPHER_ALG, Buffer.from(this.cipherKey), Buffer.from(CIPHER_IV));
885
- const dec = Buffer.concat([decipher.update(Buffer.from(state, 'base64url')), decipher.final()]);
886
- const json = JSON.parse(node_zlib_1.default.inflateRawSync(dec).toString('utf8'));
887
- if (json) {
888
- if (json.url)
889
- url = json.url;
890
- if (json.verifier)
891
- verifier = json.verifier;
892
- }
893
- }
894
- catch {
895
- // do nothing
896
- }
897
- }
898
- return {
899
- url,
900
- verifier,
901
- };
902
- }
903
284
  _requiresAuthCacheControl() {
904
285
  return (this.authType === tunnel_1.TUNNEL_HTTP_AUTH_TYPE.BASIC ||
905
286
  this.authType === tunnel_1.TUNNEL_HTTP_AUTH_TYPE.BUDDY);
906
287
  }
907
- _redirectHttpToBuddyAuth(pathname, search, req, res) {
908
- let host = this.agent.host;
909
- if (/^https:\/\/\d+\.\d+\.\d+\.\d+$/.test(host)) {
910
- host = 'https://app.local.io';
911
- }
912
- const verifier = require('uuid').v4();
913
- const challenge = node_crypto_1.default
914
- .createHash('sha256')
915
- .update(verifier)
916
- .digest('hex');
917
- const callback = `https://${this.subdomain}.${(this.region || '').toLowerCase()}-${this.sshId}.${this.domain}`;
918
- let redirect;
919
- if (req.headers['x-forwarded-host']) {
920
- if (req.headers['x-forwarded-proto'] === 'http') {
921
- redirect = 'http://';
922
- }
923
- else {
924
- redirect = 'https://';
925
- }
926
- redirect += req.headers['x-forwarded-host'];
927
- }
928
- else {
929
- redirect = callback;
930
- }
931
- redirect += pathname;
932
- if (search)
933
- redirect += search;
934
- const enc = this._httpEncryptState(redirect, verifier);
935
- let url = `${host}/tunnel/auth?redirect_url=${encodeURIComponent(callback)}&id=${encodeURIComponent(this.id)}&agentId=${encodeURIComponent(this.agent.id)}&challenge=${encodeURIComponent(challenge)}&state=${encodeURIComponent(enc)}`;
936
- if (/app\.local\.io/.test(host)) {
937
- url += '&response_type=token';
938
- }
939
- this.httpEndFast(req, res, 302, 'Found', {
940
- location: url,
941
- });
942
- }
943
- async httpBuddyAuth(req, res) {
944
- if (this.authType === tunnel_1.TUNNEL_HTTP_AUTH_TYPE.BUDDY) {
945
- const { searchParams, pathname, search } = new URL(req.url, 'https://abc.com');
946
- const code = searchParams.get('code') || '';
947
- const state = searchParams.get('state') || '';
948
- const token = searchParams.get('access_token') || '';
949
- const { url, verifier } = this._httpDecryptState(state);
950
- const redirectByAuthToken = this._checkHttpAuthTokenRedirect(req, res, code, state, token, url);
951
- if (redirectByAuthToken) {
952
- return false;
953
- }
954
- const authByToken = await this._checkHttpAuthToken(code, verifier || '', token, req, res);
955
- if (authByToken) {
956
- if (url) {
957
- this.httpEndFast(req, res, 302, 'Found', {
958
- location: url,
959
- });
960
- return false;
961
- }
962
- return true;
963
- }
964
- if (url && verifier && (code || token)) {
965
- this.httpEndFast(req, res, 404, 'Not found');
966
- return false;
967
- }
968
- const auth = require('basic-auth')(req);
969
- if (auth) {
970
- const authorized = await this._checkHttpPat(req, res, true);
971
- if (authorized) {
972
- return true;
973
- }
974
- }
975
- this._redirectHttpToBuddyAuth(pathname, search, req, res);
976
- return false;
977
- }
978
- return true;
288
+ httpEndFastJson(req, res, statusCode, obj, headers = {}) {
289
+ headers['content-type'] = 'application/json';
290
+ this.httpEndFast(req, res, statusCode, JSON.stringify(obj), headers);
979
291
  }
980
292
  httpEndFast(req, res, statusCode, msg, headers = {}) {
981
293
  if (this._requiresAuthCacheControl() && !headers['cache-control']) {
@@ -1074,8 +386,10 @@ class Tunnel extends events_1.default {
1074
386
  }
1075
387
  }
1076
388
  async httpRequest(req, res) {
1077
- const isAuth = (await this.httpBasicAuth(req, res)) &&
1078
- (await this.httpBuddyAuth(req, res)) &&
389
+ if (await this.auth.buddyAuthMe(req, res))
390
+ return;
391
+ const isAuth = (await this.auth.basicAuth(req, res)) &&
392
+ (await this.auth.buddyAuth(req, res)) &&
1079
393
  this.httpUserAgent(req, res) &&
1080
394
  this.httpRateLimit(req, res) &&
1081
395
  this.httpCircuitBreaker(req, res);
@@ -1229,7 +543,7 @@ class Tunnel extends events_1.default {
1229
543
  this.regionLatency.startChecking();
1230
544
  // target latency
1231
545
  if (!this.serve && this.type !== tunnel_1.TUNNEL_TYPE.SSH) {
1232
- this.targetLatency = new latency_1.default(this.targetHost || '', this.targetPort || 0);
546
+ this.targetLatency = new latency_1.default(this.targetHost, this.targetPort);
1233
547
  this.targetLatency.on(tunnel_1.TUNNEL_EVENT_LATENCY.RECONNECTED, () => this.targetReconnected());
1234
548
  this.targetLatency.startChecking();
1235
549
  }
@@ -1249,7 +563,7 @@ class Tunnel extends events_1.default {
1249
563
  this.httpLog = new log_1.default(this.log, this.circuitBreaker);
1250
564
  this.httpLog.on(tunnel_1.TUNNEL_EVENT_HTTP.NEW_REQUEST, (logRequest) => this.httpLogRequest(logRequest));
1251
565
  this.httpLog.on(tunnel_1.TUNNEL_EVENT_HTTP.NEW_RESPONSE, (logRequest) => this.httpLogResponse(logRequest));
1252
- this.identify = new identification_1.default(this.targetProto || '', this.targetHost || '', this.targetPort || 0, this.http2 || !!this.serve);
566
+ this.identify = new identification_1.default(this.targetProto, this.targetHost, this.targetPort, this.http2 || !!this.serve);
1253
567
  this.identify.on(tunnel_1.TUNNEL_EVENT.IDENTIFIED, (type) => this.httpIdentified(type));
1254
568
  const host = format_1.default.entryHostEncoded(this);
1255
569
  this.http2server = new http2_1.default(host);