@push-rpc/next 2.0.8 → 2.0.9
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/README.md +4 -0
- package/dist/client/HttpClient.d.ts +3 -1
- package/dist/client/HttpClient.js +15 -1
- package/dist/client/HttpClient.js.map +1 -1
- package/dist/client/RpcClientImpl.d.ts +1 -0
- package/dist/client/RpcClientImpl.js +4 -2
- package/dist/client/RpcClientImpl.js.map +1 -1
- package/dist/client/WebSocketConnection.d.ts +3 -1
- package/dist/client/WebSocketConnection.js +21 -2
- package/dist/client/WebSocketConnection.js.map +1 -1
- package/dist/utils/cookies.d.ts +7 -0
- package/dist/utils/cookies.js +31 -0
- package/dist/utils/cookies.js.map +1 -0
- package/dist/utils/env.d.ts +6 -0
- package/dist/utils/env.js +22 -0
- package/dist/utils/env.js.map +1 -0
- package/package.json +1 -1
- package/src/client/HttpClient.ts +20 -1
- package/src/client/RpcClientImpl.ts +4 -1
- package/src/client/WebSocketConnection.ts +24 -1
- package/src/utils/cookies.ts +27 -0
- package/src/utils/env.ts +17 -0
- package/tests/connection.ts +87 -2
package/README.md
CHANGED
|
@@ -42,3 +42,7 @@ triggers.
|
|
|
42
42
|
- Supports compressed HTTP requests.
|
|
43
43
|
- Server runs on Node.JS, client runs in the Node.JS/Browser/ReactNative. For RN some extra setup is required (
|
|
44
44
|
document). Bun/Deno should also work, but not officially supported.
|
|
45
|
+
- Limited cookie support. Due to limited support in React Native, Cookies can be set and read during HTTP requests and
|
|
46
|
+
set during WS connection establishment. So if you need to share cookies between HTTP and WS, you need to make call (
|
|
47
|
+
HTTP POST) right after creating client, and establish WS connection (ie make subscribe, HTTP PUT) only after that.
|
|
48
|
+
Cookies cannot be shared when `connectOnCreate` client option is true.
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { ClientCookies } from "../utils/cookies.js";
|
|
1
2
|
export declare class HttpClient {
|
|
2
3
|
private url;
|
|
3
4
|
private clientId;
|
|
4
5
|
private getHeaders;
|
|
5
|
-
|
|
6
|
+
private cookies;
|
|
7
|
+
constructor(url: string, clientId: string, getHeaders: () => Promise<Record<string, string>>, cookies: ClientCookies);
|
|
6
8
|
call(itemName: string, params: unknown[], callTimeout: number): Promise<unknown>;
|
|
7
9
|
subscribe(itemName: string, params: unknown[], callTimeout: number): Promise<unknown>;
|
|
8
10
|
unsubscribe(itemName: string, params: unknown[], callTimeout: number): Promise<void>;
|
|
@@ -3,11 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.HttpClient = void 0;
|
|
4
4
|
const rpc_js_1 = require("../rpc.js");
|
|
5
5
|
const json_js_1 = require("../utils/json.js");
|
|
6
|
+
const env_js_1 = require("../utils/env.js");
|
|
6
7
|
class HttpClient {
|
|
7
|
-
constructor(url, clientId, getHeaders) {
|
|
8
|
+
constructor(url, clientId, getHeaders, cookies) {
|
|
8
9
|
this.url = url;
|
|
9
10
|
this.clientId = clientId;
|
|
10
11
|
this.getHeaders = getHeaders;
|
|
12
|
+
this.cookies = cookies;
|
|
11
13
|
}
|
|
12
14
|
async call(itemName, params, callTimeout) {
|
|
13
15
|
return this.httpRequest("POST", itemName, params, callTimeout, await this.getHeaders());
|
|
@@ -25,6 +27,12 @@ class HttpClient {
|
|
|
25
27
|
const itemUrl = this.getItemUrl(itemName);
|
|
26
28
|
try {
|
|
27
29
|
const { signal, finished } = timeoutSignal(callTimeout);
|
|
30
|
+
if (env_js_1.environment != env_js_1.Environment.Browser) {
|
|
31
|
+
const cookie = this.cookies.getCookieString();
|
|
32
|
+
if (cookie) {
|
|
33
|
+
headers["Cookie"] = cookie;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
28
36
|
const response = await fetch(itemUrl, {
|
|
29
37
|
method,
|
|
30
38
|
headers: {
|
|
@@ -36,6 +44,12 @@ class HttpClient {
|
|
|
36
44
|
signal,
|
|
37
45
|
});
|
|
38
46
|
finished();
|
|
47
|
+
if (env_js_1.environment != env_js_1.Environment.Browser) {
|
|
48
|
+
const cookie = response.headers.get("set-cookie");
|
|
49
|
+
if (cookie) {
|
|
50
|
+
this.cookies.updateCookies(cookie.split(","));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
39
53
|
if (response.status == 204) {
|
|
40
54
|
return;
|
|
41
55
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HttpClient.js","sourceRoot":"","sources":["../../src/client/HttpClient.ts"],"names":[],"mappings":";;;AAAA,sCAAqD;AACrD,8CAA6D;AAE7D,MAAa,UAAU;IACrB,YACU,GAAW,EACX,QAAgB,EAChB,UAAiD;
|
|
1
|
+
{"version":3,"file":"HttpClient.js","sourceRoot":"","sources":["../../src/client/HttpClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,6 +8,7 @@ export declare class RpcClientImpl<S extends Services<S>> implements RpcClient {
|
|
|
8
8
|
private readonly httpClient;
|
|
9
9
|
private readonly remoteSubscriptions;
|
|
10
10
|
private readonly connection;
|
|
11
|
+
private readonly cookies;
|
|
11
12
|
isConnected(): boolean;
|
|
12
13
|
close(): Promise<void>;
|
|
13
14
|
_allSubscriptions(): [itemName: string, parameters: unknown[], consumers: (d: unknown) => void][];
|
|
@@ -8,10 +8,12 @@ const WebSocketConnection_js_1 = require("./WebSocketConnection.js");
|
|
|
8
8
|
const nanoid_1 = require("nanoid");
|
|
9
9
|
const remote_js_1 = require("./remote.js");
|
|
10
10
|
const middleware_js_1 = require("../utils/middleware.js");
|
|
11
|
+
const cookies_js_1 = require("../utils/cookies.js");
|
|
11
12
|
class RpcClientImpl {
|
|
12
13
|
constructor(url, options) {
|
|
13
14
|
this.options = options;
|
|
14
15
|
this.clientId = (0, nanoid_1.nanoid)();
|
|
16
|
+
this.cookies = new cookies_js_1.ClientCookies();
|
|
15
17
|
this.call = (itemName, parameters, callOptions) => {
|
|
16
18
|
return this.invoke(itemName, rpc_js_1.InvocationType.Call, (...parameters) => this.httpClient.call(itemName, parameters, callOptions?.timeout ?? this.options.callTimeout), parameters);
|
|
17
19
|
};
|
|
@@ -58,9 +60,9 @@ class RpcClientImpl {
|
|
|
58
60
|
});
|
|
59
61
|
}
|
|
60
62
|
};
|
|
61
|
-
this.httpClient = new HttpClient_js_1.HttpClient(url, this.clientId, options.getHeaders);
|
|
63
|
+
this.httpClient = new HttpClient_js_1.HttpClient(url, this.clientId, options.getHeaders, this.cookies);
|
|
62
64
|
this.remoteSubscriptions = new RemoteSubscriptions_js_1.RemoteSubscriptions();
|
|
63
|
-
this.connection = new WebSocketConnection_js_1.WebSocketConnection(options.getSubscriptionsUrl(url), this.clientId, {
|
|
65
|
+
this.connection = new WebSocketConnection_js_1.WebSocketConnection(options.getSubscriptionsUrl(url), this.clientId, this.cookies, {
|
|
64
66
|
subscriptions: options.subscriptions,
|
|
65
67
|
errorDelayMaxDuration: options.errorDelayMaxDuration,
|
|
66
68
|
reconnectDelay: options.reconnectDelay,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RpcClientImpl.js","sourceRoot":"","sources":["../../src/client/RpcClientImpl.ts"],"names":[],"mappings":";;;AAAA,sCAA2E;AAC3E,mDAA0C;AAC1C,qEAA4D;AAC5D,qEAA4D;AAC5D,mCAA6B;AAC7B,2CAAmE;AAEnE,0DAAsD;
|
|
1
|
+
{"version":3,"file":"RpcClientImpl.js","sourceRoot":"","sources":["../../src/client/RpcClientImpl.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
+
import { ClientCookies } from "../utils/cookies.js";
|
|
1
2
|
export declare class WebSocketConnection {
|
|
2
3
|
private readonly url;
|
|
3
4
|
private readonly clientId;
|
|
5
|
+
private readonly cookies;
|
|
4
6
|
private readonly options;
|
|
5
7
|
private readonly consume;
|
|
6
8
|
private readonly onConnected;
|
|
7
9
|
private readonly onDisconnected;
|
|
8
|
-
constructor(url: string, clientId: string, options: {
|
|
10
|
+
constructor(url: string, clientId: string, cookies: ClientCookies, options: {
|
|
9
11
|
subscriptions: boolean;
|
|
10
12
|
reconnectDelay: number;
|
|
11
13
|
errorDelayMaxDuration: number;
|
|
@@ -4,10 +4,12 @@ exports.WebSocketConnection = void 0;
|
|
|
4
4
|
const logger_js_1 = require("../logger.js");
|
|
5
5
|
const json_js_1 = require("../utils/json.js");
|
|
6
6
|
const promises_js_1 = require("../utils/promises.js");
|
|
7
|
+
const env_js_1 = require("../utils/env.js");
|
|
7
8
|
class WebSocketConnection {
|
|
8
|
-
constructor(url, clientId, options, consume, onConnected, onDisconnected) {
|
|
9
|
+
constructor(url, clientId, cookies, options, consume, onConnected, onDisconnected) {
|
|
9
10
|
this.url = url;
|
|
10
11
|
this.clientId = clientId;
|
|
12
|
+
this.cookies = cookies;
|
|
11
13
|
this.options = options;
|
|
12
14
|
this.consume = consume;
|
|
13
15
|
this.onConnected = onConnected;
|
|
@@ -89,7 +91,24 @@ class WebSocketConnection {
|
|
|
89
91
|
async establishConnection(onDisconnected) {
|
|
90
92
|
return new Promise(async (resolve, reject) => {
|
|
91
93
|
try {
|
|
92
|
-
|
|
94
|
+
let socket;
|
|
95
|
+
if ([env_js_1.Environment.ReactNative, env_js_1.Environment.Node].includes(env_js_1.environment)) {
|
|
96
|
+
// use RN WS or node-ws headers extensions to set cookie
|
|
97
|
+
let options = undefined;
|
|
98
|
+
const cookie = this.cookies.getCookieString();
|
|
99
|
+
if (cookie) {
|
|
100
|
+
options = {
|
|
101
|
+
headers: {
|
|
102
|
+
Cookie: cookie,
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
socket = new WebSocket(this.url, this.clientId, options);
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
// rely on browser cookie handling
|
|
110
|
+
socket = new WebSocket(this.url, this.clientId);
|
|
111
|
+
}
|
|
93
112
|
let connected = false;
|
|
94
113
|
socket.addEventListener("open", () => {
|
|
95
114
|
this.socket = socket;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WebSocketConnection.js","sourceRoot":"","sources":["../../src/client/WebSocketConnection.ts"],"names":[],"mappings":";;;AAAA,4CAAgC;AAChC,8CAA8C;AAC9C,sDAA2C;
|
|
1
|
+
{"version":3,"file":"WebSocketConnection.js","sourceRoot":"","sources":["../../src/client/WebSocketConnection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseCookies = exports.ClientCookies = void 0;
|
|
4
|
+
/** Limited Cookie support for non-browser clients */
|
|
5
|
+
class ClientCookies {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.cookies = {};
|
|
8
|
+
}
|
|
9
|
+
updateCookies(setCookies) {
|
|
10
|
+
setCookies.forEach((c) => {
|
|
11
|
+
const [name, value] = c.split(";")[0].split("=");
|
|
12
|
+
this.cookies[name] = value;
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
getCookieString() {
|
|
16
|
+
return Object.entries(this.cookies)
|
|
17
|
+
.map(([k, v]) => `${k}=${v}`)
|
|
18
|
+
.join("; ");
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
exports.ClientCookies = ClientCookies;
|
|
22
|
+
function parseCookies(str) {
|
|
23
|
+
const rx = /([^;=\s]*)=([^;]*)/g;
|
|
24
|
+
const r = {};
|
|
25
|
+
for (let m; (m = rx.exec(str));) {
|
|
26
|
+
r[m[1]] = decodeURIComponent(m[2]);
|
|
27
|
+
}
|
|
28
|
+
return r;
|
|
29
|
+
}
|
|
30
|
+
exports.parseCookies = parseCookies;
|
|
31
|
+
//# sourceMappingURL=cookies.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cookies.js","sourceRoot":"","sources":["../../src/utils/cookies.ts"],"names":[],"mappings":";;;AAAA,qDAAqD;AACrD,MAAa,aAAa;IAA1B;QACU,YAAO,GAA2B,EAAE,CAAA;IAc9C,CAAC;IAZC,aAAa,CAAC,UAAoB;QAChC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;YACvB,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;YAChD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,KAAK,CAAA;QAC5B,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,eAAe;QACb,OAAO,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;aAChC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;aAC5B,IAAI,CAAC,IAAI,CAAC,CAAA;IACf,CAAC;CACF;AAfD,sCAeC;AAED,SAAgB,YAAY,CAAC,GAAW;IACtC,MAAM,EAAE,GAAG,qBAAqB,CAAA;IAChC,MAAM,CAAC,GAA2B,EAAE,CAAA;IAEpC,KAAK,IAAI,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAI,CAAC;QACjC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IACpC,CAAC;IACD,OAAO,CAAC,CAAA;AACV,CAAC;AARD,oCAQC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.environment = exports.Environment = void 0;
|
|
4
|
+
var Environment;
|
|
5
|
+
(function (Environment) {
|
|
6
|
+
Environment[Environment["Browser"] = 0] = "Browser";
|
|
7
|
+
Environment[Environment["Node"] = 1] = "Node";
|
|
8
|
+
Environment[Environment["ReactNative"] = 2] = "ReactNative";
|
|
9
|
+
})(Environment || (exports.Environment = Environment = {}));
|
|
10
|
+
exports.environment = getEnvironment();
|
|
11
|
+
function getEnvironment() {
|
|
12
|
+
if (typeof document !== "undefined") {
|
|
13
|
+
return Environment.Browser;
|
|
14
|
+
}
|
|
15
|
+
else if (typeof navigator !== "undefined" && navigator.product === "ReactNative") {
|
|
16
|
+
return Environment.ReactNative;
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
return Environment.Node;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=env.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/utils/env.ts"],"names":[],"mappings":";;;AAAA,IAAY,WAIX;AAJD,WAAY,WAAW;IACrB,mDAAO,CAAA;IACP,6CAAI,CAAA;IACJ,2DAAW,CAAA;AACb,CAAC,EAJW,WAAW,2BAAX,WAAW,QAItB;AAEY,QAAA,WAAW,GAAG,cAAc,EAAE,CAAA;AAE3C,SAAS,cAAc;IACrB,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE,CAAC;QACpC,OAAO,WAAW,CAAC,OAAO,CAAA;IAC5B,CAAC;SAAM,IAAI,OAAO,SAAS,KAAK,WAAW,IAAI,SAAS,CAAC,OAAO,KAAK,aAAa,EAAE,CAAC;QACnF,OAAO,WAAW,CAAC,WAAW,CAAA;IAChC,CAAC;SAAM,CAAC;QACN,OAAO,WAAW,CAAC,IAAI,CAAA;IACzB,CAAC;AACH,CAAC"}
|
package/package.json
CHANGED
package/src/client/HttpClient.ts
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import {CLIENT_ID_HEADER, RpcErrors} from "../rpc.js"
|
|
2
2
|
import {safeParseJson, safeStringify} from "../utils/json.js"
|
|
3
|
+
import {ClientCookies} from "../utils/cookies.js"
|
|
4
|
+
import {environment, Environment} from "../utils/env.js"
|
|
3
5
|
|
|
4
6
|
export class HttpClient {
|
|
5
7
|
constructor(
|
|
6
8
|
private url: string,
|
|
7
9
|
private clientId: string,
|
|
8
|
-
private getHeaders: () => Promise<Record<string, string
|
|
10
|
+
private getHeaders: () => Promise<Record<string, string>>,
|
|
11
|
+
private cookies: ClientCookies
|
|
9
12
|
) {}
|
|
10
13
|
|
|
11
14
|
async call(itemName: string, params: unknown[], callTimeout: number): Promise<unknown> {
|
|
@@ -36,6 +39,14 @@ export class HttpClient {
|
|
|
36
39
|
try {
|
|
37
40
|
const {signal, finished} = timeoutSignal(callTimeout)
|
|
38
41
|
|
|
42
|
+
if (environment != Environment.Browser) {
|
|
43
|
+
const cookie = this.cookies.getCookieString()
|
|
44
|
+
|
|
45
|
+
if (cookie) {
|
|
46
|
+
headers["Cookie"] = cookie
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
39
50
|
const response = await fetch(itemUrl, {
|
|
40
51
|
method,
|
|
41
52
|
headers: {
|
|
@@ -49,6 +60,14 @@ export class HttpClient {
|
|
|
49
60
|
|
|
50
61
|
finished()
|
|
51
62
|
|
|
63
|
+
if (environment != Environment.Browser) {
|
|
64
|
+
const cookie = response.headers.get("set-cookie")
|
|
65
|
+
|
|
66
|
+
if (cookie) {
|
|
67
|
+
this.cookies.updateCookies(cookie.split(","))
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
52
71
|
if (response.status == 204) {
|
|
53
72
|
return
|
|
54
73
|
}
|
|
@@ -6,18 +6,20 @@ import {nanoid} from "nanoid"
|
|
|
6
6
|
import {createRemote, ServicesWithSubscriptions} from "./remote.js"
|
|
7
7
|
import {ConsumeServicesOptions, RpcClient} from "./index.js"
|
|
8
8
|
import {withMiddlewares} from "../utils/middleware.js"
|
|
9
|
+
import {ClientCookies} from "../utils/cookies.js"
|
|
9
10
|
|
|
10
11
|
export class RpcClientImpl<S extends Services<S>> implements RpcClient {
|
|
11
12
|
constructor(
|
|
12
13
|
url: string,
|
|
13
14
|
private readonly options: ConsumeServicesOptions
|
|
14
15
|
) {
|
|
15
|
-
this.httpClient = new HttpClient(url, this.clientId, options.getHeaders)
|
|
16
|
+
this.httpClient = new HttpClient(url, this.clientId, options.getHeaders, this.cookies)
|
|
16
17
|
this.remoteSubscriptions = new RemoteSubscriptions()
|
|
17
18
|
|
|
18
19
|
this.connection = new WebSocketConnection(
|
|
19
20
|
options.getSubscriptionsUrl(url),
|
|
20
21
|
this.clientId,
|
|
22
|
+
this.cookies,
|
|
21
23
|
{
|
|
22
24
|
subscriptions: options.subscriptions,
|
|
23
25
|
errorDelayMaxDuration: options.errorDelayMaxDuration,
|
|
@@ -41,6 +43,7 @@ export class RpcClientImpl<S extends Services<S>> implements RpcClient {
|
|
|
41
43
|
private readonly httpClient: HttpClient
|
|
42
44
|
private readonly remoteSubscriptions: RemoteSubscriptions
|
|
43
45
|
private readonly connection: WebSocketConnection
|
|
46
|
+
private readonly cookies: ClientCookies = new ClientCookies()
|
|
44
47
|
|
|
45
48
|
isConnected() {
|
|
46
49
|
return this.connection.isConnected()
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import {log} from "../logger.js"
|
|
2
2
|
import {safeParseJson} from "../utils/json.js"
|
|
3
3
|
import {adelay} from "../utils/promises.js"
|
|
4
|
+
import {environment, Environment} from "../utils/env.js"
|
|
5
|
+
import {ClientCookies} from "../utils/cookies.js"
|
|
6
|
+
import type {IncomingMessage} from "http"
|
|
4
7
|
|
|
5
8
|
export class WebSocketConnection {
|
|
6
9
|
constructor(
|
|
7
10
|
private readonly url: string,
|
|
8
11
|
private readonly clientId: string,
|
|
12
|
+
private readonly cookies: ClientCookies,
|
|
9
13
|
private readonly options: {
|
|
10
14
|
subscriptions: boolean
|
|
11
15
|
reconnectDelay: number
|
|
@@ -118,7 +122,26 @@ export class WebSocketConnection {
|
|
|
118
122
|
private async establishConnection(onDisconnected: () => void): Promise<void> {
|
|
119
123
|
return new Promise(async (resolve, reject) => {
|
|
120
124
|
try {
|
|
121
|
-
|
|
125
|
+
let socket: WebSocket
|
|
126
|
+
|
|
127
|
+
if ([Environment.ReactNative, Environment.Node].includes(environment)) {
|
|
128
|
+
// use RN WS or node-ws headers extensions to set cookie
|
|
129
|
+
let options = undefined
|
|
130
|
+
|
|
131
|
+
const cookie = this.cookies.getCookieString()
|
|
132
|
+
if (cookie) {
|
|
133
|
+
options = {
|
|
134
|
+
headers: {
|
|
135
|
+
Cookie: cookie,
|
|
136
|
+
},
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
socket = new (WebSocket as any)(this.url, this.clientId, options)
|
|
141
|
+
} else {
|
|
142
|
+
// rely on browser cookie handling
|
|
143
|
+
socket = new WebSocket(this.url, this.clientId)
|
|
144
|
+
}
|
|
122
145
|
|
|
123
146
|
let connected = false
|
|
124
147
|
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** Limited Cookie support for non-browser clients */
|
|
2
|
+
export class ClientCookies {
|
|
3
|
+
private cookies: Record<string, string> = {}
|
|
4
|
+
|
|
5
|
+
updateCookies(setCookies: string[]) {
|
|
6
|
+
setCookies.forEach((c) => {
|
|
7
|
+
const [name, value] = c.split(";")[0].split("=")
|
|
8
|
+
this.cookies[name] = value
|
|
9
|
+
})
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
getCookieString(): string {
|
|
13
|
+
return Object.entries(this.cookies)
|
|
14
|
+
.map(([k, v]) => `${k}=${v}`)
|
|
15
|
+
.join("; ")
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function parseCookies(str: string): Record<string, string> {
|
|
20
|
+
const rx = /([^;=\s]*)=([^;]*)/g
|
|
21
|
+
const r: Record<string, string> = {}
|
|
22
|
+
|
|
23
|
+
for (let m; (m = rx.exec(str)); ) {
|
|
24
|
+
r[m[1]] = decodeURIComponent(m[2])
|
|
25
|
+
}
|
|
26
|
+
return r
|
|
27
|
+
}
|
package/src/utils/env.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export enum Environment {
|
|
2
|
+
Browser,
|
|
3
|
+
Node,
|
|
4
|
+
ReactNative,
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export const environment = getEnvironment()
|
|
8
|
+
|
|
9
|
+
function getEnvironment(): Environment {
|
|
10
|
+
if (typeof document !== "undefined") {
|
|
11
|
+
return Environment.Browser
|
|
12
|
+
} else if (typeof navigator !== "undefined" && navigator.product === "ReactNative") {
|
|
13
|
+
return Environment.ReactNative
|
|
14
|
+
} else {
|
|
15
|
+
return Environment.Node
|
|
16
|
+
}
|
|
17
|
+
}
|
package/tests/connection.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import {assert} from "chai"
|
|
2
|
-
import {createTestClient, startTestServer, testClient, testServer} from "./testUtils.js"
|
|
3
|
-
import WebSocket from "ws"
|
|
2
|
+
import {createTestClient, startTestServer, TEST_PORT, testClient, testServer} from "./testUtils.js"
|
|
3
|
+
import WebSocket, {WebSocketServer} from "ws"
|
|
4
4
|
import {adelay} from "../src/utils/promises.js"
|
|
5
|
+
import http, {IncomingMessage} from "http"
|
|
6
|
+
import {parseCookies} from "../src/utils/cookies.js"
|
|
5
7
|
|
|
6
8
|
describe("connection", () => {
|
|
7
9
|
it("server close connection on ping timeout", async () => {
|
|
@@ -132,4 +134,87 @@ describe("connection", () => {
|
|
|
132
134
|
|
|
133
135
|
assert.equal(disconnected, true)
|
|
134
136
|
})
|
|
137
|
+
|
|
138
|
+
describe("cookies", () => {
|
|
139
|
+
it("handle cookies in subseq requests", async () => {
|
|
140
|
+
let call = 0
|
|
141
|
+
|
|
142
|
+
let sentClientCookies: Record<string, string> = {}
|
|
143
|
+
|
|
144
|
+
const httpServer = http.createServer((req, res) => {
|
|
145
|
+
const headers: Record<string, string> = {"Content-Type": "text/plain"}
|
|
146
|
+
|
|
147
|
+
if (!call++) {
|
|
148
|
+
headers["Set-Cookie"] = `name=value; path=/; secure; samesite=none; httponly`
|
|
149
|
+
} else {
|
|
150
|
+
sentClientCookies = parseCookies(req.headers.cookie || "")
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
res.writeHead(200, headers)
|
|
154
|
+
|
|
155
|
+
res.end("ok")
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
let resolveStarted = () => {}
|
|
159
|
+
const started = new Promise<void>((r) => (resolveStarted = r))
|
|
160
|
+
httpServer.listen(TEST_PORT, () => resolveStarted())
|
|
161
|
+
await started
|
|
162
|
+
|
|
163
|
+
const client = await createTestClient<{call(): Promise<string>}>()
|
|
164
|
+
|
|
165
|
+
await client.call()
|
|
166
|
+
await client.call()
|
|
167
|
+
|
|
168
|
+
assert.equal(Object.keys(sentClientCookies).length, 1)
|
|
169
|
+
assert.equal(sentClientCookies["name"], "value")
|
|
170
|
+
|
|
171
|
+
let resolveStopped = () => {}
|
|
172
|
+
const stopped = new Promise<void>((r) => (resolveStopped = r))
|
|
173
|
+
httpServer.closeAllConnections()
|
|
174
|
+
httpServer.close(() => resolveStopped())
|
|
175
|
+
await stopped
|
|
176
|
+
})
|
|
177
|
+
|
|
178
|
+
it("set cookie in http, use in ws", async () => {
|
|
179
|
+
const httpServer = http.createServer((req, res) => {
|
|
180
|
+
const headers: Record<string, string> = {
|
|
181
|
+
"Content-Type": "text/plain",
|
|
182
|
+
"Set-Cookie": "name=value; path=/; secure; samesite=none; httponly",
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
res.writeHead(200, headers)
|
|
186
|
+
|
|
187
|
+
res.end("ok")
|
|
188
|
+
})
|
|
189
|
+
|
|
190
|
+
const wss = new WebSocketServer({server: httpServer})
|
|
191
|
+
|
|
192
|
+
let sentClientCookies: Record<string, string> = {}
|
|
193
|
+
wss.on("connection", (ws: unknown, req: IncomingMessage) => {
|
|
194
|
+
sentClientCookies = parseCookies(req.headers.cookie || "")
|
|
195
|
+
})
|
|
196
|
+
|
|
197
|
+
let resolveStarted = () => {}
|
|
198
|
+
const started = new Promise<void>((r) => (resolveStarted = r))
|
|
199
|
+
httpServer.listen(TEST_PORT, () => resolveStarted())
|
|
200
|
+
await started
|
|
201
|
+
|
|
202
|
+
const client = await createTestClient<{call(): Promise<string>}>()
|
|
203
|
+
await client.call()
|
|
204
|
+
|
|
205
|
+
await client.call.subscribe(() => {})
|
|
206
|
+
|
|
207
|
+
assert.equal(Object.keys(sentClientCookies).length, 1)
|
|
208
|
+
assert.equal(sentClientCookies["name"], "value")
|
|
209
|
+
|
|
210
|
+
await testClient!.close()
|
|
211
|
+
|
|
212
|
+
let resolveStopped = () => {}
|
|
213
|
+
const stopped = new Promise<void>((r) => (resolveStopped = r))
|
|
214
|
+
httpServer.closeIdleConnections()
|
|
215
|
+
httpServer.closeAllConnections()
|
|
216
|
+
httpServer.close(() => resolveStopped())
|
|
217
|
+
await stopped
|
|
218
|
+
})
|
|
219
|
+
})
|
|
135
220
|
})
|