-
Notifications
You must be signed in to change notification settings - Fork 376
/
Copy pathindex.js
138 lines (119 loc) · 3.91 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
import { xml, jid, Client } from "@xmpp/client-core";
import getDomain from "./lib/getDomain.js";
import createOnAuthenticate from "./lib/createOnAuthenticate.js";
import _reconnect from "@xmpp/reconnect";
import _websocket from "@xmpp/websocket";
import _tcp from "@xmpp/tcp";
import _tls from "@xmpp/tls";
import _middleware from "@xmpp/middleware";
import _streamFeatures from "@xmpp/stream-features";
import _iqCaller from "@xmpp/iq/caller.js";
import _iqCallee from "@xmpp/iq/callee.js";
import _resolve from "@xmpp/resolve";
import _starttls from "@xmpp/starttls";
import _sasl2 from "@xmpp/sasl2";
import _sasl from "@xmpp/sasl";
import _resourceBinding from "@xmpp/resource-binding";
import _streamManagement from "@xmpp/stream-management";
import _bind2 from "@xmpp/client-core/src/bind2/bind2.js";
import _fast from "@xmpp/client-core/src/fast/fast.js";
import SASLFactory from "saslmechanisms";
import scramsha1 from "@xmpp/sasl-scram-sha-1";
import plain from "@xmpp/sasl-plain";
import anonymous from "@xmpp/sasl-anonymous";
import htsha256none from "@xmpp/sasl-ht-sha-256-none";
function client(options = {}) {
let { resource, credentials, username, password, userAgent, ...params } =
options;
const { domain, service } = params;
if (!domain && service) {
params.domain = getDomain(service);
}
const entity = new Client(params);
if (username && params.domain) {
entity.jid = jid(username, params.domain);
}
const reconnect = _reconnect({ entity });
const websocket = _websocket({ entity });
const tcp = setupIfAvailable(_tcp, { entity });
const tls = setupIfAvailable(_tls, { entity });
const middleware = _middleware({ entity });
const streamFeatures = _streamFeatures({ middleware });
const iqCaller = _iqCaller({ middleware, entity });
const iqCallee = _iqCallee({ middleware, entity });
const resolve = _resolve({ entity });
// SASL mechanisms - order matters and define priority
const saslFactory = new SASLFactory();
const mechanisms = Object.entries({
...(typeof scramsha1 === "function" && { scramsha1 }),
plain,
anonymous,
}).map(([k, v]) => ({ [k]: v(saslFactory) }));
// eslint-disable-next-line n/no-unsupported-features/node-builtins
userAgent ??= xml("user-agent", { id: globalThis.crypto.randomUUID() });
// Stream features - order matters and define priority
const starttls = setupIfAvailable(_starttls, { streamFeatures });
const sasl2 = _sasl2(
{ streamFeatures, saslFactory },
createOnAuthenticate(credentials ?? { username, password }, userAgent),
);
const fast = _fast({
sasl2,
entity,
});
sasl2.setup({ fast });
// SASL2 inline features
const bind2 = _bind2({ sasl2, entity }, resource);
// FAST mechanisms - order matters and define priority
htsha256none(fast.saslFactory);
// Stream features - order matters and define priority
const sasl = _sasl(
{ streamFeatures, saslFactory },
createOnAuthenticate(credentials ?? { username, password }, userAgent),
);
const streamManagement = _streamManagement({
streamFeatures,
entity,
middleware,
bind2,
sasl2,
});
const resourceBinding = _resourceBinding(
{ iqCaller, streamFeatures },
resource,
);
iqCallee?.get("urn:xmpp:ping", "ping", () => {
return {};
});
return Object.assign(entity, {
entity,
reconnect,
tcp,
websocket,
tls,
middleware,
streamFeatures,
iqCaller,
iqCallee,
resolve,
starttls,
saslFactory,
sasl2,
sasl,
resourceBinding,
streamManagement,
mechanisms,
bind2,
fast,
});
}
// In browsers and react-native some packages are excluded
// see package.json and https://metrobundler.dev/docs/configuration/#resolvermainfields
// in which case the default import returns an empty object
function setupIfAvailable(module, ...args) {
if (typeof module !== "function") {
return undefined;
}
return module(...args);
}
export { xml, jid, client };