Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement SASL2 #1030

Merged
merged 38 commits into from
Dec 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
4c3a481
Include stream from when possible
singpolyma Nov 21, 2023
3fb0a08
Implement SASL HT-SHA-256-NONE mechanism
singpolyma Nov 21, 2023
36f543f
Implement SASL2 (with optional BIND2 and FAST)
singpolyma Nov 21, 2023
2d3bde9
Use SASL2 from client
singpolyma Nov 21, 2023
46f3ee6
Allow other modules to inline into sasl2/bind2
singpolyma Nov 22, 2023
917f30b
Inline stream management into sasl2/bind2
singpolyma Nov 22, 2023
d9b0711
Add SASL2/BIND2/FAST tests
singpolyma Jul 4, 2024
3477d68
Merge branch 'main' into sasl2
sonnyp Dec 12, 2024
42cccdb
fix eslint
sonnyp Dec 12, 2024
296000d
Remove sasl-ht-sha-256-none from @xmpp/client browser
sonnyp Dec 12, 2024
b8e0fac
Add doc comment to sasl-h2-sha-256-none
singpolyma Dec 18, 2024
9f6ad2f
Update sasl2 doc link comment
singpolyma Dec 18, 2024
675aab9
Add explanatory comment about bind2 inline setting to online
singpolyma Dec 18, 2024
30ca0a7
Explanation of setting stream from
singpolyma Dec 18, 2024
f2e29fa
Workaround for bug in babel-plugin-transform-async-to-promises
singpolyma Dec 18, 2024
2fd7003
Enable SASL2 for test server
singpolyma Dec 18, 2024
96d50c8
e2e tests for bind2 and fast
singpolyma Dec 18, 2024
faf34ef
Fix for 0.12+
singpolyma Dec 18, 2024
07f4250
SASL2 et al need prosody trunk
singpolyma Dec 18, 2024
069d0f6
Enable sasl2 in react-native
sonnyp Dec 20, 2024
54db23a
Merge branch 'main' into sasl2
sonnyp Dec 21, 2024
7ce1b2f
fixes
sonnyp Dec 21, 2024
21bb7cb
Merge branch 'main' into sasl2
sonnyp Dec 21, 2024
441efe0
Stop vendoring prosody modules
sonnyp Dec 21, 2024
ca6b6f5
Merge branch 'main' into sasl2
sonnyp Dec 22, 2024
e37dfbf
Address some review comments
sonnyp Dec 22, 2024
c5645bc
f
sonnyp Dec 22, 2024
195cda5
Fix CI install modules
sonnyp Dec 22, 2024
2e1782f
Remove sasl2 SASLError
sonnyp Dec 22, 2024
c7e17c9
Move sasl factory to client
sonnyp Dec 22, 2024
9973b6f
add make e2e with prosody modules install
sonnyp Dec 22, 2024
d0c8030
remove bind2 and fast for now
sonnyp Dec 22, 2024
eb52715
Revert "Include stream from when possible"
sonnyp Dec 22, 2024
968204f
fixes
sonnyp Dec 22, 2024
a53d94a
Do not include sasl2 in @xmpp/client
sonnyp Dec 22, 2024
5880c50
Merge branch 'main' into sasl2-bis
sonnyp Dec 22, 2024
e560649
fixes
sonnyp Dec 22, 2024
40a28ff
Remove browser file and use index.js instead
sonnyp Dec 22, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
echo deb http://packages.prosody.im/debian $(lsb_release -sc) main | sudo tee /etc/apt/sources.list.d/prosody.list
sudo wget https://prosody.im/files/prosody-debian-packages.key -O/etc/apt/trusted.gpg.d/prosody.gpg
sudo apt-get update
sudo apt-get -y install prosody lua-bitop lua-sec
sudo apt-get -y install lua5.3 liblua5.3-dev prosody-trunk lua-bitop lua-sec luarocks
sudo service prosody stop

# - run: npm install -g npm
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ server/certs/
server/prosody.err
server/prosody.log
server/prosody.pid
server/modules
server/.cache

!.gitkeep
!.editorconfig
Expand Down
10 changes: 8 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,16 @@ ci:
make bundlesize

unit:
npx jest
npm run test

e2e:
NODE_TLS_REJECT_UNAUTHORIZED=0 npx jest --runInBand --config e2e.config.cjs
$(warning e2e tests require prosody-trunk and luarocks)
cd server && prosodyctl --config prosody.cfg.lua install mod_sasl2 > /dev/null
# https://github.com/xmppjs/xmpp.js/pull/1006
# cd server && prosodyctl --config prosody.cfg.lua install mod_sasl2_bind2 > /dev/null
# cd server && prosodyctl --config prosody.cfg.lua install mod_sasl2_fast > /dev/null
# cd server && prosodyctl --config prosody.cfg.lua install mod_sasl2_sm > /dev/null
npm run e2e

clean:
make stop
Expand Down
33 changes: 33 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
"selfsigned": "^2.4.1"
},
"scripts": {
"test": "npx jest",
"e2e": "NODE_TLS_REJECT_UNAUTHORIZED=0 npx jest --runInBand --config e2e.config.cjs",
"preversion": "make bundle"
},
"engines": {
Expand Down
4 changes: 3 additions & 1 deletion packages/client/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ xmpp.on("stanza", async (stanza) => {
});

xmpp.on("online", async (address) => {
console.log("online as", address.toString());

// Makes itself available
await xmpp.send(xml("presence"));

Expand All @@ -75,7 +77,7 @@ xmpp.on("online", async (address) => {
await xmpp.send(message);
});

xmpp.start().catch(console.error);
await xmpp.start();
```

## xml
Expand Down
85 changes: 0 additions & 85 deletions packages/client/browser.js

This file was deleted.

1 change: 0 additions & 1 deletion packages/client/example.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { client, xml } from "@xmpp/client";

// eslint-disable-next-line n/no-extraneous-import
import debug from "@xmpp/debug";

Expand Down
30 changes: 24 additions & 6 deletions packages/client/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ 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 _sessionEstablishment from "@xmpp/session-establishment";
Expand All @@ -23,8 +23,20 @@ import scramsha1 from "@xmpp/sasl-scram-sha-1";
import plain from "@xmpp/sasl-plain";
import anonymous from "@xmpp/sasl-anonymous";

// 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);
}

function client(options = {}) {
const { resource, credentials, username, password, ...params } = options;
const { clientId, software, device } = params;

const { domain, service } = params;
if (!domain && service) {
Expand All @@ -35,8 +47,8 @@ function client(options = {}) {

const reconnect = _reconnect({ entity });
const websocket = _websocket({ entity });
const tcp = _tcp({ entity });
const tls = _tls({ entity });
const tcp = setupIfAvailable(_tcp, { entity });
const tls = setupIfAvailable(_tls, { entity });

const middleware = _middleware({ entity });
const streamFeatures = _streamFeatures({ middleware });
Expand All @@ -47,13 +59,18 @@ function client(options = {}) {
// SASL mechanisms - order matters and define priority
const saslFactory = new SASLFactory();
const mechanisms = Object.entries({
scramsha1,
...(typeof scramsha1 === "function" && { scramsha1 }),
plain,
anonymous,
}).map(([k, v]) => ({ [k]: v(saslFactory) }));

// Stream features - order matters and define priority
const starttls = _starttls({ streamFeatures });
const starttls = setupIfAvailable(_starttls, { streamFeatures });
const sasl2 = _sasl2(
{ streamFeatures, saslFactory },
createOnAuthenticate(credentials ?? { username, password }),
{ clientId, software, device },
);
const sasl = _sasl(
{ streamFeatures, saslFactory },
createOnAuthenticate(credentials ?? { username, password }),
Expand Down Expand Up @@ -84,12 +101,13 @@ function client(options = {}) {
iqCallee,
resolve,
starttls,
saslFactory,
sasl2,
sasl,
resourceBinding,
sessionEstablishment,
streamManagement,
mechanisms,
saslFactory,
});
}

Expand Down
9 changes: 7 additions & 2 deletions packages/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"@xmpp/resolve": "^0.13.2",
"@xmpp/resource-binding": "^0.13.2",
"@xmpp/sasl": "^0.13.2",
"@xmpp/sasl2": "^0.13.0",
"@xmpp/sasl-anonymous": "^0.13.2",
"@xmpp/sasl-plain": "^0.13.2",
"@xmpp/sasl-scram-sha-1": "^0.13.2",
Expand All @@ -27,8 +28,12 @@
"@xmpp/websocket": "^0.13.2",
"saslmechanisms": "^0.1.1"
},
"browser": "browser.js",
"react-native": "browser.js",
"browser": {
"@xmpp/tcp": false,
"@xmpp/tls": false,
"@xmpp/starttls": false,
"@xmpp/sasl-scram-sha-1": false
},
"engines": {
"node": ">= 20"
},
Expand Down
2 changes: 1 addition & 1 deletion packages/component/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ xmpp.on("online", async (address) => {
await xmpp.send(message);
});

xmpp.start().catch(console.error);
await xmpp.start();
```

## xml
Expand Down
2 changes: 2 additions & 0 deletions packages/error/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ test("fromElement", () => {
const error = XMPPError.fromElement(nonza);

expect(error instanceof Error).toBe(true);
expect(error instanceof XMPPError).toBe(true);
expect(error.name).toBe("XMPPError");
expect(error.condition).toBe("some-condition");
expect(error.text).toBe("foo");
Expand All @@ -42,6 +43,7 @@ test("fromElement - whitespaces", () => {
const error = XMPPError.fromElement(nonza);

expect(error instanceof Error).toBe(true);
expect(error instanceof XMPPError).toBe(true);
expect(error.name).toBe("XMPPError");
expect(error.condition).toBe("some-condition");
expect(error.text).toBe("\n foo\n ");
Expand Down
4 changes: 2 additions & 2 deletions packages/sasl/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import xml from "@xmpp/xml";

const NS = "urn:ietf:params:xml:ns:xmpp-sasl";

function getMechanismNames(features) {
return features
function getMechanismNames(stanza) {
return stanza
.getChild("mechanisms", NS)
.getChildElements()
.map((el) => el.text());
Expand Down
Loading
Loading