@dxos/websocket-rpc 0.5.1-main.bc05254 → 0.5.1-main.bc9b6d3

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.
@@ -92,6 +92,7 @@ var WebsocketRpcClient = class {
92
92
  requested: this._params.requested,
93
93
  exposed: this._params.exposed,
94
94
  handlers: this._params.handlers,
95
+ noHandshake: this._params.noHandshake,
95
96
  port: {
96
97
  send: (msg) => {
97
98
  this._socket.send(msg);
@@ -120,7 +121,7 @@ var WebsocketRpcClient = class {
120
121
  this._socket.onopen = async () => {
121
122
  log2("Socket open", void 0, {
122
123
  F: __dxlog_file2,
123
- L: 61,
124
+ L: 62,
124
125
  S: this,
125
126
  C: (f, a) => f(...a)
126
127
  });
@@ -128,7 +129,7 @@ var WebsocketRpcClient = class {
128
129
  await this._rpc.open();
129
130
  log2(`RPC open ${this._params.url}`, void 0, {
130
131
  F: __dxlog_file2,
131
- L: 64,
132
+ L: 65,
132
133
  S: this,
133
134
  C: (f, a) => f(...a)
134
135
  });
@@ -141,7 +142,7 @@ var WebsocketRpcClient = class {
141
142
  this._socket.onclose = async () => {
142
143
  log2(`Disconnected ${this._params.url}`, void 0, {
143
144
  F: __dxlog_file2,
144
- L: 73,
145
+ L: 74,
145
146
  S: this,
146
147
  C: (f, a) => f(...a)
147
148
  });
@@ -153,7 +154,7 @@ var WebsocketRpcClient = class {
153
154
  url: this._params.url
154
155
  }, {
155
156
  F: __dxlog_file2,
156
- L: 80,
157
+ L: 81,
157
158
  S: this,
158
159
  C: (f, a) => f(...a)
159
160
  });
@@ -169,7 +170,7 @@ var WebsocketRpcClient = class {
169
170
  } catch (err) {
170
171
  log2.catch(err, void 0, {
171
172
  F: __dxlog_file2,
172
- L: 93,
173
+ L: 94,
173
174
  S: this,
174
175
  C: (f, a) => f(...a)
175
176
  });
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/client.ts", "../../../src/token-auth.ts", "../../../src/server.ts"],
4
- "sourcesContent": ["//\n// Copyright 2022 DXOS.org\n//\n\nimport WebSocket from 'isomorphic-ws';\n\nimport { Event, Trigger } from '@dxos/async';\nimport { log, logInfo } from '@dxos/log';\nimport { createProtoRpcPeer, type ProtoRpcPeer, type ProtoRpcPeerOptions } from '@dxos/rpc';\n\nimport { WebSocketWithTokenAuth } from './token-auth';\n\nexport type WebsocketRpcClientParams<C, S> = {\n url: string;\n authenticationToken?: string;\n} & Pick<ProtoRpcPeerOptions<C, S>, 'requested' | 'exposed' | 'handlers'>;\n\nexport class WebsocketRpcClient<C, S> {\n private _socket?: WebSocket;\n private _rpc?: ProtoRpcPeer<C>;\n private readonly _connectTrigger = new Trigger();\n\n readonly connected = new Event();\n readonly disconnected = new Event();\n readonly error = new Event<Error>();\n\n constructor(private readonly _params: WebsocketRpcClientParams<C, S>) {\n this._rpc = createProtoRpcPeer({\n requested: this._params.requested,\n exposed: this._params.exposed,\n handlers: this._params.handlers,\n port: {\n send: (msg) => {\n this._socket!.send(msg);\n },\n subscribe: (cb) => {\n this._socket!.onmessage = async (msg: WebSocket.MessageEvent) => {\n if (typeof Blob !== 'undefined' && msg.data instanceof Blob) {\n cb(Buffer.from(await msg.data.arrayBuffer()));\n } else {\n cb(msg.data as any);\n }\n };\n },\n },\n });\n }\n\n @logInfo\n get url() {\n return this._params.url;\n }\n\n async open() {\n if (this._params.authenticationToken) {\n this._socket = new WebSocketWithTokenAuth(this._params.url, this._params.authenticationToken);\n } else {\n this._socket = new WebSocket(this._params.url);\n }\n this._socket.onopen = async () => {\n log('Socket open');\n try {\n await this._rpc!.open();\n log(`RPC open ${this._params.url}`);\n this.connected.emit();\n this._connectTrigger.wake();\n } catch (err: any) {\n this.error.emit(err);\n }\n };\n\n this._socket.onclose = async () => {\n log(`Disconnected ${this._params.url}`);\n this.disconnected.emit();\n await this.close();\n };\n\n this._socket.onerror = (event: WebSocket.ErrorEvent) => {\n // Browsers do not include the error message in the event object, so we cannot discern 401 errors from other errors.\n log.error(event.message ?? 'Socket error', { url: this._params.url });\n const error = event.error ?? new Error(event.message);\n this.error.emit(error);\n this._connectTrigger.throw(error);\n };\n\n await this._connectTrigger.wait();\n }\n\n async close() {\n try {\n await this._rpc?.close();\n } catch (err) {\n log.catch(err);\n }\n this._socket?.close();\n }\n\n get rpc() {\n return this._rpc!.rpc;\n }\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\n// Implement WS header-based auth similar to https://github.com/kubernetes/kubernetes/commit/714f97d7baf4975ad3aa47735a868a81a984d1f0\n// https://stackoverflow.com/questions/4361173/http-headers-in-websockets-client-api/77060459#77060459\n\nimport { type IncomingMessage } from 'http';\nimport WebSocket from 'isomorphic-ws';\nimport { type Socket } from 'node:net';\n\nimport { log } from '@dxos/log';\n\nconst PROTOCOL_TOKEN_PREFIX = 'base64url.bearer.authorization.dxos.org';\n\n// TODO: implement middleware which removes the token from the request\n\nexport const authenticateRequestWithTokenAuth = (\n request: IncomingMessage,\n socket: Socket,\n upgradeHead: Buffer,\n token: string,\n cb: (request: IncomingMessage, socket: Socket, upgradeHead: Buffer) => void,\n) => {\n const protocolHeader = request.headers['sec-websocket-protocol'];\n\n if (!protocolHeader) {\n log('upgrade unauthorized, header missing', { header: request.headers['sec-websocket-protocol'] });\n socket.write('HTTP/1.1 401 Unauthorized\\r\\n\\r\\n');\n socket.destroy();\n return;\n }\n\n const tokenHeader = protocolHeader.replace(new RegExp(`^${PROTOCOL_TOKEN_PREFIX}.`), '');\n\n // padding characters are not allowed as a websocket protocol.\n const encodedToken = Buffer.from(token).toString('base64').replace(/=*$/, '');\n\n if (tokenHeader !== encodedToken) {\n log('upgrade unauthorized', { token, foo: encodedToken });\n socket.write('HTTP/1.1 401 Unauthorized\\r\\n\\r\\n');\n socket.destroy();\n return;\n }\n\n cb(request, socket, upgradeHead);\n};\n\nexport class WebSocketWithTokenAuth extends WebSocket {\n constructor(url: string, token: string) {\n const encodedToken = Buffer.from(token).toString('base64').replace(/=*$/, '');\n\n const wsProtocols = [`base64url.bearer.authorization.dxos.org.${encodedToken}`];\n super(url, wsProtocols);\n log('encodedToken', {\n encodedToken,\n });\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { type IncomingMessage } from 'http';\nimport WebSocket from 'isomorphic-ws';\nimport { type Socket } from 'node:net';\n\nimport { log } from '@dxos/log';\nimport { createProtoRpcPeer, type ProtoRpcPeer, type ProtoRpcPeerOptions } from '@dxos/rpc';\n\nexport type ConnectionInfo = {\n request: IncomingMessage;\n};\n\nexport type ConnectionHandler<C, S> = {\n onOpen?: (rpc: ProtoRpcPeer<C>) => Promise<void>;\n onClose?: (rpc: ProtoRpcPeer<C>) => Promise<void>;\n} & Pick<ProtoRpcPeerOptions<C, S>, 'requested' | 'exposed' | 'handlers'>;\n\nexport type WebsocketRpcServerParams<C, S> = {\n onConnection: (info: ConnectionInfo) => Promise<ConnectionHandler<C, S>>;\n} & WebSocket.ServerOptions;\n\nexport class WebsocketRpcServer<C, S> {\n private _server?: WebSocket.Server;\n\n constructor(private readonly _params: WebsocketRpcServerParams<C, S>) {}\n handleUpgrade(request: IncomingMessage, socket: Socket, head: Buffer) {\n this._server?.handleUpgrade(request, socket, head, (ws) => {\n this._server?.emit('connection', ws, request);\n });\n }\n\n async open() {\n this._server = new WebSocket.Server({\n ...this._params,\n });\n this._server.on('connection', async (socket, request) => {\n log('connection', { request });\n const info: ConnectionInfo = {\n request,\n };\n const { onOpen, onClose, ...options } = await this._params.onConnection(info);\n const rpc = createProtoRpcPeer<C, S>({\n ...options,\n port: {\n send: (msg) => {\n socket.send(msg);\n },\n subscribe: (cb) => {\n socket.onmessage = async (msg: WebSocket.MessageEvent) => {\n if (typeof Blob !== 'undefined' && msg.data instanceof Blob) {\n cb(Buffer.from(await msg.data.arrayBuffer()));\n } else {\n cb(msg.data as any);\n }\n };\n },\n },\n });\n\n await rpc.open();\n await onOpen?.(rpc);\n socket.onclose = async () => {\n await onClose?.(rpc);\n await rpc.close();\n };\n });\n }\n\n async close() {\n this._server?.close();\n }\n}\n"],
5
- "mappings": "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",
6
- "names": ["WebSocket", "Event", "Trigger", "log", "logInfo", "createProtoRpcPeer", "WebSocket", "log", "PROTOCOL_TOKEN_PREFIX", "authenticateRequestWithTokenAuth", "request", "socket", "upgradeHead", "token", "cb", "protocolHeader", "headers", "header", "write", "destroy", "tokenHeader", "replace", "RegExp", "encodedToken", "Buffer", "from", "toString", "foo", "WebSocketWithTokenAuth", "constructor", "url", "wsProtocols", "WebsocketRpcClient", "constructor", "_params", "_connectTrigger", "Trigger", "connected", "Event", "disconnected", "error", "_rpc", "createProtoRpcPeer", "requested", "exposed", "handlers", "port", "send", "msg", "_socket", "subscribe", "cb", "onmessage", "Blob", "data", "Buffer", "from", "arrayBuffer", "url", "open", "authenticationToken", "WebSocketWithTokenAuth", "WebSocket", "onopen", "log", "emit", "wake", "err", "onclose", "close", "onerror", "event", "message", "Error", "throw", "wait", "catch", "rpc", "logInfo", "WebSocket", "log", "createProtoRpcPeer", "WebsocketRpcServer", "constructor", "_params", "handleUpgrade", "request", "socket", "head", "_server", "ws", "emit", "open", "Server", "on", "info", "onOpen", "onClose", "options", "onConnection", "rpc", "port", "send", "msg", "subscribe", "cb", "onmessage", "Blob", "data", "Buffer", "from", "arrayBuffer", "onclose", "close"]
4
+ "sourcesContent": ["//\n// Copyright 2022 DXOS.org\n//\n\nimport WebSocket from 'isomorphic-ws';\n\nimport { Event, Trigger } from '@dxos/async';\nimport { log, logInfo } from '@dxos/log';\nimport { createProtoRpcPeer, type ProtoRpcPeer, type ProtoRpcPeerOptions } from '@dxos/rpc';\n\nimport { WebSocketWithTokenAuth } from './token-auth';\n\nexport type WebsocketRpcClientParams<C, S> = {\n url: string;\n authenticationToken?: string;\n} & Pick<ProtoRpcPeerOptions<C, S>, 'requested' | 'exposed' | 'handlers' | 'noHandshake'>;\n\nexport class WebsocketRpcClient<C, S> {\n private _socket?: WebSocket;\n private _rpc?: ProtoRpcPeer<C>;\n private readonly _connectTrigger = new Trigger();\n\n readonly connected = new Event();\n readonly disconnected = new Event();\n readonly error = new Event<Error>();\n\n constructor(private readonly _params: WebsocketRpcClientParams<C, S>) {\n this._rpc = createProtoRpcPeer({\n requested: this._params.requested,\n exposed: this._params.exposed,\n handlers: this._params.handlers,\n noHandshake: this._params.noHandshake,\n port: {\n send: (msg) => {\n this._socket!.send(msg);\n },\n subscribe: (cb) => {\n this._socket!.onmessage = async (msg: WebSocket.MessageEvent) => {\n if (typeof Blob !== 'undefined' && msg.data instanceof Blob) {\n cb(Buffer.from(await msg.data.arrayBuffer()));\n } else {\n cb(msg.data as any);\n }\n };\n },\n },\n });\n }\n\n @logInfo\n get url() {\n return this._params.url;\n }\n\n async open() {\n if (this._params.authenticationToken) {\n this._socket = new WebSocketWithTokenAuth(this._params.url, this._params.authenticationToken);\n } else {\n this._socket = new WebSocket(this._params.url);\n }\n this._socket.onopen = async () => {\n log('Socket open');\n try {\n await this._rpc!.open();\n log(`RPC open ${this._params.url}`);\n this.connected.emit();\n this._connectTrigger.wake();\n } catch (err: any) {\n this.error.emit(err);\n }\n };\n\n this._socket.onclose = async () => {\n log(`Disconnected ${this._params.url}`);\n this.disconnected.emit();\n await this.close();\n };\n\n this._socket.onerror = (event: WebSocket.ErrorEvent) => {\n // Browsers do not include the error message in the event object, so we cannot discern 401 errors from other errors.\n log.error(event.message ?? 'Socket error', { url: this._params.url });\n const error = event.error ?? new Error(event.message);\n this.error.emit(error);\n this._connectTrigger.throw(error);\n };\n\n await this._connectTrigger.wait();\n }\n\n async close() {\n try {\n await this._rpc?.close();\n } catch (err) {\n log.catch(err);\n }\n this._socket?.close();\n }\n\n get rpc() {\n return this._rpc!.rpc;\n }\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\n// Implement WS header-based auth similar to https://github.com/kubernetes/kubernetes/commit/714f97d7baf4975ad3aa47735a868a81a984d1f0\n// https://stackoverflow.com/questions/4361173/http-headers-in-websockets-client-api/77060459#77060459\n\nimport { type IncomingMessage } from 'http';\nimport WebSocket from 'isomorphic-ws';\nimport { type Socket } from 'node:net';\n\nimport { log } from '@dxos/log';\n\nconst PROTOCOL_TOKEN_PREFIX = 'base64url.bearer.authorization.dxos.org';\n\n// TODO: implement middleware which removes the token from the request\n\nexport const authenticateRequestWithTokenAuth = (\n request: IncomingMessage,\n socket: Socket,\n upgradeHead: Buffer,\n token: string,\n cb: (request: IncomingMessage, socket: Socket, upgradeHead: Buffer) => void,\n) => {\n const protocolHeader = request.headers['sec-websocket-protocol'];\n\n if (!protocolHeader) {\n log('upgrade unauthorized, header missing', { header: request.headers['sec-websocket-protocol'] });\n socket.write('HTTP/1.1 401 Unauthorized\\r\\n\\r\\n');\n socket.destroy();\n return;\n }\n\n const tokenHeader = protocolHeader.replace(new RegExp(`^${PROTOCOL_TOKEN_PREFIX}.`), '');\n\n // padding characters are not allowed as a websocket protocol.\n const encodedToken = Buffer.from(token).toString('base64').replace(/=*$/, '');\n\n if (tokenHeader !== encodedToken) {\n log('upgrade unauthorized', { token, foo: encodedToken });\n socket.write('HTTP/1.1 401 Unauthorized\\r\\n\\r\\n');\n socket.destroy();\n return;\n }\n\n cb(request, socket, upgradeHead);\n};\n\nexport class WebSocketWithTokenAuth extends WebSocket {\n constructor(url: string, token: string) {\n const encodedToken = Buffer.from(token).toString('base64').replace(/=*$/, '');\n\n const wsProtocols = [`base64url.bearer.authorization.dxos.org.${encodedToken}`];\n super(url, wsProtocols);\n log('encodedToken', {\n encodedToken,\n });\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { type IncomingMessage } from 'http';\nimport WebSocket from 'isomorphic-ws';\nimport { type Socket } from 'node:net';\n\nimport { log } from '@dxos/log';\nimport { createProtoRpcPeer, type ProtoRpcPeer, type ProtoRpcPeerOptions } from '@dxos/rpc';\n\nexport type ConnectionInfo = {\n request: IncomingMessage;\n};\n\nexport type ConnectionHandler<C, S> = {\n onOpen?: (rpc: ProtoRpcPeer<C>) => Promise<void>;\n onClose?: (rpc: ProtoRpcPeer<C>) => Promise<void>;\n} & Pick<ProtoRpcPeerOptions<C, S>, 'requested' | 'exposed' | 'handlers'>;\n\nexport type WebsocketRpcServerParams<C, S> = {\n onConnection: (info: ConnectionInfo) => Promise<ConnectionHandler<C, S>>;\n} & WebSocket.ServerOptions;\n\nexport class WebsocketRpcServer<C, S> {\n private _server?: WebSocket.Server;\n\n constructor(private readonly _params: WebsocketRpcServerParams<C, S>) {}\n handleUpgrade(request: IncomingMessage, socket: Socket, head: Buffer) {\n this._server?.handleUpgrade(request, socket, head, (ws) => {\n this._server?.emit('connection', ws, request);\n });\n }\n\n async open() {\n this._server = new WebSocket.Server({\n ...this._params,\n });\n this._server.on('connection', async (socket, request) => {\n log('connection', { request });\n const info: ConnectionInfo = {\n request,\n };\n const { onOpen, onClose, ...options } = await this._params.onConnection(info);\n const rpc = createProtoRpcPeer<C, S>({\n ...options,\n port: {\n send: (msg) => {\n socket.send(msg);\n },\n subscribe: (cb) => {\n socket.onmessage = async (msg: WebSocket.MessageEvent) => {\n if (typeof Blob !== 'undefined' && msg.data instanceof Blob) {\n cb(Buffer.from(await msg.data.arrayBuffer()));\n } else {\n cb(msg.data as any);\n }\n };\n },\n },\n });\n\n await rpc.open();\n await onOpen?.(rpc);\n socket.onclose = async () => {\n await onClose?.(rpc);\n await rpc.close();\n };\n });\n }\n\n async close() {\n this._server?.close();\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["WebSocket", "Event", "Trigger", "log", "logInfo", "createProtoRpcPeer", "WebSocket", "log", "PROTOCOL_TOKEN_PREFIX", "authenticateRequestWithTokenAuth", "request", "socket", "upgradeHead", "token", "cb", "protocolHeader", "headers", "header", "write", "destroy", "tokenHeader", "replace", "RegExp", "encodedToken", "Buffer", "from", "toString", "foo", "WebSocketWithTokenAuth", "constructor", "url", "wsProtocols", "WebsocketRpcClient", "constructor", "_params", "_connectTrigger", "Trigger", "connected", "Event", "disconnected", "error", "_rpc", "createProtoRpcPeer", "requested", "exposed", "handlers", "noHandshake", "port", "send", "msg", "_socket", "subscribe", "cb", "onmessage", "Blob", "data", "Buffer", "from", "arrayBuffer", "url", "open", "authenticationToken", "WebSocketWithTokenAuth", "WebSocket", "onopen", "log", "emit", "wake", "err", "onclose", "close", "onerror", "event", "message", "Error", "throw", "wait", "catch", "rpc", "logInfo", "WebSocket", "log", "createProtoRpcPeer", "WebsocketRpcServer", "constructor", "_params", "handleUpgrade", "request", "socket", "head", "_server", "ws", "emit", "open", "Server", "on", "info", "onOpen", "onClose", "options", "onConnection", "rpc", "port", "send", "msg", "subscribe", "cb", "onmessage", "Blob", "data", "Buffer", "from", "arrayBuffer", "onclose", "close"]
7
7
  }
@@ -1 +1 @@
1
- {"inputs":{"inject-globals:@inject-globals":{"bytes":384,"imports":[{"path":"@dxos/node-std/inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/core/mesh/websocket-rpc/src/token-auth.ts":{"bytes":6800,"imports":[{"path":"isomorphic-ws","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/core/mesh/websocket-rpc/src/client.ts":{"bytes":12028,"imports":[{"path":"isomorphic-ws","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/rpc","kind":"import-statement","external":true},{"path":"packages/core/mesh/websocket-rpc/src/token-auth.ts","kind":"import-statement","original":"./token-auth"},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/core/mesh/websocket-rpc/src/server.ts":{"bytes":7161,"imports":[{"path":"isomorphic-ws","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/rpc","kind":"import-statement","external":true},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/core/mesh/websocket-rpc/src/index.ts":{"bytes":646,"imports":[{"path":"packages/core/mesh/websocket-rpc/src/client.ts","kind":"import-statement","original":"./client"},{"path":"packages/core/mesh/websocket-rpc/src/server.ts","kind":"import-statement","original":"./server"},{"path":"packages/core/mesh/websocket-rpc/src/token-auth.ts","kind":"import-statement","original":"./token-auth"},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"}},"outputs":{"packages/core/mesh/websocket-rpc/dist/lib/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":12349},"packages/core/mesh/websocket-rpc/dist/lib/browser/index.mjs":{"imports":[{"path":"@dxos/node-std/inject-globals","kind":"import-statement","external":true},{"path":"isomorphic-ws","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/rpc","kind":"import-statement","external":true},{"path":"isomorphic-ws","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"isomorphic-ws","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/rpc","kind":"import-statement","external":true}],"exports":["WebSocketWithTokenAuth","WebsocketRpcClient","WebsocketRpcServer","authenticateRequestWithTokenAuth"],"entryPoint":"packages/core/mesh/websocket-rpc/src/index.ts","inputs":{"inject-globals:@inject-globals":{"bytesInOutput":79},"packages/core/mesh/websocket-rpc/src/client.ts":{"bytesInOutput":3457},"packages/core/mesh/websocket-rpc/src/token-auth.ts":{"bytesInOutput":1669},"packages/core/mesh/websocket-rpc/src/index.ts":{"bytesInOutput":0},"packages/core/mesh/websocket-rpc/src/server.ts":{"bytesInOutput":1645}},"bytes":7278}}}
1
+ {"inputs":{"inject-globals:@inject-globals":{"bytes":384,"imports":[{"path":"@dxos/node-std/inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/core/mesh/websocket-rpc/src/token-auth.ts":{"bytes":6800,"imports":[{"path":"isomorphic-ws","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/core/mesh/websocket-rpc/src/client.ts":{"bytes":12247,"imports":[{"path":"isomorphic-ws","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/rpc","kind":"import-statement","external":true},{"path":"packages/core/mesh/websocket-rpc/src/token-auth.ts","kind":"import-statement","original":"./token-auth"},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/core/mesh/websocket-rpc/src/server.ts":{"bytes":7161,"imports":[{"path":"isomorphic-ws","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/rpc","kind":"import-statement","external":true},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"},"packages/core/mesh/websocket-rpc/src/index.ts":{"bytes":646,"imports":[{"path":"packages/core/mesh/websocket-rpc/src/client.ts","kind":"import-statement","original":"./client"},{"path":"packages/core/mesh/websocket-rpc/src/server.ts","kind":"import-statement","original":"./server"},{"path":"packages/core/mesh/websocket-rpc/src/token-auth.ts","kind":"import-statement","original":"./token-auth"},{"path":"@inject-globals","kind":"import-statement","external":true}],"format":"esm"}},"outputs":{"packages/core/mesh/websocket-rpc/dist/lib/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":12450},"packages/core/mesh/websocket-rpc/dist/lib/browser/index.mjs":{"imports":[{"path":"@dxos/node-std/inject-globals","kind":"import-statement","external":true},{"path":"isomorphic-ws","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/rpc","kind":"import-statement","external":true},{"path":"isomorphic-ws","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"isomorphic-ws","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/rpc","kind":"import-statement","external":true}],"exports":["WebSocketWithTokenAuth","WebsocketRpcClient","WebsocketRpcServer","authenticateRequestWithTokenAuth"],"entryPoint":"packages/core/mesh/websocket-rpc/src/index.ts","inputs":{"inject-globals:@inject-globals":{"bytesInOutput":79},"packages/core/mesh/websocket-rpc/src/client.ts":{"bytesInOutput":3502},"packages/core/mesh/websocket-rpc/src/token-auth.ts":{"bytesInOutput":1669},"packages/core/mesh/websocket-rpc/src/index.ts":{"bytesInOutput":0},"packages/core/mesh/websocket-rpc/src/server.ts":{"bytesInOutput":1645}},"bytes":7323}}}
@@ -117,6 +117,7 @@ var WebsocketRpcClient = class {
117
117
  requested: this._params.requested,
118
118
  exposed: this._params.exposed,
119
119
  handlers: this._params.handlers,
120
+ noHandshake: this._params.noHandshake,
120
121
  port: {
121
122
  send: (msg) => {
122
123
  this._socket.send(msg);
@@ -145,7 +146,7 @@ var WebsocketRpcClient = class {
145
146
  this._socket.onopen = async () => {
146
147
  (0, import_log.log)("Socket open", void 0, {
147
148
  F: __dxlog_file2,
148
- L: 61,
149
+ L: 62,
149
150
  S: this,
150
151
  C: (f, a) => f(...a)
151
152
  });
@@ -153,7 +154,7 @@ var WebsocketRpcClient = class {
153
154
  await this._rpc.open();
154
155
  (0, import_log.log)(`RPC open ${this._params.url}`, void 0, {
155
156
  F: __dxlog_file2,
156
- L: 64,
157
+ L: 65,
157
158
  S: this,
158
159
  C: (f, a) => f(...a)
159
160
  });
@@ -166,7 +167,7 @@ var WebsocketRpcClient = class {
166
167
  this._socket.onclose = async () => {
167
168
  (0, import_log.log)(`Disconnected ${this._params.url}`, void 0, {
168
169
  F: __dxlog_file2,
169
- L: 73,
170
+ L: 74,
170
171
  S: this,
171
172
  C: (f, a) => f(...a)
172
173
  });
@@ -178,7 +179,7 @@ var WebsocketRpcClient = class {
178
179
  url: this._params.url
179
180
  }, {
180
181
  F: __dxlog_file2,
181
- L: 80,
182
+ L: 81,
182
183
  S: this,
183
184
  C: (f, a) => f(...a)
184
185
  });
@@ -194,7 +195,7 @@ var WebsocketRpcClient = class {
194
195
  } catch (err) {
195
196
  import_log.log.catch(err, void 0, {
196
197
  F: __dxlog_file2,
197
- L: 93,
198
+ L: 94,
198
199
  S: this,
199
200
  C: (f, a) => f(...a)
200
201
  });
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/client.ts", "../../../src/token-auth.ts", "../../../src/server.ts"],
4
- "sourcesContent": ["//\n// Copyright 2022 DXOS.org\n//\n\nimport WebSocket from 'isomorphic-ws';\n\nimport { Event, Trigger } from '@dxos/async';\nimport { log, logInfo } from '@dxos/log';\nimport { createProtoRpcPeer, type ProtoRpcPeer, type ProtoRpcPeerOptions } from '@dxos/rpc';\n\nimport { WebSocketWithTokenAuth } from './token-auth';\n\nexport type WebsocketRpcClientParams<C, S> = {\n url: string;\n authenticationToken?: string;\n} & Pick<ProtoRpcPeerOptions<C, S>, 'requested' | 'exposed' | 'handlers'>;\n\nexport class WebsocketRpcClient<C, S> {\n private _socket?: WebSocket;\n private _rpc?: ProtoRpcPeer<C>;\n private readonly _connectTrigger = new Trigger();\n\n readonly connected = new Event();\n readonly disconnected = new Event();\n readonly error = new Event<Error>();\n\n constructor(private readonly _params: WebsocketRpcClientParams<C, S>) {\n this._rpc = createProtoRpcPeer({\n requested: this._params.requested,\n exposed: this._params.exposed,\n handlers: this._params.handlers,\n port: {\n send: (msg) => {\n this._socket!.send(msg);\n },\n subscribe: (cb) => {\n this._socket!.onmessage = async (msg: WebSocket.MessageEvent) => {\n if (typeof Blob !== 'undefined' && msg.data instanceof Blob) {\n cb(Buffer.from(await msg.data.arrayBuffer()));\n } else {\n cb(msg.data as any);\n }\n };\n },\n },\n });\n }\n\n @logInfo\n get url() {\n return this._params.url;\n }\n\n async open() {\n if (this._params.authenticationToken) {\n this._socket = new WebSocketWithTokenAuth(this._params.url, this._params.authenticationToken);\n } else {\n this._socket = new WebSocket(this._params.url);\n }\n this._socket.onopen = async () => {\n log('Socket open');\n try {\n await this._rpc!.open();\n log(`RPC open ${this._params.url}`);\n this.connected.emit();\n this._connectTrigger.wake();\n } catch (err: any) {\n this.error.emit(err);\n }\n };\n\n this._socket.onclose = async () => {\n log(`Disconnected ${this._params.url}`);\n this.disconnected.emit();\n await this.close();\n };\n\n this._socket.onerror = (event: WebSocket.ErrorEvent) => {\n // Browsers do not include the error message in the event object, so we cannot discern 401 errors from other errors.\n log.error(event.message ?? 'Socket error', { url: this._params.url });\n const error = event.error ?? new Error(event.message);\n this.error.emit(error);\n this._connectTrigger.throw(error);\n };\n\n await this._connectTrigger.wait();\n }\n\n async close() {\n try {\n await this._rpc?.close();\n } catch (err) {\n log.catch(err);\n }\n this._socket?.close();\n }\n\n get rpc() {\n return this._rpc!.rpc;\n }\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\n// Implement WS header-based auth similar to https://github.com/kubernetes/kubernetes/commit/714f97d7baf4975ad3aa47735a868a81a984d1f0\n// https://stackoverflow.com/questions/4361173/http-headers-in-websockets-client-api/77060459#77060459\n\nimport { type IncomingMessage } from 'http';\nimport WebSocket from 'isomorphic-ws';\nimport { type Socket } from 'node:net';\n\nimport { log } from '@dxos/log';\n\nconst PROTOCOL_TOKEN_PREFIX = 'base64url.bearer.authorization.dxos.org';\n\n// TODO: implement middleware which removes the token from the request\n\nexport const authenticateRequestWithTokenAuth = (\n request: IncomingMessage,\n socket: Socket,\n upgradeHead: Buffer,\n token: string,\n cb: (request: IncomingMessage, socket: Socket, upgradeHead: Buffer) => void,\n) => {\n const protocolHeader = request.headers['sec-websocket-protocol'];\n\n if (!protocolHeader) {\n log('upgrade unauthorized, header missing', { header: request.headers['sec-websocket-protocol'] });\n socket.write('HTTP/1.1 401 Unauthorized\\r\\n\\r\\n');\n socket.destroy();\n return;\n }\n\n const tokenHeader = protocolHeader.replace(new RegExp(`^${PROTOCOL_TOKEN_PREFIX}.`), '');\n\n // padding characters are not allowed as a websocket protocol.\n const encodedToken = Buffer.from(token).toString('base64').replace(/=*$/, '');\n\n if (tokenHeader !== encodedToken) {\n log('upgrade unauthorized', { token, foo: encodedToken });\n socket.write('HTTP/1.1 401 Unauthorized\\r\\n\\r\\n');\n socket.destroy();\n return;\n }\n\n cb(request, socket, upgradeHead);\n};\n\nexport class WebSocketWithTokenAuth extends WebSocket {\n constructor(url: string, token: string) {\n const encodedToken = Buffer.from(token).toString('base64').replace(/=*$/, '');\n\n const wsProtocols = [`base64url.bearer.authorization.dxos.org.${encodedToken}`];\n super(url, wsProtocols);\n log('encodedToken', {\n encodedToken,\n });\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { type IncomingMessage } from 'http';\nimport WebSocket from 'isomorphic-ws';\nimport { type Socket } from 'node:net';\n\nimport { log } from '@dxos/log';\nimport { createProtoRpcPeer, type ProtoRpcPeer, type ProtoRpcPeerOptions } from '@dxos/rpc';\n\nexport type ConnectionInfo = {\n request: IncomingMessage;\n};\n\nexport type ConnectionHandler<C, S> = {\n onOpen?: (rpc: ProtoRpcPeer<C>) => Promise<void>;\n onClose?: (rpc: ProtoRpcPeer<C>) => Promise<void>;\n} & Pick<ProtoRpcPeerOptions<C, S>, 'requested' | 'exposed' | 'handlers'>;\n\nexport type WebsocketRpcServerParams<C, S> = {\n onConnection: (info: ConnectionInfo) => Promise<ConnectionHandler<C, S>>;\n} & WebSocket.ServerOptions;\n\nexport class WebsocketRpcServer<C, S> {\n private _server?: WebSocket.Server;\n\n constructor(private readonly _params: WebsocketRpcServerParams<C, S>) {}\n handleUpgrade(request: IncomingMessage, socket: Socket, head: Buffer) {\n this._server?.handleUpgrade(request, socket, head, (ws) => {\n this._server?.emit('connection', ws, request);\n });\n }\n\n async open() {\n this._server = new WebSocket.Server({\n ...this._params,\n });\n this._server.on('connection', async (socket, request) => {\n log('connection', { request });\n const info: ConnectionInfo = {\n request,\n };\n const { onOpen, onClose, ...options } = await this._params.onConnection(info);\n const rpc = createProtoRpcPeer<C, S>({\n ...options,\n port: {\n send: (msg) => {\n socket.send(msg);\n },\n subscribe: (cb) => {\n socket.onmessage = async (msg: WebSocket.MessageEvent) => {\n if (typeof Blob !== 'undefined' && msg.data instanceof Blob) {\n cb(Buffer.from(await msg.data.arrayBuffer()));\n } else {\n cb(msg.data as any);\n }\n };\n },\n },\n });\n\n await rpc.open();\n await onOpen?.(rpc);\n socket.onclose = async () => {\n await onClose?.(rpc);\n await rpc.close();\n };\n });\n }\n\n async close() {\n this._server?.close();\n }\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIA,2BAAsB;AAEtB,mBAA+B;AAC/B,iBAA6B;AAC7B,iBAAgF;ACAhF,IAAAA,wBAAsB;AAGtB,IAAAC,cAAoB;ACNpB,IAAAD,wBAAsB;AAGtB,IAAAC,cAAoB;AACpB,IAAAC,cAAgF;;ADIhF,IAAMC,wBAAwB;AAIvB,IAAMC,mCAAmC,CAC9CC,SACAC,QACAC,aACAC,OACAC,OAAAA;AAEA,QAAMC,iBAAiBL,QAAQM,QAAQ,wBAAA;AAEvC,MAAI,CAACD,gBAAgB;AACnBE,yBAAI,wCAAwC;MAAEC,QAAQR,QAAQM,QAAQ,wBAAA;IAA0B,GAAA;;;;;;AAChGL,WAAOQ,MAAM,mCAAA;AACbR,WAAOS,QAAO;AACd;EACF;AAEA,QAAMC,cAAcN,eAAeO,QAAQ,IAAIC,OAAO,IAAIf,qBAAAA,GAAwB,GAAG,EAAA;AAGrF,QAAMgB,eAAeC,OAAOC,KAAKb,KAAAA,EAAOc,SAAS,QAAA,EAAUL,QAAQ,OAAO,EAAA;AAE1E,MAAID,gBAAgBG,cAAc;AAChCP,yBAAI,wBAAwB;MAAEJ;MAAOe,KAAKJ;IAAa,GAAA;;;;;;AACvDb,WAAOQ,MAAM,mCAAA;AACbR,WAAOS,QAAO;AACd;EACF;AAEAN,KAAGJ,SAASC,QAAQC,WAAAA;AACtB;AAEO,IAAMiB,yBAAN,cAAqCC,sBAAAA,QAAAA;EAC1CC,YAAYC,KAAanB,OAAe;AACtC,UAAMW,eAAeC,OAAOC,KAAKb,KAAAA,EAAOc,SAAS,QAAA,EAAUL,QAAQ,OAAO,EAAA;AAE1E,UAAMW,cAAc;MAAC,2CAA2CT,YAAAA;;AAChE,UAAMQ,KAAKC,WAAAA;AACXhB,yBAAI,gBAAgB;MAClBO;IACF,GAAA;;;;;;EACF;AACF;;;;;;;;;;;;ADzCO,IAAMU,qBAAN,MAAMA;EASXH,YAA6BI,SAAyC;SAAzCA,UAAAA;SANZC,kBAAkB,IAAIC,qBAAAA;SAE9BC,YAAY,IAAIC,mBAAAA;SAChBC,eAAe,IAAID,mBAAAA;SACnBE,QAAQ,IAAIF,mBAAAA;AAGnB,SAAKG,WAAOC,+BAAmB;MAC7BC,WAAW,KAAKT,QAAQS;MACxBC,SAAS,KAAKV,QAAQU;MACtBC,UAAU,KAAKX,QAAQW;MACvBC,MAAM;QACJC,MAAM,CAACC,QAAAA;AACL,eAAKC,QAASF,KAAKC,GAAAA;QACrB;QACAE,WAAW,CAACrC,OAAAA;AACV,eAAKoC,QAASE,YAAY,OAAOH,QAAAA;AAC/B,gBAAI,OAAOI,SAAS,eAAeJ,IAAIK,gBAAgBD,MAAM;AAC3DvC,iBAAGW,OAAOC,KAAK,MAAMuB,IAAIK,KAAKC,YAAW,CAAA,CAAA;YAC3C,OAAO;AACLzC,iBAAGmC,IAAIK,IAAI;YACb;UACF;QACF;MACF;IACF,CAAA;EACF;EAEA,IACItB,MAAM;AACR,WAAO,KAAKG,QAAQH;EACtB;EAEA,MAAMwB,OAAO;AACX,QAAI,KAAKrB,QAAQsB,qBAAqB;AACpC,WAAKP,UAAU,IAAIrB,uBAAuB,KAAKM,QAAQH,KAAK,KAAKG,QAAQsB,mBAAmB;IAC9F,OAAO;AACL,WAAKP,UAAU,IAAIpB,qBAAAA,QAAU,KAAKK,QAAQH,GAAG;IAC/C;AACA,SAAKkB,QAAQQ,SAAS,YAAA;AACpBzC,qBAAAA,KAAI,eAAA,QAAA;;;;;;AACJ,UAAI;AACF,cAAM,KAAKyB,KAAMc,KAAI;AACrBvC,uBAAAA,KAAI,YAAY,KAAKkB,QAAQH,GAAG,IAAE,QAAA;;;;;;AAClC,aAAKM,UAAUqB,KAAI;AACnB,aAAKvB,gBAAgBwB,KAAI;MAC3B,SAASC,KAAU;AACjB,aAAKpB,MAAMkB,KAAKE,GAAAA;MAClB;IACF;AAEA,SAAKX,QAAQY,UAAU,YAAA;AACrB7C,qBAAAA,KAAI,gBAAgB,KAAKkB,QAAQH,GAAG,IAAE,QAAA;;;;;;AACtC,WAAKQ,aAAamB,KAAI;AACtB,YAAM,KAAKI,MAAK;IAClB;AAEA,SAAKb,QAAQc,UAAU,CAACC,UAAAA;AAEtBhD,iBAAAA,IAAIwB,MAAMwB,MAAMC,WAAW,gBAAgB;QAAElC,KAAK,KAAKG,QAAQH;MAAI,GAAA;;;;;;AACnE,YAAMS,QAAQwB,MAAMxB,SAAS,IAAI0B,MAAMF,MAAMC,OAAO;AACpD,WAAKzB,MAAMkB,KAAKlB,KAAAA;AAChB,WAAKL,gBAAgBgC,MAAM3B,KAAAA;IAC7B;AAEA,UAAM,KAAKL,gBAAgBiC,KAAI;EACjC;EAEA,MAAMN,QAAQ;AACZ,QAAI;AACF,YAAM,KAAKrB,MAAMqB,MAAAA;IACnB,SAASF,KAAK;AACZ5C,iBAAAA,IAAIqD,MAAMT,KAAAA,QAAAA;;;;;;IACZ;AACA,SAAKX,SAASa,MAAAA;EAChB;EAEA,IAAIQ,MAAM;AACR,WAAO,KAAK7B,KAAM6B;EACpB;AACF;;EApDGC;GA/BUtC,mBAAAA,WAAAA,OAAAA,IAAAA;;AEON,IAAMuC,qBAAN,MAAMA;EAGX1C,YAA6BI,SAAyC;SAAzCA,UAAAA;EAA0C;EACvEuC,cAAchE,SAA0BC,QAAgBgE,MAAc;AACpE,SAAKC,SAASF,cAAchE,SAASC,QAAQgE,MAAM,CAACE,OAAAA;AAClD,WAAKD,SAASjB,KAAK,cAAckB,IAAInE,OAAAA;IACvC,CAAA;EACF;EAEA,MAAM8C,OAAO;AACX,SAAKoB,UAAU,IAAI9C,sBAAAA,QAAUgD,OAAO;MAClC,GAAG,KAAK3C;IACV,CAAA;AACA,SAAKyC,QAAQG,GAAG,cAAc,OAAOpE,QAAQD,YAAAA;AAC3CO,sBAAAA,KAAI,cAAc;QAAEP;MAAQ,GAAA;;;;;;AAC5B,YAAMsE,OAAuB;QAC3BtE;MACF;AACA,YAAM,EAAEuE,QAAQC,SAAS,GAAGC,QAAAA,IAAY,MAAM,KAAKhD,QAAQiD,aAAaJ,IAAAA;AACxE,YAAMT,UAAM5B,YAAAA,oBAAyB;QACnC,GAAGwC;QACHpC,MAAM;UACJC,MAAM,CAACC,QAAAA;AACLtC,mBAAOqC,KAAKC,GAAAA;UACd;UACAE,WAAW,CAACrC,OAAAA;AACVH,mBAAOyC,YAAY,OAAOH,QAAAA;AACxB,kBAAI,OAAOI,SAAS,eAAeJ,IAAIK,gBAAgBD,MAAM;AAC3DvC,mBAAGW,OAAOC,KAAK,MAAMuB,IAAIK,KAAKC,YAAW,CAAA,CAAA;cAC3C,OAAO;AACLzC,mBAAGmC,IAAIK,IAAI;cACb;YACF;UACF;QACF;MACF,CAAA;AAEA,YAAMiB,IAAIf,KAAI;AACd,YAAMyB,SAASV,GAAAA;AACf5D,aAAOmD,UAAU,YAAA;AACf,cAAMoB,UAAUX,GAAAA;AAChB,cAAMA,IAAIR,MAAK;MACjB;IACF,CAAA;EACF;EAEA,MAAMA,QAAQ;AACZ,SAAKa,SAASb,MAAAA;EAChB;AACF;",
6
- "names": ["import_isomorphic_ws", "import_log", "import_rpc", "PROTOCOL_TOKEN_PREFIX", "authenticateRequestWithTokenAuth", "request", "socket", "upgradeHead", "token", "cb", "protocolHeader", "headers", "log", "header", "write", "destroy", "tokenHeader", "replace", "RegExp", "encodedToken", "Buffer", "from", "toString", "foo", "WebSocketWithTokenAuth", "WebSocket", "constructor", "url", "wsProtocols", "WebsocketRpcClient", "_params", "_connectTrigger", "Trigger", "connected", "Event", "disconnected", "error", "_rpc", "createProtoRpcPeer", "requested", "exposed", "handlers", "port", "send", "msg", "_socket", "subscribe", "onmessage", "Blob", "data", "arrayBuffer", "open", "authenticationToken", "onopen", "emit", "wake", "err", "onclose", "close", "onerror", "event", "message", "Error", "throw", "wait", "catch", "rpc", "logInfo", "WebsocketRpcServer", "handleUpgrade", "head", "_server", "ws", "Server", "on", "info", "onOpen", "onClose", "options", "onConnection"]
4
+ "sourcesContent": ["//\n// Copyright 2022 DXOS.org\n//\n\nimport WebSocket from 'isomorphic-ws';\n\nimport { Event, Trigger } from '@dxos/async';\nimport { log, logInfo } from '@dxos/log';\nimport { createProtoRpcPeer, type ProtoRpcPeer, type ProtoRpcPeerOptions } from '@dxos/rpc';\n\nimport { WebSocketWithTokenAuth } from './token-auth';\n\nexport type WebsocketRpcClientParams<C, S> = {\n url: string;\n authenticationToken?: string;\n} & Pick<ProtoRpcPeerOptions<C, S>, 'requested' | 'exposed' | 'handlers' | 'noHandshake'>;\n\nexport class WebsocketRpcClient<C, S> {\n private _socket?: WebSocket;\n private _rpc?: ProtoRpcPeer<C>;\n private readonly _connectTrigger = new Trigger();\n\n readonly connected = new Event();\n readonly disconnected = new Event();\n readonly error = new Event<Error>();\n\n constructor(private readonly _params: WebsocketRpcClientParams<C, S>) {\n this._rpc = createProtoRpcPeer({\n requested: this._params.requested,\n exposed: this._params.exposed,\n handlers: this._params.handlers,\n noHandshake: this._params.noHandshake,\n port: {\n send: (msg) => {\n this._socket!.send(msg);\n },\n subscribe: (cb) => {\n this._socket!.onmessage = async (msg: WebSocket.MessageEvent) => {\n if (typeof Blob !== 'undefined' && msg.data instanceof Blob) {\n cb(Buffer.from(await msg.data.arrayBuffer()));\n } else {\n cb(msg.data as any);\n }\n };\n },\n },\n });\n }\n\n @logInfo\n get url() {\n return this._params.url;\n }\n\n async open() {\n if (this._params.authenticationToken) {\n this._socket = new WebSocketWithTokenAuth(this._params.url, this._params.authenticationToken);\n } else {\n this._socket = new WebSocket(this._params.url);\n }\n this._socket.onopen = async () => {\n log('Socket open');\n try {\n await this._rpc!.open();\n log(`RPC open ${this._params.url}`);\n this.connected.emit();\n this._connectTrigger.wake();\n } catch (err: any) {\n this.error.emit(err);\n }\n };\n\n this._socket.onclose = async () => {\n log(`Disconnected ${this._params.url}`);\n this.disconnected.emit();\n await this.close();\n };\n\n this._socket.onerror = (event: WebSocket.ErrorEvent) => {\n // Browsers do not include the error message in the event object, so we cannot discern 401 errors from other errors.\n log.error(event.message ?? 'Socket error', { url: this._params.url });\n const error = event.error ?? new Error(event.message);\n this.error.emit(error);\n this._connectTrigger.throw(error);\n };\n\n await this._connectTrigger.wait();\n }\n\n async close() {\n try {\n await this._rpc?.close();\n } catch (err) {\n log.catch(err);\n }\n this._socket?.close();\n }\n\n get rpc() {\n return this._rpc!.rpc;\n }\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\n// Implement WS header-based auth similar to https://github.com/kubernetes/kubernetes/commit/714f97d7baf4975ad3aa47735a868a81a984d1f0\n// https://stackoverflow.com/questions/4361173/http-headers-in-websockets-client-api/77060459#77060459\n\nimport { type IncomingMessage } from 'http';\nimport WebSocket from 'isomorphic-ws';\nimport { type Socket } from 'node:net';\n\nimport { log } from '@dxos/log';\n\nconst PROTOCOL_TOKEN_PREFIX = 'base64url.bearer.authorization.dxos.org';\n\n// TODO: implement middleware which removes the token from the request\n\nexport const authenticateRequestWithTokenAuth = (\n request: IncomingMessage,\n socket: Socket,\n upgradeHead: Buffer,\n token: string,\n cb: (request: IncomingMessage, socket: Socket, upgradeHead: Buffer) => void,\n) => {\n const protocolHeader = request.headers['sec-websocket-protocol'];\n\n if (!protocolHeader) {\n log('upgrade unauthorized, header missing', { header: request.headers['sec-websocket-protocol'] });\n socket.write('HTTP/1.1 401 Unauthorized\\r\\n\\r\\n');\n socket.destroy();\n return;\n }\n\n const tokenHeader = protocolHeader.replace(new RegExp(`^${PROTOCOL_TOKEN_PREFIX}.`), '');\n\n // padding characters are not allowed as a websocket protocol.\n const encodedToken = Buffer.from(token).toString('base64').replace(/=*$/, '');\n\n if (tokenHeader !== encodedToken) {\n log('upgrade unauthorized', { token, foo: encodedToken });\n socket.write('HTTP/1.1 401 Unauthorized\\r\\n\\r\\n');\n socket.destroy();\n return;\n }\n\n cb(request, socket, upgradeHead);\n};\n\nexport class WebSocketWithTokenAuth extends WebSocket {\n constructor(url: string, token: string) {\n const encodedToken = Buffer.from(token).toString('base64').replace(/=*$/, '');\n\n const wsProtocols = [`base64url.bearer.authorization.dxos.org.${encodedToken}`];\n super(url, wsProtocols);\n log('encodedToken', {\n encodedToken,\n });\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { type IncomingMessage } from 'http';\nimport WebSocket from 'isomorphic-ws';\nimport { type Socket } from 'node:net';\n\nimport { log } from '@dxos/log';\nimport { createProtoRpcPeer, type ProtoRpcPeer, type ProtoRpcPeerOptions } from '@dxos/rpc';\n\nexport type ConnectionInfo = {\n request: IncomingMessage;\n};\n\nexport type ConnectionHandler<C, S> = {\n onOpen?: (rpc: ProtoRpcPeer<C>) => Promise<void>;\n onClose?: (rpc: ProtoRpcPeer<C>) => Promise<void>;\n} & Pick<ProtoRpcPeerOptions<C, S>, 'requested' | 'exposed' | 'handlers'>;\n\nexport type WebsocketRpcServerParams<C, S> = {\n onConnection: (info: ConnectionInfo) => Promise<ConnectionHandler<C, S>>;\n} & WebSocket.ServerOptions;\n\nexport class WebsocketRpcServer<C, S> {\n private _server?: WebSocket.Server;\n\n constructor(private readonly _params: WebsocketRpcServerParams<C, S>) {}\n handleUpgrade(request: IncomingMessage, socket: Socket, head: Buffer) {\n this._server?.handleUpgrade(request, socket, head, (ws) => {\n this._server?.emit('connection', ws, request);\n });\n }\n\n async open() {\n this._server = new WebSocket.Server({\n ...this._params,\n });\n this._server.on('connection', async (socket, request) => {\n log('connection', { request });\n const info: ConnectionInfo = {\n request,\n };\n const { onOpen, onClose, ...options } = await this._params.onConnection(info);\n const rpc = createProtoRpcPeer<C, S>({\n ...options,\n port: {\n send: (msg) => {\n socket.send(msg);\n },\n subscribe: (cb) => {\n socket.onmessage = async (msg: WebSocket.MessageEvent) => {\n if (typeof Blob !== 'undefined' && msg.data instanceof Blob) {\n cb(Buffer.from(await msg.data.arrayBuffer()));\n } else {\n cb(msg.data as any);\n }\n };\n },\n },\n });\n\n await rpc.open();\n await onOpen?.(rpc);\n socket.onclose = async () => {\n await onClose?.(rpc);\n await rpc.close();\n };\n });\n }\n\n async close() {\n this._server?.close();\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["import_isomorphic_ws", "import_log", "import_rpc", "PROTOCOL_TOKEN_PREFIX", "authenticateRequestWithTokenAuth", "request", "socket", "upgradeHead", "token", "cb", "protocolHeader", "headers", "log", "header", "write", "destroy", "tokenHeader", "replace", "RegExp", "encodedToken", "Buffer", "from", "toString", "foo", "WebSocketWithTokenAuth", "WebSocket", "constructor", "url", "wsProtocols", "WebsocketRpcClient", "_params", "_connectTrigger", "Trigger", "connected", "Event", "disconnected", "error", "_rpc", "createProtoRpcPeer", "requested", "exposed", "handlers", "noHandshake", "port", "send", "msg", "_socket", "subscribe", "onmessage", "Blob", "data", "arrayBuffer", "open", "authenticationToken", "onopen", "emit", "wake", "err", "onclose", "close", "onerror", "event", "message", "Error", "throw", "wait", "catch", "rpc", "logInfo", "WebsocketRpcServer", "handleUpgrade", "head", "_server", "ws", "Server", "on", "info", "onOpen", "onClose", "options", "onConnection"]
7
7
  }
@@ -1 +1 @@
1
- {"inputs":{"packages/core/mesh/websocket-rpc/src/token-auth.ts":{"bytes":6800,"imports":[{"path":"isomorphic-ws","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true}],"format":"esm"},"packages/core/mesh/websocket-rpc/src/client.ts":{"bytes":12028,"imports":[{"path":"isomorphic-ws","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/rpc","kind":"import-statement","external":true},{"path":"packages/core/mesh/websocket-rpc/src/token-auth.ts","kind":"import-statement","original":"./token-auth"}],"format":"esm"},"packages/core/mesh/websocket-rpc/src/server.ts":{"bytes":7161,"imports":[{"path":"isomorphic-ws","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/rpc","kind":"import-statement","external":true}],"format":"esm"},"packages/core/mesh/websocket-rpc/src/index.ts":{"bytes":646,"imports":[{"path":"packages/core/mesh/websocket-rpc/src/client.ts","kind":"import-statement","original":"./client"},{"path":"packages/core/mesh/websocket-rpc/src/server.ts","kind":"import-statement","original":"./server"},{"path":"packages/core/mesh/websocket-rpc/src/token-auth.ts","kind":"import-statement","original":"./token-auth"}],"format":"esm"}},"outputs":{"packages/core/mesh/websocket-rpc/dist/lib/node/index.cjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":12340},"packages/core/mesh/websocket-rpc/dist/lib/node/index.cjs":{"imports":[{"path":"isomorphic-ws","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/rpc","kind":"import-statement","external":true},{"path":"isomorphic-ws","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"isomorphic-ws","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/rpc","kind":"import-statement","external":true}],"exports":["WebSocketWithTokenAuth","WebsocketRpcClient","WebsocketRpcServer","authenticateRequestWithTokenAuth"],"entryPoint":"packages/core/mesh/websocket-rpc/src/index.ts","inputs":{"packages/core/mesh/websocket-rpc/src/client.ts":{"bytesInOutput":3457},"packages/core/mesh/websocket-rpc/src/token-auth.ts":{"bytesInOutput":1669},"packages/core/mesh/websocket-rpc/src/index.ts":{"bytesInOutput":0},"packages/core/mesh/websocket-rpc/src/server.ts":{"bytesInOutput":1645}},"bytes":7130}}}
1
+ {"inputs":{"packages/core/mesh/websocket-rpc/src/token-auth.ts":{"bytes":6800,"imports":[{"path":"isomorphic-ws","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true}],"format":"esm"},"packages/core/mesh/websocket-rpc/src/client.ts":{"bytes":12247,"imports":[{"path":"isomorphic-ws","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/rpc","kind":"import-statement","external":true},{"path":"packages/core/mesh/websocket-rpc/src/token-auth.ts","kind":"import-statement","original":"./token-auth"}],"format":"esm"},"packages/core/mesh/websocket-rpc/src/server.ts":{"bytes":7161,"imports":[{"path":"isomorphic-ws","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/rpc","kind":"import-statement","external":true}],"format":"esm"},"packages/core/mesh/websocket-rpc/src/index.ts":{"bytes":646,"imports":[{"path":"packages/core/mesh/websocket-rpc/src/client.ts","kind":"import-statement","original":"./client"},{"path":"packages/core/mesh/websocket-rpc/src/server.ts","kind":"import-statement","original":"./server"},{"path":"packages/core/mesh/websocket-rpc/src/token-auth.ts","kind":"import-statement","original":"./token-auth"}],"format":"esm"}},"outputs":{"packages/core/mesh/websocket-rpc/dist/lib/node/index.cjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":12441},"packages/core/mesh/websocket-rpc/dist/lib/node/index.cjs":{"imports":[{"path":"isomorphic-ws","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/rpc","kind":"import-statement","external":true},{"path":"isomorphic-ws","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"isomorphic-ws","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/rpc","kind":"import-statement","external":true}],"exports":["WebSocketWithTokenAuth","WebsocketRpcClient","WebsocketRpcServer","authenticateRequestWithTokenAuth"],"entryPoint":"packages/core/mesh/websocket-rpc/src/index.ts","inputs":{"packages/core/mesh/websocket-rpc/src/client.ts":{"bytesInOutput":3502},"packages/core/mesh/websocket-rpc/src/token-auth.ts":{"bytesInOutput":1669},"packages/core/mesh/websocket-rpc/src/index.ts":{"bytesInOutput":0},"packages/core/mesh/websocket-rpc/src/server.ts":{"bytesInOutput":1645}},"bytes":7175}}}
@@ -3,7 +3,7 @@ import { type ProtoRpcPeerOptions } from '@dxos/rpc';
3
3
  export type WebsocketRpcClientParams<C, S> = {
4
4
  url: string;
5
5
  authenticationToken?: string;
6
- } & Pick<ProtoRpcPeerOptions<C, S>, 'requested' | 'exposed' | 'handlers'>;
6
+ } & Pick<ProtoRpcPeerOptions<C, S>, 'requested' | 'exposed' | 'handlers' | 'noHandshake'>;
7
7
  export declare class WebsocketRpcClient<C, S> {
8
8
  private readonly _params;
9
9
  private _socket?;
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/client.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,EAAW,MAAM,aAAa,CAAC;AAE7C,OAAO,EAAyC,KAAK,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAI5F,MAAM,MAAM,wBAAwB,CAAC,CAAC,EAAE,CAAC,IAAI;IAC3C,GAAG,EAAE,MAAM,CAAC;IACZ,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B,GAAG,IAAI,CAAC,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,WAAW,GAAG,SAAS,GAAG,UAAU,CAAC,CAAC;AAE1E,qBAAa,kBAAkB,CAAC,CAAC,EAAE,CAAC;IAStB,OAAO,CAAC,QAAQ,CAAC,OAAO;IARpC,OAAO,CAAC,OAAO,CAAC,CAAY;IAC5B,OAAO,CAAC,IAAI,CAAC,CAAkB;IAC/B,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAiB;IAEjD,QAAQ,CAAC,SAAS,cAAe;IACjC,QAAQ,CAAC,YAAY,cAAe;IACpC,QAAQ,CAAC,KAAK,eAAsB;gBAEP,OAAO,EAAE,wBAAwB,CAAC,CAAC,EAAE,CAAC,CAAC;IAsBpE,IACI,GAAG,WAEN;IAEK,IAAI;IAmCJ,KAAK;IASX,IAAI,GAAG,MAEN;CACF"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/client.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,EAAW,MAAM,aAAa,CAAC;AAE7C,OAAO,EAAyC,KAAK,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAI5F,MAAM,MAAM,wBAAwB,CAAC,CAAC,EAAE,CAAC,IAAI;IAC3C,GAAG,EAAE,MAAM,CAAC;IACZ,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B,GAAG,IAAI,CAAC,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,WAAW,GAAG,SAAS,GAAG,UAAU,GAAG,aAAa,CAAC,CAAC;AAE1F,qBAAa,kBAAkB,CAAC,CAAC,EAAE,CAAC;IAStB,OAAO,CAAC,QAAQ,CAAC,OAAO;IARpC,OAAO,CAAC,OAAO,CAAC,CAAY;IAC5B,OAAO,CAAC,IAAI,CAAC,CAAkB;IAC/B,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAiB;IAEjD,QAAQ,CAAC,SAAS,cAAe;IACjC,QAAQ,CAAC,YAAY,cAAe;IACpC,QAAQ,CAAC,KAAK,eAAsB;gBAEP,OAAO,EAAE,wBAAwB,CAAC,CAAC,EAAE,CAAC,CAAC;IAuBpE,IACI,GAAG,WAEN;IAEK,IAAI;IAmCJ,KAAK;IASX,IAAI,GAAG,MAEN;CACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/websocket-rpc",
3
- "version": "0.5.1-main.bc05254",
3
+ "version": "0.5.1-main.bc9b6d3",
4
4
  "description": "websocket-rpc",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -17,17 +17,17 @@
17
17
  "README.md"
18
18
  ],
19
19
  "dependencies": {
20
- "isomorphic-ws": "^4.0.1",
20
+ "isomorphic-ws": "^5.0.0",
21
21
  "ws": "^8.14.2",
22
- "@dxos/async": "0.5.1-main.bc05254",
23
- "@dxos/codec-protobuf": "0.5.1-main.bc05254",
24
- "@dxos/context": "0.5.1-main.bc05254",
25
- "@dxos/keys": "0.5.1-main.bc05254",
26
- "@dxos/log": "0.5.1-main.bc05254",
27
- "@dxos/node-std": "0.5.1-main.bc05254",
28
- "@dxos/protocols": "0.5.1-main.bc05254",
29
- "@dxos/rpc": "0.5.1-main.bc05254",
30
- "@dxos/util": "0.5.1-main.bc05254"
22
+ "@dxos/codec-protobuf": "0.5.1-main.bc9b6d3",
23
+ "@dxos/async": "0.5.1-main.bc9b6d3",
24
+ "@dxos/context": "0.5.1-main.bc9b6d3",
25
+ "@dxos/keys": "0.5.1-main.bc9b6d3",
26
+ "@dxos/log": "0.5.1-main.bc9b6d3",
27
+ "@dxos/rpc": "0.5.1-main.bc9b6d3",
28
+ "@dxos/node-std": "0.5.1-main.bc9b6d3",
29
+ "@dxos/protocols": "0.5.1-main.bc9b6d3",
30
+ "@dxos/util": "0.5.1-main.bc9b6d3"
31
31
  },
32
32
  "devDependencies": {
33
33
  "@types/node": "^18.11.9",
package/src/client.ts CHANGED
@@ -13,7 +13,7 @@ import { WebSocketWithTokenAuth } from './token-auth';
13
13
  export type WebsocketRpcClientParams<C, S> = {
14
14
  url: string;
15
15
  authenticationToken?: string;
16
- } & Pick<ProtoRpcPeerOptions<C, S>, 'requested' | 'exposed' | 'handlers'>;
16
+ } & Pick<ProtoRpcPeerOptions<C, S>, 'requested' | 'exposed' | 'handlers' | 'noHandshake'>;
17
17
 
18
18
  export class WebsocketRpcClient<C, S> {
19
19
  private _socket?: WebSocket;
@@ -29,6 +29,7 @@ export class WebsocketRpcClient<C, S> {
29
29
  requested: this._params.requested,
30
30
  exposed: this._params.exposed,
31
31
  handlers: this._params.handlers,
32
+ noHandshake: this._params.noHandshake,
32
33
  port: {
33
34
  send: (msg) => {
34
35
  this._socket!.send(msg);