286 lines
8.8 KiB
TypeScript
286 lines
8.8 KiB
TypeScript
const imageChecker = require("../../utils/imageChecker");
|
|
import crypto from "crypto";
|
|
const videoChecker = require("../../utils/videoChecker");
|
|
const mongoose = require("../../db/mongoose")
|
|
const conn = mongoose.connection;
|
|
const createThumbnail = require("../../services/FileService/utils/createThumbnail");
|
|
import Thumbnail, {ThumbnailInterface} from "../../models/thumbnail";
|
|
const ObjectID = require('mongodb').ObjectID
|
|
import NotAuthorizedError from "../../utils/NotAuthorizedError";
|
|
import NotFoundError from "../../utils/NotFoundError";
|
|
const env = require("../../enviroment/env");
|
|
const jwt = require("jsonwebtoken");
|
|
const removeChunks = require("./utils/removeChunks");
|
|
const User = require("../../models/user");
|
|
|
|
|
|
const Folder = require("../../models/folder");
|
|
const sortBySwitch = require("../../utils/sortBySwitch")
|
|
const createQuery = require("../../utils/createQuery");
|
|
const ffmpeg = require("fluent-ffmpeg");
|
|
const temp = require("temp").track();
|
|
const progress = require("progress-stream");
|
|
const fs = require("fs")
|
|
import DbUtilFile from "../../db/utils/fileUtils/index";
|
|
const DbUtilFolder = require("../../db/utils/folderUtils");
|
|
|
|
const dbUtilsFile = new DbUtilFile();
|
|
const dbUtilsFolder = new DbUtilFolder();
|
|
|
|
import { UserInterface } from "../../models/user";
|
|
import { FileInterface } from "../../models/file";
|
|
|
|
class MongoFileService {
|
|
|
|
constructor() {
|
|
|
|
}
|
|
|
|
getThumbnail = async(user: UserInterface, id: string) => {
|
|
|
|
const password: Buffer = user.getEncryptionKey();
|
|
|
|
const thumbnail = await Thumbnail.findById(id) as ThumbnailInterface;
|
|
|
|
if (thumbnail.owner !== user._id.toString()) {
|
|
|
|
throw new NotAuthorizedError('Thumbnail Unauthorized Error');
|
|
}
|
|
|
|
const iv = thumbnail.data.slice(0, 16);
|
|
|
|
const chunk = thumbnail.data.slice(16);
|
|
|
|
const CIPHER_KEY = crypto.createHash('sha256').update(password).digest()
|
|
|
|
const decipher = crypto.createDecipheriv("aes256", CIPHER_KEY, iv);
|
|
|
|
const decryptedThumbnail = Buffer.concat([decipher.update(chunk), decipher.final()]);
|
|
|
|
return decryptedThumbnail;
|
|
}
|
|
|
|
removePublicOneTimeLink = async(currentFile: FileInterface) => {
|
|
|
|
const fileID = currentFile._id;
|
|
|
|
if (currentFile.metadata.linkType === "one") {
|
|
|
|
await dbUtilsFile.removeOneTimePublicLink(fileID);
|
|
}
|
|
}
|
|
|
|
removeLink = async(userID: string, fileID: string) => {
|
|
|
|
const file = await dbUtilsFile.removeLink(fileID, userID);
|
|
|
|
if (!file.lastErrorObject.updatedExisting) throw new NotFoundError("Remove Link File Not Found Error")
|
|
}
|
|
|
|
makePublic = async(user: UserInterface, fileID: string) => {
|
|
|
|
const userID = user._id;
|
|
const token = await jwt.sign({_id: userID.toString()}, env.password);
|
|
|
|
const file = await dbUtilsFile.makePublic(fileID, userID, token);
|
|
|
|
if (!file.lastErrorObject.updatedExisting) throw new NotFoundError("Make Public File Not Found Error");
|
|
|
|
return token;
|
|
}
|
|
|
|
getPublicInfo = async(fileID: string, tempToken: string) => {
|
|
|
|
const file: FileInterface = await dbUtilsFile.getPublicInfo(fileID, tempToken);
|
|
|
|
if (!file || !file.metadata.link || file.metadata.link !== tempToken) {
|
|
|
|
throw new NotFoundError("Public Info Not Found");
|
|
|
|
} else {
|
|
|
|
return file;
|
|
}
|
|
}
|
|
|
|
makeOneTimePublic = async(userID: string, fileID: string) => {
|
|
|
|
const token = await jwt.sign({_id: userID.toString()}, env.password);
|
|
|
|
const file = await dbUtilsFile.makeOneTimePublic(fileID, userID, token);
|
|
|
|
if (!file.lastErrorObject.updatedExisting) throw new NotFoundError("Make One Time Public Not Found Error");
|
|
|
|
return token;
|
|
}
|
|
|
|
getFileInfo = async(userID: string, fileID: string) => {
|
|
|
|
let currentFile = await dbUtilsFile.getFileInfo(fileID, userID)
|
|
|
|
if (!currentFile) throw new NotFoundError("Get File Info Not Found Error");
|
|
|
|
const parentID = currentFile.metadata.parent
|
|
|
|
let parentName = "";
|
|
|
|
if (parentID === "/") {
|
|
|
|
parentName = "Home"
|
|
|
|
} else {
|
|
|
|
const parentFolder = await Folder.findOne({"owner": userID, "_id": parentID});
|
|
|
|
if (parentFolder) {
|
|
|
|
parentName = parentFolder.name;
|
|
|
|
} else {
|
|
|
|
parentName = "Unknown"
|
|
}
|
|
|
|
}
|
|
|
|
return {...currentFile, parentName}
|
|
}
|
|
|
|
getQuickList = async(userID: string) => {
|
|
|
|
const quickList = await dbUtilsFile.getQuickList(userID);
|
|
|
|
if (!quickList) throw new NotFoundError("Quick List Not Found Error");
|
|
|
|
return quickList;
|
|
}
|
|
|
|
getList = async(userID: string, query: any) => {
|
|
|
|
let searchQuery = query.search || "";
|
|
const parent = query.parent || "/";
|
|
let limit = query.limit || 50;
|
|
let sortBy = query.sortby || "DEFAULT"
|
|
const startAt = query.startAt || undefined
|
|
const startAtDate = query.startAtDate || "0"
|
|
const startAtName = query.startAtName || ""
|
|
sortBy = sortBySwitch(sortBy)
|
|
limit = parseInt(limit)
|
|
|
|
const queryObj = createQuery(userID, parent, query.sortby,startAt, startAtDate, searchQuery, startAtName)
|
|
|
|
const fileList = await dbUtilsFile.getList(queryObj, sortBy, limit);
|
|
|
|
if (!fileList) throw new NotFoundError("File List Not Found");
|
|
|
|
return fileList;
|
|
}
|
|
|
|
getDownloadToken = async(user: UserInterface) => {
|
|
|
|
const tempToken = await user.generateTempAuthToken();
|
|
|
|
if (!tempToken) throw new NotAuthorizedError("Get Download Token Not Authorized Error");
|
|
|
|
return tempToken;
|
|
}
|
|
|
|
getDownloadTokenVideo = async(user: UserInterface, cookie: string) => {
|
|
|
|
if (!cookie) throw new NotAuthorizedError("Get Download Token Video Cookie Not Authorized Error");
|
|
|
|
const tempToken = await user.generateTempAuthTokenVideo(cookie);
|
|
|
|
if (!tempToken) throw new NotAuthorizedError("Get Download Token Video Not Authorized Error");
|
|
|
|
return tempToken;
|
|
}
|
|
|
|
removeTempToken = async(user: UserInterface, tempToken: any) => {
|
|
|
|
const key = user.getEncryptionKey();
|
|
|
|
const decoded = await jwt.verify(tempToken, env.password);
|
|
|
|
const publicKey = decoded.iv;
|
|
|
|
const encryptedToken = user.encryptToken(tempToken, key, publicKey);
|
|
|
|
const removedTokenUser = await dbUtilsFile.removeTempToken(user, encryptedToken);
|
|
|
|
if (!removedTokenUser) throw new NotFoundError("Remove Temp Token User Not Found Errors");
|
|
|
|
await removedTokenUser.save();
|
|
}
|
|
|
|
getSuggestedList = async(userID: string, searchQuery: any) => {
|
|
|
|
searchQuery = new RegExp(searchQuery, 'i')
|
|
|
|
const fileList = await dbUtilsFile.getFileSearchList(userID, searchQuery);
|
|
const folderList = await dbUtilsFolder.getFolderSearchList(userID, searchQuery);
|
|
|
|
if (!fileList || !folderList) throw new NotFoundError("Suggested List Not Found Error");
|
|
|
|
return {
|
|
fileList,
|
|
folderList
|
|
}
|
|
}
|
|
|
|
renameFile = async(userID: string, fileID: string, title: string) => {
|
|
|
|
const file = await dbUtilsFile.renameFile(fileID, userID, title);
|
|
|
|
if (!file.lastErrorObject.updatedExisting) throw new NotFoundError("Rename File Not Found Error");
|
|
|
|
return file;
|
|
}
|
|
|
|
moveFile = async(userID: string, fileID: string, parentID: string) => {
|
|
|
|
let parentList = ["/"];
|
|
|
|
if (parentID.length !== 1) {
|
|
|
|
const parentFile = await dbUtilsFolder.getFolderInfo(parentID, userID);
|
|
if (!parentFile) throw new NotFoundError("Rename Parent File Not Found Error")
|
|
const parentList = parentFile.parentList;
|
|
parentList.push(parentID);
|
|
}
|
|
|
|
const file = await dbUtilsFile.moveFile(fileID, userID, parentID, parentList.toString());
|
|
|
|
if (!file.lastErrorObject.updatedExisting) throw new NotFoundError("Rename File Not Found Error");
|
|
|
|
return file;
|
|
}
|
|
|
|
deleteFile = async(userID: string, fileID: string) => {
|
|
|
|
let bucket = new mongoose.mongo.GridFSBucket(conn.db, {
|
|
chunkSizeBytes: 1024 * 255,
|
|
});
|
|
|
|
const file = await dbUtilsFile.getFileInfo(fileID, userID);
|
|
|
|
if (!file) throw new NotFoundError("Delete File Not Found Error");
|
|
|
|
if (file.metadata.thumbnailID) {
|
|
|
|
await Thumbnail.deleteOne({_id: file.metadata.thumbnailID});
|
|
}
|
|
|
|
if (file.metadata.isVideo && file.metadata.transcoded) {
|
|
try {
|
|
await bucket.delete(ObjectID(file.metadata.transcodedID));
|
|
} catch (e) {
|
|
console.log("Could Not Find Transcoded Video");
|
|
}
|
|
}
|
|
|
|
await bucket.delete(ObjectID(fileID));
|
|
}
|
|
}
|
|
|
|
export default MongoFileService; |