import * as log from "loglevel"; import { ChatMessageDTO } from "../dto/ChatMessageDTO"; import { EncryptionService } from "../service/EncryptionService"; import { NotificationService } from "../service/NotificationService"; import { JsonAPI } from "../singleton/JsonAPI"; import { Sprintf } from "../singleton/Sprintf"; import { ChatMessageViewModel } from "../viewmodel/ChatMessageViewModel"; import { fetchErrorHandler } from "./FetchErrorHandler"; export class ChatModelHelper { private readonly _encryptionService: EncryptionService; private readonly _notificationService: NotificationService; constructor( encryptionService: EncryptionService, notificationService: NotificationService ) { this._encryptionService = encryptionService; this._notificationService = notificationService; } public async getMessages( userName: string, passphrase: string, page: number | null, lastMessageTime: Date | null, op: string ): Promise { switch (op) { case "page": { const data: ChatMessageDTO[] = await this._getPaginatedMessagesAjax( userName, page! ); const cVMs = Promise.all( data.map((vm) => this._toChatMessageVMAsync(vm, passphrase)).reverse() ); return cVMs; } case "new": { const data: ChatMessageDTO[] = await this._getPaginatedMessagesAjax( userName, page! ); const cVMs = Promise.all( data.map((vm) => this._toChatMessageVMAsync(vm, passphrase)).reverse() ); return cVMs; } case "update": { const data: ChatMessageDTO[] = await this._getNewMessagesAjax( userName, lastMessageTime! ); const cVMs = Promise.all( data.map((vm) => this._toChatMessageVMAsync(vm, passphrase)).reverse() ); return cVMs; } default: { log.error("Invalid operation"); return Array(); } } } public async isPassphraseValid( passphrase: string, userName: string ): Promise { const messages: ChatMessageDTO[] = await this._getPaginatedMessagesAjax( userName, 0 ); if (messages.length === 0) return true; try { this._encryptionService.decrypt(passphrase, messages[0].messageCipher); } catch (error) { return false; } return true; } private async _toChatMessageVMAsync( chatMessageDTO: ChatMessageDTO, passphrase: string ): Promise { const vm = new ChatMessageViewModel(); vm.fromUser = chatMessageDTO.fromUser; vm.toUser = chatMessageDTO.toUser; // vm.messageTime = chatMessageDTO.messageTime; chatMessageDTO.messageTime == null ? log.error("Message time somehow null") : (vm.messageTime = chatMessageDTO.messageTime); vm.message = await this._encryptionService.decryptAsPromise( passphrase, chatMessageDTO.messageCipher ); return vm; } private _toChatMessageVM( chatMessageDTO: ChatMessageDTO, passphrase: string ): ChatMessageViewModel { const vm = new ChatMessageViewModel(); vm.fromUser = chatMessageDTO.fromUser; vm.toUser = chatMessageDTO.toUser; // vm.messageTime = chatMessageDTO.messageTime; chatMessageDTO.messageTime == null ? log.error("Message time somehow null") : (vm.messageTime = chatMessageDTO.messageTime); vm.message = this._encryptionService.decrypt( passphrase, chatMessageDTO.messageCipher ) as string; return vm; } private async _getAllMessagesAjax(toUser: string): Promise { const headers = new Headers(); if (JsonAPI.authToken == null) { log.error("authToken null"); return; } headers.append("X-AUTH-TOKEN", JsonAPI.authToken); const url = Sprintf(JsonAPI.CHAT_MESSAGES_GET, toUser); log.debug(url); const response = await fetch(url, { method: "GET", headers: headers, }); log.debug(response.clone()); if (fetchErrorHandler(response.clone(), this._notificationService)) { return null; } const data: Promise = await response.json(); return data; } private async _getPaginatedMessagesAjax( toUser: string, page: number ): Promise { const headers = new Headers(); if (JsonAPI.authToken == null) { log.error("authToken null"); return; } headers.append("X-AUTH-TOKEN", JsonAPI.authToken); const url = Sprintf(JsonAPI.CHAT_MESSAGE_PAGE_GET, toUser, page, JsonAPI.CHAT_PAGE_SIZE); log.debug(url); const response = await fetch(url, { method: "GET", headers: headers, }); log.debug(response.clone()); if (fetchErrorHandler(response.clone(), this._notificationService)) { return null; } const data: Promise = await response.json(); function func(data: any) { const d1 = data.map((d: any) => { if (d.messageTime == null) return null; d.messageTime = new Date(d.messageTime); return d; }); return d1; } const data2 = func(data); return data2; } private async _getMessagesAjax( toUser: string, lastMessageTimeStamp: Date ): Promise { const headers = new Headers(); if (JsonAPI.authToken == null) { log.error("authToken null"); return; } headers.append("X-AUTH-TOKEN", JsonAPI.authToken); // const url = Sprintf(JsonAPI.CHAT_MESSAGES_GET, toUser, page, 5); // log.debug(url) const response = await fetch(`/api/chat/get/messages/${toUser}`, { method: "GET", headers: headers, }); log.debug(response.clone()); if (fetchErrorHandler(response.clone(), this._notificationService)) { return null; } const data: Promise = await response.json(); function func(data: any) { const d1 = data.map((d: any) => { if (d.messageTime == null) return null; d.messageTime = new Date(d.messageTime); return d; }); return d1; } const data2 = func(data); return data2; } private async _getNewMessagesAjax( toUser: string, lastMessageTimeStamp: Date ): Promise { const headers = new Headers(); headers.append("X-AUTH-TOKEN", JsonAPI.authToken); // const url = Sprintf(JsonAPI.CHAT_MESSAGES_GET, toUser, page, 5); // log.debug(url) // log.debug(lastMessageTimeStamp); // log.debug(lastMessageTimeStamp.toISOString()) const response = await fetch( `/api/chat/get/messages/${toUser}/${lastMessageTimeStamp.toISOString()}`, { method: "GET", headers: headers, } ); log.debug(response.clone()); if(!response.ok) location.reload(); const data: Promise = await response.json(); function func(data: any) { const d1 = data.map((d: any) => { if (d.messageTime == null) return null; d.messageTime = new Date(d.messageTime); return d; }); return d1; } const data2 = func(data); return data2; } }