Skip to content

Commit

Permalink
Add @xmpp/events procedure to simplify code
Browse files Browse the repository at this point in the history
  • Loading branch information
sonnyp committed Jan 1, 2025
1 parent 499b718 commit 532204c
Show file tree
Hide file tree
Showing 10 changed files with 91 additions and 83 deletions.
4 changes: 4 additions & 0 deletions package-lock.json

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

11 changes: 10 additions & 1 deletion packages/events/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,14 @@ import delay from "./lib/delay.js";
import TimeoutError from "./lib/TimeoutError.js";
import promise from "./lib/promise.js";
import Deferred from "./lib/Deferred.js";
import procedure from "./lib/procedure.js";

export { EventEmitter, timeout, delay, TimeoutError, promise, Deferred };
export {
EventEmitter,
timeout,
delay,
TimeoutError,
promise,
Deferred,
procedure,
};
24 changes: 24 additions & 0 deletions packages/events/lib/procedure.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
export default function procedure(entity, stanza = null, handler) {
return new Promise((resolve, reject) => {
function stop(...args) {
entity.removeListener("nonza", listener);
resolve(...args);
}

async function listener(element) {
try {
await handler(element, stop);
} catch (err) {
reject(err);
entity.removeListener("nonza", listener);
}
}

stanza &&
entity.send(stanza).catch((err) => {
entity.removeListener("nonza", listener);
reject(err);
});
entity.on("nonza", listener);
});
}
42 changes: 18 additions & 24 deletions packages/sasl/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { encode, decode } from "@xmpp/base64";
import SASLError from "./lib/SASLError.js";
import xml from "@xmpp/xml";
import { procedure } from "@xmpp/events";

// https://xmpp.org/rfcs/rfc6120.html#sasl

Expand Down Expand Up @@ -28,16 +29,21 @@ async function authenticate({ saslFactory, entity, mechanism, credentials }) {
...credentials,
};

return new Promise((resolve, reject) => {
const handler = (element) => {
if (element.attrs.xmlns !== NS) {
return;
}
await procedure(
entity,
mech.clientFirst &&
xml(
"auth",
{ xmlns: NS, mechanism: mech.name },
encode(mech.response(creds)),
),
async (element, stop) => {
if (element.getNS() !== NS) return;

if (element.name === "challenge") {
mech.challenge(decode(element.text()));
const resp = mech.response(creds);
entity.send(
await entity.send(
xml(
"response",
{ xmlns: NS, mechanism: mech.name },
Expand All @@ -48,26 +54,14 @@ async function authenticate({ saslFactory, entity, mechanism, credentials }) {
}

if (element.name === "failure") {
reject(SASLError.fromElement(element));
} else if (element.name === "success") {
resolve();
throw SASLError.fromElement(element);
}

entity.removeListener("nonza", handler);
};

entity.on("nonza", handler);

if (mech.clientFirst) {
entity.send(
xml(
"auth",
{ xmlns: NS, mechanism: mech.name },
encode(mech.response(creds)),
),
);
}
});
if (element.name === "success") {
return stop();
}
},
);
}

export default function sasl({ streamFeatures, saslFactory }, onAuthenticate) {
Expand Down
1 change: 1 addition & 0 deletions packages/sasl/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"dependencies": {
"@xmpp/base64": "^0.14.0",
"@xmpp/error": "^0.14.0",
"@xmpp/events": "^0.14.0",
"@xmpp/xml": "^0.14.0"
},
"engines": {
Expand Down
43 changes: 16 additions & 27 deletions packages/sasl2/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { encode, decode } from "@xmpp/base64";
import SASLError from "@xmpp/sasl/lib/SASLError.js";
import xml from "@xmpp/xml";
import { procedure } from "@xmpp/events";

// https://xmpp.org/extensions/xep-0388.html

Expand Down Expand Up @@ -36,11 +37,16 @@ async function authenticate({
...credentials,
};

return new Promise((resolve, reject) => {
const handler = (element) => {
if (element.getNS() !== NS) {
return;
}
await procedure(
entity,
xml("authenticate", { xmlns: NS, mechanism: mech.name }, [
mech.clientFirst &&
xml("initial-response", {}, encode(mech.response(creds))),
userAgent,
...streamFeatures,
]),
async (element, stop) => {
if (element.getNS() !== NS) return;

if (element.name === "challenge") {
mech.challenge(decode(element.text()));
Expand All @@ -56,13 +62,11 @@ async function authenticate({
}

if (element.name === "failure") {
reject(SASLError.fromElement(element));
return;
throw SASLError.fromElement(element);
}

if (element.name === "continue") {
reject(new Error("continue is not supported yet"));
return;
throw new Error("SASL continue is not supported yet");
}

if (element.name === "success") {
Expand All @@ -83,25 +87,10 @@ async function authenticate({
feature?.[1]?.(child);
}

resolve(element);
return stop();
}

entity.removeListener("nonza", handler);
};

entity.on("nonza", handler);

entity
.send(
xml("authenticate", { xmlns: NS, mechanism: mech.name }, [
mech.clientFirst &&
xml("initial-response", {}, encode(mech.response(creds))),
userAgent,
...streamFeatures,
]),
)
.catch(reject);
});
},
);
}

export default function sasl2({ streamFeatures, saslFactory }, onAuthenticate) {
Expand Down
1 change: 1 addition & 0 deletions packages/sasl2/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"dependencies": {
"@xmpp/base64": "^0.14.0",
"@xmpp/error": "^0.14.0",
"@xmpp/events": "^0.14.0",
"@xmpp/jid": "^0.14.0",
"@xmpp/sasl": "^0.14.0",
"@xmpp/xml": "^0.14.0"
Expand Down
38 changes: 15 additions & 23 deletions packages/stream-management/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import XMPPError from "@xmpp/error";
import { procedure } from "@xmpp/events";
import xml from "@xmpp/xml";

// https://xmpp.org/extensions/xep-0198.html
Expand All @@ -16,34 +18,24 @@ function makeResumeElement({ sm }) {
return xml("resume", { xmlns: NS, h: sm.inbound, previd: sm.id });
}

async function enable(entity, sm) {
await entity.send(makeEnableElement({ sm }));

return new Promise((resolve, reject) => {
function listener(nonza) {
if (nonza.is("enabled", NS)) {
resolve(nonza);
} else if (nonza.is("failed", NS)) {
reject(nonza);
} else {
return;
}

entity.removeListener("nonza", listener);
function enable(entity, sm) {
return procedure(entity, makeEnableElement({ sm }), (element, stop) => {
if (element.is("enabled", NS)) {
return stop(element);
} else if (element.is("failed", NS)) {
throw XMPPError.fromElement(element);
}

entity.on("nonza", listener);
});
}

async function resume(entity, sm) {
const response = await entity.sendReceive(makeResumeElement({ sm }));

if (!response.is("resumed", NS)) {
throw response;
}

return response;
return procedure(entity, makeResumeElement({ sm }), (element, stop) => {
if (element.is("resumed", NS)) {
return stop(element);
} else if (element.is("failed", NS)) {
throw XMPPError.fromElement(element);
}
});
}

export default function streamManagement({
Expand Down
2 changes: 2 additions & 0 deletions packages/stream-management/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
"management"
],
"dependencies": {
"@xmpp/error": "^0.14.0",
"@xmpp/events": "^0.14.0",
"@xmpp/xml": "^0.14.0"
},
"engines": {
Expand Down
8 changes: 0 additions & 8 deletions packages/stream-management/stream-features.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ test("enable - enabled", async () => {
<enable xmlns="urn:xmpp:sm:3" resume="true" />,
);

await tick();

expect(entity.streamManagement.outbound).toBe(0);
expect(entity.streamManagement.enabled).toBe(false);
expect(entity.streamManagement.id).toBe("");
Expand Down Expand Up @@ -56,8 +54,6 @@ test("enable - send rejects", async () => {
/>,
);

await tick();

expect(entity.streamManagement.enabled).toBe(false);
});

Expand All @@ -80,8 +76,6 @@ test("enable - message - enabled", async () => {
expect(entity.streamManagement.enabled).toBe(false);
expect(entity.streamManagement.id).toBe("");

await tick();

entity.mockInput(<message />);

expect(entity.streamManagement.enabled).toBe(false);
Expand Down Expand Up @@ -120,8 +114,6 @@ test("enable - failed", async () => {
expect(entity.streamManagement.outbound).toBe(0);
entity.streamManagement.enabled = true;

await tick();

entity.mockInput(<failed xmlns="urn:xmpp:sm:3" />);

await tick();
Expand Down

0 comments on commit 532204c

Please sign in to comment.