108 lines
3.6 KiB
TypeScript
108 lines
3.6 KiB
TypeScript
|
/*
|
||
|
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";
|
||
|
import { ComponentClass } from "../@types/common";
|
||
|
import { UPDATE_EVENT } from "./AsyncStore";
|
||
|
import { base32, base64 } from "rfc4648";
|
||
|
|
||
|
// 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;
|
||
|
room_name: string;
|
||
|
room_avatar_url: string;
|
||
|
inviter_name: string;
|
||
|
|
||
|
// TODO: Figure out if these are ever populated
|
||
|
guest_access_token?: string;
|
||
|
guest_user_id?: string;
|
||
|
}
|
||
|
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
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 {
|
||
|
console.log("Storing invite: ", {roomId, ...wireInvite});
|
||
|
const invite = <IPersistedThreepidInvite>{roomId, ...wireInvite};
|
||
|
const id = this.generateIdOf(invite);
|
||
|
localStorage.setItem(`${STORAGE_PREFIX}${id}`, JSON.stringify(invite));
|
||
|
return this.translateInvite(invite);
|
||
|
}
|
||
|
|
||
|
public getInvites(): IThreepidInvite[] {
|
||
|
const result: IThreepidInvite[] = [];
|
||
|
for (let i = 0; i < localStorage.length; i++) {
|
||
|
const keyName = localStorage.key(i);
|
||
|
if (!keyName.startsWith(STORAGE_PREFIX)) continue;
|
||
|
|
||
|
const persisted = JSON.parse(localStorage.getItem(keyName)) as IPersistedThreepidInvite;
|
||
|
result.push(this.translateInvite(persisted));
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
// Currently Element can only handle one invite at a time, so handle that
|
||
|
public pickBestInvite(): IThreepidInvite {
|
||
|
return this.getInvites()[0];
|
||
|
}
|
||
|
|
||
|
public resolveInvite(invite: IThreepidInvite) {
|
||
|
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,
|
||
|
};
|
||
|
}
|
||
|
}
|