Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
17 changes: 13 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,21 @@ increase its availability and avoid tampering.

The matrix.to URL scheme is

| Entity type: | Example URL |
|--------------|---------------------------------------------------------------------|
| Rooms: | <https://matrix.to/#/r/matrix:matrix.org> |
| Rooms by ID: | <https://matrix.to/#/roomid/cURbafjkfsMDVwdRDQ:matrix.org> |
| Users: | <https://matrix.to/#/u/matthew:matrix.org> |
| Messages: | <https://matrix.to/#/r/matrix:matrix.org/e/1448831580433WbpiJ:jki.re> |

The legacy scheme is deprecated, but as follows

| Entity type: | Example URL |
|--------------|-------------------------------------------------------------------|
| Rooms: | https://matrix.to/#/#matrix:matrix.org |
| Rooms by ID: | https://matrix.to/#/!cURbafjkfsMDVwdRDQ:matrix.org |
| Users: | https://matrix.to/#/@matthew:matrix.org |
| Messages: | https://matrix.to/#/#matrix:matrix.org/$1448831580433WbpiJ:jki.re |
| Rooms: | <https://matrix.to/#/#matrix:matrix.org> |
| Rooms by ID: | <https://matrix.to/#/!cURbafjkfsMDVwdRDQ:matrix.org> |
| Users: | <https://matrix.to/#/@matthew:matrix.org> |
| Messages: | <https://matrix.to/#/#matrix:matrix.org/$1448831580433WbpiJ:jki.re> |

The #/ component is mandatory and exists to avoid leaking the target URL to the
server hosting matrix.to.
Expand Down
40 changes: 33 additions & 7 deletions src/Link.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ limitations under the License.
import {createEnum} from "./utils/enum.js";
import {orderedUnique} from "./utils/unique.js";

const ROOMALIAS_PATTERN = /^#([^:]*):(.+)$/;
const ROOMID_PATTERN = /^!([^:]*)(:(.+))?$/; // As of room version 12, room IDs don't have domains
const USERID_PATTERN = /^@([^:]+):(.+)$/;
const EVENTID_PATTERN = /^$([^:]+):(.+)$/;
const ROOMALIAS_PATTERN = /^(?:#|r\/)([^:]*):(.+)$/;
const ROOMID_PATTERN = /^(?:!|roomid\/)([^:]*)(:(.+))?$/; // As of room version 12, room IDs don't have domains
const USERID_PATTERN = /^(?:@|u\/)([^:]+):(.+)$/;
const EVENTID_PATTERN = /^(?:$|e\/)([^:]+):(.+)$/;
const GROUPID_PATTERN = /^\+([^:]+):(.+)$/;

export const IdentifierKind = createEnum(
Expand All @@ -40,6 +40,16 @@ function asPrefix(identifierKind) {
}
}

function asMSC4481Prefix(identifierKind) {
switch (identifierKind) {
case IdentifierKind.RoomId: return "roomid/";
case IdentifierKind.RoomAlias: return "r/";
case IdentifierKind.GroupId: return asPrefix(identifierKind);
case IdentifierKind.UserId: return "u/";
default: throw new Error("invalid id kind " + identifierKind);
}
}

function getWebInstanceMap(queryParams) {
const prefix = "web-instance[";
const postfix = "]";
Expand Down Expand Up @@ -111,7 +121,22 @@ export class Link {
return null;
}
linkStr = linkStr.slice(2);
const [identifier, eventId] = linkStr.split("/");
const segments = linkStr.split("/");
let _1, identifier, _2, eventId;
if (/^(roomid|r|u)/.test(linkStr)) {
[_1, identifier, _2, eventId] = segments;
if (_1 === "roomid")
identifier = "!" + identifier;
else if (_1 === "r")
identifier = "#" + identifier;
else
identifier = "@" + identifier;

if (_2 === "e")
eventId = "$" + eventId;
} else {
[identifier, eventId] = segments;
}

let viaServers = [];
let clientId = null;
Expand Down Expand Up @@ -210,10 +235,11 @@ export class Link {
}

toFragment() {
const id = `/${asMSC4481Prefix(this.identifierKind)}${this.identifier.substring(1)}`;
if (this.eventId) {
return `/${this.identifier}/${this.eventId}`;
return `${id}/e/${this.eventId.substring(1)}`;
} else {
return `/${this.identifier}`;
return id;
}
}
}
4 changes: 2 additions & 2 deletions src/create/CreateLinkView.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export class CreateLinkView extends TemplateView {
type: "text",
name: "identifier",
required: true,
placeholder: "#room:example.com, @user:example.com",
placeholder: "r/room:example.com, u/user:example.com",
onChange: evt => this._onIdentifierChange(evt)
})),
t.div(t.input({className: "primary fullwidth icon link", type: "submit", value: "Create link"}))
Expand All @@ -48,7 +48,7 @@ export class CreateLinkView extends TemplateView {
_onIdentifierChange(evt) {
const inputField = evt.target;
if (!this.value.validateIdentifier(inputField.value)) {
inputField.setCustomValidity("That doesn't seem valid. Try #room:example.com, @user:example.com or +group:example.com.");
inputField.setCustomValidity("That doesn't seem valid. Try r/room:example.com, u/user:example.com or +group:example.com.");
} else {
inputField.setCustomValidity("");
}
Expand Down
2 changes: 1 addition & 1 deletion src/create/CreateLinkViewModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export class CreateLinkViewModel extends ViewModel {
}

async createLink(identifier) {
this._link = Link.parseIdentifier(identifier);
this._link = Link.parseFragment(`#/${identifier}`);
if (this._link) {
this.openLink("#" + this._link.toFragment());
}
Expand Down