Skip to content

Commit

Permalink
spec-suggested character mapping for virtual localparts
Browse files Browse the repository at this point in the history
  • Loading branch information
kbleeke committed Oct 1, 2023
1 parent 513337f commit 24e8591
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 3 deletions.
52 changes: 52 additions & 0 deletions spec/unit/IrcServer.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,5 +69,57 @@ describe("IrcServer", function() {
);
expect(() => {server.getNick("@💩ケ:foobar")}).toThrow();
});
})
describe("getUserLocalpart", function() {
it("does not touch valid characters", function() {
const server = new IrcServer("irc.foobar",
extend(true, IrcServer.DEFAULT_CONFIG, {})
);
expect(server.getUserLocalpart("foobar09.-+")).toEqual("irc.foobar_foobar09.-+");
});
it("encodes capital letters", function() {
const server = new IrcServer("irc.foobar",
extend(true, IrcServer.DEFAULT_CONFIG, {})
);
expect(server.getUserLocalpart("foOBaR_09.-+")).toEqual("irc.foobar_fo_o_ba_r__09.-+");
});
it("encodes invalid characters", function() {
const server = new IrcServer("irc.foobar",
extend(true, IrcServer.DEFAULT_CONFIG, {})
);
expect(server.getUserLocalpart("foobar=[m]")).toEqual("irc.foobar_foobar=3d=5bm=5d");
});
it("encodes both capital letters and invalid chars", function() {
const server = new IrcServer("irc.foobar",
extend(true, IrcServer.DEFAULT_CONFIG, {})
);
expect(server.getUserLocalpart("f_oObAr=[m]")).toEqual("irc.foobar_f__o_ob_ar=3d=5bm=5d");
});
});
describe("getNickFromUserId", function() {
it("does not touch valid characters", function() {
const server = new IrcServer("irc.foobar",
extend(true, IrcServer.DEFAULT_CONFIG, {})
);
expect(server.getNickFromUserId("irc.foobar_foobar09.-+")).toEqual("foobar09.-+");
});
it("encodes capital letters", function() {
const server = new IrcServer("irc.foobar",
extend(true, IrcServer.DEFAULT_CONFIG, {})
);
expect(server.getNickFromUserId("irc.foobar_fo_o_ba_r__09.-+")).toEqual("foOBaR_09.-+");
});
it("decodes invalid characters", function() {
const server = new IrcServer("irc.foobar",
extend(true, IrcServer.DEFAULT_CONFIG, {})
);
expect(server.getNickFromUserId("irc.foobar_foobar=3d=5bm=5d")).toEqual("foobar=[m]");
});
it("encodes both capital letters and invalid chars", function() {
const server = new IrcServer("irc.foobar",
extend(true, IrcServer.DEFAULT_CONFIG, {})
);
expect(server.getNickFromUserId("irc.foobar_f__o_ob_ar=3d=5bm=5d")).toEqual("f_oObAr=[m]");
});
});
});
19 changes: 16 additions & 3 deletions src/irc/IrcServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -545,10 +545,16 @@ export class IrcServer {
public getUserLocalpart(nick: string): string {
// the template is just a literal string with special vars; so find/replace
// the vars and strip the @

// https://spec.matrix.org/v1.8/appendices/#mapping-from-other-character-sets
const escaped = nick.replaceAll(/[A-Z_]/g, (c) => "_" + c.toLowerCase());
const escaped2 = escaped.replaceAll(/[^a-z0-9\.\_\-\/+]/g,
(c) => "=" + c.charCodeAt(0).toString(16).padStart(2, '0'));

return renderTemplate(this.config.matrixClients.userTemplate, {
server: this.domain,
nick,
}).substring(1).toLowerCase(); // the first character is guaranteed by config schema to be '@'
nick: escaped2,
}).substring(1); // the first character is guaranteed by config schema to be '@'
}

public claimsUserId(userId: string): boolean {
Expand Down Expand Up @@ -582,7 +588,14 @@ export class IrcServer {
if (!match) {
return null;
}
return match[1];

// https://spec.matrix.org/v1.8/appendices/#mapping-from-other-character-sets
const unescaped = match[1].replaceAll(/=([0-9a-f][0-9a-f])/g,
(_m, g1) => String.fromCharCode(parseInt(g1, 16)));

const unescaped2 = unescaped.replaceAll(/_([a-z_])/g, (m, g1) => g1.toUppercose());

return unescaped2;
}

public getUserIdFromNick(nick: string): string {
Expand Down

0 comments on commit 24e8591

Please sign in to comment.