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

117 lines
3.1 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-27 18:03:12 +02:00
import { decryptString, encryptString } from "../Utility/crypto";
import { generateRandomToken, parse, stringify } from "../Utility/utility";
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;
// general
2024-07-27 17:41:54 +02:00
generateTransferData = (): TransferData => {
2024-07-28 00:25:51 +02:00
const transferData: TransferData = {
2024-07-27 17:41:54 +02:00
channel: generateRandomToken(2),
key: generateRandomToken(3),
};
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;
if (data.messageChannel != this.transferData.channel) return;
};
handleFile = async (encryptedFileData: string): Promise<void> => {
if (this.transferData == undefined) return;
const decrypted: string = await decryptString(
encryptedFileData,
this.transferData.key
);
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);
};
// 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(
fileContent,
stringifiedFileData
);
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: "",
};