@nocobase/plugin-idp-oauth 2.1.0-alpha.17 → 2.1.0-alpha.19

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.
Files changed (221) hide show
  1. package/build.config.ts +1 -1
  2. package/dist/externalVersion.js +6 -4
  3. package/dist/node_modules/light-my-request/package.json +1 -1
  4. package/dist/node_modules/undici/LICENSE +21 -0
  5. package/dist/node_modules/undici/README.md +741 -0
  6. package/dist/node_modules/undici/docs/docs/api/Agent.md +84 -0
  7. package/dist/node_modules/undici/docs/docs/api/BalancedPool.md +99 -0
  8. package/dist/node_modules/undici/docs/docs/api/CacheStorage.md +30 -0
  9. package/dist/node_modules/undici/docs/docs/api/CacheStore.md +164 -0
  10. package/dist/node_modules/undici/docs/docs/api/Client.md +285 -0
  11. package/dist/node_modules/undici/docs/docs/api/ClientStats.md +27 -0
  12. package/dist/node_modules/undici/docs/docs/api/Connector.md +115 -0
  13. package/dist/node_modules/undici/docs/docs/api/ContentType.md +57 -0
  14. package/dist/node_modules/undici/docs/docs/api/Cookies.md +101 -0
  15. package/dist/node_modules/undici/docs/docs/api/Debug.md +62 -0
  16. package/dist/node_modules/undici/docs/docs/api/DiagnosticsChannel.md +315 -0
  17. package/dist/node_modules/undici/docs/docs/api/Dispatcher.md +1392 -0
  18. package/dist/node_modules/undici/docs/docs/api/EnvHttpProxyAgent.md +159 -0
  19. package/dist/node_modules/undici/docs/docs/api/Errors.md +49 -0
  20. package/dist/node_modules/undici/docs/docs/api/EventSource.md +45 -0
  21. package/dist/node_modules/undici/docs/docs/api/Fetch.md +60 -0
  22. package/dist/node_modules/undici/docs/docs/api/GlobalInstallation.md +139 -0
  23. package/dist/node_modules/undici/docs/docs/api/H2CClient.md +263 -0
  24. package/dist/node_modules/undici/docs/docs/api/MockAgent.md +603 -0
  25. package/dist/node_modules/undici/docs/docs/api/MockCallHistory.md +197 -0
  26. package/dist/node_modules/undici/docs/docs/api/MockCallHistoryLog.md +43 -0
  27. package/dist/node_modules/undici/docs/docs/api/MockClient.md +81 -0
  28. package/dist/node_modules/undici/docs/docs/api/MockErrors.md +12 -0
  29. package/dist/node_modules/undici/docs/docs/api/MockPool.md +555 -0
  30. package/dist/node_modules/undici/docs/docs/api/Pool.md +84 -0
  31. package/dist/node_modules/undici/docs/docs/api/PoolStats.md +35 -0
  32. package/dist/node_modules/undici/docs/docs/api/ProxyAgent.md +229 -0
  33. package/dist/node_modules/undici/docs/docs/api/RedirectHandler.md +93 -0
  34. package/dist/node_modules/undici/docs/docs/api/RetryAgent.md +50 -0
  35. package/dist/node_modules/undici/docs/docs/api/RetryHandler.md +118 -0
  36. package/dist/node_modules/undici/docs/docs/api/RoundRobinPool.md +145 -0
  37. package/dist/node_modules/undici/docs/docs/api/SnapshotAgent.md +616 -0
  38. package/dist/node_modules/undici/docs/docs/api/Socks5ProxyAgent.md +274 -0
  39. package/dist/node_modules/undici/docs/docs/api/Util.md +25 -0
  40. package/dist/node_modules/undici/docs/docs/api/WebSocket.md +141 -0
  41. package/dist/node_modules/undici/docs/docs/api/api-lifecycle.md +91 -0
  42. package/dist/node_modules/undici/docs/docs/best-practices/client-certificate.md +64 -0
  43. package/dist/node_modules/undici/docs/docs/best-practices/crawling.md +58 -0
  44. package/dist/node_modules/undici/docs/docs/best-practices/mocking-request.md +190 -0
  45. package/dist/node_modules/undici/docs/docs/best-practices/proxy.md +127 -0
  46. package/dist/node_modules/undici/docs/docs/best-practices/undici-vs-builtin-fetch.md +224 -0
  47. package/dist/node_modules/undici/docs/docs/best-practices/writing-tests.md +63 -0
  48. package/dist/node_modules/undici/index-fetch.js +65 -0
  49. package/dist/node_modules/undici/index.d.ts +3 -0
  50. package/dist/node_modules/undici/index.js +234 -0
  51. package/dist/node_modules/undici/lib/api/abort-signal.js +59 -0
  52. package/dist/node_modules/undici/lib/api/api-connect.js +110 -0
  53. package/dist/node_modules/undici/lib/api/api-pipeline.js +252 -0
  54. package/dist/node_modules/undici/lib/api/api-request.js +214 -0
  55. package/dist/node_modules/undici/lib/api/api-stream.js +209 -0
  56. package/dist/node_modules/undici/lib/api/api-upgrade.js +111 -0
  57. package/dist/node_modules/undici/lib/api/index.js +7 -0
  58. package/dist/node_modules/undici/lib/api/readable.js +580 -0
  59. package/dist/node_modules/undici/lib/cache/memory-cache-store.js +234 -0
  60. package/dist/node_modules/undici/lib/cache/sqlite-cache-store.js +461 -0
  61. package/dist/node_modules/undici/lib/core/connect.js +137 -0
  62. package/dist/node_modules/undici/lib/core/constants.js +143 -0
  63. package/dist/node_modules/undici/lib/core/diagnostics.js +227 -0
  64. package/dist/node_modules/undici/lib/core/errors.js +477 -0
  65. package/dist/node_modules/undici/lib/core/request.js +438 -0
  66. package/dist/node_modules/undici/lib/core/socks5-client.js +407 -0
  67. package/dist/node_modules/undici/lib/core/socks5-utils.js +203 -0
  68. package/dist/node_modules/undici/lib/core/symbols.js +75 -0
  69. package/dist/node_modules/undici/lib/core/tree.js +160 -0
  70. package/dist/node_modules/undici/lib/core/util.js +992 -0
  71. package/dist/node_modules/undici/lib/dispatcher/agent.js +158 -0
  72. package/dist/node_modules/undici/lib/dispatcher/balanced-pool.js +219 -0
  73. package/dist/node_modules/undici/lib/dispatcher/client-h1.js +1610 -0
  74. package/dist/node_modules/undici/lib/dispatcher/client-h2.js +995 -0
  75. package/dist/node_modules/undici/lib/dispatcher/client.js +659 -0
  76. package/dist/node_modules/undici/lib/dispatcher/dispatcher-base.js +165 -0
  77. package/dist/node_modules/undici/lib/dispatcher/dispatcher.js +48 -0
  78. package/dist/node_modules/undici/lib/dispatcher/env-http-proxy-agent.js +146 -0
  79. package/dist/node_modules/undici/lib/dispatcher/fixed-queue.js +135 -0
  80. package/dist/node_modules/undici/lib/dispatcher/h2c-client.js +51 -0
  81. package/dist/node_modules/undici/lib/dispatcher/pool-base.js +214 -0
  82. package/dist/node_modules/undici/lib/dispatcher/pool.js +118 -0
  83. package/dist/node_modules/undici/lib/dispatcher/proxy-agent.js +318 -0
  84. package/dist/node_modules/undici/lib/dispatcher/retry-agent.js +35 -0
  85. package/dist/node_modules/undici/lib/dispatcher/round-robin-pool.js +137 -0
  86. package/dist/node_modules/undici/lib/dispatcher/socks5-proxy-agent.js +249 -0
  87. package/dist/node_modules/undici/lib/encoding/index.js +33 -0
  88. package/dist/node_modules/undici/lib/global.js +50 -0
  89. package/dist/node_modules/undici/lib/handler/cache-handler.js +578 -0
  90. package/dist/node_modules/undici/lib/handler/cache-revalidation-handler.js +124 -0
  91. package/dist/node_modules/undici/lib/handler/decorator-handler.js +67 -0
  92. package/dist/node_modules/undici/lib/handler/deduplication-handler.js +460 -0
  93. package/dist/node_modules/undici/lib/handler/redirect-handler.js +238 -0
  94. package/dist/node_modules/undici/lib/handler/retry-handler.js +394 -0
  95. package/dist/node_modules/undici/lib/handler/unwrap-handler.js +100 -0
  96. package/dist/node_modules/undici/lib/handler/wrap-handler.js +105 -0
  97. package/dist/node_modules/undici/lib/interceptor/cache.js +495 -0
  98. package/dist/node_modules/undici/lib/interceptor/decompress.js +259 -0
  99. package/dist/node_modules/undici/lib/interceptor/deduplicate.js +117 -0
  100. package/dist/node_modules/undici/lib/interceptor/dns.js +571 -0
  101. package/dist/node_modules/undici/lib/interceptor/dump.js +112 -0
  102. package/dist/node_modules/undici/lib/interceptor/redirect.js +21 -0
  103. package/dist/node_modules/undici/lib/interceptor/response-error.js +95 -0
  104. package/dist/node_modules/undici/lib/interceptor/retry.js +19 -0
  105. package/dist/node_modules/undici/lib/llhttp/.gitkeep +0 -0
  106. package/dist/node_modules/undici/lib/llhttp/constants.d.ts +195 -0
  107. package/dist/node_modules/undici/lib/llhttp/constants.js +531 -0
  108. package/dist/node_modules/undici/lib/llhttp/llhttp-wasm.js +15 -0
  109. package/dist/node_modules/undici/lib/llhttp/llhttp_simd-wasm.js +15 -0
  110. package/dist/node_modules/undici/lib/llhttp/utils.d.ts +2 -0
  111. package/dist/node_modules/undici/lib/llhttp/utils.js +12 -0
  112. package/dist/node_modules/undici/lib/mock/mock-agent.js +232 -0
  113. package/dist/node_modules/undici/lib/mock/mock-call-history.js +248 -0
  114. package/dist/node_modules/undici/lib/mock/mock-client.js +68 -0
  115. package/dist/node_modules/undici/lib/mock/mock-errors.js +29 -0
  116. package/dist/node_modules/undici/lib/mock/mock-interceptor.js +209 -0
  117. package/dist/node_modules/undici/lib/mock/mock-pool.js +68 -0
  118. package/dist/node_modules/undici/lib/mock/mock-symbols.js +32 -0
  119. package/dist/node_modules/undici/lib/mock/mock-utils.js +486 -0
  120. package/dist/node_modules/undici/lib/mock/pending-interceptors-formatter.js +43 -0
  121. package/dist/node_modules/undici/lib/mock/snapshot-agent.js +353 -0
  122. package/dist/node_modules/undici/lib/mock/snapshot-recorder.js +588 -0
  123. package/dist/node_modules/undici/lib/mock/snapshot-utils.js +158 -0
  124. package/dist/node_modules/undici/lib/util/cache.js +407 -0
  125. package/dist/node_modules/undici/lib/util/date.js +653 -0
  126. package/dist/node_modules/undici/lib/util/promise.js +28 -0
  127. package/dist/node_modules/undici/lib/util/runtime-features.js +124 -0
  128. package/dist/node_modules/undici/lib/util/stats.js +32 -0
  129. package/dist/node_modules/undici/lib/util/timers.js +425 -0
  130. package/dist/node_modules/undici/lib/web/cache/cache.js +864 -0
  131. package/dist/node_modules/undici/lib/web/cache/cachestorage.js +152 -0
  132. package/dist/node_modules/undici/lib/web/cache/util.js +45 -0
  133. package/dist/node_modules/undici/lib/web/cookies/constants.js +12 -0
  134. package/dist/node_modules/undici/lib/web/cookies/index.js +199 -0
  135. package/dist/node_modules/undici/lib/web/cookies/parse.js +322 -0
  136. package/dist/node_modules/undici/lib/web/cookies/util.js +282 -0
  137. package/dist/node_modules/undici/lib/web/eventsource/eventsource-stream.js +399 -0
  138. package/dist/node_modules/undici/lib/web/eventsource/eventsource.js +501 -0
  139. package/dist/node_modules/undici/lib/web/eventsource/util.js +29 -0
  140. package/dist/node_modules/undici/lib/web/fetch/LICENSE +21 -0
  141. package/dist/node_modules/undici/lib/web/fetch/body.js +509 -0
  142. package/dist/node_modules/undici/lib/web/fetch/constants.js +131 -0
  143. package/dist/node_modules/undici/lib/web/fetch/data-url.js +596 -0
  144. package/dist/node_modules/undici/lib/web/fetch/formdata-parser.js +575 -0
  145. package/dist/node_modules/undici/lib/web/fetch/formdata.js +259 -0
  146. package/dist/node_modules/undici/lib/web/fetch/global.js +40 -0
  147. package/dist/node_modules/undici/lib/web/fetch/headers.js +719 -0
  148. package/dist/node_modules/undici/lib/web/fetch/index.js +2397 -0
  149. package/dist/node_modules/undici/lib/web/fetch/request.js +1115 -0
  150. package/dist/node_modules/undici/lib/web/fetch/response.js +641 -0
  151. package/dist/node_modules/undici/lib/web/fetch/util.js +1520 -0
  152. package/dist/node_modules/undici/lib/web/infra/index.js +229 -0
  153. package/dist/node_modules/undici/lib/web/subresource-integrity/Readme.md +9 -0
  154. package/dist/node_modules/undici/lib/web/subresource-integrity/subresource-integrity.js +307 -0
  155. package/dist/node_modules/undici/lib/web/webidl/index.js +1006 -0
  156. package/dist/node_modules/undici/lib/web/websocket/connection.js +329 -0
  157. package/dist/node_modules/undici/lib/web/websocket/constants.js +126 -0
  158. package/dist/node_modules/undici/lib/web/websocket/events.js +331 -0
  159. package/dist/node_modules/undici/lib/web/websocket/frame.js +133 -0
  160. package/dist/node_modules/undici/lib/web/websocket/permessage-deflate.js +118 -0
  161. package/dist/node_modules/undici/lib/web/websocket/receiver.js +450 -0
  162. package/dist/node_modules/undici/lib/web/websocket/sender.js +109 -0
  163. package/dist/node_modules/undici/lib/web/websocket/stream/websocketerror.js +104 -0
  164. package/dist/node_modules/undici/lib/web/websocket/stream/websocketstream.js +497 -0
  165. package/dist/node_modules/undici/lib/web/websocket/util.js +347 -0
  166. package/dist/node_modules/undici/lib/web/websocket/websocket.js +751 -0
  167. package/dist/node_modules/undici/package.json +152 -0
  168. package/dist/node_modules/undici/scripts/strip-comments.js +10 -0
  169. package/dist/node_modules/undici/types/README.md +6 -0
  170. package/dist/node_modules/undici/types/agent.d.ts +32 -0
  171. package/dist/node_modules/undici/types/api.d.ts +43 -0
  172. package/dist/node_modules/undici/types/balanced-pool.d.ts +30 -0
  173. package/dist/node_modules/undici/types/cache-interceptor.d.ts +179 -0
  174. package/dist/node_modules/undici/types/cache.d.ts +36 -0
  175. package/dist/node_modules/undici/types/client-stats.d.ts +15 -0
  176. package/dist/node_modules/undici/types/client.d.ts +123 -0
  177. package/dist/node_modules/undici/types/connector.d.ts +36 -0
  178. package/dist/node_modules/undici/types/content-type.d.ts +21 -0
  179. package/dist/node_modules/undici/types/cookies.d.ts +30 -0
  180. package/dist/node_modules/undici/types/diagnostics-channel.d.ts +74 -0
  181. package/dist/node_modules/undici/types/dispatcher.d.ts +273 -0
  182. package/dist/node_modules/undici/types/env-http-proxy-agent.d.ts +22 -0
  183. package/dist/node_modules/undici/types/errors.d.ts +177 -0
  184. package/dist/node_modules/undici/types/eventsource.d.ts +66 -0
  185. package/dist/node_modules/undici/types/fetch.d.ts +231 -0
  186. package/dist/node_modules/undici/types/formdata.d.ts +114 -0
  187. package/dist/node_modules/undici/types/global-dispatcher.d.ts +9 -0
  188. package/dist/node_modules/undici/types/global-origin.d.ts +7 -0
  189. package/dist/node_modules/undici/types/h2c-client.d.ts +73 -0
  190. package/dist/node_modules/undici/types/handlers.d.ts +14 -0
  191. package/dist/node_modules/undici/types/header.d.ts +160 -0
  192. package/dist/node_modules/undici/types/index.d.ts +91 -0
  193. package/dist/node_modules/undici/types/interceptors.d.ts +80 -0
  194. package/dist/node_modules/undici/types/mock-agent.d.ts +68 -0
  195. package/dist/node_modules/undici/types/mock-call-history.d.ts +111 -0
  196. package/dist/node_modules/undici/types/mock-client.d.ts +27 -0
  197. package/dist/node_modules/undici/types/mock-errors.d.ts +12 -0
  198. package/dist/node_modules/undici/types/mock-interceptor.d.ts +94 -0
  199. package/dist/node_modules/undici/types/mock-pool.d.ts +27 -0
  200. package/dist/node_modules/undici/types/patch.d.ts +29 -0
  201. package/dist/node_modules/undici/types/pool-stats.d.ts +19 -0
  202. package/dist/node_modules/undici/types/pool.d.ts +41 -0
  203. package/dist/node_modules/undici/types/proxy-agent.d.ts +29 -0
  204. package/dist/node_modules/undici/types/readable.d.ts +68 -0
  205. package/dist/node_modules/undici/types/retry-agent.d.ts +8 -0
  206. package/dist/node_modules/undici/types/retry-handler.d.ts +125 -0
  207. package/dist/node_modules/undici/types/round-robin-pool.d.ts +41 -0
  208. package/dist/node_modules/undici/types/snapshot-agent.d.ts +109 -0
  209. package/dist/node_modules/undici/types/socks5-proxy-agent.d.ts +25 -0
  210. package/dist/node_modules/undici/types/util.d.ts +18 -0
  211. package/dist/node_modules/undici/types/utility.d.ts +7 -0
  212. package/dist/node_modules/undici/types/webidl.d.ts +347 -0
  213. package/dist/node_modules/undici/types/websocket.d.ts +188 -0
  214. package/dist/server/collections/oidcStates.d.ts +10 -0
  215. package/dist/server/collections/oidcStates.js +96 -0
  216. package/dist/server/db-adapter.d.ts +25 -0
  217. package/dist/server/db-adapter.js +156 -0
  218. package/dist/server/service.js +11 -10
  219. package/package.json +2 -2
  220. package/dist/server/cache-adapter.d.ts +0 -33
  221. package/dist/server/cache-adapter.js +0 -159
@@ -0,0 +1,407 @@
1
+ 'use strict'
2
+
3
+ const { EventEmitter } = require('node:events')
4
+ const { Buffer } = require('node:buffer')
5
+ const { InvalidArgumentError, Socks5ProxyError } = require('./errors')
6
+ const { debuglog } = require('node:util')
7
+ const { parseAddress } = require('./socks5-utils')
8
+
9
+ const debug = debuglog('undici:socks5')
10
+
11
+ // SOCKS5 constants
12
+ const SOCKS_VERSION = 0x05
13
+
14
+ // Authentication methods
15
+ const AUTH_METHODS = {
16
+ NO_AUTH: 0x00,
17
+ GSSAPI: 0x01,
18
+ USERNAME_PASSWORD: 0x02,
19
+ NO_ACCEPTABLE: 0xFF
20
+ }
21
+
22
+ // SOCKS5 commands
23
+ const COMMANDS = {
24
+ CONNECT: 0x01,
25
+ BIND: 0x02,
26
+ UDP_ASSOCIATE: 0x03
27
+ }
28
+
29
+ // Address types
30
+ const ADDRESS_TYPES = {
31
+ IPV4: 0x01,
32
+ DOMAIN: 0x03,
33
+ IPV6: 0x04
34
+ }
35
+
36
+ // Reply codes
37
+ const REPLY_CODES = {
38
+ SUCCEEDED: 0x00,
39
+ GENERAL_FAILURE: 0x01,
40
+ CONNECTION_NOT_ALLOWED: 0x02,
41
+ NETWORK_UNREACHABLE: 0x03,
42
+ HOST_UNREACHABLE: 0x04,
43
+ CONNECTION_REFUSED: 0x05,
44
+ TTL_EXPIRED: 0x06,
45
+ COMMAND_NOT_SUPPORTED: 0x07,
46
+ ADDRESS_TYPE_NOT_SUPPORTED: 0x08
47
+ }
48
+
49
+ // State machine states
50
+ const STATES = {
51
+ INITIAL: 'initial',
52
+ HANDSHAKING: 'handshaking',
53
+ AUTHENTICATING: 'authenticating',
54
+ CONNECTING: 'connecting',
55
+ CONNECTED: 'connected',
56
+ ERROR: 'error',
57
+ CLOSED: 'closed'
58
+ }
59
+
60
+ /**
61
+ * SOCKS5 client implementation
62
+ * Handles SOCKS5 protocol negotiation and connection establishment
63
+ */
64
+ class Socks5Client extends EventEmitter {
65
+ constructor (socket, options = {}) {
66
+ super()
67
+
68
+ if (!socket) {
69
+ throw new InvalidArgumentError('socket is required')
70
+ }
71
+
72
+ this.socket = socket
73
+ this.options = options
74
+ this.state = STATES.INITIAL
75
+ this.buffer = Buffer.alloc(0)
76
+
77
+ // Authentication settings
78
+ this.authMethods = []
79
+ if (options.username && options.password) {
80
+ this.authMethods.push(AUTH_METHODS.USERNAME_PASSWORD)
81
+ }
82
+ this.authMethods.push(AUTH_METHODS.NO_AUTH)
83
+
84
+ // Socket event handlers
85
+ this.socket.on('data', this.onData.bind(this))
86
+ this.socket.on('error', this.onError.bind(this))
87
+ this.socket.on('close', this.onClose.bind(this))
88
+ }
89
+
90
+ /**
91
+ * Handle incoming data from the socket
92
+ */
93
+ onData (data) {
94
+ debug('received data', data.length, 'bytes in state', this.state)
95
+ this.buffer = Buffer.concat([this.buffer, data])
96
+
97
+ try {
98
+ switch (this.state) {
99
+ case STATES.HANDSHAKING:
100
+ this.handleHandshakeResponse()
101
+ break
102
+ case STATES.AUTHENTICATING:
103
+ this.handleAuthResponse()
104
+ break
105
+ case STATES.CONNECTING:
106
+ this.handleConnectResponse()
107
+ break
108
+ }
109
+ } catch (err) {
110
+ this.onError(err)
111
+ }
112
+ }
113
+
114
+ /**
115
+ * Handle socket errors
116
+ */
117
+ onError (err) {
118
+ debug('socket error', err)
119
+ this.state = STATES.ERROR
120
+ this.emit('error', err)
121
+ this.destroy()
122
+ }
123
+
124
+ /**
125
+ * Handle socket close
126
+ */
127
+ onClose () {
128
+ debug('socket closed')
129
+ this.state = STATES.CLOSED
130
+ this.emit('close')
131
+ }
132
+
133
+ /**
134
+ * Destroy the client and underlying socket
135
+ */
136
+ destroy () {
137
+ if (this.socket && !this.socket.destroyed) {
138
+ this.socket.destroy()
139
+ }
140
+ }
141
+
142
+ /**
143
+ * Start the SOCKS5 handshake
144
+ */
145
+ handshake () {
146
+ if (this.state !== STATES.INITIAL) {
147
+ throw new InvalidArgumentError('Handshake already started')
148
+ }
149
+
150
+ debug('starting handshake with', this.authMethods.length, 'auth methods')
151
+ this.state = STATES.HANDSHAKING
152
+
153
+ // Build handshake request
154
+ // +----+----------+----------+
155
+ // |VER | NMETHODS | METHODS |
156
+ // +----+----------+----------+
157
+ // | 1 | 1 | 1 to 255 |
158
+ // +----+----------+----------+
159
+ const request = Buffer.alloc(2 + this.authMethods.length)
160
+ request[0] = SOCKS_VERSION
161
+ request[1] = this.authMethods.length
162
+ this.authMethods.forEach((method, i) => {
163
+ request[2 + i] = method
164
+ })
165
+
166
+ this.socket.write(request)
167
+ }
168
+
169
+ /**
170
+ * Handle handshake response from server
171
+ */
172
+ handleHandshakeResponse () {
173
+ if (this.buffer.length < 2) {
174
+ return // Not enough data yet
175
+ }
176
+
177
+ const version = this.buffer[0]
178
+ const method = this.buffer[1]
179
+
180
+ if (version !== SOCKS_VERSION) {
181
+ throw new Socks5ProxyError(`Invalid SOCKS version: ${version}`, 'UND_ERR_SOCKS5_VERSION')
182
+ }
183
+
184
+ if (method === AUTH_METHODS.NO_ACCEPTABLE) {
185
+ throw new Socks5ProxyError('No acceptable authentication method', 'UND_ERR_SOCKS5_AUTH_REJECTED')
186
+ }
187
+
188
+ this.buffer = this.buffer.subarray(2)
189
+ debug('server selected auth method', method)
190
+
191
+ if (method === AUTH_METHODS.NO_AUTH) {
192
+ this.emit('authenticated')
193
+ } else if (method === AUTH_METHODS.USERNAME_PASSWORD) {
194
+ this.state = STATES.AUTHENTICATING
195
+ this.sendAuthRequest()
196
+ } else {
197
+ throw new Socks5ProxyError(`Unsupported authentication method: ${method}`, 'UND_ERR_SOCKS5_AUTH_METHOD')
198
+ }
199
+ }
200
+
201
+ /**
202
+ * Send username/password authentication request
203
+ */
204
+ sendAuthRequest () {
205
+ const { username, password } = this.options
206
+
207
+ if (!username || !password) {
208
+ throw new InvalidArgumentError('Username and password required for authentication')
209
+ }
210
+
211
+ debug('sending username/password auth')
212
+
213
+ // Username/Password authentication request (RFC 1929)
214
+ // +----+------+----------+------+----------+
215
+ // |VER | ULEN | UNAME | PLEN | PASSWD |
216
+ // +----+------+----------+------+----------+
217
+ // | 1 | 1 | 1 to 255 | 1 | 1 to 255 |
218
+ // +----+------+----------+------+----------+
219
+ const usernameBuffer = Buffer.from(username)
220
+ const passwordBuffer = Buffer.from(password)
221
+
222
+ if (usernameBuffer.length > 255 || passwordBuffer.length > 255) {
223
+ throw new InvalidArgumentError('Username or password too long')
224
+ }
225
+
226
+ const request = Buffer.alloc(3 + usernameBuffer.length + passwordBuffer.length)
227
+ request[0] = 0x01 // Sub-negotiation version
228
+ request[1] = usernameBuffer.length
229
+ usernameBuffer.copy(request, 2)
230
+ request[2 + usernameBuffer.length] = passwordBuffer.length
231
+ passwordBuffer.copy(request, 3 + usernameBuffer.length)
232
+
233
+ this.socket.write(request)
234
+ }
235
+
236
+ /**
237
+ * Handle authentication response
238
+ */
239
+ handleAuthResponse () {
240
+ if (this.buffer.length < 2) {
241
+ return // Not enough data yet
242
+ }
243
+
244
+ const version = this.buffer[0]
245
+ const status = this.buffer[1]
246
+
247
+ if (version !== 0x01) {
248
+ throw new Socks5ProxyError(`Invalid auth sub-negotiation version: ${version}`, 'UND_ERR_SOCKS5_AUTH_VERSION')
249
+ }
250
+
251
+ if (status !== 0x00) {
252
+ throw new Socks5ProxyError('Authentication failed', 'UND_ERR_SOCKS5_AUTH_FAILED')
253
+ }
254
+
255
+ this.buffer = this.buffer.subarray(2)
256
+ debug('authentication successful')
257
+ this.emit('authenticated')
258
+ }
259
+
260
+ /**
261
+ * Send CONNECT command
262
+ * @param {string} address - Target address (IP or domain)
263
+ * @param {number} port - Target port
264
+ */
265
+ connect (address, port) {
266
+ if (this.state === STATES.CONNECTED) {
267
+ throw new InvalidArgumentError('Already connected')
268
+ }
269
+
270
+ debug('connecting to', address, port)
271
+ this.state = STATES.CONNECTING
272
+
273
+ const request = this.buildConnectRequest(COMMANDS.CONNECT, address, port)
274
+ this.socket.write(request)
275
+ }
276
+
277
+ /**
278
+ * Build a SOCKS5 request
279
+ */
280
+ buildConnectRequest (command, address, port) {
281
+ // Parse address to determine type and buffer
282
+ const { type: addressType, buffer: addressBuffer } = parseAddress(address)
283
+
284
+ // Build request
285
+ // +----+-----+-------+------+----------+----------+
286
+ // |VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT |
287
+ // +----+-----+-------+------+----------+----------+
288
+ // | 1 | 1 | X'00' | 1 | Variable | 2 |
289
+ // +----+-----+-------+------+----------+----------+
290
+ const request = Buffer.alloc(4 + addressBuffer.length + 2)
291
+ request[0] = SOCKS_VERSION
292
+ request[1] = command
293
+ request[2] = 0x00 // Reserved
294
+ request[3] = addressType
295
+ addressBuffer.copy(request, 4)
296
+ request.writeUInt16BE(port, 4 + addressBuffer.length)
297
+
298
+ return request
299
+ }
300
+
301
+ /**
302
+ * Handle CONNECT response
303
+ */
304
+ handleConnectResponse () {
305
+ if (this.buffer.length < 4) {
306
+ return // Not enough data for header
307
+ }
308
+
309
+ const version = this.buffer[0]
310
+ const reply = this.buffer[1]
311
+ const addressType = this.buffer[3]
312
+
313
+ if (version !== SOCKS_VERSION) {
314
+ throw new Socks5ProxyError(`Invalid SOCKS version in reply: ${version}`, 'UND_ERR_SOCKS5_REPLY_VERSION')
315
+ }
316
+
317
+ // Calculate the expected response length
318
+ let responseLength = 4 // VER + REP + RSV + ATYP
319
+ if (addressType === ADDRESS_TYPES.IPV4) {
320
+ responseLength += 4 + 2 // IPv4 + port
321
+ } else if (addressType === ADDRESS_TYPES.DOMAIN) {
322
+ if (this.buffer.length < 5) {
323
+ return // Need domain length byte
324
+ }
325
+ responseLength += 1 + this.buffer[4] + 2 // length byte + domain + port
326
+ } else if (addressType === ADDRESS_TYPES.IPV6) {
327
+ responseLength += 16 + 2 // IPv6 + port
328
+ } else {
329
+ throw new Socks5ProxyError(`Invalid address type in reply: ${addressType}`, 'UND_ERR_SOCKS5_ADDR_TYPE')
330
+ }
331
+
332
+ if (this.buffer.length < responseLength) {
333
+ return // Not enough data for full response
334
+ }
335
+
336
+ if (reply !== REPLY_CODES.SUCCEEDED) {
337
+ const errorMessage = this.getReplyErrorMessage(reply)
338
+ throw new Socks5ProxyError(`SOCKS5 connection failed: ${errorMessage}`, `UND_ERR_SOCKS5_REPLY_${reply}`)
339
+ }
340
+
341
+ // Parse bound address and port
342
+ let boundAddress
343
+ let offset = 4
344
+
345
+ if (addressType === ADDRESS_TYPES.IPV4) {
346
+ boundAddress = Array.from(this.buffer.subarray(offset, offset + 4)).join('.')
347
+ offset += 4
348
+ } else if (addressType === ADDRESS_TYPES.DOMAIN) {
349
+ const domainLength = this.buffer[offset]
350
+ offset += 1
351
+ boundAddress = this.buffer.subarray(offset, offset + domainLength).toString()
352
+ offset += domainLength
353
+ } else if (addressType === ADDRESS_TYPES.IPV6) {
354
+ // Parse IPv6 address from 16-byte buffer
355
+ const parts = []
356
+ for (let i = 0; i < 8; i++) {
357
+ const value = this.buffer.readUInt16BE(offset + i * 2)
358
+ parts.push(value.toString(16))
359
+ }
360
+ boundAddress = parts.join(':')
361
+ offset += 16
362
+ }
363
+
364
+ const boundPort = this.buffer.readUInt16BE(offset)
365
+
366
+ this.buffer = this.buffer.subarray(responseLength)
367
+ this.state = STATES.CONNECTED
368
+
369
+ debug('connected, bound address:', boundAddress, 'port:', boundPort)
370
+ this.emit('connected', { address: boundAddress, port: boundPort })
371
+ }
372
+
373
+ /**
374
+ * Get human-readable error message for reply code
375
+ */
376
+ getReplyErrorMessage (reply) {
377
+ switch (reply) {
378
+ case REPLY_CODES.GENERAL_FAILURE:
379
+ return 'General SOCKS server failure'
380
+ case REPLY_CODES.CONNECTION_NOT_ALLOWED:
381
+ return 'Connection not allowed by ruleset'
382
+ case REPLY_CODES.NETWORK_UNREACHABLE:
383
+ return 'Network unreachable'
384
+ case REPLY_CODES.HOST_UNREACHABLE:
385
+ return 'Host unreachable'
386
+ case REPLY_CODES.CONNECTION_REFUSED:
387
+ return 'Connection refused'
388
+ case REPLY_CODES.TTL_EXPIRED:
389
+ return 'TTL expired'
390
+ case REPLY_CODES.COMMAND_NOT_SUPPORTED:
391
+ return 'Command not supported'
392
+ case REPLY_CODES.ADDRESS_TYPE_NOT_SUPPORTED:
393
+ return 'Address type not supported'
394
+ default:
395
+ return `Unknown error code: ${reply}`
396
+ }
397
+ }
398
+ }
399
+
400
+ module.exports = {
401
+ Socks5Client,
402
+ AUTH_METHODS,
403
+ COMMANDS,
404
+ ADDRESS_TYPES,
405
+ REPLY_CODES,
406
+ STATES
407
+ }
@@ -0,0 +1,203 @@
1
+ 'use strict'
2
+
3
+ const { Buffer } = require('node:buffer')
4
+ const net = require('node:net')
5
+ const { InvalidArgumentError } = require('./errors')
6
+
7
+ /**
8
+ * Parse an address and determine its type
9
+ * @param {string} address - The address to parse
10
+ * @returns {{type: number, buffer: Buffer}} Address type and buffer
11
+ */
12
+ function parseAddress (address) {
13
+ // Check if it's an IPv4 address
14
+ if (net.isIPv4(address)) {
15
+ const parts = address.split('.').map(Number)
16
+ return {
17
+ type: 0x01, // IPv4
18
+ buffer: Buffer.from(parts)
19
+ }
20
+ }
21
+
22
+ // Check if it's an IPv6 address
23
+ if (net.isIPv6(address)) {
24
+ return {
25
+ type: 0x04, // IPv6
26
+ buffer: parseIPv6(address)
27
+ }
28
+ }
29
+
30
+ // Otherwise, treat as domain name
31
+ const domainBuffer = Buffer.from(address, 'utf8')
32
+ if (domainBuffer.length > 255) {
33
+ throw new InvalidArgumentError('Domain name too long (max 255 bytes)')
34
+ }
35
+
36
+ return {
37
+ type: 0x03, // Domain
38
+ buffer: Buffer.concat([Buffer.from([domainBuffer.length]), domainBuffer])
39
+ }
40
+ }
41
+
42
+ /**
43
+ * Parse IPv6 address to buffer
44
+ * @param {string} address - IPv6 address string
45
+ * @returns {Buffer} 16-byte buffer
46
+ */
47
+ function parseIPv6 (address) {
48
+ const buffer = Buffer.alloc(16)
49
+ const parts = address.split(':')
50
+ let partIndex = 0
51
+ let bufferIndex = 0
52
+
53
+ // Handle compressed notation (::)
54
+ const doubleColonIndex = address.indexOf('::')
55
+ if (doubleColonIndex !== -1) {
56
+ // Count non-empty parts
57
+ const nonEmptyParts = parts.filter(p => p.length > 0).length
58
+ const skipParts = 8 - nonEmptyParts
59
+
60
+ for (let i = 0; i < parts.length; i++) {
61
+ if (parts[i] === '' && i === doubleColonIndex / 3) {
62
+ // Skip empty parts for ::
63
+ bufferIndex += skipParts * 2
64
+ } else if (parts[i] !== '') {
65
+ const value = parseInt(parts[i], 16)
66
+ buffer.writeUInt16BE(value, bufferIndex)
67
+ bufferIndex += 2
68
+ }
69
+ }
70
+ } else {
71
+ // No compression, parse normally
72
+ for (const part of parts) {
73
+ if (part === '') continue
74
+ const value = parseInt(part, 16)
75
+ buffer.writeUInt16BE(value, partIndex * 2)
76
+ partIndex++
77
+ }
78
+ }
79
+
80
+ return buffer
81
+ }
82
+
83
+ /**
84
+ * Build a SOCKS5 address buffer
85
+ * @param {number} type - Address type (1=IPv4, 3=Domain, 4=IPv6)
86
+ * @param {Buffer} addressBuffer - The address data
87
+ * @param {number} port - Port number
88
+ * @returns {Buffer} Complete address buffer including type, address, and port
89
+ */
90
+ function buildAddressBuffer (type, addressBuffer, port) {
91
+ const portBuffer = Buffer.allocUnsafe(2)
92
+ portBuffer.writeUInt16BE(port, 0)
93
+
94
+ return Buffer.concat([
95
+ Buffer.from([type]),
96
+ addressBuffer,
97
+ portBuffer
98
+ ])
99
+ }
100
+
101
+ /**
102
+ * Parse address from SOCKS5 response
103
+ * @param {Buffer} buffer - Buffer containing the address
104
+ * @param {number} offset - Starting offset in buffer
105
+ * @returns {{address: string, port: number, bytesRead: number}}
106
+ */
107
+ function parseResponseAddress (buffer, offset = 0) {
108
+ if (buffer.length < offset + 1) {
109
+ throw new InvalidArgumentError('Buffer too small to contain address type')
110
+ }
111
+
112
+ const addressType = buffer[offset]
113
+ let address
114
+ let currentOffset = offset + 1
115
+
116
+ switch (addressType) {
117
+ case 0x01: { // IPv4
118
+ if (buffer.length < currentOffset + 6) {
119
+ throw new InvalidArgumentError('Buffer too small for IPv4 address')
120
+ }
121
+ address = Array.from(buffer.subarray(currentOffset, currentOffset + 4)).join('.')
122
+ currentOffset += 4
123
+ break
124
+ }
125
+
126
+ case 0x03: { // Domain
127
+ if (buffer.length < currentOffset + 1) {
128
+ throw new InvalidArgumentError('Buffer too small for domain length')
129
+ }
130
+ const domainLength = buffer[currentOffset]
131
+ currentOffset += 1
132
+
133
+ if (buffer.length < currentOffset + domainLength + 2) {
134
+ throw new InvalidArgumentError('Buffer too small for domain address')
135
+ }
136
+ address = buffer.subarray(currentOffset, currentOffset + domainLength).toString('utf8')
137
+ currentOffset += domainLength
138
+ break
139
+ }
140
+
141
+ case 0x04: { // IPv6
142
+ if (buffer.length < currentOffset + 18) {
143
+ throw new InvalidArgumentError('Buffer too small for IPv6 address')
144
+ }
145
+ // Convert buffer to IPv6 string
146
+ const parts = []
147
+ for (let i = 0; i < 8; i++) {
148
+ const value = buffer.readUInt16BE(currentOffset + i * 2)
149
+ parts.push(value.toString(16))
150
+ }
151
+ address = parts.join(':')
152
+ currentOffset += 16
153
+ break
154
+ }
155
+
156
+ default:
157
+ throw new InvalidArgumentError(`Invalid address type: ${addressType}`)
158
+ }
159
+
160
+ // Parse port
161
+ if (buffer.length < currentOffset + 2) {
162
+ throw new InvalidArgumentError('Buffer too small for port')
163
+ }
164
+ const port = buffer.readUInt16BE(currentOffset)
165
+ currentOffset += 2
166
+
167
+ return {
168
+ address,
169
+ port,
170
+ bytesRead: currentOffset - offset
171
+ }
172
+ }
173
+
174
+ /**
175
+ * Create error for SOCKS5 reply code
176
+ * @param {number} replyCode - SOCKS5 reply code
177
+ * @returns {Error} Appropriate error object
178
+ */
179
+ function createReplyError (replyCode) {
180
+ const messages = {
181
+ 0x01: 'General SOCKS server failure',
182
+ 0x02: 'Connection not allowed by ruleset',
183
+ 0x03: 'Network unreachable',
184
+ 0x04: 'Host unreachable',
185
+ 0x05: 'Connection refused',
186
+ 0x06: 'TTL expired',
187
+ 0x07: 'Command not supported',
188
+ 0x08: 'Address type not supported'
189
+ }
190
+
191
+ const message = messages[replyCode] || `Unknown SOCKS5 error code: ${replyCode}`
192
+ const error = new Error(message)
193
+ error.code = `SOCKS5_${replyCode}`
194
+ return error
195
+ }
196
+
197
+ module.exports = {
198
+ parseAddress,
199
+ parseIPv6,
200
+ buildAddressBuffer,
201
+ parseResponseAddress,
202
+ createReplyError
203
+ }
@@ -0,0 +1,75 @@
1
+ 'use strict'
2
+
3
+ module.exports = {
4
+ kClose: Symbol('close'),
5
+ kDestroy: Symbol('destroy'),
6
+ kDispatch: Symbol('dispatch'),
7
+ kUrl: Symbol('url'),
8
+ kWriting: Symbol('writing'),
9
+ kResuming: Symbol('resuming'),
10
+ kQueue: Symbol('queue'),
11
+ kConnect: Symbol('connect'),
12
+ kConnecting: Symbol('connecting'),
13
+ kKeepAliveDefaultTimeout: Symbol('default keep alive timeout'),
14
+ kKeepAliveMaxTimeout: Symbol('max keep alive timeout'),
15
+ kKeepAliveTimeoutThreshold: Symbol('keep alive timeout threshold'),
16
+ kKeepAliveTimeoutValue: Symbol('keep alive timeout'),
17
+ kKeepAlive: Symbol('keep alive'),
18
+ kHeadersTimeout: Symbol('headers timeout'),
19
+ kBodyTimeout: Symbol('body timeout'),
20
+ kServerName: Symbol('server name'),
21
+ kLocalAddress: Symbol('local address'),
22
+ kHost: Symbol('host'),
23
+ kNoRef: Symbol('no ref'),
24
+ kBodyUsed: Symbol('used'),
25
+ kBody: Symbol('abstracted request body'),
26
+ kRunning: Symbol('running'),
27
+ kBlocking: Symbol('blocking'),
28
+ kPending: Symbol('pending'),
29
+ kSize: Symbol('size'),
30
+ kBusy: Symbol('busy'),
31
+ kQueued: Symbol('queued'),
32
+ kFree: Symbol('free'),
33
+ kConnected: Symbol('connected'),
34
+ kClosed: Symbol('closed'),
35
+ kNeedDrain: Symbol('need drain'),
36
+ kReset: Symbol('reset'),
37
+ kDestroyed: Symbol.for('nodejs.stream.destroyed'),
38
+ kResume: Symbol('resume'),
39
+ kOnError: Symbol('on error'),
40
+ kMaxHeadersSize: Symbol('max headers size'),
41
+ kRunningIdx: Symbol('running index'),
42
+ kPendingIdx: Symbol('pending index'),
43
+ kError: Symbol('error'),
44
+ kClients: Symbol('clients'),
45
+ kClient: Symbol('client'),
46
+ kParser: Symbol('parser'),
47
+ kOnDestroyed: Symbol('destroy callbacks'),
48
+ kPipelining: Symbol('pipelining'),
49
+ kSocket: Symbol('socket'),
50
+ kHostHeader: Symbol('host header'),
51
+ kConnector: Symbol('connector'),
52
+ kStrictContentLength: Symbol('strict content length'),
53
+ kMaxRedirections: Symbol('maxRedirections'),
54
+ kMaxRequests: Symbol('maxRequestsPerClient'),
55
+ kProxy: Symbol('proxy agent options'),
56
+ kCounter: Symbol('socket request counter'),
57
+ kMaxResponseSize: Symbol('max response size'),
58
+ kHTTP2Session: Symbol('http2Session'),
59
+ kHTTP2SessionState: Symbol('http2Session state'),
60
+ kRetryHandlerDefaultRetry: Symbol('retry agent default retry'),
61
+ kConstruct: Symbol('constructable'),
62
+ kListeners: Symbol('listeners'),
63
+ kHTTPContext: Symbol('http context'),
64
+ kMaxConcurrentStreams: Symbol('max concurrent streams'),
65
+ kHTTP2InitialWindowSize: Symbol('http2 initial window size'),
66
+ kHTTP2ConnectionWindowSize: Symbol('http2 connection window size'),
67
+ kEnableConnectProtocol: Symbol('http2session connect protocol'),
68
+ kRemoteSettings: Symbol('http2session remote settings'),
69
+ kHTTP2Stream: Symbol('http2session client stream'),
70
+ kPingInterval: Symbol('ping interval'),
71
+ kNoProxyAgent: Symbol('no proxy agent'),
72
+ kHttpProxyAgent: Symbol('http proxy agent'),
73
+ kHttpsProxyAgent: Symbol('https proxy agent'),
74
+ kSocks5ProxyAgent: Symbol('socks5 proxy agent')
75
+ }