@inkeep/agents-work-apps 0.50.1 → 0.50.3
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/dist/_virtual/rolldown_runtime.js +32 -0
- package/dist/env.d.ts +2 -0
- package/dist/env.js +1 -0
- package/dist/github/mcp/auth.d.ts +2 -2
- package/dist/github/mcp/index.d.ts +2 -2
- package/dist/github/routes/setup.d.ts +2 -2
- package/dist/github/routes/tokenExchange.d.ts +2 -2
- package/dist/github/routes/webhooks.d.ts +2 -2
- package/dist/node_modules/.pnpm/@slack_logger@4.0.0/node_modules/@slack/logger/dist/index.js +89 -0
- package/dist/node_modules/.pnpm/@slack_socket-mode@2.0.5/node_modules/@slack/socket-mode/dist/package.js +85 -0
- package/dist/node_modules/.pnpm/@slack_socket-mode@2.0.5/node_modules/@slack/socket-mode/dist/src/SlackWebSocket.js +223 -0
- package/dist/node_modules/.pnpm/@slack_socket-mode@2.0.5/node_modules/@slack/socket-mode/dist/src/SocketModeClient.js +367 -0
- package/dist/node_modules/.pnpm/@slack_socket-mode@2.0.5/node_modules/@slack/socket-mode/dist/src/UnrecoverableSocketModeStartError.js +20 -0
- package/dist/node_modules/.pnpm/@slack_socket-mode@2.0.5/node_modules/@slack/socket-mode/dist/src/errors.js +71 -0
- package/dist/node_modules/.pnpm/@slack_socket-mode@2.0.5/node_modules/@slack/socket-mode/dist/src/index.js +44 -0
- package/dist/node_modules/.pnpm/@slack_socket-mode@2.0.5/node_modules/@slack/socket-mode/dist/src/logger.js +32 -0
- package/dist/node_modules/.pnpm/eventemitter3@5.0.1/node_modules/eventemitter3/index.js +241 -0
- package/dist/node_modules/.pnpm/ws@8.19.0/node_modules/ws/index.js +23 -0
- package/dist/node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/buffer-util.js +107 -0
- package/dist/node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/constants.js +29 -0
- package/dist/node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/event-target.js +226 -0
- package/dist/node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/extension.js +150 -0
- package/dist/node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/limiter.js +57 -0
- package/dist/node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/permessage-deflate.js +342 -0
- package/dist/node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/receiver.js +457 -0
- package/dist/node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/sender.js +505 -0
- package/dist/node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/stream.js +123 -0
- package/dist/node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/subprotocol.js +46 -0
- package/dist/node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/validation.js +203 -0
- package/dist/node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/websocket-server.js +385 -0
- package/dist/node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/websocket.js +985 -0
- package/dist/slack/dispatcher.d.ts +16 -0
- package/dist/slack/dispatcher.js +335 -0
- package/dist/slack/i18n/strings.d.ts +5 -5
- package/dist/slack/i18n/strings.js +9 -9
- package/dist/slack/index.d.ts +3 -1
- package/dist/slack/index.js +4 -2
- package/dist/slack/middleware/permissions.js +120 -107
- package/dist/slack/routes/events.js +10 -328
- package/dist/slack/routes/oauth.js +6 -3
- package/dist/slack/routes/users.js +12 -6
- package/dist/slack/routes/workspaces.js +31 -36
- package/dist/slack/services/blocks/index.js +7 -11
- package/dist/slack/services/commands/index.js +2 -2
- package/dist/slack/services/dev-config.d.ts +23 -0
- package/dist/slack/services/dev-config.js +91 -0
- package/dist/slack/services/events/app-mention.js +6 -17
- package/dist/slack/services/events/modal-submission.js +5 -5
- package/dist/slack/services/events/streaming.js +4 -3
- package/dist/slack/services/events/utils.js +8 -8
- package/dist/slack/services/index.js +1 -1
- package/dist/slack/services/modals.js +4 -4
- package/dist/slack/services/nango.d.ts +2 -0
- package/dist/slack/services/nango.js +84 -2
- package/dist/slack/socket-mode.d.ts +4 -0
- package/dist/slack/socket-mode.js +130 -0
- package/package.json +3 -2
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import { __commonJSMin, __require } from "../../../../../../_virtual/rolldown_runtime.js";
|
|
2
|
+
import { require_constants } from "./constants.js";
|
|
3
|
+
|
|
4
|
+
//#region ../../node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/validation.js
|
|
5
|
+
var require_validation = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
6
|
+
const { isUtf8 } = __require("buffer");
|
|
7
|
+
const { hasBlob } = require_constants();
|
|
8
|
+
const tokenChars = [
|
|
9
|
+
0,
|
|
10
|
+
0,
|
|
11
|
+
0,
|
|
12
|
+
0,
|
|
13
|
+
0,
|
|
14
|
+
0,
|
|
15
|
+
0,
|
|
16
|
+
0,
|
|
17
|
+
0,
|
|
18
|
+
0,
|
|
19
|
+
0,
|
|
20
|
+
0,
|
|
21
|
+
0,
|
|
22
|
+
0,
|
|
23
|
+
0,
|
|
24
|
+
0,
|
|
25
|
+
0,
|
|
26
|
+
0,
|
|
27
|
+
0,
|
|
28
|
+
0,
|
|
29
|
+
0,
|
|
30
|
+
0,
|
|
31
|
+
0,
|
|
32
|
+
0,
|
|
33
|
+
0,
|
|
34
|
+
0,
|
|
35
|
+
0,
|
|
36
|
+
0,
|
|
37
|
+
0,
|
|
38
|
+
0,
|
|
39
|
+
0,
|
|
40
|
+
0,
|
|
41
|
+
0,
|
|
42
|
+
1,
|
|
43
|
+
0,
|
|
44
|
+
1,
|
|
45
|
+
1,
|
|
46
|
+
1,
|
|
47
|
+
1,
|
|
48
|
+
1,
|
|
49
|
+
0,
|
|
50
|
+
0,
|
|
51
|
+
1,
|
|
52
|
+
1,
|
|
53
|
+
0,
|
|
54
|
+
1,
|
|
55
|
+
1,
|
|
56
|
+
0,
|
|
57
|
+
1,
|
|
58
|
+
1,
|
|
59
|
+
1,
|
|
60
|
+
1,
|
|
61
|
+
1,
|
|
62
|
+
1,
|
|
63
|
+
1,
|
|
64
|
+
1,
|
|
65
|
+
1,
|
|
66
|
+
1,
|
|
67
|
+
0,
|
|
68
|
+
0,
|
|
69
|
+
0,
|
|
70
|
+
0,
|
|
71
|
+
0,
|
|
72
|
+
0,
|
|
73
|
+
0,
|
|
74
|
+
1,
|
|
75
|
+
1,
|
|
76
|
+
1,
|
|
77
|
+
1,
|
|
78
|
+
1,
|
|
79
|
+
1,
|
|
80
|
+
1,
|
|
81
|
+
1,
|
|
82
|
+
1,
|
|
83
|
+
1,
|
|
84
|
+
1,
|
|
85
|
+
1,
|
|
86
|
+
1,
|
|
87
|
+
1,
|
|
88
|
+
1,
|
|
89
|
+
1,
|
|
90
|
+
1,
|
|
91
|
+
1,
|
|
92
|
+
1,
|
|
93
|
+
1,
|
|
94
|
+
1,
|
|
95
|
+
1,
|
|
96
|
+
1,
|
|
97
|
+
1,
|
|
98
|
+
1,
|
|
99
|
+
1,
|
|
100
|
+
0,
|
|
101
|
+
0,
|
|
102
|
+
0,
|
|
103
|
+
1,
|
|
104
|
+
1,
|
|
105
|
+
1,
|
|
106
|
+
1,
|
|
107
|
+
1,
|
|
108
|
+
1,
|
|
109
|
+
1,
|
|
110
|
+
1,
|
|
111
|
+
1,
|
|
112
|
+
1,
|
|
113
|
+
1,
|
|
114
|
+
1,
|
|
115
|
+
1,
|
|
116
|
+
1,
|
|
117
|
+
1,
|
|
118
|
+
1,
|
|
119
|
+
1,
|
|
120
|
+
1,
|
|
121
|
+
1,
|
|
122
|
+
1,
|
|
123
|
+
1,
|
|
124
|
+
1,
|
|
125
|
+
1,
|
|
126
|
+
1,
|
|
127
|
+
1,
|
|
128
|
+
1,
|
|
129
|
+
1,
|
|
130
|
+
1,
|
|
131
|
+
1,
|
|
132
|
+
0,
|
|
133
|
+
1,
|
|
134
|
+
0,
|
|
135
|
+
1,
|
|
136
|
+
0
|
|
137
|
+
];
|
|
138
|
+
/**
|
|
139
|
+
* Checks if a status code is allowed in a close frame.
|
|
140
|
+
*
|
|
141
|
+
* @param {Number} code The status code
|
|
142
|
+
* @return {Boolean} `true` if the status code is valid, else `false`
|
|
143
|
+
* @public
|
|
144
|
+
*/
|
|
145
|
+
function isValidStatusCode(code) {
|
|
146
|
+
return code >= 1e3 && code <= 1014 && code !== 1004 && code !== 1005 && code !== 1006 || code >= 3e3 && code <= 4999;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Checks if a given buffer contains only correct UTF-8.
|
|
150
|
+
* Ported from https://www.cl.cam.ac.uk/%7Emgk25/ucs/utf8_check.c by
|
|
151
|
+
* Markus Kuhn.
|
|
152
|
+
*
|
|
153
|
+
* @param {Buffer} buf The buffer to check
|
|
154
|
+
* @return {Boolean} `true` if `buf` contains only correct UTF-8, else `false`
|
|
155
|
+
* @public
|
|
156
|
+
*/
|
|
157
|
+
function _isValidUTF8(buf) {
|
|
158
|
+
const len = buf.length;
|
|
159
|
+
let i = 0;
|
|
160
|
+
while (i < len) if ((buf[i] & 128) === 0) i++;
|
|
161
|
+
else if ((buf[i] & 224) === 192) {
|
|
162
|
+
if (i + 1 === len || (buf[i + 1] & 192) !== 128 || (buf[i] & 254) === 192) return false;
|
|
163
|
+
i += 2;
|
|
164
|
+
} else if ((buf[i] & 240) === 224) {
|
|
165
|
+
if (i + 2 >= len || (buf[i + 1] & 192) !== 128 || (buf[i + 2] & 192) !== 128 || buf[i] === 224 && (buf[i + 1] & 224) === 128 || buf[i] === 237 && (buf[i + 1] & 224) === 160) return false;
|
|
166
|
+
i += 3;
|
|
167
|
+
} else if ((buf[i] & 248) === 240) {
|
|
168
|
+
if (i + 3 >= len || (buf[i + 1] & 192) !== 128 || (buf[i + 2] & 192) !== 128 || (buf[i + 3] & 192) !== 128 || buf[i] === 240 && (buf[i + 1] & 240) === 128 || buf[i] === 244 && buf[i + 1] > 143 || buf[i] > 244) return false;
|
|
169
|
+
i += 4;
|
|
170
|
+
} else return false;
|
|
171
|
+
return true;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Determines whether a value is a `Blob`.
|
|
175
|
+
*
|
|
176
|
+
* @param {*} value The value to be tested
|
|
177
|
+
* @return {Boolean} `true` if `value` is a `Blob`, else `false`
|
|
178
|
+
* @private
|
|
179
|
+
*/
|
|
180
|
+
function isBlob(value) {
|
|
181
|
+
return hasBlob && typeof value === "object" && typeof value.arrayBuffer === "function" && typeof value.type === "string" && typeof value.stream === "function" && (value[Symbol.toStringTag] === "Blob" || value[Symbol.toStringTag] === "File");
|
|
182
|
+
}
|
|
183
|
+
module.exports = {
|
|
184
|
+
isBlob,
|
|
185
|
+
isValidStatusCode,
|
|
186
|
+
isValidUTF8: _isValidUTF8,
|
|
187
|
+
tokenChars
|
|
188
|
+
};
|
|
189
|
+
if (isUtf8) module.exports.isValidUTF8 = function(buf) {
|
|
190
|
+
return buf.length < 24 ? _isValidUTF8(buf) : isUtf8(buf);
|
|
191
|
+
};
|
|
192
|
+
else if (!process.env.WS_NO_UTF_8_VALIDATE) try {
|
|
193
|
+
const isValidUTF8 = __require("utf-8-validate");
|
|
194
|
+
module.exports.isValidUTF8 = function(buf) {
|
|
195
|
+
return buf.length < 32 ? _isValidUTF8(buf) : isValidUTF8(buf);
|
|
196
|
+
};
|
|
197
|
+
} catch (e) {}
|
|
198
|
+
}));
|
|
199
|
+
|
|
200
|
+
//#endregion
|
|
201
|
+
export default require_validation();
|
|
202
|
+
|
|
203
|
+
export { require_validation };
|
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
import { __commonJSMin, __require } from "../../../../../../_virtual/rolldown_runtime.js";
|
|
2
|
+
import { require_constants } from "./constants.js";
|
|
3
|
+
import { require_permessage_deflate } from "./permessage-deflate.js";
|
|
4
|
+
import { require_extension } from "./extension.js";
|
|
5
|
+
import { require_websocket } from "./websocket.js";
|
|
6
|
+
import { require_subprotocol } from "./subprotocol.js";
|
|
7
|
+
|
|
8
|
+
//#region ../../node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/websocket-server.js
|
|
9
|
+
var require_websocket_server = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
10
|
+
const EventEmitter = __require("events");
|
|
11
|
+
const http = __require("http");
|
|
12
|
+
const { Duplex } = __require("stream");
|
|
13
|
+
const { createHash } = __require("crypto");
|
|
14
|
+
const extension = require_extension();
|
|
15
|
+
const PerMessageDeflate = require_permessage_deflate();
|
|
16
|
+
const subprotocol = require_subprotocol();
|
|
17
|
+
const WebSocket = require_websocket();
|
|
18
|
+
const { CLOSE_TIMEOUT, GUID, kWebSocket } = require_constants();
|
|
19
|
+
const keyRegex = /^[+/0-9A-Za-z]{22}==$/;
|
|
20
|
+
const RUNNING = 0;
|
|
21
|
+
const CLOSING = 1;
|
|
22
|
+
const CLOSED = 2;
|
|
23
|
+
/**
|
|
24
|
+
* Class representing a WebSocket server.
|
|
25
|
+
*
|
|
26
|
+
* @extends EventEmitter
|
|
27
|
+
*/
|
|
28
|
+
var WebSocketServer = class extends EventEmitter {
|
|
29
|
+
/**
|
|
30
|
+
* Create a `WebSocketServer` instance.
|
|
31
|
+
*
|
|
32
|
+
* @param {Object} options Configuration options
|
|
33
|
+
* @param {Boolean} [options.allowSynchronousEvents=true] Specifies whether
|
|
34
|
+
* any of the `'message'`, `'ping'`, and `'pong'` events can be emitted
|
|
35
|
+
* multiple times in the same tick
|
|
36
|
+
* @param {Boolean} [options.autoPong=true] Specifies whether or not to
|
|
37
|
+
* automatically send a pong in response to a ping
|
|
38
|
+
* @param {Number} [options.backlog=511] The maximum length of the queue of
|
|
39
|
+
* pending connections
|
|
40
|
+
* @param {Boolean} [options.clientTracking=true] Specifies whether or not to
|
|
41
|
+
* track clients
|
|
42
|
+
* @param {Number} [options.closeTimeout=30000] Duration in milliseconds to
|
|
43
|
+
* wait for the closing handshake to finish after `websocket.close()` is
|
|
44
|
+
* called
|
|
45
|
+
* @param {Function} [options.handleProtocols] A hook to handle protocols
|
|
46
|
+
* @param {String} [options.host] The hostname where to bind the server
|
|
47
|
+
* @param {Number} [options.maxPayload=104857600] The maximum allowed message
|
|
48
|
+
* size
|
|
49
|
+
* @param {Boolean} [options.noServer=false] Enable no server mode
|
|
50
|
+
* @param {String} [options.path] Accept only connections matching this path
|
|
51
|
+
* @param {(Boolean|Object)} [options.perMessageDeflate=false] Enable/disable
|
|
52
|
+
* permessage-deflate
|
|
53
|
+
* @param {Number} [options.port] The port where to bind the server
|
|
54
|
+
* @param {(http.Server|https.Server)} [options.server] A pre-created HTTP/S
|
|
55
|
+
* server to use
|
|
56
|
+
* @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or
|
|
57
|
+
* not to skip UTF-8 validation for text and close messages
|
|
58
|
+
* @param {Function} [options.verifyClient] A hook to reject connections
|
|
59
|
+
* @param {Function} [options.WebSocket=WebSocket] Specifies the `WebSocket`
|
|
60
|
+
* class to use. It must be the `WebSocket` class or class that extends it
|
|
61
|
+
* @param {Function} [callback] A listener for the `listening` event
|
|
62
|
+
*/
|
|
63
|
+
constructor(options, callback) {
|
|
64
|
+
super();
|
|
65
|
+
options = {
|
|
66
|
+
allowSynchronousEvents: true,
|
|
67
|
+
autoPong: true,
|
|
68
|
+
maxPayload: 100 * 1024 * 1024,
|
|
69
|
+
skipUTF8Validation: false,
|
|
70
|
+
perMessageDeflate: false,
|
|
71
|
+
handleProtocols: null,
|
|
72
|
+
clientTracking: true,
|
|
73
|
+
closeTimeout: CLOSE_TIMEOUT,
|
|
74
|
+
verifyClient: null,
|
|
75
|
+
noServer: false,
|
|
76
|
+
backlog: null,
|
|
77
|
+
server: null,
|
|
78
|
+
host: null,
|
|
79
|
+
path: null,
|
|
80
|
+
port: null,
|
|
81
|
+
WebSocket,
|
|
82
|
+
...options
|
|
83
|
+
};
|
|
84
|
+
if (options.port == null && !options.server && !options.noServer || options.port != null && (options.server || options.noServer) || options.server && options.noServer) throw new TypeError("One and only one of the \"port\", \"server\", or \"noServer\" options must be specified");
|
|
85
|
+
if (options.port != null) {
|
|
86
|
+
this._server = http.createServer((req, res) => {
|
|
87
|
+
const body = http.STATUS_CODES[426];
|
|
88
|
+
res.writeHead(426, {
|
|
89
|
+
"Content-Length": body.length,
|
|
90
|
+
"Content-Type": "text/plain"
|
|
91
|
+
});
|
|
92
|
+
res.end(body);
|
|
93
|
+
});
|
|
94
|
+
this._server.listen(options.port, options.host, options.backlog, callback);
|
|
95
|
+
} else if (options.server) this._server = options.server;
|
|
96
|
+
if (this._server) {
|
|
97
|
+
const emitConnection = this.emit.bind(this, "connection");
|
|
98
|
+
this._removeListeners = addListeners(this._server, {
|
|
99
|
+
listening: this.emit.bind(this, "listening"),
|
|
100
|
+
error: this.emit.bind(this, "error"),
|
|
101
|
+
upgrade: (req, socket, head) => {
|
|
102
|
+
this.handleUpgrade(req, socket, head, emitConnection);
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
if (options.perMessageDeflate === true) options.perMessageDeflate = {};
|
|
107
|
+
if (options.clientTracking) {
|
|
108
|
+
this.clients = /* @__PURE__ */ new Set();
|
|
109
|
+
this._shouldEmitClose = false;
|
|
110
|
+
}
|
|
111
|
+
this.options = options;
|
|
112
|
+
this._state = RUNNING;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Returns the bound address, the address family name, and port of the server
|
|
116
|
+
* as reported by the operating system if listening on an IP socket.
|
|
117
|
+
* If the server is listening on a pipe or UNIX domain socket, the name is
|
|
118
|
+
* returned as a string.
|
|
119
|
+
*
|
|
120
|
+
* @return {(Object|String|null)} The address of the server
|
|
121
|
+
* @public
|
|
122
|
+
*/
|
|
123
|
+
address() {
|
|
124
|
+
if (this.options.noServer) throw new Error("The server is operating in \"noServer\" mode");
|
|
125
|
+
if (!this._server) return null;
|
|
126
|
+
return this._server.address();
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Stop the server from accepting new connections and emit the `'close'` event
|
|
130
|
+
* when all existing connections are closed.
|
|
131
|
+
*
|
|
132
|
+
* @param {Function} [cb] A one-time listener for the `'close'` event
|
|
133
|
+
* @public
|
|
134
|
+
*/
|
|
135
|
+
close(cb) {
|
|
136
|
+
if (this._state === CLOSED) {
|
|
137
|
+
if (cb) this.once("close", () => {
|
|
138
|
+
cb(/* @__PURE__ */ new Error("The server is not running"));
|
|
139
|
+
});
|
|
140
|
+
process.nextTick(emitClose, this);
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
if (cb) this.once("close", cb);
|
|
144
|
+
if (this._state === CLOSING) return;
|
|
145
|
+
this._state = CLOSING;
|
|
146
|
+
if (this.options.noServer || this.options.server) {
|
|
147
|
+
if (this._server) {
|
|
148
|
+
this._removeListeners();
|
|
149
|
+
this._removeListeners = this._server = null;
|
|
150
|
+
}
|
|
151
|
+
if (this.clients) if (!this.clients.size) process.nextTick(emitClose, this);
|
|
152
|
+
else this._shouldEmitClose = true;
|
|
153
|
+
else process.nextTick(emitClose, this);
|
|
154
|
+
} else {
|
|
155
|
+
const server = this._server;
|
|
156
|
+
this._removeListeners();
|
|
157
|
+
this._removeListeners = this._server = null;
|
|
158
|
+
server.close(() => {
|
|
159
|
+
emitClose(this);
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* See if a given request should be handled by this server instance.
|
|
165
|
+
*
|
|
166
|
+
* @param {http.IncomingMessage} req Request object to inspect
|
|
167
|
+
* @return {Boolean} `true` if the request is valid, else `false`
|
|
168
|
+
* @public
|
|
169
|
+
*/
|
|
170
|
+
shouldHandle(req) {
|
|
171
|
+
if (this.options.path) {
|
|
172
|
+
const index = req.url.indexOf("?");
|
|
173
|
+
if ((index !== -1 ? req.url.slice(0, index) : req.url) !== this.options.path) return false;
|
|
174
|
+
}
|
|
175
|
+
return true;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Handle a HTTP Upgrade request.
|
|
179
|
+
*
|
|
180
|
+
* @param {http.IncomingMessage} req The request object
|
|
181
|
+
* @param {Duplex} socket The network socket between the server and client
|
|
182
|
+
* @param {Buffer} head The first packet of the upgraded stream
|
|
183
|
+
* @param {Function} cb Callback
|
|
184
|
+
* @public
|
|
185
|
+
*/
|
|
186
|
+
handleUpgrade(req, socket, head, cb) {
|
|
187
|
+
socket.on("error", socketOnError);
|
|
188
|
+
const key = req.headers["sec-websocket-key"];
|
|
189
|
+
const upgrade = req.headers.upgrade;
|
|
190
|
+
const version = +req.headers["sec-websocket-version"];
|
|
191
|
+
if (req.method !== "GET") {
|
|
192
|
+
abortHandshakeOrEmitwsClientError(this, req, socket, 405, "Invalid HTTP method");
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
if (upgrade === void 0 || upgrade.toLowerCase() !== "websocket") {
|
|
196
|
+
abortHandshakeOrEmitwsClientError(this, req, socket, 400, "Invalid Upgrade header");
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
if (key === void 0 || !keyRegex.test(key)) {
|
|
200
|
+
abortHandshakeOrEmitwsClientError(this, req, socket, 400, "Missing or invalid Sec-WebSocket-Key header");
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
if (version !== 13 && version !== 8) {
|
|
204
|
+
abortHandshakeOrEmitwsClientError(this, req, socket, 400, "Missing or invalid Sec-WebSocket-Version header", { "Sec-WebSocket-Version": "13, 8" });
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
if (!this.shouldHandle(req)) {
|
|
208
|
+
abortHandshake(socket, 400);
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
const secWebSocketProtocol = req.headers["sec-websocket-protocol"];
|
|
212
|
+
let protocols = /* @__PURE__ */ new Set();
|
|
213
|
+
if (secWebSocketProtocol !== void 0) try {
|
|
214
|
+
protocols = subprotocol.parse(secWebSocketProtocol);
|
|
215
|
+
} catch (err) {
|
|
216
|
+
abortHandshakeOrEmitwsClientError(this, req, socket, 400, "Invalid Sec-WebSocket-Protocol header");
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
const secWebSocketExtensions = req.headers["sec-websocket-extensions"];
|
|
220
|
+
const extensions = {};
|
|
221
|
+
if (this.options.perMessageDeflate && secWebSocketExtensions !== void 0) {
|
|
222
|
+
const perMessageDeflate = new PerMessageDeflate(this.options.perMessageDeflate, true, this.options.maxPayload);
|
|
223
|
+
try {
|
|
224
|
+
const offers = extension.parse(secWebSocketExtensions);
|
|
225
|
+
if (offers[PerMessageDeflate.extensionName]) {
|
|
226
|
+
perMessageDeflate.accept(offers[PerMessageDeflate.extensionName]);
|
|
227
|
+
extensions[PerMessageDeflate.extensionName] = perMessageDeflate;
|
|
228
|
+
}
|
|
229
|
+
} catch (err) {
|
|
230
|
+
abortHandshakeOrEmitwsClientError(this, req, socket, 400, "Invalid or unacceptable Sec-WebSocket-Extensions header");
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
if (this.options.verifyClient) {
|
|
235
|
+
const info = {
|
|
236
|
+
origin: req.headers[`${version === 8 ? "sec-websocket-origin" : "origin"}`],
|
|
237
|
+
secure: !!(req.socket.authorized || req.socket.encrypted),
|
|
238
|
+
req
|
|
239
|
+
};
|
|
240
|
+
if (this.options.verifyClient.length === 2) {
|
|
241
|
+
this.options.verifyClient(info, (verified, code, message, headers) => {
|
|
242
|
+
if (!verified) return abortHandshake(socket, code || 401, message, headers);
|
|
243
|
+
this.completeUpgrade(extensions, key, protocols, req, socket, head, cb);
|
|
244
|
+
});
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
if (!this.options.verifyClient(info)) return abortHandshake(socket, 401);
|
|
248
|
+
}
|
|
249
|
+
this.completeUpgrade(extensions, key, protocols, req, socket, head, cb);
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Upgrade the connection to WebSocket.
|
|
253
|
+
*
|
|
254
|
+
* @param {Object} extensions The accepted extensions
|
|
255
|
+
* @param {String} key The value of the `Sec-WebSocket-Key` header
|
|
256
|
+
* @param {Set} protocols The subprotocols
|
|
257
|
+
* @param {http.IncomingMessage} req The request object
|
|
258
|
+
* @param {Duplex} socket The network socket between the server and client
|
|
259
|
+
* @param {Buffer} head The first packet of the upgraded stream
|
|
260
|
+
* @param {Function} cb Callback
|
|
261
|
+
* @throws {Error} If called more than once with the same socket
|
|
262
|
+
* @private
|
|
263
|
+
*/
|
|
264
|
+
completeUpgrade(extensions, key, protocols, req, socket, head, cb) {
|
|
265
|
+
if (!socket.readable || !socket.writable) return socket.destroy();
|
|
266
|
+
if (socket[kWebSocket]) throw new Error("server.handleUpgrade() was called more than once with the same socket, possibly due to a misconfiguration");
|
|
267
|
+
if (this._state > RUNNING) return abortHandshake(socket, 503);
|
|
268
|
+
const headers = [
|
|
269
|
+
"HTTP/1.1 101 Switching Protocols",
|
|
270
|
+
"Upgrade: websocket",
|
|
271
|
+
"Connection: Upgrade",
|
|
272
|
+
`Sec-WebSocket-Accept: ${createHash("sha1").update(key + GUID).digest("base64")}`
|
|
273
|
+
];
|
|
274
|
+
const ws = new this.options.WebSocket(null, void 0, this.options);
|
|
275
|
+
if (protocols.size) {
|
|
276
|
+
const protocol = this.options.handleProtocols ? this.options.handleProtocols(protocols, req) : protocols.values().next().value;
|
|
277
|
+
if (protocol) {
|
|
278
|
+
headers.push(`Sec-WebSocket-Protocol: ${protocol}`);
|
|
279
|
+
ws._protocol = protocol;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
if (extensions[PerMessageDeflate.extensionName]) {
|
|
283
|
+
const params = extensions[PerMessageDeflate.extensionName].params;
|
|
284
|
+
const value = extension.format({ [PerMessageDeflate.extensionName]: [params] });
|
|
285
|
+
headers.push(`Sec-WebSocket-Extensions: ${value}`);
|
|
286
|
+
ws._extensions = extensions;
|
|
287
|
+
}
|
|
288
|
+
this.emit("headers", headers, req);
|
|
289
|
+
socket.write(headers.concat("\r\n").join("\r\n"));
|
|
290
|
+
socket.removeListener("error", socketOnError);
|
|
291
|
+
ws.setSocket(socket, head, {
|
|
292
|
+
allowSynchronousEvents: this.options.allowSynchronousEvents,
|
|
293
|
+
maxPayload: this.options.maxPayload,
|
|
294
|
+
skipUTF8Validation: this.options.skipUTF8Validation
|
|
295
|
+
});
|
|
296
|
+
if (this.clients) {
|
|
297
|
+
this.clients.add(ws);
|
|
298
|
+
ws.on("close", () => {
|
|
299
|
+
this.clients.delete(ws);
|
|
300
|
+
if (this._shouldEmitClose && !this.clients.size) process.nextTick(emitClose, this);
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
cb(ws, req);
|
|
304
|
+
}
|
|
305
|
+
};
|
|
306
|
+
module.exports = WebSocketServer;
|
|
307
|
+
/**
|
|
308
|
+
* Add event listeners on an `EventEmitter` using a map of <event, listener>
|
|
309
|
+
* pairs.
|
|
310
|
+
*
|
|
311
|
+
* @param {EventEmitter} server The event emitter
|
|
312
|
+
* @param {Object.<String, Function>} map The listeners to add
|
|
313
|
+
* @return {Function} A function that will remove the added listeners when
|
|
314
|
+
* called
|
|
315
|
+
* @private
|
|
316
|
+
*/
|
|
317
|
+
function addListeners(server, map) {
|
|
318
|
+
for (const event of Object.keys(map)) server.on(event, map[event]);
|
|
319
|
+
return function removeListeners() {
|
|
320
|
+
for (const event of Object.keys(map)) server.removeListener(event, map[event]);
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Emit a `'close'` event on an `EventEmitter`.
|
|
325
|
+
*
|
|
326
|
+
* @param {EventEmitter} server The event emitter
|
|
327
|
+
* @private
|
|
328
|
+
*/
|
|
329
|
+
function emitClose(server) {
|
|
330
|
+
server._state = CLOSED;
|
|
331
|
+
server.emit("close");
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Handle socket errors.
|
|
335
|
+
*
|
|
336
|
+
* @private
|
|
337
|
+
*/
|
|
338
|
+
function socketOnError() {
|
|
339
|
+
this.destroy();
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Close the connection when preconditions are not fulfilled.
|
|
343
|
+
*
|
|
344
|
+
* @param {Duplex} socket The socket of the upgrade request
|
|
345
|
+
* @param {Number} code The HTTP response status code
|
|
346
|
+
* @param {String} [message] The HTTP response body
|
|
347
|
+
* @param {Object} [headers] Additional HTTP response headers
|
|
348
|
+
* @private
|
|
349
|
+
*/
|
|
350
|
+
function abortHandshake(socket, code, message, headers) {
|
|
351
|
+
message = message || http.STATUS_CODES[code];
|
|
352
|
+
headers = {
|
|
353
|
+
Connection: "close",
|
|
354
|
+
"Content-Type": "text/html",
|
|
355
|
+
"Content-Length": Buffer.byteLength(message),
|
|
356
|
+
...headers
|
|
357
|
+
};
|
|
358
|
+
socket.once("finish", socket.destroy);
|
|
359
|
+
socket.end(`HTTP/1.1 ${code} ${http.STATUS_CODES[code]}\r\n` + Object.keys(headers).map((h) => `${h}: ${headers[h]}`).join("\r\n") + "\r\n\r\n" + message);
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Emit a `'wsClientError'` event on a `WebSocketServer` if there is at least
|
|
363
|
+
* one listener for it, otherwise call `abortHandshake()`.
|
|
364
|
+
*
|
|
365
|
+
* @param {WebSocketServer} server The WebSocket server
|
|
366
|
+
* @param {http.IncomingMessage} req The request object
|
|
367
|
+
* @param {Duplex} socket The socket of the upgrade request
|
|
368
|
+
* @param {Number} code The HTTP response status code
|
|
369
|
+
* @param {String} message The HTTP response body
|
|
370
|
+
* @param {Object} [headers] The HTTP response headers
|
|
371
|
+
* @private
|
|
372
|
+
*/
|
|
373
|
+
function abortHandshakeOrEmitwsClientError(server, req, socket, code, message, headers) {
|
|
374
|
+
if (server.listenerCount("wsClientError")) {
|
|
375
|
+
const err = new Error(message);
|
|
376
|
+
Error.captureStackTrace(err, abortHandshakeOrEmitwsClientError);
|
|
377
|
+
server.emit("wsClientError", err, socket, req);
|
|
378
|
+
} else abortHandshake(socket, code, message, headers);
|
|
379
|
+
}
|
|
380
|
+
}));
|
|
381
|
+
|
|
382
|
+
//#endregion
|
|
383
|
+
export default require_websocket_server();
|
|
384
|
+
|
|
385
|
+
export { require_websocket_server };
|