2020-09-12 04:49:48 +03:00
|
|
|
/*
|
|
|
|
Copyright 2020 The Matrix.org Foundation C.I.C.
|
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
import EventEmitter from "events";
|
2020-09-12 06:05:54 +03:00
|
|
|
import { base32 } from "rfc4648";
|
2021-09-17 12:19:30 +03:00
|
|
|
import { RoomType } from "matrix-js-sdk/src/@types/event";
|
2020-09-12 04:49:48 +03:00
|
|
|
|
|
|
|
// Dev note: the interface is split in two so we don't have to disable the
|
|
|
|
// linter across the whole project.
|
|
|
|
export interface IThreepidInviteWireFormat {
|
|
|
|
email: string;
|
|
|
|
signurl: string;
|
2020-09-12 06:05:54 +03:00
|
|
|
room_name: string; // eslint-disable-line camelcase
|
|
|
|
room_avatar_url: string; // eslint-disable-line camelcase
|
|
|
|
inviter_name: string; // eslint-disable-line camelcase
|
2020-09-12 04:49:48 +03:00
|
|
|
|
|
|
|
// TODO: Figure out if these are ever populated
|
2020-09-12 06:05:54 +03:00
|
|
|
guest_access_token?: string; // eslint-disable-line camelcase
|
|
|
|
guest_user_id?: string; // eslint-disable-line camelcase
|
2020-09-12 04:49:48 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
interface IPersistedThreepidInvite extends IThreepidInviteWireFormat {
|
|
|
|
roomId: string;
|
|
|
|
}
|
|
|
|
|
|
|
|
export interface IThreepidInvite {
|
|
|
|
id: string; // generated by us
|
|
|
|
roomId: string;
|
|
|
|
toEmail: string;
|
|
|
|
signUrl: string;
|
|
|
|
roomName: string;
|
|
|
|
roomAvatarUrl: string;
|
|
|
|
inviterName: string;
|
|
|
|
}
|
|
|
|
|
2021-07-01 21:54:05 +03:00
|
|
|
// Any data about the room that would normally come from the homeserver
|
|
|
|
// but has been passed out-of-band, eg. the room name and avatar URL
|
|
|
|
// from an email invite (a workaround for the fact that we can't
|
|
|
|
// get this information from the HS using an email invite).
|
|
|
|
export interface IOOBData {
|
|
|
|
name?: string; // The room's name
|
|
|
|
avatarUrl?: string; // The mxc:// avatar URL for the room
|
|
|
|
inviterName?: string; // The display name of the person who invited us to the room
|
2021-09-16 13:07:59 +03:00
|
|
|
// eslint-disable-next-line camelcase
|
|
|
|
room_name?: string; // The name of the room, to be used until we are told better by the server
|
2022-10-24 11:58:36 +03:00
|
|
|
roomType?: RoomType | string; // The type of the room, to be used until we are told better by the server
|
2021-07-01 21:54:05 +03:00
|
|
|
}
|
|
|
|
|
2020-09-12 04:49:48 +03:00
|
|
|
const STORAGE_PREFIX = "mx_threepid_invite_";
|
|
|
|
|
|
|
|
export default class ThreepidInviteStore extends EventEmitter {
|
|
|
|
private static _instance: ThreepidInviteStore;
|
|
|
|
|
|
|
|
public static get instance(): ThreepidInviteStore {
|
|
|
|
if (!ThreepidInviteStore._instance) {
|
|
|
|
ThreepidInviteStore._instance = new ThreepidInviteStore();
|
|
|
|
}
|
|
|
|
return ThreepidInviteStore._instance;
|
|
|
|
}
|
|
|
|
|
|
|
|
public storeInvite(roomId: string, wireInvite: IThreepidInviteWireFormat): IThreepidInvite {
|
2021-06-29 15:11:58 +03:00
|
|
|
const invite = <IPersistedThreepidInvite>{ roomId, ...wireInvite };
|
2020-09-12 04:49:48 +03:00
|
|
|
const id = this.generateIdOf(invite);
|
|
|
|
localStorage.setItem(`${STORAGE_PREFIX}${id}`, JSON.stringify(invite));
|
|
|
|
return this.translateInvite(invite);
|
|
|
|
}
|
|
|
|
|
2020-09-12 05:20:33 +03:00
|
|
|
public getWireInvites(): IPersistedThreepidInvite[] {
|
|
|
|
const results: IPersistedThreepidInvite[] = [];
|
2020-09-12 04:49:48 +03:00
|
|
|
for (let i = 0; i < localStorage.length; i++) {
|
|
|
|
const keyName = localStorage.key(i);
|
2023-02-24 18:28:40 +03:00
|
|
|
if (!keyName?.startsWith(STORAGE_PREFIX)) continue;
|
2020-09-12 05:20:33 +03:00
|
|
|
results.push(JSON.parse(localStorage.getItem(keyName)) as IPersistedThreepidInvite);
|
2020-09-12 04:49:48 +03:00
|
|
|
}
|
2020-09-12 05:20:33 +03:00
|
|
|
return results;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getInvites(): IThreepidInvite[] {
|
2022-12-12 14:24:14 +03:00
|
|
|
return this.getWireInvites().map((i) => this.translateInvite(i));
|
2020-09-12 04:49:48 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// Currently Element can only handle one invite at a time, so handle that
|
|
|
|
public pickBestInvite(): IThreepidInvite {
|
|
|
|
return this.getInvites()[0];
|
|
|
|
}
|
|
|
|
|
2023-01-12 16:25:14 +03:00
|
|
|
public resolveInvite(invite: IThreepidInvite): void {
|
2020-09-12 04:49:48 +03:00
|
|
|
localStorage.removeItem(`${STORAGE_PREFIX}${invite.id}`);
|
|
|
|
}
|
|
|
|
|
|
|
|
private generateIdOf(persisted: IPersistedThreepidInvite): string {
|
|
|
|
// Use a consistent "hash" to form an ID.
|
|
|
|
return base32.stringify(Buffer.from(JSON.stringify(persisted)));
|
|
|
|
}
|
|
|
|
|
|
|
|
private translateInvite(persisted: IPersistedThreepidInvite): IThreepidInvite {
|
|
|
|
return {
|
|
|
|
id: this.generateIdOf(persisted),
|
|
|
|
roomId: persisted.roomId,
|
|
|
|
toEmail: persisted.email,
|
|
|
|
signUrl: persisted.signurl,
|
|
|
|
roomName: persisted.room_name,
|
|
|
|
roomAvatarUrl: persisted.room_avatar_url,
|
|
|
|
inviterName: persisted.inviter_name,
|
|
|
|
};
|
|
|
|
}
|
2020-09-12 05:20:33 +03:00
|
|
|
|
|
|
|
public translateToWireFormat(invite: IThreepidInvite): IThreepidInviteWireFormat {
|
|
|
|
return {
|
|
|
|
email: invite.toEmail,
|
|
|
|
signurl: invite.signUrl,
|
|
|
|
room_name: invite.roomName,
|
|
|
|
room_avatar_url: invite.roomAvatarUrl,
|
|
|
|
inviter_name: invite.inviterName,
|
|
|
|
};
|
|
|
|
}
|
2020-09-12 04:49:48 +03:00
|
|
|
}
|