Files
CT/src/Model/Global/fileTransferModel.ts
T

132 lines
3.5 KiB
TypeScript
Raw Normal View History

2024-07-27 17:03:52 +02:00
// this file is responsible for sending and handling files.
2024-07-28 03:46:08 +02:00
import {
HandlerManager,
generateRandomToken,
parse,
stringify,
} from "../Utility/utility";
2024-07-27 18:03:12 +02:00
import { decryptString, encryptString } from "../Utility/crypto";
2024-07-27 17:03:52 +02:00
import ConnectionModel from "./connectionModel";
2024-07-27 18:03:12 +02:00
import { Message } from "udn-frontend";
2024-07-27 17:03:52 +02:00
import StorageModel from "./storageModel";
2024-07-27 18:03:12 +02:00
import { checkMatchesObjectStructure } from "../Utility/typeSafety";
2024-07-27 17:03:52 +02:00
export default class FileTransferModel {
2024-07-27 17:41:54 +02:00
storageModel: StorageModel;
connectionModel: ConnectionModel;
2024-07-27 18:03:12 +02:00
// data
transferData: TransferData | undefined;
2024-07-28 03:46:08 +02:00
fileHandlerManager: HandlerManager<string> = new HandlerManager();
2024-07-27 18:03:12 +02:00
// general
2024-07-27 17:41:54 +02:00
generateTransferData = (): TransferData => {
2024-07-28 00:25:51 +02:00
const transferData: TransferData = {
2024-07-28 03:46:08 +02:00
channel: generateRandomToken(2).substring(0, 4),
key: generateRandomToken(3).substring(0, 6),
2024-07-27 17:41:54 +02:00
};
2024-07-28 00:25:51 +02:00
this.transferData = transferData;
return transferData;
2024-07-27 17:41:54 +02:00
};
2024-07-27 18:03:12 +02:00
prepareToReceive = (transferData: TransferData) => {
this.connectionModel.addChannel(transferData.channel);
this.transferData = transferData;
};
// handlers
handleMessage = (data: Message): void => {
if (this.transferData == undefined) return;
2024-07-28 03:46:08 +02:00
if (data.messageBody == undefined) return;
2024-07-27 18:03:12 +02:00
if (data.messageChannel != this.transferData.channel) return;
2024-07-28 03:46:08 +02:00
this.handleFile(data.messageBody);
2024-07-27 18:03:12 +02:00
};
handleFile = async (encryptedFileData: string): Promise<void> => {
if (this.transferData == undefined) return;
const decrypted: string = await decryptString(
encryptedFileData,
this.transferData.key
);
2024-07-28 03:46:08 +02:00
console.log(decrypted);
2024-07-28 00:25:51 +02:00
2024-07-27 18:03:12 +02:00
const parsed: any = parse(decrypted);
2024-07-28 00:25:51 +02:00
const isFileData: boolean = checkMatchesObjectStructure(
parsed,
FileDataReference
);
2024-07-27 18:03:12 +02:00
if (isFileData == false) return;
2024-07-28 00:25:51 +02:00
2024-07-27 18:03:12 +02:00
const fileData: FileData = parsed;
this.storageModel.write(fileData.path, fileData.body);
2024-07-28 03:46:08 +02:00
const pathString: string = StorageModel.pathComponentsToString(
...fileData.path
);
this.fileHandlerManager.trigger(pathString);
2024-07-27 18:03:12 +02:00
};
// sending
2024-07-28 02:27:09 +02:00
sendFiles = (
directoryPaths: BuiltinIterator<string[]>,
callback: (path: string) => void
): void => {
2024-07-27 18:03:12 +02:00
for (const directoryPath of directoryPaths) {
this.storageModel.recurse(directoryPath, (filePath: string[]) => {
this.sendFile(filePath);
2024-07-28 02:27:09 +02:00
const pathString: string = StorageModel.pathComponentsToString(
...filePath
);
callback(pathString);
2024-07-27 18:03:12 +02:00
});
}
};
sendFile = async (filePath: string[]): Promise<void> => {
if (this.transferData == undefined) return;
const fileContent: string | null = this.storageModel.read(filePath);
if (fileContent == null) return;
const fileData: FileData = {
path: filePath,
body: fileContent,
};
const stringifiedFileData: string = stringify(fileData);
const encryptedFileData: string = await encryptString(
2024-07-28 03:46:08 +02:00
stringifiedFileData,
this.transferData.key
2024-07-27 18:03:12 +02:00
);
this.connectionModel.sendPlainMessage(
this.transferData.channel,
encryptedFileData
);
};
2024-07-27 17:41:54 +02:00
// init
constructor(storageModel: StorageModel, connectionModel: ConnectionModel) {
this.storageModel = storageModel;
this.connectionModel = connectionModel;
2024-07-27 18:03:12 +02:00
this.connectionModel.messageHandlerManager.addHandler(this.handleMessage);
2024-07-27 17:41:54 +02:00
}
}
export interface TransferData {
channel: string;
key: string;
}
2024-07-27 18:03:12 +02:00
export interface FileData {
path: string[];
body: string;
}
export const FileDataReference: FileData = {
path: [""],
body: "",
};