import { mockClient, promise } from "@xmpp/test";
const username = "foo";
const password = "bar";
const credentials = { username, password };
const userAgent = (
software
device
);
test("No compatible mechanism available", async () => {
const { entity } = mockClient({ username, password });
entity.mockInput(
FOO
,
);
const error = await promise(entity, "error");
expect(error instanceof Error).toBe(true);
expect(error.message).toBe("SASL: No compatible mechanism available.");
});
test("with object credentials", async () => {
const { entity } = mockClient({ credentials, userAgent });
entity.mockInput(
PLAIN
,
);
expect(await promise(entity, "send")).toEqual(
AGZvbwBiYXI=
{userAgent}
,
);
const jid = "username@localhost/example~Ln8YSSzsyK-b_3-vIFvOJNnE";
expect(entity.jid?.toString()).not.toBe(jid);
entity.mockInput(
{jid}
,
);
expect(entity.jid.toString()).toBe(jid);
});
test("with function credentials", async () => {
const mech = "PLAIN";
const userAgent = (
xmpp.js
Sonny's Laptop
);
function onAuthenticate(authenticate, mechanisms) {
expect(mechanisms).toEqual([mech]);
return authenticate(credentials, mech, userAgent);
}
const { entity } = mockClient({ credentials: onAuthenticate });
entity.mockInput(
{mech}
,
);
expect(await promise(entity, "send")).toEqual(
AGZvbwBiYXI=
{userAgent}
,
);
const jid = "username@localhost/example~Ln8YSSzsyK-b_3-vIFvOJNnE";
expect(entity.jid?.toString()).not.toBe(jid);
entity.mockInput(
{jid}
,
);
expect(entity.jid.toString()).toBe(jid);
});
// https://github.com/xmppjs/xmpp.js/pull/1045#discussion_r1904611099
test("with FAST token only", async () => {
const mech = "HT-SHA-256-NONE";
function onAuthenticate(authenticate, mechanisms, fast) {
expect(mechanisms).toEqual([]);
expect(fast.mechanism).toEqual(mech);
return authenticate(
{
token: {
token: "hai",
mechanism: fast.mechanism,
},
},
null,
userAgent,
);
}
const { entity } = mockClient({ credentials: onAuthenticate });
entity.mockInput(
{mech}
,
);
expect(await promise(entity, "send")).toEqual(
bnVsbACNMNimsTBnxS04m8x7wgKjBHdDUL/nXPU4J4vqxqjBIg==
{userAgent}
,
);
const jid = "username@localhost/example~Ln8YSSzsyK-b_3-vIFvOJNnE";
expect(entity.jid?.toString()).not.toBe(jid);
entity.mockInput(
{jid}
,
);
expect(entity.jid.toString()).toBe(jid);
});
test("failure", async () => {
const { entity } = mockClient({ credentials, userAgent });
entity.mockInput(
PLAIN
,
);
expect(await promise(entity, "send")).toEqual(
AGZvbwBiYXI=
{userAgent}
,
);
const failure = (
);
entity.mockInput(failure);
const error = await promise(entity, "error");
expect(error instanceof Error).toBe(true);
expect(error.name).toBe("SASLError");
expect(error.condition).toBe("some-condition");
expect(error.element).toBe(failure);
});
test("prefers SCRAM-SHA-1", async () => {
const { entity } = mockClient({ credentials });
entity.mockInput(
ANONYMOUS
SCRAM-SHA-1
PLAIN
,
);
const result = await promise(entity, "send");
expect(result.attrs.mechanism).toEqual("SCRAM-SHA-1");
});
test("use ANONYMOUS if username and password are not provided", async () => {
const { entity } = mockClient();
entity.mockInput(
ANONYMOUS
PLAIN
SCRAM-SHA-1
,
);
const result = await promise(entity, "send");
expect(result.attrs.mechanism).toEqual("ANONYMOUS");
});