stanza 12.17.1 → 12.18.0
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/Client.d.ts +2 -0
- package/Client.js +45 -25
- package/Constants.js +1 -1
- package/README.md +0 -8
- package/Utils.d.ts +2 -0
- package/Utils.js +30 -6
- package/helpers/LegacyEntityCapabilities.js +4 -5
- package/helpers/NetworkDiscovery.d.ts +36 -0
- package/helpers/NetworkDiscovery.js +152 -0
- package/helpers/RSM.d.ts +6 -0
- package/helpers/RSM.js +20 -0
- package/index.d.ts +21 -7
- package/index.js +3 -1
- package/index.module.js +23 -0
- package/jingle/FileTransferSession.d.ts +1 -1
- package/jingle/FileTransferSession.js +1 -1
- package/jingle/SessionManager.js +4 -4
- package/jxt/Definitions.d.ts +2 -2
- package/jxt/Parser.js +2 -2
- package/jxt/StreamParser.d.ts +1 -1
- package/jxt/StreamParser.js +2 -2
- package/jxt/Types.d.ts +1 -0
- package/jxt/Types.js +3 -2
- package/lib/sasl/index.js +34 -35
- package/package.json +10 -18
- package/platform/browser/buffer/base64-js/index.d.ts +3 -0
- package/platform/browser/buffer/base64-js/index.js +110 -0
- package/platform/browser/buffer/ieee754/index.d.ts +2 -0
- package/platform/browser/buffer/ieee754/index.js +81 -0
- package/platform/browser/buffer/index.d.ts +120 -0
- package/platform/browser/buffer/index.js +1877 -0
- package/platform/browser/crypto/Hash.d.ts +28 -0
- package/platform/browser/crypto/Hash.js +114 -0
- package/platform/browser/crypto/Hmac.d.ts +27 -0
- package/platform/browser/crypto/Hmac.js +82 -0
- package/platform/browser/crypto/MD5.d.ts +22 -0
- package/platform/browser/crypto/MD5.js +129 -0
- package/platform/browser/crypto/SHA-1.d.ts +23 -0
- package/platform/browser/crypto/SHA-1.js +94 -0
- package/platform/browser/crypto/SHA-256.d.ts +33 -0
- package/platform/browser/crypto/SHA-256.js +173 -0
- package/platform/browser/crypto/SHA-512.d.ts +34 -0
- package/platform/browser/crypto/SHA-512.js +352 -0
- package/platform/browser/crypto/createHash.d.ts +3 -0
- package/platform/browser/crypto/createHash.js +31 -0
- package/platform/browser/index.d.ts +21 -0
- package/platform/browser/index.js +46 -0
- package/platform/browser/process.d.ts +1 -0
- package/platform/browser/process.js +62 -0
- package/platform/browser/stream/index.d.ts +5 -0
- package/platform/browser/stream/index.js +6 -0
- package/platform/browser/stream/lib/_stream_duplex.d.ts +12 -0
- package/platform/browser/stream/lib/_stream_duplex.js +114 -0
- package/platform/browser/stream/lib/_stream_passthrough.d.ts +6 -0
- package/platform/browser/stream/lib/_stream_passthrough.js +38 -0
- package/platform/browser/stream/lib/_stream_readable.d.ts +60 -0
- package/platform/browser/stream/lib/_stream_readable.js +980 -0
- package/platform/browser/stream/lib/_stream_transform.d.ts +20 -0
- package/platform/browser/stream/lib/_stream_transform.js +189 -0
- package/platform/browser/stream/lib/_stream_writable.d.ts +62 -0
- package/platform/browser/stream/lib/_stream_writable.js +632 -0
- package/platform/browser/stream/lib/internal/streams/BufferList.d.ts +11 -0
- package/platform/browser/stream/lib/internal/streams/BufferList.js +68 -0
- package/platform/browser/stream/lib/internal/streams/destroy.d.ts +2 -0
- package/platform/browser/stream/lib/internal/streams/destroy.js +62 -0
- package/platform/browser/stream/string_decoder.d.ts +24 -0
- package/platform/browser/stream/string_decoder.js +312 -0
- package/platform/browser/stream/util.d.ts +1 -0
- package/platform/browser/stream/util.js +34 -0
- package/platform/index.d.ts +1 -0
- package/platform/index.js +4 -0
- package/platform/node/index.d.ts +16 -0
- package/platform/node/index.js +53 -0
- package/platform/react-native/index.d.ts +2 -0
- package/platform/react-native/index.js +7 -0
- package/plugins/entity.js +1 -1
- package/plugins/hostmeta.d.ts +17 -10
- package/plugins/hostmeta.js +40 -62
- package/plugins/jingle.js +2 -2
- package/plugins/muc.js +1 -1
- package/protocol/xep0030.js +3 -1
- package/protocol/xep0084.js +6 -4
- package/protocol/xep0085.d.ts +1 -1
- package/protocol/xep0153.d.ts +1 -1
- package/protocol/xep0199.d.ts +1 -1
- package/protocol/xep0224.d.ts +1 -1
- package/protocol/xep0308.d.ts +1 -1
- package/protocol/xep0319.d.ts +1 -1
- package/protocol/xep0334.d.ts +1 -1
- package/transports/bosh.d.ts +2 -1
- package/transports/bosh.js +3 -4
- package/transports/websocket.d.ts +2 -1
- package/transports/websocket.js +9 -6
- package/module.js +0 -15317
package/Client.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ import * as JXT from './jxt';
|
|
|
7
7
|
import { JSONData } from './jxt';
|
|
8
8
|
import * as SASL from './lib/sasl';
|
|
9
9
|
import { IQ, Message, Presence, StreamError, Stream } from './protocol';
|
|
10
|
+
import NetworkDiscovery from './helpers/NetworkDiscovery';
|
|
10
11
|
interface StreamData {
|
|
11
12
|
kind: string;
|
|
12
13
|
stanza: any;
|
|
@@ -18,6 +19,7 @@ export default class Client extends EventEmitter {
|
|
|
18
19
|
sm: StreamManagement;
|
|
19
20
|
transport?: Transport;
|
|
20
21
|
stanzas: JXT.Registry;
|
|
22
|
+
resolver: NetworkDiscovery;
|
|
21
23
|
sessionStarting?: boolean;
|
|
22
24
|
sessionStarted?: boolean;
|
|
23
25
|
sessionTerminating?: boolean;
|
package/Client.js
CHANGED
|
@@ -12,6 +12,7 @@ const protocol_1 = tslib_1.__importDefault(require("./protocol"));
|
|
|
12
12
|
const bosh_1 = tslib_1.__importDefault(require("./transports/bosh"));
|
|
13
13
|
const websocket_1 = tslib_1.__importDefault(require("./transports/websocket"));
|
|
14
14
|
const Utils_1 = require("./Utils");
|
|
15
|
+
const NetworkDiscovery_1 = tslib_1.__importDefault(require("./helpers/NetworkDiscovery"));
|
|
15
16
|
class Client extends events_1.EventEmitter {
|
|
16
17
|
constructor(opts = {}) {
|
|
17
18
|
super();
|
|
@@ -34,6 +35,7 @@ class Client extends events_1.EventEmitter {
|
|
|
34
35
|
this.sasl.register('ANONYMOUS', SASL.ANONYMOUS, 0);
|
|
35
36
|
this.stanzas = new JXT.Registry();
|
|
36
37
|
this.stanzas.define(protocol_1.default);
|
|
38
|
+
this.resolver = new NetworkDiscovery_1.default();
|
|
37
39
|
this.use(plugins_1.core);
|
|
38
40
|
this.sm = new StreamManagement_1.default();
|
|
39
41
|
if (this.config.allowResumption !== undefined) {
|
|
@@ -220,6 +222,7 @@ class Client extends events_1.EventEmitter {
|
|
|
220
222
|
});
|
|
221
223
|
}
|
|
222
224
|
updateConfig(opts = {}) {
|
|
225
|
+
var _a;
|
|
223
226
|
const currConfig = this.config || {};
|
|
224
227
|
this.config = {
|
|
225
228
|
allowResumption: true,
|
|
@@ -229,6 +232,7 @@ class Client extends events_1.EventEmitter {
|
|
|
229
232
|
websocket: true
|
|
230
233
|
},
|
|
231
234
|
useStreamManagement: true,
|
|
235
|
+
transportPreferenceOrder: ['websocket', 'bosh'],
|
|
232
236
|
...currConfig,
|
|
233
237
|
...opts
|
|
234
238
|
};
|
|
@@ -240,6 +244,9 @@ class Client extends events_1.EventEmitter {
|
|
|
240
244
|
this.config.credentials.password = this.config.password;
|
|
241
245
|
delete this.config.password;
|
|
242
246
|
}
|
|
247
|
+
if (!this.config.transportPreferenceOrder) {
|
|
248
|
+
this.config.transportPreferenceOrder = Object.keys((_a = this.config.transports) !== null && _a !== void 0 ? _a : {});
|
|
249
|
+
}
|
|
243
250
|
}
|
|
244
251
|
get stream() {
|
|
245
252
|
return this.transport ? this.transport.stream : undefined;
|
|
@@ -270,47 +277,60 @@ class Client extends events_1.EventEmitter {
|
|
|
270
277
|
return this._getConfiguredCredentials();
|
|
271
278
|
}
|
|
272
279
|
async connect() {
|
|
280
|
+
var _a, _b, _c;
|
|
273
281
|
this.sessionTerminating = false;
|
|
274
282
|
this.sessionStarting = true;
|
|
275
283
|
this.emit('--reset-stream-features');
|
|
276
284
|
if (this.transport) {
|
|
277
285
|
this.transport.disconnect(false);
|
|
278
286
|
}
|
|
279
|
-
const transportPref = [
|
|
287
|
+
const transportPref = (_a = this.config.transportPreferenceOrder) !== null && _a !== void 0 ? _a : [];
|
|
280
288
|
let endpoints;
|
|
281
289
|
for (const name of transportPref) {
|
|
282
|
-
|
|
283
|
-
if (!
|
|
290
|
+
const settings = this.config.transports[name];
|
|
291
|
+
if (!settings || !this.transports[name]) {
|
|
284
292
|
continue;
|
|
285
293
|
}
|
|
286
|
-
|
|
287
|
-
|
|
294
|
+
let config = {
|
|
295
|
+
acceptLanguages: this.config.acceptLanguages || [(_b = this.config.lang) !== null && _b !== void 0 ? _b : 'en'],
|
|
296
|
+
jid: this.config.jid,
|
|
297
|
+
lang: (_c = this.config.lang) !== null && _c !== void 0 ? _c : 'en',
|
|
298
|
+
server: this.config.server
|
|
299
|
+
};
|
|
300
|
+
const transport = new this.transports[name](this, this.sm, this.stanzas);
|
|
301
|
+
if (typeof settings === 'string') {
|
|
302
|
+
config.url = settings;
|
|
288
303
|
}
|
|
289
|
-
else if (
|
|
290
|
-
if (
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
}
|
|
294
|
-
catch (err) {
|
|
295
|
-
console.error(err);
|
|
304
|
+
else if (settings == true) {
|
|
305
|
+
if (transport.discoverBindings) {
|
|
306
|
+
const discovered = await transport.discoverBindings(this.config.server);
|
|
307
|
+
if (!discovered) {
|
|
296
308
|
continue;
|
|
297
309
|
}
|
|
310
|
+
config = {
|
|
311
|
+
...config,
|
|
312
|
+
...discovered
|
|
313
|
+
};
|
|
298
314
|
}
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
315
|
+
else {
|
|
316
|
+
if (!endpoints) {
|
|
317
|
+
try {
|
|
318
|
+
endpoints = await this.discoverBindings(this.config.server);
|
|
319
|
+
}
|
|
320
|
+
catch (err) {
|
|
321
|
+
console.error(err);
|
|
322
|
+
continue;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
endpoints[name] = (endpoints[name] || []).filter(url => url.startsWith('wss:') || url.startsWith('https:'));
|
|
326
|
+
if (!endpoints[name] || !endpoints[name].length) {
|
|
327
|
+
continue;
|
|
328
|
+
}
|
|
329
|
+
config.url = endpoints[name][0];
|
|
302
330
|
}
|
|
303
|
-
conf = { url: endpoints[name][0] };
|
|
304
331
|
}
|
|
305
|
-
this.transport =
|
|
306
|
-
this.transport.connect(
|
|
307
|
-
acceptLanguages: this.config.acceptLanguages || ['en'],
|
|
308
|
-
jid: this.config.jid,
|
|
309
|
-
lang: this.config.lang || 'en',
|
|
310
|
-
server: this.config.server,
|
|
311
|
-
url: conf.url,
|
|
312
|
-
...conf
|
|
313
|
-
});
|
|
332
|
+
this.transport = transport;
|
|
333
|
+
this.transport.connect(config);
|
|
314
334
|
return;
|
|
315
335
|
}
|
|
316
336
|
console.error('No endpoints found for the requested transports.');
|
package/Constants.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.directionToSenders = exports.sendersToDirection = exports.JINGLE_INFO_RECEIVED_5 = exports.JINGLE_INFO_CHECKSUM_5 = exports.JINGLE_INFO_RINGING = exports.JINGLE_INFO_ACTIVE = exports.JINGLE_INFO_UNHOLD = exports.JINGLE_INFO_HOLD = exports.JINGLE_INFO_UNMUTE = exports.JINGLE_INFO_MUTE = exports.JINGLE_INFO = exports.USER_ACTIVITY_SPECIFIC = exports.USER_ACTIVITY_GENERAL = exports.USER_MOODS = exports.JingleReasonCondition = exports.JingleErrorCondition = exports.JingleAction = exports.JingleContentSenders = exports.JingleApplicationDirection = exports.JingleSessionRole = exports.ChatState = exports.PubsubErrorCondition = exports.MUCStatusCode = exports.MUCRole = exports.MUCAffiliation = exports.DataFormFieldType = exports.DataFormType = exports.RosterSubscription = exports.PresenceShow = exports.IQType = exports.PresenceType = exports.MessageType = exports.StanzaErrorCondition = exports.StreamErrorCondition = exports.SASLFailureCondition = exports.StreamType = exports.VERSION = void 0;
|
|
4
4
|
const Namespaces_1 = require("./Namespaces");
|
|
5
|
-
exports.VERSION = '12.
|
|
5
|
+
exports.VERSION = '12.18.0';
|
|
6
6
|
// ====================================================================
|
|
7
7
|
// Frequently Used Values
|
|
8
8
|
// ====================================================================
|
package/README.md
CHANGED
|
@@ -69,14 +69,6 @@ client.connect();
|
|
|
69
69
|
|
|
70
70
|
MUC Room: [discuss@stanzajs.org](https://stanzajs.org/discuss/logs) / [Logs](https://stanzajs.org/discuss/logs)
|
|
71
71
|
|
|
72
|
-
## Related Modules
|
|
73
|
-
|
|
74
|
-
These are related modules that form part of StanzaJS:
|
|
75
|
-
|
|
76
|
-
| Name | Description | Source |
|
|
77
|
-
| ------------------------------------------------------ | -------------------------------------------------------------------- | --------------------------------------------------- |
|
|
78
|
-
| [stanza-shims](https://npmjs.org/package/stanza-shims) | Runtime shims used by StanzaJS for node, browsers, and React Native. | [Source](https://github.com/legastero/stanza-shims) |
|
|
79
|
-
|
|
80
72
|
## Recommended Modules
|
|
81
73
|
|
|
82
74
|
These are some additional modules that are highly recommended for use with StanzaJS:
|
package/Utils.d.ts
CHANGED
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
*/
|
|
9
9
|
/// <reference types="node" />
|
|
10
10
|
export declare function timeoutPromise<T>(target: Promise<T>, delay: number, rejectValue?: () => any): Promise<T>;
|
|
11
|
+
export declare function promiseAny<T>(promises: Array<Promise<T>>): Promise<T>;
|
|
12
|
+
export declare function shuffle<T>(array: T[]): T[];
|
|
11
13
|
export declare function sleep(time: number): Promise<void>;
|
|
12
14
|
export declare function octetCompare(str1: string | Buffer, str2: string | Buffer): number;
|
|
13
15
|
export declare function uuid(): string;
|
package/Utils.js
CHANGED
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
* - uuid, Copyright (c) 2010-2016 Robert Kieffer and other contributors
|
|
9
9
|
*/
|
|
10
10
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
-
exports.reviveData = exports.uuid = exports.octetCompare = exports.sleep = exports.timeoutPromise = void 0;
|
|
11
|
+
exports.reviveData = exports.uuid = exports.octetCompare = exports.sleep = exports.shuffle = exports.promiseAny = exports.timeoutPromise = void 0;
|
|
12
12
|
// tslint:disable no-bitwise
|
|
13
|
-
const
|
|
13
|
+
const platform_1 = require("./platform");
|
|
14
14
|
const bth = [];
|
|
15
15
|
for (let i = 0; i < 256; ++i) {
|
|
16
16
|
bth[i] = (i + 0x100).toString(16).substr(1);
|
|
@@ -27,6 +27,30 @@ async function timeoutPromise(target, delay, rejectValue = () => undefined) {
|
|
|
27
27
|
return result;
|
|
28
28
|
}
|
|
29
29
|
exports.timeoutPromise = timeoutPromise;
|
|
30
|
+
async function promiseAny(promises) {
|
|
31
|
+
try {
|
|
32
|
+
const errors = await Promise.all(promises.map(p => {
|
|
33
|
+
return p.then(val => Promise.reject(val), err => Promise.resolve(err));
|
|
34
|
+
}));
|
|
35
|
+
return Promise.reject(errors);
|
|
36
|
+
}
|
|
37
|
+
catch (val) {
|
|
38
|
+
return Promise.resolve(val);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
exports.promiseAny = promiseAny;
|
|
42
|
+
function shuffle(array) {
|
|
43
|
+
let end = array.length;
|
|
44
|
+
while (end > 0) {
|
|
45
|
+
const selected = Math.floor(Math.random() * end);
|
|
46
|
+
end -= 1;
|
|
47
|
+
const tmp = array[end];
|
|
48
|
+
array[end] = array[selected];
|
|
49
|
+
array[selected] = tmp;
|
|
50
|
+
}
|
|
51
|
+
return array;
|
|
52
|
+
}
|
|
53
|
+
exports.shuffle = shuffle;
|
|
30
54
|
async function sleep(time) {
|
|
31
55
|
return new Promise(resolve => {
|
|
32
56
|
setTimeout(() => resolve(), time);
|
|
@@ -34,13 +58,13 @@ async function sleep(time) {
|
|
|
34
58
|
}
|
|
35
59
|
exports.sleep = sleep;
|
|
36
60
|
function octetCompare(str1, str2) {
|
|
37
|
-
const b1 = typeof str1 === 'string' ? Buffer.from(str1, 'utf8') : str1;
|
|
38
|
-
const b2 = typeof str2 === 'string' ? Buffer.from(str2, 'utf8') : str2;
|
|
61
|
+
const b1 = typeof str1 === 'string' ? platform_1.Buffer.from(str1, 'utf8') : str1;
|
|
62
|
+
const b2 = typeof str2 === 'string' ? platform_1.Buffer.from(str2, 'utf8') : str2;
|
|
39
63
|
return b1.compare(b2);
|
|
40
64
|
}
|
|
41
65
|
exports.octetCompare = octetCompare;
|
|
42
66
|
function uuid() {
|
|
43
|
-
const buf =
|
|
67
|
+
const buf = platform_1.randomBytes(16);
|
|
44
68
|
// Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
|
|
45
69
|
buf[6] = (buf[6] & 0x0f) | 0x40;
|
|
46
70
|
buf[8] = (buf[8] & 0x3f) | 0x80;
|
|
@@ -90,7 +114,7 @@ function reviveData(key, value) {
|
|
|
90
114
|
typeof value === 'object' &&
|
|
91
115
|
value.type === 'Buffer' &&
|
|
92
116
|
Array.isArray(value.data)) {
|
|
93
|
-
return Buffer.from(value);
|
|
117
|
+
return platform_1.Buffer.from(value);
|
|
94
118
|
}
|
|
95
119
|
return value;
|
|
96
120
|
}
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.verify = exports.generate = void 0;
|
|
4
|
-
const
|
|
5
|
-
const Hashes = tslib_1.__importStar(require("stanza-shims"));
|
|
4
|
+
const platform_1 = require("../platform");
|
|
6
5
|
const Utils_1 = require("../Utils");
|
|
7
6
|
function escape(value) {
|
|
8
|
-
return Buffer.from(value.replace(/</g, '<'), 'utf-8');
|
|
7
|
+
return platform_1.Buffer.from(value.replace(/</g, '<'), 'utf-8');
|
|
9
8
|
}
|
|
10
9
|
function encodeIdentities(identities = []) {
|
|
11
10
|
const result = [];
|
|
@@ -115,7 +114,7 @@ function encodeForms(extensions = []) {
|
|
|
115
114
|
}
|
|
116
115
|
function generate(info, hashName) {
|
|
117
116
|
const S = [];
|
|
118
|
-
const separator = Buffer.from('<', 'utf8');
|
|
117
|
+
const separator = platform_1.Buffer.from('<', 'utf8');
|
|
119
118
|
const append = (b1) => {
|
|
120
119
|
S.push(b1);
|
|
121
120
|
S.push(separator);
|
|
@@ -135,7 +134,7 @@ function generate(info, hashName) {
|
|
|
135
134
|
for (const form of extensions) {
|
|
136
135
|
append(form);
|
|
137
136
|
}
|
|
138
|
-
return
|
|
137
|
+
return platform_1.createHash(hashName).update(platform_1.Buffer.concat(S)).digest('base64');
|
|
139
138
|
}
|
|
140
139
|
exports.generate = generate;
|
|
141
140
|
function verify(info, hashName, check) {
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { XRD } from '../protocol/xrd';
|
|
2
|
+
export interface Candidate {
|
|
3
|
+
host: string;
|
|
4
|
+
port: number;
|
|
5
|
+
secure?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface DNSOptions {
|
|
8
|
+
srvType?: string;
|
|
9
|
+
srvTypeSecure?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface SRVRecord {
|
|
12
|
+
name: string;
|
|
13
|
+
port: number;
|
|
14
|
+
priority: number;
|
|
15
|
+
weight: number;
|
|
16
|
+
secure?: boolean;
|
|
17
|
+
used?: boolean;
|
|
18
|
+
runningSum?: number;
|
|
19
|
+
id?: number;
|
|
20
|
+
}
|
|
21
|
+
export interface SRVResult {
|
|
22
|
+
records: SRVRecord[];
|
|
23
|
+
allowFallback: boolean;
|
|
24
|
+
}
|
|
25
|
+
export default class NetworkDiscovery {
|
|
26
|
+
private resolver?;
|
|
27
|
+
private registry;
|
|
28
|
+
private hostMetaCache;
|
|
29
|
+
private hostMetaTTL;
|
|
30
|
+
constructor();
|
|
31
|
+
getHostMeta(domain: string): Promise<XRD>;
|
|
32
|
+
resolveTXT(domain: string): Promise<string[][]>;
|
|
33
|
+
resolve(domain: string, defaultPort: number, opts?: DNSOptions): Promise<Candidate[]>;
|
|
34
|
+
resolveWeightedSRV(domain: string, srvType: string, srvTypeSecure?: string): Promise<SRVResult>;
|
|
35
|
+
resolveSRV(domain: string, srvType: string, secure?: boolean): Promise<SRVResult>;
|
|
36
|
+
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const platform_1 = require("../platform");
|
|
5
|
+
const Utils_1 = require("../Utils");
|
|
6
|
+
const jxt_1 = require("../jxt");
|
|
7
|
+
const xrd_1 = tslib_1.__importDefault(require("../protocol/xrd"));
|
|
8
|
+
class NetworkDiscovery {
|
|
9
|
+
constructor() {
|
|
10
|
+
this.hostMetaCache = new Map();
|
|
11
|
+
this.hostMetaTTL = 30000;
|
|
12
|
+
this.resolver = platform_1.createResolver();
|
|
13
|
+
this.registry = new jxt_1.Registry();
|
|
14
|
+
this.registry.define(xrd_1.default);
|
|
15
|
+
}
|
|
16
|
+
async getHostMeta(domain) {
|
|
17
|
+
const cached = this.hostMetaCache.get(domain);
|
|
18
|
+
if (cached) {
|
|
19
|
+
if (cached.created + this.hostMetaTTL < Date.now()) {
|
|
20
|
+
return cached.hostmeta;
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
this.hostMetaCache.delete(domain);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
const hostmeta = Utils_1.promiseAny([
|
|
27
|
+
platform_1.fetch(`https://${domain}/.well-known/host-meta.json`).then(async (res) => {
|
|
28
|
+
if (!res.ok) {
|
|
29
|
+
throw new Error('could-not-fetch-json');
|
|
30
|
+
}
|
|
31
|
+
return res.json();
|
|
32
|
+
}),
|
|
33
|
+
platform_1.fetch(`https://${domain}/.well-known/host-meta`).then(async (res) => {
|
|
34
|
+
if (!res.ok) {
|
|
35
|
+
throw new Error('could-not-fetch-xml');
|
|
36
|
+
}
|
|
37
|
+
const data = await res.text();
|
|
38
|
+
const xml = jxt_1.parse(data);
|
|
39
|
+
if (xml) {
|
|
40
|
+
return this.registry.import(xml);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
throw new Error('could-not-import-xml');
|
|
44
|
+
}
|
|
45
|
+
})
|
|
46
|
+
]);
|
|
47
|
+
this.hostMetaCache.set(domain, { created: Date.now(), hostmeta });
|
|
48
|
+
hostmeta.catch(() => {
|
|
49
|
+
this.hostMetaCache.delete(domain);
|
|
50
|
+
});
|
|
51
|
+
return hostmeta;
|
|
52
|
+
}
|
|
53
|
+
async resolveTXT(domain) {
|
|
54
|
+
var _a, _b;
|
|
55
|
+
return (_b = (_a = this.resolver) === null || _a === void 0 ? void 0 : _a.resolveTxt(domain)) !== null && _b !== void 0 ? _b : [];
|
|
56
|
+
}
|
|
57
|
+
async resolve(domain, defaultPort, opts = {}) {
|
|
58
|
+
if (!this.resolver) {
|
|
59
|
+
return [];
|
|
60
|
+
}
|
|
61
|
+
let candidates = [];
|
|
62
|
+
let allowFallback = true;
|
|
63
|
+
if (opts.srvType) {
|
|
64
|
+
const srvResults = await this.resolveWeightedSRV(domain, opts.srvType, opts.srvTypeSecure);
|
|
65
|
+
allowFallback = srvResults.allowFallback;
|
|
66
|
+
candidates = srvResults.records.map(record => ({
|
|
67
|
+
host: record.name,
|
|
68
|
+
port: record.port,
|
|
69
|
+
secure: record.secure
|
|
70
|
+
}));
|
|
71
|
+
}
|
|
72
|
+
if (allowFallback) {
|
|
73
|
+
candidates.push({ host: domain, port: defaultPort });
|
|
74
|
+
}
|
|
75
|
+
return candidates;
|
|
76
|
+
}
|
|
77
|
+
async resolveWeightedSRV(domain, srvType, srvTypeSecure) {
|
|
78
|
+
const [records, secureRecords] = await Promise.all([
|
|
79
|
+
this.resolveSRV(domain, srvType),
|
|
80
|
+
srvTypeSecure
|
|
81
|
+
? this.resolveSRV(domain, srvTypeSecure, true)
|
|
82
|
+
: Promise.resolve({ records: [], allowFallback: false })
|
|
83
|
+
]);
|
|
84
|
+
const allRecords = [...records.records, ...secureRecords.records];
|
|
85
|
+
const priorities = new Map();
|
|
86
|
+
let id = 0;
|
|
87
|
+
for (const record of allRecords) {
|
|
88
|
+
record.id = id++;
|
|
89
|
+
record.runningSum = 0;
|
|
90
|
+
if (!priorities.has(record.priority)) {
|
|
91
|
+
priorities.set(record.priority, []);
|
|
92
|
+
}
|
|
93
|
+
const priorityGroup = priorities.get(record.priority);
|
|
94
|
+
priorityGroup.push(record);
|
|
95
|
+
}
|
|
96
|
+
const weightRecords = (unweightedRecords) => {
|
|
97
|
+
const sorted = [];
|
|
98
|
+
while (sorted.length < unweightedRecords.length) {
|
|
99
|
+
const ordered = Utils_1.shuffle(unweightedRecords.filter(record => record.weight === 0 && !record.used));
|
|
100
|
+
const unordered = Utils_1.shuffle(unweightedRecords.filter(record => {
|
|
101
|
+
return record.weight !== 0 && !record.used;
|
|
102
|
+
}));
|
|
103
|
+
let weightSum = 0;
|
|
104
|
+
for (const record of unordered) {
|
|
105
|
+
weightSum += record.weight;
|
|
106
|
+
record.runningSum = weightSum;
|
|
107
|
+
ordered.push(record);
|
|
108
|
+
}
|
|
109
|
+
const selector = Math.floor(Math.random() * (weightSum + 1));
|
|
110
|
+
for (const record of ordered) {
|
|
111
|
+
if (record.runningSum >= selector) {
|
|
112
|
+
record.used = true;
|
|
113
|
+
sorted.push(record);
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return sorted;
|
|
119
|
+
};
|
|
120
|
+
let sortedRecords = [];
|
|
121
|
+
for (const priority of Array.from(priorities.keys()).sort((a, b) => a < b ? -1 : a > b ? 1 : 0)) {
|
|
122
|
+
const priorityGroup = priorities.get(priority);
|
|
123
|
+
sortedRecords = sortedRecords.concat(weightRecords(priorityGroup));
|
|
124
|
+
}
|
|
125
|
+
return {
|
|
126
|
+
records: sortedRecords,
|
|
127
|
+
allowFallback: records.allowFallback
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
async resolveSRV(domain, srvType, secure) {
|
|
131
|
+
var _a, _b;
|
|
132
|
+
try {
|
|
133
|
+
const records = (_b = (await ((_a = this.resolver) === null || _a === void 0 ? void 0 : _a.resolveSrv(`${srvType}.${domain}`)))) !== null && _b !== void 0 ? _b : [];
|
|
134
|
+
if (records.length === 1 && (records[0].name === '.' || records[0].name === '')) {
|
|
135
|
+
return { records: [], allowFallback: false };
|
|
136
|
+
}
|
|
137
|
+
return {
|
|
138
|
+
records: records
|
|
139
|
+
.map(record => ({ secure, ...record }))
|
|
140
|
+
.filter(record => record.name !== '' && record.name !== '.'),
|
|
141
|
+
allowFallback: false
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
catch (_c) {
|
|
145
|
+
return {
|
|
146
|
+
records: [],
|
|
147
|
+
allowFallback: true
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
exports.default = NetworkDiscovery;
|
package/helpers/RSM.d.ts
CHANGED
|
@@ -18,9 +18,15 @@ export declare class ResultSetPager<T> {
|
|
|
18
18
|
private direction;
|
|
19
19
|
private reverse;
|
|
20
20
|
private pageSize;
|
|
21
|
+
private resultCount?;
|
|
22
|
+
private resultComplete;
|
|
23
|
+
private fetchedCount;
|
|
24
|
+
private yieldedCount;
|
|
21
25
|
constructor(opts: RSMOptions<T>);
|
|
22
26
|
[Symbol.asyncIterator](): AsyncGenerator<T>;
|
|
23
27
|
size(): Promise<number | undefined>;
|
|
28
|
+
queryCompleted(): boolean;
|
|
29
|
+
finished(): boolean;
|
|
24
30
|
private fetchPage;
|
|
25
31
|
}
|
|
26
32
|
export declare function createPager<T>(opts: RSMOptions<T>): ResultSetPager<T>;
|
package/helpers/RSM.js
CHANGED
|
@@ -4,6 +4,9 @@ exports.createPager = exports.ResultSetPager = void 0;
|
|
|
4
4
|
class ResultSetPager {
|
|
5
5
|
constructor(opts) {
|
|
6
6
|
var _a, _b, _c;
|
|
7
|
+
this.resultComplete = false;
|
|
8
|
+
this.fetchedCount = 0;
|
|
9
|
+
this.yieldedCount = 0;
|
|
7
10
|
this.cursor = { first: opts.before, last: opts.after };
|
|
8
11
|
this.query = opts.query;
|
|
9
12
|
this.direction = (_a = opts.direction) !== null && _a !== void 0 ? _a : 'forward';
|
|
@@ -15,14 +18,25 @@ class ResultSetPager {
|
|
|
15
18
|
do {
|
|
16
19
|
currentResults = await this.fetchPage();
|
|
17
20
|
for (const item of currentResults) {
|
|
21
|
+
this.yieldedCount += 1;
|
|
18
22
|
yield item;
|
|
19
23
|
}
|
|
20
24
|
} while (currentResults.length > 0);
|
|
21
25
|
}
|
|
22
26
|
async size() {
|
|
27
|
+
if (this.resultCount !== undefined) {
|
|
28
|
+
return this.resultCount;
|
|
29
|
+
}
|
|
23
30
|
const { paging } = await this.query({ max: 0 });
|
|
31
|
+
this.resultCount = paging.count;
|
|
24
32
|
return paging.count;
|
|
25
33
|
}
|
|
34
|
+
queryCompleted() {
|
|
35
|
+
return this.resultComplete;
|
|
36
|
+
}
|
|
37
|
+
finished() {
|
|
38
|
+
return this.resultComplete && this.yieldedCount === this.fetchedCount;
|
|
39
|
+
}
|
|
26
40
|
async fetchPage() {
|
|
27
41
|
var _a;
|
|
28
42
|
const { results, paging } = await this.query({
|
|
@@ -31,6 +45,12 @@ class ResultSetPager {
|
|
|
31
45
|
max: this.pageSize
|
|
32
46
|
});
|
|
33
47
|
this.cursor = paging;
|
|
48
|
+
this.resultCount = paging.count;
|
|
49
|
+
this.fetchedCount += results.length;
|
|
50
|
+
if ((this.pageSize && results.length < this.pageSize) ||
|
|
51
|
+
(this.resultCount && this.fetchedCount === this.resultCount)) {
|
|
52
|
+
this.resultComplete = true;
|
|
53
|
+
}
|
|
34
54
|
if (this.reverse) {
|
|
35
55
|
results.reverse();
|
|
36
56
|
}
|
package/index.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { EventEmitter } from 'events';
|
|
|
3
3
|
import Client from './Client';
|
|
4
4
|
import * as Constants from './Constants';
|
|
5
5
|
import * as RTT from './helpers/RTT';
|
|
6
|
+
import NetworkDiscovery from './helpers/NetworkDiscovery';
|
|
6
7
|
import SM from './helpers/StreamManagement';
|
|
7
8
|
import * as JID from './JID';
|
|
8
9
|
import * as Jingle from './jingle';
|
|
@@ -13,6 +14,7 @@ import * as Namespaces from './Namespaces';
|
|
|
13
14
|
import * as Stanzas from './protocol';
|
|
14
15
|
import { CSI, IQ, Message, Presence, SASL, Stream, StreamError, StreamFeatures, StreamManagement } from './protocol';
|
|
15
16
|
import * as Utils from './Utils';
|
|
17
|
+
import * as Platform from './platform';
|
|
16
18
|
export * from './helpers/StreamManagement';
|
|
17
19
|
export interface TopLevelElements {
|
|
18
20
|
message: Message;
|
|
@@ -102,9 +104,13 @@ export interface Agent extends StrictEventEmitter<EventEmitter, AgentEvents> {
|
|
|
102
104
|
sm: SM;
|
|
103
105
|
sasl: LibSASL.Factory;
|
|
104
106
|
stanzas: JXT.Registry;
|
|
107
|
+
resolver: NetworkDiscovery;
|
|
105
108
|
sessionStarting: boolean;
|
|
106
109
|
sessionStarted: boolean;
|
|
107
110
|
sessionTerminating: boolean;
|
|
111
|
+
transports: {
|
|
112
|
+
[key: string]: new (client: Agent, sm: StreamManagement, registry: JXT.Registry) => Transport;
|
|
113
|
+
};
|
|
108
114
|
use(plugin: (agent: Agent, registry: JXT.Registry, config: AgentConfig) => void): void;
|
|
109
115
|
nextId(): string;
|
|
110
116
|
updateConfig(opts?: AgentConfig): void;
|
|
@@ -177,14 +183,21 @@ export interface AgentConfig {
|
|
|
177
183
|
*
|
|
178
184
|
* If a transport is set to a string, that will be used as the connection URL.
|
|
179
185
|
*
|
|
180
|
-
* If a transport is set to an object, it MUST include a <code>url</code> value for
|
|
181
|
-
* the connection URL.
|
|
182
|
-
*
|
|
183
186
|
* @default { websocket: true, bosh: true }
|
|
184
187
|
*/
|
|
185
188
|
transports?: {
|
|
186
189
|
[key: string]: boolean | string | Partial<TransportConfig>;
|
|
187
190
|
};
|
|
191
|
+
/**
|
|
192
|
+
* Transport Preference Order
|
|
193
|
+
*
|
|
194
|
+
* Specify the order in which transports should be tried when connecting.
|
|
195
|
+
*
|
|
196
|
+
* If a configured transport type is not listed, it will be skipped.
|
|
197
|
+
*
|
|
198
|
+
* @default ['websocket', 'bosh']
|
|
199
|
+
*/
|
|
200
|
+
transportPreferenceOrder?: string[];
|
|
188
201
|
/**
|
|
189
202
|
* Account Password
|
|
190
203
|
*
|
|
@@ -208,17 +221,18 @@ export interface Transport {
|
|
|
208
221
|
hasStream?: boolean;
|
|
209
222
|
stream?: Stream;
|
|
210
223
|
authenticated?: boolean;
|
|
224
|
+
discoverBindings?(host: string): Promise<Partial<TransportConfig> | null>;
|
|
211
225
|
connect(opts: TransportConfig): void;
|
|
212
226
|
disconnect(cleanly?: boolean): void;
|
|
213
227
|
restart(): void;
|
|
214
228
|
send(name: string, data?: JXT.JSONData): Promise<void>;
|
|
215
229
|
}
|
|
216
230
|
export interface TransportConfig {
|
|
217
|
-
lang?: string;
|
|
218
|
-
acceptLanguages?: string[];
|
|
219
231
|
server: string;
|
|
220
|
-
url: string;
|
|
221
232
|
jid: string;
|
|
233
|
+
lang?: string;
|
|
234
|
+
acceptLanguages?: string[];
|
|
235
|
+
url?: string;
|
|
222
236
|
sid?: string;
|
|
223
237
|
rid?: number;
|
|
224
238
|
maxRetries?: number;
|
|
@@ -227,7 +241,7 @@ export interface TransportConfig {
|
|
|
227
241
|
}
|
|
228
242
|
import * as RSM from './helpers/RSM';
|
|
229
243
|
import * as DataForms from './helpers/DataForms';
|
|
230
|
-
export { Client, Constants, DataForms, JXT, JID, Namespaces, Stanzas, Jingle, Utils, RSM, RTT, LibSASL as SASL };
|
|
244
|
+
export { Client, Constants, DataForms, JXT, JID, Namespaces, Stanzas, Jingle, Utils, RSM, RTT, LibSASL as SASL, Platform };
|
|
231
245
|
export declare const VERSION = "__STANZAJS_VERSION__";
|
|
232
246
|
export * from './plugins';
|
|
233
247
|
export declare function createClient(opts: AgentConfig): Agent;
|
package/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createClient = exports.VERSION = exports.SASL = exports.RTT = exports.RSM = exports.Utils = exports.Jingle = exports.Stanzas = exports.Namespaces = exports.JID = exports.JXT = exports.DataForms = exports.Constants = exports.Client = void 0;
|
|
3
|
+
exports.createClient = exports.VERSION = exports.Platform = exports.SASL = exports.RTT = exports.RSM = exports.Utils = exports.Jingle = exports.Stanzas = exports.Namespaces = exports.JID = exports.JXT = exports.DataForms = exports.Constants = exports.Client = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const Client_1 = tslib_1.__importDefault(require("./Client"));
|
|
6
6
|
exports.Client = Client_1.default;
|
|
@@ -22,6 +22,8 @@ const Stanzas = tslib_1.__importStar(require("./protocol"));
|
|
|
22
22
|
exports.Stanzas = Stanzas;
|
|
23
23
|
const Utils = tslib_1.__importStar(require("./Utils"));
|
|
24
24
|
exports.Utils = Utils;
|
|
25
|
+
const Platform = tslib_1.__importStar(require("./platform"));
|
|
26
|
+
exports.Platform = Platform;
|
|
25
27
|
tslib_1.__exportStar(require("./helpers/StreamManagement"), exports);
|
|
26
28
|
const RSM = tslib_1.__importStar(require("./helpers/RSM"));
|
|
27
29
|
exports.RSM = RSM;
|
package/index.module.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import Client from './Client';
|
|
2
|
+
import * as Constants from './Constants';
|
|
3
|
+
import * as RTT from './helpers/RTT';
|
|
4
|
+
import * as JID from './JID';
|
|
5
|
+
import * as Jingle from './jingle';
|
|
6
|
+
import * as JXT from './jxt';
|
|
7
|
+
import * as LibSASL from './lib/sasl';
|
|
8
|
+
import * as Namespaces from './Namespaces';
|
|
9
|
+
import * as Stanzas from './protocol';
|
|
10
|
+
import * as Utils from './Utils';
|
|
11
|
+
import * as Platform from './platform';
|
|
12
|
+
export * from './helpers/StreamManagement';
|
|
13
|
+
import * as RSM from './helpers/RSM';
|
|
14
|
+
import * as DataForms from './helpers/DataForms';
|
|
15
|
+
export { Client, Constants, DataForms, JXT, JID, Namespaces, Stanzas, Jingle, Utils, RSM, RTT, LibSASL as SASL, Platform };
|
|
16
|
+
export const VERSION = Constants.VERSION;
|
|
17
|
+
import Plugins from './plugins';
|
|
18
|
+
export * from './plugins';
|
|
19
|
+
export function createClient(opts) {
|
|
20
|
+
const client = new Client(opts);
|
|
21
|
+
client.use(Plugins);
|
|
22
|
+
return client;
|
|
23
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import { EventEmitter } from 'events';
|
|
3
|
-
import * as Hashes from '
|
|
3
|
+
import * as Hashes from '../platform';
|
|
4
4
|
import { FileDescription, Hash, Jingle } from '../protocol';
|
|
5
5
|
import ICESession, { ICESessionOpts } from './ICESession';
|
|
6
6
|
import { ActionCallback } from './Session';
|