chamesu
Version:
This package contains all packages of the chat application.
181 lines (142 loc) • 4.96 kB
text/typescript
/*
* Copyright (c) 2022.
* Author Peter Placzek (tada5hi)
* For the full copyright and license information,
* view the LICENSE file that was distributed with this source code.
*/
import {AuthContact} from "@chamesu/common/domains/auth/contact";
import localforage from "localforage";
import {getters, mutations} from "~/modules/security/store";
import {
createSymmetricEncryptionKey,
decryptMessageSymmetric,
encryptMessageSymmetric
} from "~/modules/security/encryption/utils";
import {addContactData} from "~/domains/contact-data/api";
import {encodeContactMessage} from "~/domains/contact/encryption";
import {getRoomMemberContacts} from "~/domains/chat-room/api";
import {ContactDataSecretType} from "~/domains/contact-data/utils";
export function encodeChatRoomMessage(message: string, roomId: string) {
const symmetricKey : string | undefined = getters.roomKey(roomId);
if(typeof symmetricKey === 'undefined') {
throw new Error('Die benötigte symmetrische Schlüssel existiert nicht...');
}
return encryptMessageSymmetric(message, symmetricKey);
}
export function decodeChatRoomMessage(message: string, roomId: string) {
const symmetricKey : string | undefined = getters.roomKey(roomId);
if(typeof symmetricKey === 'undefined') {
throw new Error('Die benötigte symmetrische Schlüssel existiert nicht...');
}
return decryptMessageSymmetric(message, symmetricKey);
}
//
export async function createAndSaveChatRoomKey(roomId: string) {
const key = createSymmetricEncryptionKey();
await saveChatRoomKey(roomId, key);
return key;
}
export async function saveChatRoomKey(roomId: string, key: string) {
await (await useChatRoomKeyStorage()).setItem(roomId, key);
mutations.setChatRoomKey(roomId, key);
}
export async function dropChatRoomKey(roomId: string) {
await (await useChatRoomKeyStorage()).removeItem(roomId);
}
export async function getChatRoomKey(roomId: string) : Promise<string|undefined> {
const key = await (await useChatRoomKeyStorage())
.getItem<string>(roomId);
if(!key) {
return undefined;
}
return key;
}
//-------------------------------------------------------------------
/**
* Share chat room key with specific contact
*
* @param contactId
* @param roomId
* @param key
*/
export async function shareChatRoomKey(contactId: string, roomId: string, key?: string) {
key = typeof key === 'undefined' ? await getChatRoomKey(roomId) : key;
const data = {
roomId,
key: key
};
try {
const content = encodeContactMessage(JSON.stringify(data), contactId);
await addContactData({
type: ContactDataSecretType.ROOM,
content: content,
encrypted: true,
contactId: contactId
});
} catch (e) {
await addContactData({
type: ContactDataSecretType.ROOM,
content: data,
encrypted: false,
contactId: contactId
});
}
}
/**
* Share a chat secret key request with a specific contact.
*
* @param contactId
* @param roomId
*/
export async function shareChatRoomKeyRequest(contactId: string, roomId: string) {
await addContactData({
type: ContactDataSecretType.ROOM_REQUEST,
content: {
roomId
},
encrypted: false,
contactId: contactId
});
}
//-------------------------------------------------------------------
export async function createAndShareRoomKeyToContacts(roomId: string) {
const response = await getRoomMemberContacts(roomId);
const key = await createAndSaveChatRoomKey(roomId);
for(let i=0; i<response.data.length; i++) {
await shareChatRoomKey(response.data[i].id, roomId, key);
}
}
export async function searchAndShareChatRoomKeyRequest(roomId: string) {
const response = await getRoomMemberContacts(roomId, {
page: {
limit: 1
}
});
if(response.data.length !== 1) {
return;
}
const contact : AuthContact = response.data.pop() as AuthContact;
await shareChatRoomKeyRequest(contact.id, roomId);
}
let chatRoomKeyStorage : undefined | LocalForage;
export async function useChatRoomKeyStorage() : Promise<LocalForage> {
if(typeof chatRoomKeyStorage !== 'undefined') {
return chatRoomKeyStorage;
}
chatRoomKeyStorage = localforage.createInstance({
driver: localforage.INDEXEDDB,
name: 'app',
storeName: 'chatRoomKeys'
});
initChatRoomKeys(chatRoomKeyStorage)
.then(r => r);
return chatRoomKeyStorage;
}
async function initChatRoomKeys(storage: LocalForage) {
const keys : string[] = await storage.keys();
for(let i=0; i<keys.length; i++) {
const key : string = keys[i];
const secret = <string> await storage.getItem(key);
mutations.setChatRoomKey(key, secret);
}
}