Started converting some of the backend over to Typescript, still trying to figure out a overall file strucure, in terms of adding the ability to have multiple backend fileserver options

This commit is contained in:
subnub
2020-04-12 17:40:17 -04:00
parent 306e519eaa
commit cf9ad3a632
71 changed files with 3930 additions and 180 deletions
Vendored
BIN
View File
Binary file not shown.
@@ -1,15 +1,32 @@
const FileService = require("../services/FileService")
import { Request, Response } from "express";
//const FileService = require("../services/FileService")
import FileService from "../services/FileService/indexnew";
const fileService = new FileService()
import MongoService from "../services/ChunkService/MongoService";
const mongoService = new MongoService();
import {UserInterface} from "../models/user";
interface RequestType extends Request {
user?: UserInterface,
auth?: any,
busboy?: any,
}
class FileController {
// fileService: ;
constructor() {
}
getThumbnail = async(req: RequestType, res: Response) => {
async getThumbnail(req, res) {
if (!req.user) {
@@ -17,6 +34,7 @@ class FileController {
}
try {
const user = req.user;
const id = req.params.id;
@@ -35,73 +53,73 @@ class FileController {
}
async getFullThumbnail(req, res) {
// async getFullThumbnail(req: RequestType, res: Response) {
if (!req.user) {
return;
}
// if (!req.user) {
// return;
// }
try {
// try {
const user = req.user;
const fileID = req.params.id;
// const user = req.user;
// const fileID = req.params.id;
await fileService.getFullThumbnail(user, fileID, res);
// await fileService.getFullThumbnail(user, fileID, res);
} catch (e) {
const code = e.code || 500;
console.log(e.message, e.exception)
return res.status(code).send();
}
}
// } catch (e) {
// const code = e.code || 500;
// console.log(e.message, e.exception)
// return res.status(code).send();
// }
// }
async uploadFile(req, res) {
// async uploadFile(req: RequestType, res: Response) {
if (!req.user) {
// if (!req.user) {
return
}
// return
// }
try {
// try {
const user = req.user;
const busboy = req.busboy;
// const user = req.user;
// const busboy = req.busboy;
req.pipe(busboy);
// req.pipe(busboy);
const file = await fileService.upload(user, busboy, req);
// const file = await fileService.upload(user, busboy, req);
res.send(file);
// res.send(file);
console.log("file uploaded");
// console.log("file uploaded");
} catch (e) {
const code = e.code || 500;
console.log(e.message, e.exception)
return res.status(code).send();
}
}
// } catch (e) {
// const code = e.code || 500;
// console.log(e.message, e.exception)
// return res.status(code).send();
// }
// }
async getPublicDownload(req, res) {
// async getPublicDownload(req: RequestType, res: Response) {
try {
// try {
const ID = req.params.id;
const tempToken = req.params.tempToken;
// const ID = req.params.id;
// const tempToken = req.params.tempToken;
await fileService.publicDownload(ID, tempToken, res);
// await fileService.publicDownload(ID, tempToken, res);
} catch (e) {
// } catch (e) {
const code = e.code || 500;
const message = e.message || e;
// const code = e.code || 500;
// const message = e.message || e;
console.log(message, e);
res.status(code).send();
}
}
// console.log(message, e);
// res.status(code).send();
// }
// }
async removeLink(req, res) {
async removeLink(req: RequestType, res: Response) {
if (!req.user) {
return;
@@ -126,7 +144,7 @@ class FileController {
}
async makePublic(req, res) {
async makePublic(req: RequestType, res: Response) {
if (!req.user) {
return;
@@ -150,7 +168,7 @@ class FileController {
}
}
async getPublicInfo(req, res) {
async getPublicInfo(req: RequestType, res: Response) {
try {
@@ -170,7 +188,7 @@ class FileController {
}
}
async makeOneTimePublic(req, res) {
async makeOneTimePublic(req: RequestType, res: Response) {
if (!req.user) {
return;
@@ -195,7 +213,7 @@ class FileController {
}
async getFileInfo(req, res) {
async getFileInfo(req: RequestType, res: Response) {
if (!req.user) {
return;
@@ -219,7 +237,7 @@ class FileController {
}
}
async getQuickList(req, res) {
async getQuickList(req: RequestType, res: Response) {
if (!req.user) {
return;
@@ -242,7 +260,7 @@ class FileController {
}
}
async getList(req, res) {
async getList(req: RequestType, res: Response) {
if (!req.user) {
return
@@ -266,7 +284,7 @@ class FileController {
}
}
async getDownloadToken(req, res) {
async getDownloadToken(req: RequestType, res: Response) {
if (!req.user) {
return
@@ -289,7 +307,7 @@ class FileController {
}
}
async getDownloadTokenVideo(req, res) {
async getDownloadTokenVideo(req: RequestType, res: Response) {
if (!req.user) {
return
@@ -298,7 +316,7 @@ class FileController {
try {
const user = req.user;
const cookie = req.headers.uuid
const cookie = req.headers.uuid as string;
const tempToken = await fileService.getDownloadTokenVideo(user, cookie);
@@ -313,7 +331,7 @@ class FileController {
}
}
async removeTempToken(req, res) {
async removeTempToken(req: RequestType, res: Response) {
if (!req.user) {
return
@@ -337,111 +355,111 @@ class FileController {
}
}
async transcodeVideo(req, res) {
// async transcodeVideo(req: RequestType, res: Response) {
if (!req.user) {
// if (!req.user) {
return;
}
// return;
// }
try {
// try {
console.log("transcode request", req.body.file._id)
// console.log("transcode request", req.body.file._id)
const user = req.user;
const body = req.body;
// const user = req.user;
// const body = req.body;
await fileService.transcodeVideo(user, body);
// await fileService.transcodeVideo(user, body);
res.send("Finished");
// res.send("Finished");
} catch (e) {
// } catch (e) {
const code = e.code || 500;
console.log(e.message, e.exception)
return res.status(code).send();
}
}
// const code = e.code || 500;
// console.log(e.message, e.exception)
// return res.status(code).send();
// }
// }
async removeTranscodeVideo(req, res) {
// async removeTranscodeVideo(req: RequestType, res: Response) {
if (!req.user) {
// if (!req.user) {
return;
}
// return;
// }
try {
// try {
const fileID = req.body.id;
const userID = req.user._id;
// const fileID = req.body.id;
// const userID = req.user._id;
await fileService.removeTranscodeVideo(userID, fileID);
// await fileService.removeTranscodeVideo(userID, fileID);
res.send();
// res.send();
} catch (e) {
// } catch (e) {
const code = e.code || 500;
// const code = e.code || 500;
console.log(e);
res.status(code).send()
}
}
// console.log(e);
// res.status(code).send()
// }
// }
async streamTranscodedVideo(req, res) {
// async streamTranscodedVideo(req: RequestType, res: Response) {
if (!req.auth || !req.user) {
return;
}
// if (!req.auth || !req.user) {
// return;
// }
try {
// try {
console.log("stream request transcoded", req.params.id)
// console.log("stream request transcoded", req.params.id)
const fileID = req.params.id;
const userID = req.user._id;
const headers = req.headers;
// const fileID = req.params.id;
// const userID = req.user._id;
// const headers = req.headers;
await fileService.streamTranscodedVideo(userID, fileID, headers, res);
// await fileService.streamTranscodedVideo(userID, fileID, headers, res);
} catch (e) {
// } catch (e) {
const code = e.code || 500;
const message = e.message || e;
// const code = e.code || 500;
// const message = e.message || e;
console.log(message, e);
res.status(code).send();
}
}
// console.log(message, e);
// res.status(code).send();
// }
// }
async streamVideo(req, res) {
// async streamVideo(req: RequestType, res: Response) {
if (!req.auth || !req.user) {
return;
}
// if (!req.auth || !req.user) {
// return;
// }
try {
// try {
const user = req.user;
const fileID = req.params.id;
const headers = req.headers;
// const user = req.user;
// const fileID = req.params.id;
// const headers = req.headers;
console.log("stream request", req.params.id)
// console.log("stream request", req.params.id)
await fileService.streamVideo(user, fileID, headers, res);
// await fileService.streamVideo(user, fileID, headers, res);
} catch (e) {
// } catch (e) {
const code = e.code || 500;
const message = e.message || e;
// const code = e.code || 500;
// const message = e.message || e;
console.log(message, e);
res.status(code).send();
}
// console.log(message, e);
// res.status(code).send();
// }
}
// }
async downloadFile(req, res) {
async downloadFile(req: RequestType, res: Response) {
if (!req.auth || !req.user) {
return;
@@ -454,7 +472,8 @@ class FileController {
const user = req.user;
const fileID = req.params.id;
await fileService.downloadFile(user, fileID, res);
//await fileService.downloadFile(user, fileID, res);
await mongoService.downloadFile(user, fileID, res);
} catch (e) {
@@ -466,7 +485,7 @@ class FileController {
}
}
async getSuggestedList(req, res) {
async getSuggestedList(req: RequestType, res: Response) {
if (!req.user) {
return;
@@ -491,7 +510,7 @@ class FileController {
}
}
async renameFile(req, res) {
async renameFile(req: RequestType, res: Response) {
if (!req.user) {
return;
@@ -517,7 +536,7 @@ class FileController {
}
async moveFile(req, res) {
async moveFile(req: RequestType, res: Response) {
console.log("move request");
@@ -547,7 +566,7 @@ class FileController {
}
async deleteFile(req, res) {
async deleteFile(req: RequestType, res: Response) {
if (!req.user) {
return;
@@ -572,4 +591,4 @@ class FileController {
}
}
module.exports = FileController;
export default FileController;
@@ -1,21 +1,24 @@
const express = require("express");
const router = new express.Router;
import {Router} from "express";
const router = Router();
const auth = require("../middleware/auth");
const tempAuth = require("../middleware/tempAuth")
const tempAuthVideo = require("../middleware/tempAuthVideo")
const FileController = require("../controllers/file");
import FileController from "../controllers/file";
const fileController = new FileController()
router.post("/file-service/upload", auth, fileController.uploadFile);
//router.post("/file-service/upload", auth, fileController.uploadFile);
router.post("/file-service/transcode-video", auth, fileController.transcodeVideo);
//router.post("/file-service/transcode-video", auth, fileController.transcodeVideo);
router.get("/file-service/thumbnail/:id", auth, fileController.getThumbnail);
router.get("/file-service/full-thumbnail/:id", auth, fileController.getFullThumbnail);
//router.get("/file-service/full-thumbnail/:id", auth, fileController.getFullThumbnail);
router.get("/file-service/public/download/:id/:tempToken", fileController.getPublicDownload);
//router.get("/file-service/public/download/:id/:tempToken", fileController.getPublicDownload);
router.get("/file-service/public/info/:id/:tempToken", fileController.getPublicInfo);
@@ -29,9 +32,9 @@ router.get("/file-service/download/get-token", auth, fileController.getDownloadT
router.get("/file-service/download/get-token-video", auth, fileController.getDownloadTokenVideo);
router.get("/file-service/stream-video-transcoded/:id/:tempToken/:uuid", tempAuthVideo, fileController.streamTranscodedVideo);
//router.get("/file-service/stream-video-transcoded/:id/:tempToken/:uuid", tempAuthVideo, fileController.streamTranscodedVideo);
router.get("/file-service/stream-video/:id/:tempToken/:uuid", tempAuthVideo, fileController.streamVideo);
//router.get("/file-service/stream-video/:id/:tempToken/:uuid", tempAuthVideo, fileController.streamVideo);
router.get("/file-service/download/:id/:tempToken", tempAuth, fileController.downloadFile);
@@ -49,7 +52,7 @@ router.delete("/file-service/remove-link/:id", auth, fileController.removeLink);
router.delete("/file-service/remove/token-video/:tempToken", auth, fileController.removeTempToken);
router.delete("/file-service/transcode-video/remove", auth, fileController.removeTranscodeVideo);
//router.delete("/file-service/transcode-video/remove", auth, fileController.removeTranscodeVideo);
router.delete("/file-service/remove", auth, fileController.deleteFile);
@@ -1,5 +1,5 @@
const express = require("express");
const router = new express.Router;
import {Router} from "express";
const router = Router();
const auth = require("../middleware/auth");
const FolderController = require("../controllers/folder");
const folderController = new FolderController();
@@ -1,5 +1,5 @@
const express = require("express");
const router = new express.Router;
import {Router} from "express";
const router = Router();
const auth = require("../middleware/auth");
const StorageController = require("../controllers/storage");
const storageController = new StorageController();
@@ -1,5 +1,5 @@
const express = require("express");
const router = new express.Router;
import {Router} from "express";
const router = Router();
const auth = require("../middleware/auth");
const UserController = require("../controllers/user");
const userController = new UserController();
+30
View File
@@ -0,0 +1,30 @@
const prompt = require('password-prompt')
const env = require("../enviroment/env");
const crypto = require("crypto");
const getKey = async() => {
if (process.env.KEY) {
// For Docker
env.key = process.env.KEY
} else if (process.env.NODE_ENV) {
let password = await prompt("Enter Server Encryption Password: ", {method: "hide"});
password = crypto.createHash("md5").update(password).digest("hex");
env.key = password;
} else {
let password = "1234";
password = crypto.createHash("md5").update(password).digest("hex");
env.key = password;
}
}
module.exports = getKey;
+19
View File
@@ -0,0 +1,19 @@
export interface FileInterface {
_id: string,
length: number,
chunkSize: number,
updateDate: string,
filename: string,
metadata: {
owner: string,
parent: string,
parentList: string,
hasThumbnail: boolean,
isVideo: boolean,
thumbnailID?: string,
size: number,
IV: any,
linkType?: 'one' | 'public',
link?: string
}
}
@@ -1,4 +1,4 @@
const mongoose = require("mongoose");
import mongoose, {Document} from "mongoose";
const thumbnailSchema = new mongoose.Schema({
@@ -20,6 +20,13 @@ const thumbnailSchema = new mongoose.Schema({
timestamps: true
})
const Thumbnail = mongoose.model("Thumbnail", thumbnailSchema);
export interface ThumbnailInterface extends Document {
_id: string,
name: string,
owner: string,
data: any
}
module.exports = Thumbnail;
const Thumbnail = mongoose.model<ThumbnailInterface>("Thumbnail", thumbnailSchema);
export default Thumbnail;
@@ -1,11 +1,11 @@
const mongoose = require("mongoose");
import mongoose, {Document} from "mongoose";
const validator = require("validator");
const crypto = require("crypto");
const bcrypt = require("bcrypt");
const jwt = require("jsonwebtoken");
const env = require("../enviroment/env");
const userSchema = mongoose.Schema({
const userSchema = new mongoose.Schema({
name:
{
@@ -18,7 +18,7 @@ const userSchema = mongoose.Schema({
trim: true,
unique: true,
lowercase: true,
validate(value) {
validate(value: any): any {
if (!validator.isEmail(value)) {
throw new Error("Email is invalid");
}
@@ -28,7 +28,7 @@ const userSchema = mongoose.Schema({
type: String,
trim: true,
required: true,
validate(value) {
validate(value: any): any {
if (value.length < 6) {
throw new Error("Password Length Not Sufficent");
}
@@ -57,12 +57,30 @@ const userSchema = mongoose.Schema({
timestamps: true
})
export interface UserInterface extends Document {
_id: string,
name: string,
email: string,
password: string,
tokens: any[],
tempTokens: any[],
privateKey?: string,
publicKey?: string,
token?:string,
getEncryptionKey: () => Buffer;
generateTempAuthToken: () => any;
generateTempAuthTokenVideo: (cookie: string) => any;
encryptToken: (tempToken: any, key: any, publicKey: any) => any;
}
// userSchema.virtual("files", {
// ref: "fs.files",
// localField: "_id"
// })
userSchema.pre("save", async function(next) {
userSchema.pre("save", async function(this: any, next: any) {
const user = this;
@@ -73,7 +91,7 @@ userSchema.pre("save", async function(next) {
next();
})
userSchema.statics.findByCreds = async(email, password) => {
userSchema.statics.findByCreds = async(email: string, password: string) => {
const user = await User.findOne({email});
@@ -123,7 +141,7 @@ userSchema.methods.generateAuthToken = async function() {
return token;
}
userSchema.methods.encryptToken = function(token, key, iv) {
userSchema.methods.encryptToken = function(token: string, key: string, iv: any) {
iv = Buffer.from(iv, "hex")
@@ -135,7 +153,7 @@ userSchema.methods.encryptToken = function(token, key, iv) {
return encryptedText;
}
userSchema.methods.decryptToken = function(encryptedToken, key, iv) {
userSchema.methods.decryptToken = function(encryptedToken: any, key: string, iv: any) {
encryptedToken = Buffer.from(encryptedToken, "hex");
iv = Buffer.from(iv, "hex")
@@ -197,7 +215,7 @@ userSchema.methods.getEncryptionKey = function() {
return decrypted;
}
userSchema.methods.changeEncryptionKey = async function(randomKey) {
userSchema.methods.changeEncryptionKey = async function(randomKey: string) {
const user = this;
const userPassword = user.password;
@@ -251,7 +269,7 @@ userSchema.methods.generateTempAuthToken = async function() {
return token;
}
userSchema.methods.generateTempAuthTokenVideo = async function(cookie) {
userSchema.methods.generateTempAuthTokenVideo = async function(cookie: string) {
const iv = crypto.randomBytes(16);
@@ -270,6 +288,6 @@ userSchema.methods.generateTempAuthTokenVideo = async function(cookie) {
}
const User = mongoose.model("User", userSchema);
const User = mongoose.model<UserInterface>("User", userSchema);
module.exports = User;
@@ -1,11 +1,11 @@
const express = require("express");
const app = express();
const path = require("path")
const publicPath = path.join(__dirname, "..", "public");
const userRouter = require("../backend/express-routers/user")
const fileRouter = require("../backend/express-routers/file")
const folderRouter = require("../backend/express-routers/folder");
const storageRouter = require("../backend/express-routers/storage");
const publicPath = path.join(__dirname, "..", "..", "public");
const userRouter = require("../express-routers/user")
const fileRouter = require("../express-routers/file")
const folderRouter = require("../express-routers/folder");
const storageRouter = require("../express-routers/storage");
const bodyParser = require('body-parser');
const https = require("https");
const fs = require("fs");
@@ -39,7 +39,7 @@ server = http.createServer(app);
require("../backend/db/mongoose");
require("../db/mongoose");
app.use(helmet())
@@ -0,0 +1,81 @@
import mongoose from "../../db/mongoose";
import {Response} from "express";
const conn = mongoose.connection;
const env = require("../../enviroment/env");
const DbUtilFolder = require("../../db/utils/folderUtils");
import DbUtilFile from "../../db/utils/fileUtils/index";
import crypto from "crypto";
const ObjectID = require('mongodb').ObjectID
import { UserInterface } from "../../models/user";
import { FileInterface } from "../../models/file";
const dbUtilsFile = new DbUtilFile();
const dbUtilsFolder = new DbUtilFolder();
class MongoService {
constructor() {
}
downloadFile = (user: UserInterface, fileID: string, res: Response) => {
return new Promise((resolve, reject) => {
dbUtilsFile.getFileInfo(fileID, user._id).then((currentFile: FileInterface) => {
if (!currentFile) {
reject({
code: 401,
message: "Download File Not Found Error",
exception: undefined
})
} else {
const password: Buffer = user.getEncryptionKey();
const bucket = new mongoose.mongo.GridFSBucket(conn.db);
const IV = currentFile.metadata.IV.buffer
const readStream = bucket.openDownloadStream(ObjectID(fileID));
readStream.on("error", (e: Error) => {
reject({
code: 500,
message: "File service download decipher error",
exception: e
})
})
const CIPHER_KEY = crypto.createHash('sha256').update(password).digest()
const decipher = crypto.createDecipheriv('aes256', CIPHER_KEY, IV);
decipher.on("error", (e) => {
reject({
code: 500,
message: "File service download decipher error",
exception: e
})
})
res.set('Content-Type', 'binary/octet-stream');
res.set('Content-Disposition', 'attachment; filename="' + currentFile.filename + '"');
res.set('Content-Length', currentFile.metadata.size.toString());
readStream.pipe(decipher).pipe(res).on("finish", () => {
resolve();
});
}
})
})
}
}
export default MongoService;
+8 -8
View File
@@ -1,13 +1,13 @@
const imageChecker = require("../../../src/utils/imageChecker");
const crypto= require("crypto");
const videoChecker = require("../../../src/utils/videoChecker");
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");
const createThumbnail = require("./utils/createThumbnail");
const Thumbnail = require("../../models/thumbnail");
const ObjectID = require('mongodb').ObjectID
const NotAuthorizedError = require("../../../src/utils/NotAuthorizedError");
const NotFoundError = require("../../../src/utils/NotFoundError");
const NotAuthorizedError = require("../../utils/NotAuthorizedError");
const NotFoundError = require("../../utils/NotFoundError");
const env = require("../../enviroment/env");
const jwt = require("jsonwebtoken");
const removeChunks = require("./utils/removeChunks");
@@ -15,8 +15,8 @@ const User = require("../../models/user");
const Folder = require("../../models/folder");
const sortBySwitch = require("../../../src/utils/sortBySwitch")
const createQuery = require("../../../src/utils/createQuery");
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");
+286
View File
@@ -0,0 +1,286 @@
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;
+3 -3
View File
@@ -1,13 +1,13 @@
const Folder = require("../../models/folder");
const InternalServerError = require("../../../src/utils/InternalServerError");
const NotFoundError = require("../../../src/utils/NotFoundError");
const InternalServerError = require("../../utils/InternalServerError");
const NotFoundError = require("../../utils/NotFoundError");
const UtilsFile = require("../../db/utils/fileUtils");
const ObjectID = require('mongodb').ObjectID
const UtilsFolder = require("../../db/utils/folderUtils");
const mongoose = require("../../db/mongoose")
const conn = mongoose.connection;
const Thumbnail = require("../../models/thumbnail");
const sortBySwitch = require("../../../src/utils/sortBySwitchFolder")
const sortBySwitch = require("../../utils/sortBySwitchFolder");
const utilsFile = new UtilsFile();
const utilsFolder = new UtilsFolder();
+3 -3
View File
@@ -1,9 +1,9 @@
const User = require("../../models/user");
const bcrypt = require("bcrypt");
const crypto = require("crypto");
const NotFoundError = require("../../../src/utils/NotFoundError");
const InternalServerError = require("../../../src/utils/InternalServerError");
const NotAuthorizedError = require("../../../src/utils/NotAuthorizedError");
const NotFoundError = require("../../utils/NotFoundError");
const InternalServerError = require("../../utils/InternalServerError");
const NotAuthorizedError = require("../../utils/NotAuthorizedError");
const UserService = function() {
+10
View File
@@ -0,0 +1,10 @@
class InternalServerError extends Error {
constructor(args) {
super(args);
this.code = 500;
}
}
module.exports = InternalServerError;
+10
View File
@@ -0,0 +1,10 @@
class NotAuthorizedError extends Error {
constructor(args) {
super(args);
this.code = 401;
}
}
module.exports = NotAuthorizedError;
+10
View File
@@ -0,0 +1,10 @@
class NotFoundError extends Error {
constructor(args) {
super(args);
this.code = 404;
}
}
module.exports = NotFoundError;
+12
View File
@@ -0,0 +1,12 @@
const createError = (message, code, exception) => {
let error = new Error(message);
error.message = message
error.code = code
error.exception = exception
throw error;
}
module.exports = createError;
+41
View File
@@ -0,0 +1,41 @@
const createQuery = (owner, parent,sortBy, startAt, startAtDate,searchQuery, startAtName) => {
let query = {"metadata.owner": owner}
if (searchQuery !== "") {
searchQuery = new RegExp(searchQuery, 'i')
query = {...query, filename: searchQuery}
} else {
query = {...query, "metadata.parent": parent}
}
if (startAt) {
if (sortBy === "date_desc" || sortBy === "DEFAULT") {
query = {...query, "uploadDate": {$lt: new Date(startAtDate)}}
} else if (sortBy === "date_asc") {
query = {...query, "uploadDate": {$gt: new Date(startAtDate)}}
} else if (sortBy === "alp_desc") {
query = {...query, "filename": {$lt: startAtName}}
} else {
query = {...query, "filename": {$gt: startAtName}}
}
}
return query;
}
module.exports = createQuery
+31
View File
@@ -0,0 +1,31 @@
const videoExtList = [
"jpeg",
"jpg",
"png",
"gif",
"svg",
"tiff",
"bmp"
]
const videoChecker = (filename) => {
if (filename.length < 1 || !filename.includes(".")) {
return false;
}
const extSplit = filename.split(".");
if (extSplit < 1) {
return false;
}
const ext = extSplit[extSplit.length - 1];
return videoExtList.includes(ext.toLowerCase());
}
module.exports = videoChecker;
+6
View File
@@ -0,0 +1,6 @@
const mobilecheck = () => {
var check = false;
(function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))) check = true;})(navigator.userAgent||navigator.vendor||window.opera);
return check;
};
export default mobilecheck;
+15
View File
@@ -0,0 +1,15 @@
const sortBySwitch = (sortBy) => {
switch(sortBy) {
case "alp_asc":
return {filename: 1}
case "alp_desc":
return {filename: -1}
case "date_asc":
return {uploadDate: 1}
default:
return {uploadDate: -1}
}
}
module.exports = sortBySwitch;
+15
View File
@@ -0,0 +1,15 @@
const sortBySwitch = (sortBy) => {
switch(sortBy) {
case "alp_asc":
return {name: 1}
case "alp_desc":
return {name: -1}
case "date_asc":
return {createdAt: 1}
default:
return {createdAt: -1}
}
}
module.exports = sortBySwitch;
+57
View File
@@ -0,0 +1,57 @@
const videoExtList = [
"3g2",
"3gp",
"aaf",
"asf",
"avchd",
"avi",
"drc",
"flv",
"m2v",
"m4p",
"m4v",
"mkv",
"mng",
"mov",
"mp2",
"mp4",
"mpe",
"mpeg",
"mpg",
"mpv",
"mxf",
"nsv",
"ogg",
"ogv",
"qt",
"rm",
"rmvb",
"roq",
"svi",
"vob",
"webm",
"wmv",
"yuv"
]
const videoChecker = (filename) => {
if (filename.length < 1 || !filename.includes(".")) {
return false;
}
const extSplit = filename.split(".");
if (extSplit < 1) {
return false;
}
const ext = extSplit[extSplit.length - 1];
return videoExtList.includes(ext.toLowerCase());
}
module.exports = videoChecker;
+420
View File
@@ -0,0 +1,420 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
//const FileService = require("../services/FileService")
const indexnew_1 = __importDefault(require("../services/FileService/indexnew"));
const fileService = new indexnew_1.default();
const MongoService_1 = __importDefault(require("../services/ChunkService/MongoService"));
const mongoService = new MongoService_1.default();
class FileController {
// fileService: ;
constructor() {
this.getThumbnail = (req, res) => __awaiter(this, void 0, void 0, function* () {
if (!req.user) {
return;
}
try {
const user = req.user;
const id = req.params.id;
const decryptedThumbnail = yield fileService.getThumbnail(user, id);
res.send(decryptedThumbnail);
}
catch (e) {
const code = e.code || 500;
console.log(e);
res.status(code).send();
}
});
}
// async getFullThumbnail(req: RequestType, res: Response) {
// if (!req.user) {
// return;
// }
// try {
// const user = req.user;
// const fileID = req.params.id;
// await fileService.getFullThumbnail(user, fileID, res);
// } catch (e) {
// const code = e.code || 500;
// console.log(e.message, e.exception)
// return res.status(code).send();
// }
// }
// async uploadFile(req: RequestType, res: Response) {
// if (!req.user) {
// return
// }
// try {
// const user = req.user;
// const busboy = req.busboy;
// req.pipe(busboy);
// const file = await fileService.upload(user, busboy, req);
// res.send(file);
// console.log("file uploaded");
// } catch (e) {
// const code = e.code || 500;
// console.log(e.message, e.exception)
// return res.status(code).send();
// }
// }
// async getPublicDownload(req: RequestType, res: Response) {
// try {
// const ID = req.params.id;
// const tempToken = req.params.tempToken;
// await fileService.publicDownload(ID, tempToken, res);
// } catch (e) {
// const code = e.code || 500;
// const message = e.message || e;
// console.log(message, e);
// res.status(code).send();
// }
// }
removeLink(req, res) {
return __awaiter(this, void 0, void 0, function* () {
if (!req.user) {
return;
}
try {
const id = req.params.id;
const userID = req.user._id;
yield fileService.removeLink(userID, id);
res.send();
}
catch (e) {
const code = e.code || 500;
console.log(e);
res.status(code).send();
}
});
}
makePublic(req, res) {
return __awaiter(this, void 0, void 0, function* () {
if (!req.user) {
return;
}
try {
const fileID = req.params.id;
const user = req.user;
const token = yield fileService.makePublic(user, fileID);
res.send(token);
}
catch (e) {
const code = e.code || 500;
console.log(e);
res.status(code).send();
}
});
}
getPublicInfo(req, res) {
return __awaiter(this, void 0, void 0, function* () {
try {
const id = req.params.id;
const tempToken = req.params.tempToken;
const file = yield fileService.getPublicInfo(id, tempToken);
res.send(file);
}
catch (e) {
const code = e.code || 500;
console.log(e);
res.status(code).send();
}
});
}
makeOneTimePublic(req, res) {
return __awaiter(this, void 0, void 0, function* () {
if (!req.user) {
return;
}
try {
const id = req.params.id;
const userID = req.user._id;
const token = yield fileService.makeOneTimePublic(userID, id);
res.send(token);
}
catch (e) {
const code = e.code || 500;
console.log(e);
res.status(code).send();
}
});
}
getFileInfo(req, res) {
return __awaiter(this, void 0, void 0, function* () {
if (!req.user) {
return;
}
try {
const fileID = req.params.id;
const userID = req.user._id;
const file = yield fileService.getFileInfo(userID, fileID);
res.send(file);
}
catch (e) {
const code = e.code || 500;
console.log(e);
res.status(code).send();
}
});
}
getQuickList(req, res) {
return __awaiter(this, void 0, void 0, function* () {
if (!req.user) {
return;
}
try {
const userID = req.user._id;
const quickList = yield fileService.getQuickList(userID);
res.send(quickList);
}
catch (e) {
const code = e.code || 500;
console.log(e);
res.status(code).send();
}
});
}
getList(req, res) {
return __awaiter(this, void 0, void 0, function* () {
if (!req.user) {
return;
}
try {
const query = req.query;
const userID = req.user._id;
const fileList = yield fileService.getList(userID, query);
res.send(fileList);
}
catch (e) {
const code = e.code || 500;
console.log(e);
res.status(code).send();
}
});
}
getDownloadToken(req, res) {
return __awaiter(this, void 0, void 0, function* () {
if (!req.user) {
return;
}
try {
const user = req.user;
const tempToken = yield fileService.getDownloadToken(user);
res.send({ tempToken });
}
catch (e) {
const code = e.code || 500;
console.log(e);
res.status(code).send();
}
});
}
getDownloadTokenVideo(req, res) {
return __awaiter(this, void 0, void 0, function* () {
if (!req.user) {
return;
}
try {
const user = req.user;
const cookie = req.headers.uuid;
const tempToken = yield fileService.getDownloadTokenVideo(user, cookie);
res.send({ tempToken });
}
catch (e) {
const code = e.code || 500;
console.log(e);
res.status(code).send();
}
});
}
removeTempToken(req, res) {
return __awaiter(this, void 0, void 0, function* () {
if (!req.user) {
return;
}
try {
const user = req.user;
const tempToken = req.params.tempToken;
yield fileService.removeTempToken(user, tempToken);
res.send();
}
catch (e) {
const code = e.code || 500;
console.log(e);
res.status(code).send();
}
});
}
// async transcodeVideo(req: RequestType, res: Response) {
// if (!req.user) {
// return;
// }
// try {
// console.log("transcode request", req.body.file._id)
// const user = req.user;
// const body = req.body;
// await fileService.transcodeVideo(user, body);
// res.send("Finished");
// } catch (e) {
// const code = e.code || 500;
// console.log(e.message, e.exception)
// return res.status(code).send();
// }
// }
// async removeTranscodeVideo(req: RequestType, res: Response) {
// if (!req.user) {
// return;
// }
// try {
// const fileID = req.body.id;
// const userID = req.user._id;
// await fileService.removeTranscodeVideo(userID, fileID);
// res.send();
// } catch (e) {
// const code = e.code || 500;
// console.log(e);
// res.status(code).send()
// }
// }
// async streamTranscodedVideo(req: RequestType, res: Response) {
// if (!req.auth || !req.user) {
// return;
// }
// try {
// console.log("stream request transcoded", req.params.id)
// const fileID = req.params.id;
// const userID = req.user._id;
// const headers = req.headers;
// await fileService.streamTranscodedVideo(userID, fileID, headers, res);
// } catch (e) {
// const code = e.code || 500;
// const message = e.message || e;
// console.log(message, e);
// res.status(code).send();
// }
// }
// async streamVideo(req: RequestType, res: Response) {
// if (!req.auth || !req.user) {
// return;
// }
// try {
// const user = req.user;
// const fileID = req.params.id;
// const headers = req.headers;
// console.log("stream request", req.params.id)
// await fileService.streamVideo(user, fileID, headers, res);
// } catch (e) {
// const code = e.code || 500;
// const message = e.message || e;
// console.log(message, e);
// res.status(code).send();
// }
// }
downloadFile(req, res) {
return __awaiter(this, void 0, void 0, function* () {
if (!req.auth || !req.user) {
return;
}
try {
console.log("download request");
const user = req.user;
const fileID = req.params.id;
//await fileService.downloadFile(user, fileID, res);
yield mongoService.downloadFile(user, fileID, res);
}
catch (e) {
const code = e.code || 500;
const message = e.message || e;
console.log(message, e);
res.status(code).send();
}
});
}
getSuggestedList(req, res) {
return __awaiter(this, void 0, void 0, function* () {
if (!req.user) {
return;
}
try {
const userID = req.user._id;
let searchQuery = req.query.search || "";
const { fileList, folderList } = yield fileService.getSuggestedList(userID, searchQuery);
return res.send({ folderList, fileList });
}
catch (e) {
const code = e.code || 500;
console.log(e);
res.status(code).send();
}
});
}
renameFile(req, res) {
return __awaiter(this, void 0, void 0, function* () {
if (!req.user) {
return;
}
try {
const fileID = req.body.id;
const title = req.body.title;
const userID = req.user._id;
yield fileService.renameFile(userID, fileID, title);
res.send();
}
catch (e) {
const code = e.code || 500;
console.log(e);
res.status(code).send();
}
});
}
moveFile(req, res) {
return __awaiter(this, void 0, void 0, function* () {
console.log("move request");
if (!req.user) {
return;
}
try {
const fileID = req.body.id;
const userID = req.user._id;
const parentID = req.body.parent;
console.log(fileID, userID, parentID);
yield fileService.moveFile(userID, fileID, parentID);
res.send();
}
catch (e) {
const code = e.code || 500;
console.log(e);
res.status(code).send();
}
});
}
deleteFile(req, res) {
return __awaiter(this, void 0, void 0, function* () {
if (!req.user) {
return;
}
try {
const userID = req.user._id;
const fileID = req.body.id;
yield fileService.deleteFile(userID, fileID);
res.send();
}
catch (e) {
const code = e.code || 500;
console.log(e);
res.status(code).send();
}
});
}
}
exports.default = FileController;
+162
View File
@@ -0,0 +1,162 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
const FolderService = require("../services/FolderService");
const folderService = new FolderService();
class FolderController {
constructor() {
}
uploadFolder(req, res) {
return __awaiter(this, void 0, void 0, function* () {
if (!req.user) {
return;
}
try {
const data = req.body;
const folder = yield folderService.uploadFolder(data);
res.send(folder);
}
catch (e) {
const code = e.code || 500;
console.log(e);
res.status(code).send(e);
}
});
}
deleteFolder(req, res) {
return __awaiter(this, void 0, void 0, function* () {
if (!req.user) {
return;
}
try {
const userID = req.user._id;
const folderID = req.body.id;
const parentList = req.body.parentList;
yield folderService.deleteFolder(userID, folderID, parentList);
res.send();
}
catch (e) {
const code = e.code || 500;
console.log(e);
res.status(code).send(e);
}
});
}
deleteAll(req, res) {
return __awaiter(this, void 0, void 0, function* () {
if (!req.user) {
return;
}
try {
const userID = req.user._id;
yield folderService.deleteAll(userID);
res.send();
}
catch (e) {
const code = e.code || 500;
console.log(e);
res.status(code).send(e);
}
});
}
getInfo(req, res) {
return __awaiter(this, void 0, void 0, function* () {
if (!req.user) {
return;
}
try {
const userID = req.user._id;
const folderID = req.params.id;
const folder = yield folderService.getFolderInfo(userID, folderID);
res.send(folder);
}
catch (e) {
const code = e.code || 500;
console.log(e);
res.status(code).send(e);
}
});
}
getSubfolderList(req, res) {
return __awaiter(this, void 0, void 0, function* () {
if (!req.user) {
return;
}
try {
const userID = req.user._id;
const folderID = req.query.id;
const { folderIDList, folderNameList } = yield folderService.getFolderSublist(userID, folderID);
res.send({ folderIDList, folderNameList });
}
catch (e) {
const code = e.code || 500;
console.log(e);
res.status(code).send(e);
}
});
}
getFolderList(req, res) {
return __awaiter(this, void 0, void 0, function* () {
if (!req.user) {
return;
}
try {
const userID = req.user._id;
const query = req.query;
const folderList = yield folderService.getFolderList(userID, query);
res.send(folderList);
}
catch (e) {
const code = e.code || 500;
console.log(e);
res.status(code).send(e);
}
});
}
moveFolder(req, res) {
return __awaiter(this, void 0, void 0, function* () {
if (!req.user) {
return;
}
try {
const userID = req.user._id;
const folderID = req.body.id;
const parent = req.body.parent;
yield folderService.moveFolder(userID, folderID, parent);
res.send();
}
catch (e) {
const code = e.code || 500;
console.log(e);
res.status(code).send(e);
}
});
}
renameFolder(req, res) {
return __awaiter(this, void 0, void 0, function* () {
if (!req.user) {
return;
}
try {
const userID = req.user._id;
const folderID = req.body.id;
const title = req.body.title;
yield folderService.renameFolder(userID, folderID, title);
res.send();
}
catch (e) {
const code = e.code || 500;
console.log(e);
res.status(code).send(e);
}
});
}
}
module.exports = FolderController;
+32
View File
@@ -0,0 +1,32 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
const env = require("../enviroment/env");
const disk = require('diskusage');
class StorageController {
constructor() {
}
getStorageInfo(req, res) {
return __awaiter(this, void 0, void 0, function* () {
if (!req.user) {
return;
}
try {
const info = yield disk.check(env.root);
res.send(info);
}
catch (e) {
console.log(e);
res.status(500).send(e);
}
});
}
}
module.exports = StorageController;
+121
View File
@@ -0,0 +1,121 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
const env = require("../enviroment/env");
const UserService = require("../services/UserService");
const UserProvider = new UserService();
class UserController {
constructor() {
}
getUser(req, res) {
return __awaiter(this, void 0, void 0, function* () {
try {
const user = req.user;
user.tokens = undefined;
user.tempTokens = undefined;
user.password = undefined;
user.privateKey = undefined;
user.publicKey = undefined;
res.send(user);
}
catch (e) {
res.status(500).send(e);
}
});
}
login(req, res) {
return __awaiter(this, void 0, void 0, function* () {
try {
const body = req.body;
const { user, token } = yield UserProvider.login(body);
user.tokens = undefined;
user.tempTokens = undefined;
user.password = undefined;
user.privateKey = undefined;
user.publicKey = undefined;
res.status(200).send({ user, token });
}
catch (e) {
const code = e.code || 500;
console.log(e);
res.status(code).send(e);
}
});
}
logout(req, res) {
return __awaiter(this, void 0, void 0, function* () {
if (!req.user) {
return;
}
try {
const user = req.user;
const token = req.encryptedToken;
yield UserProvider.logout(user, token);
res.send();
}
catch (e) {
res.status(500).send(e);
}
});
}
logoutAll(req, res) {
return __awaiter(this, void 0, void 0, function* () {
try {
const user = req.user;
yield UserProvider.logoutAll(user);
res.send();
}
catch (e) {
res.status(500).send(e);
}
});
}
createUser(req, res) {
return __awaiter(this, void 0, void 0, function* () {
if (env.createAcctBlocked) {
return yield res.status(401).send();
}
try {
const { user, token } = yield UserProvider.create(req.body);
user.tokens = undefined;
user.tempTokens = undefined;
user.password = undefined;
user.privateKey = undefined;
user.publicKey = undefined;
res.status(201).send({ user, token });
}
catch (e) {
const code = e.code || 500;
console.log(e);
res.status(code).send(e);
}
});
}
changePassword(req, res) {
return __awaiter(this, void 0, void 0, function* () {
if (!req.user) {
return;
}
try {
const user = req.user;
const oldPassword = req.body.oldPassword;
const newPassword = req.body.newPassword;
const newToken = yield UserProvider.changePassword(user, oldPassword, newPassword);
res.send(newToken);
}
catch (e) {
const code = e.code || 500;
console.log(e);
res.status(code).send(e);
}
});
}
}
module.exports = UserController;
+9
View File
@@ -0,0 +1,9 @@
"use strict";
const mongoose = require("mongoose");
const env = require("../enviroment/env");
mongoose.connect(env.mongoURL, {
useNewUrlParser: true,
useCreateIndex: true,
useUnifiedTopology: true,
});
module.exports = mongoose;
+11
View File
@@ -0,0 +1,11 @@
"use strict";
const mongoose = require("mongoose");
const env = require("../enviroment/env");
mongoose.connect(env.mongoURL, {
useNewUrlParser: true,
useCreateIndex: true,
useUnifiedTopology: true,
socketTimeoutMS: 30000000,
keepAlive: true,
});
module.exports = mongoose;
+117
View File
@@ -0,0 +1,117 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
const mongoose = require("../../mongoose");
const conn = mongoose.connection;
const ObjectID = require('mongodb').ObjectID;
const DbUtil = function () {
this.getPublicFile = (fileID) => __awaiter(this, void 0, void 0, function* () {
let file = yield conn.db.collection("fs.files")
.findOne({ "_id": ObjectID(fileID) });
return file;
});
this.removeOneTimePublicLink = (fileID) => __awaiter(this, void 0, void 0, function* () {
const file = yield conn.db.collection("fs.files")
.findOneAndUpdate({ "_id": ObjectID(fileID) }, {
"$unset": { "metadata.linkType": "", "metadata.link": "" }
});
return file;
});
this.removeLink = (fileID, userID) => __awaiter(this, void 0, void 0, function* () {
const file = yield conn.db.collection("fs.files")
.findOneAndUpdate({ "_id": ObjectID(fileID),
"metadata.owner": userID }, { "$unset": { "metadata.linkType": "", "metadata.link": "" } });
return file;
});
this.makePublic = (fileID, userID, token) => __awaiter(this, void 0, void 0, function* () {
const file = yield conn.db.collection("fs.files")
.findOneAndUpdate({ "_id": ObjectID(fileID),
"metadata.owner": userID }, { "$set": { "metadata.linkType": "public", "metadata.link": token } });
return file;
});
this.getPublicInfo = (fileID, tempToken) => __awaiter(this, void 0, void 0, function* () {
const file = yield conn.db.collection("fs.files")
.findOne({ "_id": ObjectID(fileID), "metadata.link": tempToken });
return file;
});
this.makeOneTimePublic = (fileID, userID, token) => __awaiter(this, void 0, void 0, function* () {
const file = yield conn.db.collection("fs.files")
.findOneAndUpdate({ "_id": ObjectID(fileID),
"metadata.owner": userID }, { "$set": { "metadata.linkType": "one", "metadata.link": token } });
return file;
});
this.getFileInfo = (fileID, userID) => __awaiter(this, void 0, void 0, function* () {
const file = yield conn.db.collection("fs.files")
.findOne({ "metadata.owner": userID, "_id": ObjectID(fileID) });
return file;
});
this.getQuickList = (userID) => __awaiter(this, void 0, void 0, function* () {
const fileList = yield conn.db.collection("fs.files")
.find({ "metadata.owner": userID })
.sort({ uploadDate: -1 })
.limit(10)
.toArray();
return fileList;
});
this.getList = (queryObj, sortBy, limit) => __awaiter(this, void 0, void 0, function* () {
const fileList = yield conn.db.collection("fs.files")
.find(queryObj)
.sort(sortBy)
.limit(limit)
.toArray();
return fileList;
});
this.removeTempToken = (user, tempToken) => __awaiter(this, void 0, void 0, function* () {
user.tempTokens = user.tempTokens.filter((filterToken) => {
return filterToken.token !== tempToken;
});
return user;
});
this.removeTranscodeVideo = (fileID, userID) => __awaiter(this, void 0, void 0, function* () {
const file = yield conn.db.collection("fs.files")
.findOneAndUpdate({ "_id": ObjectID(fileID), "metadata.owner": userID }, { "$unset": { "metadata.transcoded": "", "metadata.transcodedIV": "",
"metadata.transcoded_size": "", "metadata.transcodedID": "" } });
return file;
});
this.getFileSearchList = (userID, searchQuery) => __awaiter(this, void 0, void 0, function* () {
const fileList = yield conn.db.collection("fs.files")
.find({ "metadata.owner": userID, "filename": searchQuery })
.limit(10)
.toArray();
return fileList;
});
this.renameFile = (fileID, userID, title) => __awaiter(this, void 0, void 0, function* () {
const file = yield conn.db.collection("fs.files")
.findOneAndUpdate({ "_id": ObjectID(fileID),
"metadata.owner": userID }, { "$set": { "filename": title } });
return file;
});
this.moveFile = (fileID, userID, parent, parentList) => __awaiter(this, void 0, void 0, function* () {
const file = yield conn.db.collection("fs.files")
.findOneAndUpdate({ "_id": ObjectID(fileID),
"metadata.owner": userID }, { "$set": { "metadata.parent": parent, "metadata.parentList": parentList } });
return file;
});
this.getFileListByParent = (userID, parentListString) => __awaiter(this, void 0, void 0, function* () {
const fileList = yield conn.db.collection("fs.files")
.find({ "metadata.owner": userID,
"metadata.parentList": { $regex: `.*${parentListString}.*` } }).toArray();
return fileList;
});
this.getFileListByOwner = (userID) => __awaiter(this, void 0, void 0, function* () {
const fileList = yield conn.db.collection("fs.files")
.find({ "metadata.owner": userID }).toArray();
return fileList;
});
this.removeChunksByID = (fileID) => __awaiter(this, void 0, void 0, function* () {
yield conn.db.collection("fs.chunks").deleteMany({ files_id: fileID });
});
};
module.exports = DbUtil;
+47
View File
@@ -0,0 +1,47 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
const Folder = require("../../../models/folder");
const ObjectID = require('mongodb').ObjectID;
const DbUtil = function () {
this.getFolderSearchList = (userID, searchQuery) => __awaiter(this, void 0, void 0, function* () {
const folderList = yield Folder.find({ "owner": userID, "name": searchQuery }).limit(10);
return folderList;
});
this.getFolderInfo = (folderID, userID) => __awaiter(this, void 0, void 0, function* () {
const folder = yield Folder.findOne({ "owner": userID, "_id": ObjectID(folderID) });
return folder;
});
this.getFolderListByParent = (userID, parent, sortBy) => __awaiter(this, void 0, void 0, function* () {
const folderList = yield Folder.find({ "owner": userID, "parent": parent })
.sort(sortBy);
return folderList;
});
this.getFolderListBySearch = (userID, searchQuery, sortBy) => __awaiter(this, void 0, void 0, function* () {
const folderList = yield Folder.find({ "name": searchQuery, "owner": userID })
.sort(sortBy);
return folderList;
});
this.moveFolder = (folderID, userID, parent, parentList) => __awaiter(this, void 0, void 0, function* () {
const folder = yield Folder.findOneAndUpdate({ "_id": ObjectID(folderID),
"owner": userID }, { "$set": { "parent": parent, "parentList": parentList } });
return folder;
});
this.renameFolder = (folderID, userID, title) => __awaiter(this, void 0, void 0, function* () {
const folder = yield Folder.findOneAndUpdate({ "_id": ObjectID(folderID),
"owner": userID }, { "$set": { "name": title } });
return folder;
});
this.findAllFoldersByParent = (parentID, userID) => __awaiter(this, void 0, void 0, function* () {
const folderList = yield Folder.find({ "parentList": parentID, "owner": userID });
return folderList;
});
};
module.exports = DbUtil;
+10
View File
@@ -0,0 +1,10 @@
"use strict";
module.exports = {
key: process.env.KEY,
newKey: process.env.NEW_KEY,
password: process.env.PASSWORD,
createAcctBlocked: process.env.BLOCK_CREATE_ACCOUNT,
root: process.env.ROOT,
url: process.env.URL,
mongoURL: process.env.MONGODB_URL
};
+36
View File
@@ -0,0 +1,36 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const express_1 = require("express");
const router = express_1.Router();
const auth = require("../middleware/auth");
const tempAuth = require("../middleware/tempAuth");
const tempAuthVideo = require("../middleware/tempAuthVideo");
const file_1 = __importDefault(require("../controllers/file"));
const fileController = new file_1.default();
//router.post("/file-service/upload", auth, fileController.uploadFile);
//router.post("/file-service/transcode-video", auth, fileController.transcodeVideo);
router.get("/file-service/thumbnail/:id", auth, fileController.getThumbnail);
//router.get("/file-service/full-thumbnail/:id", auth, fileController.getFullThumbnail);
//router.get("/file-service/public/download/:id/:tempToken", fileController.getPublicDownload);
router.get("/file-service/public/info/:id/:tempToken", fileController.getPublicInfo);
router.get("/file-service/info/:id", auth, fileController.getFileInfo);
router.get("/file-service/quick-list", auth, fileController.getQuickList);
router.get("/file-service/list", auth, fileController.getList);
router.get("/file-service/download/get-token", auth, fileController.getDownloadToken);
router.get("/file-service/download/get-token-video", auth, fileController.getDownloadTokenVideo);
//router.get("/file-service/stream-video-transcoded/:id/:tempToken/:uuid", tempAuthVideo, fileController.streamTranscodedVideo);
//router.get("/file-service/stream-video/:id/:tempToken/:uuid", tempAuthVideo, fileController.streamVideo);
router.get("/file-service/download/:id/:tempToken", tempAuth, fileController.downloadFile);
router.get("/file-service/suggested-list", auth, fileController.getSuggestedList);
router.patch("/file-service/make-public/:id", auth, fileController.makePublic);
router.patch("/file-service/make-one/:id", auth, fileController.makeOneTimePublic);
router.patch("/file-service/rename", auth, fileController.renameFile);
router.patch("/file-service/move", auth, fileController.moveFile);
router.delete("/file-service/remove-link/:id", auth, fileController.removeLink);
router.delete("/file-service/remove/token-video/:tempToken", auth, fileController.removeTempToken);
//router.delete("/file-service/transcode-video/remove", auth, fileController.removeTranscodeVideo);
router.delete("/file-service/remove", auth, fileController.deleteFile);
module.exports = router;
+16
View File
@@ -0,0 +1,16 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const express_1 = require("express");
const router = express_1.Router();
const auth = require("../middleware/auth");
const FolderController = require("../controllers/folder");
const folderController = new FolderController();
router.post("/folder-service/upload", auth, folderController.uploadFolder);
router.delete("/folder-service/remove", auth, folderController.deleteFolder);
router.delete("/folder-service/remove-all", auth, folderController.deleteAll);
router.get("/folder-service/info/:id", auth, folderController.getInfo);
router.get("/folder-service/subfolder-list", auth, folderController.getSubfolderList);
router.get("/folder-service/list", auth, folderController.getFolderList);
router.patch("/folder-service/rename", auth, folderController.renameFolder);
router.patch("/folder-service/move", auth, folderController.moveFolder);
module.exports = router;
+9
View File
@@ -0,0 +1,9 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const express_1 = require("express");
const router = express_1.Router();
const auth = require("../middleware/auth");
const StorageController = require("../controllers/storage");
const storageController = new StorageController();
router.get("/storage-service/info", auth, storageController.getStorageInfo);
module.exports = router;
+14
View File
@@ -0,0 +1,14 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const express_1 = require("express");
const router = express_1.Router();
const auth = require("../middleware/auth");
const UserController = require("../controllers/user");
const userController = new UserController();
router.get("/user-service/user", auth, userController.getUser);
router.post("/user-service/login", userController.login);
router.post("/user-service/logout", auth, userController.logout);
router.post("/user-service/logout-all", auth, userController.logoutAll);
router.post("/user-service/create", userController.createUser);
router.post("/user-service/change-password", auth, userController.changePassword);
module.exports = router;
+30
View File
@@ -0,0 +1,30 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
const prompt = require('password-prompt');
const env = require("../enviroment/env");
const crypto = require("crypto");
const getKey = () => __awaiter(void 0, void 0, void 0, function* () {
if (process.env.KEY) {
// For Docker
env.key = process.env.KEY;
}
else if (process.env.NODE_ENV) {
let password = yield prompt("Enter Server Encryption Password: ", { method: "hide" });
password = crypto.createHash("md5").update(password).digest("hex");
env.key = password;
}
else {
let password = "1234";
password = crypto.createHash("md5").update(password).digest("hex");
env.key = password;
}
});
module.exports = getKey;
+45
View File
@@ -0,0 +1,45 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
const jwt = require("jsonwebtoken");
const User = require("../models/user");
const env = require("../enviroment/env");
const auth = (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
try {
const token = req.header("Authorization").replace("Bearer ", "");
const decoded = yield jwt.verify(token, env.password);
const iv = decoded.iv;
const user = yield User.findOne({ _id: decoded._id });
const encrpytionKey = user.getEncryptionKey();
const encryptedToken = user.encryptToken(token, encrpytionKey, iv);
let tokenFound = false;
for (let i = 0; i < user.tokens.length; i++) {
const currentToken = user.tokens[i].token;
if (currentToken === encryptedToken) {
tokenFound = true;
break;
}
}
if (!user || !tokenFound) {
throw new Error("User not found");
}
else {
req.token = token;
req.encryptedToken = encryptedToken;
req.user = user;
next();
}
}
catch (e) {
console.log(e);
res.status(401).send({ error: "Error Authenticating" });
}
});
module.exports = auth;
+49
View File
@@ -0,0 +1,49 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
const jwt = require("jsonwebtoken");
const User = require("../models/user");
const env = require("../enviroment/env");
const tempAuth = (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
try {
const token = req.params.tempToken;
const decoded = yield jwt.verify(token, env.password);
const iv = decoded.iv;
const user = yield User.findOne({ _id: decoded._id });
const encrpytionKey = user.getEncryptionKey();
const encryptedToken = user.encryptToken(token, encrpytionKey, iv);
let tokenFound = false;
for (let i = 0; i < user.tempTokens.length; i++) {
const currentToken = user.tempTokens[i].token;
if (currentToken === encryptedToken) {
tokenFound = true;
break;
}
}
if (!user || !tokenFound) {
throw new Error("User Not Found");
}
else {
user.tempTokens = user.tempTokens.filter((filterToken) => {
return filterToken.token !== encryptedToken;
});
yield user.save();
req.user = user;
req.auth = true;
req.encryptedTempToken = encryptedToken;
next();
}
}
catch (e) {
console.log(e);
res.status(401).send();
}
});
module.exports = tempAuth;
+49
View File
@@ -0,0 +1,49 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
const jwt = require("jsonwebtoken");
const User = require("../models/user");
const env = require("../enviroment/env");
const tempAuthVideo = (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
try {
const token = req.params.tempToken;
const decoded = yield jwt.verify(token, env.password);
const iv = decoded.iv;
if (req.params.uuid !== decoded.cookie) {
throw new Error("Cookie mismatch");
}
const user = yield User.findOne({ _id: decoded._id });
const encrpytionKey = user.getEncryptionKey();
const encryptedToken = user.encryptToken(token, encrpytionKey, iv);
let tokenFound = false;
for (let i = 0; i < user.tempTokens.length; i++) {
const currentToken = user.tempTokens[i].token;
if (currentToken === encryptedToken) {
tokenFound = true;
break;
}
}
if (!user || !tokenFound) {
throw new Error("User not found");
}
else {
yield user.save();
req.user = user;
req.auth = true;
req.encryptedTempToken = encryptedToken;
next();
}
}
catch (e) {
console.log(e);
res.status(401).send();
}
});
module.exports = tempAuthVideo;
+2
View File
@@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
+24
View File
@@ -0,0 +1,24 @@
"use strict";
const mongoose = require("mongoose");
const folderSchema = new mongoose.Schema({
name: {
type: String,
required: true,
},
parent: {
type: String,
required: true,
},
owner: {
type: String,
required: true
},
parentList: {
type: Array,
required: true
}
}, {
timestamps: true
});
const Folder = mongoose.model("Folder", folderSchema);
module.exports = Folder;
+24
View File
@@ -0,0 +1,24 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const mongoose_1 = __importDefault(require("mongoose"));
const thumbnailSchema = new mongoose_1.default.Schema({
name: {
type: String,
required: true,
},
owner: {
type: String,
required: true
},
data: {
type: Buffer,
required: true
}
}, {
timestamps: true
});
const Thumbnail = mongoose_1.default.model("Thumbnail", thumbnailSchema);
exports.default = Thumbnail;
+224
View File
@@ -0,0 +1,224 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const mongoose_1 = __importDefault(require("mongoose"));
const validator = require("validator");
const crypto = require("crypto");
const bcrypt = require("bcrypt");
const jwt = require("jsonwebtoken");
const env = require("../enviroment/env");
const userSchema = new mongoose_1.default.Schema({
name: {
type: String,
trim: true
},
email: {
type: String,
required: true,
trim: true,
unique: true,
lowercase: true,
validate(value) {
if (!validator.isEmail(value)) {
throw new Error("Email is invalid");
}
}
},
password: {
type: String,
trim: true,
required: true,
validate(value) {
if (value.length < 6) {
throw new Error("Password Length Not Sufficent");
}
}
},
tokens: [{
token: {
type: String,
required: true
}
}],
tempTokens: [{
token: {
type: String,
required: true
}
}],
privateKey: {
type: String,
},
publicKey: {
type: String,
}
}, {
timestamps: true
});
// userSchema.virtual("files", {
// ref: "fs.files",
// localField: "_id"
// })
userSchema.pre("save", function (next) {
return __awaiter(this, void 0, void 0, function* () {
const user = this;
if (user.isModified("password")) {
user.password = yield bcrypt.hash(user.password, 8);
}
next();
});
});
userSchema.statics.findByCreds = (email, password) => __awaiter(void 0, void 0, void 0, function* () {
const user = yield User.findOne({ email });
if (!user) {
throw new Error("User not found");
}
const isMatch = yield bcrypt.compare(password, user.password);
if (!isMatch) {
console.log("incorrect password");
throw new Error("Incorrect password");
}
return user;
});
userSchema.methods.toJSON = function () {
const user = this;
const userObject = user.toObject();
delete userObject.password;
delete userObject.tokens;
delete userObject.tempTokens;
return userObject;
};
userSchema.methods.generateAuthToken = function () {
return __awaiter(this, void 0, void 0, function* () {
const iv = crypto.randomBytes(16);
const user = this;
let token = jwt.sign({ _id: user._id.toString(), iv }, env.password);
const publicKey = user.publicKey;
const encryptionKey = user.getEncryptionKey();
const encryptedToken = user.encryptToken(token, encryptionKey, iv);
user.tokens = user.tokens.concat({ token: encryptedToken });
yield user.save();
return token;
});
};
userSchema.methods.encryptToken = function (token, key, iv) {
iv = Buffer.from(iv, "hex");
const TOKEN_CIPHER_KEY = crypto.createHash('sha256').update(key).digest();
const cipher = crypto.createCipheriv('aes-256-cbc', TOKEN_CIPHER_KEY, iv);
let encryptedText = cipher.update(token);
encryptedText = Buffer.concat([encryptedText, cipher.final()]).toString("hex");
return encryptedText;
};
userSchema.methods.decryptToken = function (encryptedToken, key, iv) {
encryptedToken = Buffer.from(encryptedToken, "hex");
iv = Buffer.from(iv, "hex");
const TOKEN_CIPHER_KEY = crypto.createHash('sha256').update(key).digest();
const decipher = crypto.createDecipheriv('aes-256-cbc', TOKEN_CIPHER_KEY, iv);
let tokenDecrypted = decipher.update(encryptedToken);
tokenDecrypted = Buffer.concat([tokenDecrypted, decipher.final()]).toString();
return tokenDecrypted;
};
userSchema.methods.generateEncryptionKeys = function () {
return __awaiter(this, void 0, void 0, function* () {
const user = this;
const userPassword = user.password;
const masterPassword = env.key;
const randomKey = crypto.randomBytes(32);
const iv = crypto.randomBytes(16);
const USER_CIPHER_KEY = crypto.createHash('sha256').update(userPassword).digest();
const cipher = crypto.createCipheriv('aes-256-cbc', USER_CIPHER_KEY, iv);
let encryptedText = cipher.update(randomKey);
encryptedText = Buffer.concat([encryptedText, cipher.final()]);
const MASTER_CIPHER_KEY = crypto.createHash('sha256').update(masterPassword).digest();
const masterCipher = crypto.createCipheriv('aes-256-cbc', MASTER_CIPHER_KEY, iv);
let masterEncryptedText = masterCipher.update(encryptedText);
masterEncryptedText = Buffer.concat([masterEncryptedText, masterCipher.final()]).toString("hex");
user.privateKey = masterEncryptedText;
user.publicKey = iv.toString("hex");
yield user.save();
});
};
userSchema.methods.getEncryptionKey = function () {
const user = this;
const userPassword = user.password;
const masterEncryptedText = user.privateKey;
const masterPassword = env.key;
const iv = Buffer.from(user.publicKey, "hex");
const USER_CIPHER_KEY = crypto.createHash('sha256').update(userPassword).digest();
const MASTER_CIPHER_KEY = crypto.createHash('sha256').update(masterPassword).digest();
const unhexMasterText = Buffer.from(masterEncryptedText, "hex");
const masterDecipher = crypto.createDecipheriv('aes-256-cbc', MASTER_CIPHER_KEY, iv);
let masterDecrypted = masterDecipher.update(unhexMasterText);
masterDecrypted = Buffer.concat([masterDecrypted, masterDecipher.final()]);
let decipher = crypto.createDecipheriv('aes-256-cbc', USER_CIPHER_KEY, iv);
let decrypted = decipher.update(masterDecrypted);
decrypted = Buffer.concat([decrypted, decipher.final()]);
return decrypted;
};
userSchema.methods.changeEncryptionKey = function (randomKey) {
return __awaiter(this, void 0, void 0, function* () {
const user = this;
const userPassword = user.password;
const masterPassword = env.key;
const iv = crypto.randomBytes(16);
const USER_CIPHER_KEY = crypto.createHash('sha256').update(userPassword).digest();
const cipher = crypto.createCipheriv('aes-256-cbc', USER_CIPHER_KEY, iv);
let encryptedText = cipher.update(randomKey);
encryptedText = Buffer.concat([encryptedText, cipher.final()]);
const MASTER_CIPHER_KEY = crypto.createHash('sha256').update(masterPassword).digest();
const masterCipher = crypto.createCipheriv('aes-256-cbc', MASTER_CIPHER_KEY, iv);
let masterEncryptedText = masterCipher.update(encryptedText);
masterEncryptedText = Buffer.concat([masterEncryptedText, masterCipher.final()]).toString("hex");
user.privateKey = masterEncryptedText;
user.publicKey = iv.toString("hex");
yield user.save();
});
};
userSchema.methods.generateTempAuthToken = function () {
return __awaiter(this, void 0, void 0, function* () {
// const user = this;
// let token = jwt.sign({_id:user._id.toString()}, env.password);
// const publicKey = user.publicKey;
// const encryptionKey = user.getEncryptionKey();
// const encryptedToken = user.encryptToken(token, encryptionKey, publicKey);
// user.tokens = user.tokens.concat({token: encryptedToken});
// await user.save();
// return token;
const iv = crypto.randomBytes(16);
const user = this;
const token = jwt.sign({ _id: user._id.toString(), iv }, env.password, { expiresIn: 2 });
const publicKey = user.publicKey;
const encryptionKey = user.getEncryptionKey();
const encryptedToken = user.encryptToken(token, encryptionKey, iv);
user.tempTokens = user.tempTokens.concat({ token: encryptedToken });
yield user.save();
return token;
});
};
userSchema.methods.generateTempAuthTokenVideo = function (cookie) {
return __awaiter(this, void 0, void 0, function* () {
const iv = crypto.randomBytes(16);
const user = this;
const token = jwt.sign({ _id: user._id.toString(), cookie, iv }, env.password, { expiresIn: "5h" });
//const publicKey = user.publicKey;
const encryptionKey = user.getEncryptionKey();
const encryptedToken = user.encryptToken(token, encryptionKey, iv);
//user.tempTokens = user.tempTokens.concat({token});
user.tempTokens = user.tempTokens.concat({ token: encryptedToken });
yield user.save();
return token;
});
};
const User = mongoose_1.default.model("User", userSchema);
module.exports = User;
+52
View File
@@ -0,0 +1,52 @@
"use strict";
const express = require("express");
const app = express();
const path = require("path");
const publicPath = path.join(__dirname, "..", "..", "public");
const userRouter = require("../express-routers/user");
const fileRouter = require("../express-routers/file");
const folderRouter = require("../express-routers/folder");
const storageRouter = require("../express-routers/storage");
const bodyParser = require('body-parser');
const https = require("https");
const fs = require("fs");
const helmet = require("helmet");
const busboy = require("connect-busboy");
const compression = require("compression");
const http = require("http");
let server;
let serverHttps;
if (process.env.NODE_ENV === 'production') {
const cert = fs.readFileSync("certificate.crt");
const ca = fs.readFileSync("certificate.ca-bundle");
const key = fs.readFileSync("certificate.key");
const options = {
cert,
ca,
key
};
serverHttps = https.createServer(options, app);
}
server = http.createServer(app);
require("../db/mongoose");
app.use(helmet());
app.use(compression());
app.use(express.json());
app.use(express.static(publicPath));
app.use(bodyParser.json({ limit: "50mb" }));
app.use(bodyParser.urlencoded({ limit: "50mb", extended: true, parameterLimit: 50000 }));
app.use(busboy({
highWaterMark: 2 * 1024 * 1024,
}));
app.use(userRouter, fileRouter, folderRouter, storageRouter);
const nodeMode = process.env.NODE_ENV ? "Production" : "Development/Testing";
console.log("Node Enviroment Mode:", nodeMode);
app.get("*", (req, res) => {
res.sendFile(path.join(publicPath, "index.html"));
});
if (process.env.NODE_ENV === 'production') {
module.exports = { server, serverHttps };
}
else {
module.exports = server;
}
+36
View File
@@ -0,0 +1,36 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
const getKey = require("../key/getKey");
const serverStart = () => __awaiter(void 0, void 0, void 0, function* () {
yield getKey();
if (process.env.NODE_ENV === 'production') {
const { server, serverHttps } = require("./server");
server.listen(process.env.HTTP_PORT, process.env.URL, () => {
console.log("Http Server Running On Port:", process.env.HTTP_PORT);
});
serverHttps.listen(process.env.HTTPS_PORT, function () {
console.log('Https Server Running On Port:', process.env.HTTPS_PORT);
});
}
else if (process.env.NODE_ENV === 'production-no-ssl') {
const server = require("./server");
server.listen(process.env.HTTP_PORT, process.env.URL, () => {
console.log("Http Server (No-SSL) Running On Port:", process.env.HTTP_PORT);
});
}
else {
const server = require("./server");
server.listen(process.env.HTTP_PORT, process.env.URL, () => {
console.log("Development Server Running On Port:", process.env.HTTP_PORT);
});
}
});
serverStart();
+60
View File
@@ -0,0 +1,60 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const mongoose_1 = __importDefault(require("../../db/mongoose"));
const conn = mongoose_1.default.connection;
const env = require("../../enviroment/env");
const DbUtilFolder = require("../../db/utils/folderUtils");
const index_1 = __importDefault(require("../../db/utils/fileUtils/index"));
const crypto_1 = __importDefault(require("crypto"));
const ObjectID = require('mongodb').ObjectID;
const dbUtilsFile = new index_1.default();
const dbUtilsFolder = new DbUtilFolder();
class MongoService {
constructor() {
this.downloadFile = (user, fileID, res) => {
return new Promise((resolve, reject) => {
dbUtilsFile.getFileInfo(fileID, user._id).then((currentFile) => {
if (!currentFile) {
reject({
code: 401,
message: "Download File Not Found Error",
exception: undefined
});
}
else {
const password = user.getEncryptionKey();
const bucket = new mongoose_1.default.mongo.GridFSBucket(conn.db);
const IV = currentFile.metadata.IV.buffer;
const readStream = bucket.openDownloadStream(ObjectID(fileID));
readStream.on("error", (e) => {
reject({
code: 500,
message: "File service download decipher error",
exception: e
});
});
const CIPHER_KEY = crypto_1.default.createHash('sha256').update(password).digest();
const decipher = crypto_1.default.createDecipheriv('aes256', CIPHER_KEY, IV);
decipher.on("error", (e) => {
reject({
code: 500,
message: "File service download decipher error",
exception: e
});
});
res.set('Content-Type', 'binary/octet-stream');
res.set('Content-Disposition', 'attachment; filename="' + currentFile.filename + '"');
res.set('Content-Length', currentFile.metadata.size.toString());
readStream.pipe(decipher).pipe(res).on("finish", () => {
resolve();
});
}
});
});
};
}
}
exports.default = MongoService;
+668
View File
@@ -0,0 +1,668 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const imageChecker = require("../../utils/imageChecker");
const crypto_1 = __importDefault(require("crypto"));
const videoChecker = require("../../utils/videoChecker");
const mongoose = require("../../db/mongoose");
const conn = mongoose.connection;
const createThumbnail = require("./utils/createThumbnail");
const Thumbnail = require("../../models/thumbnail");
const ObjectID = require('mongodb').ObjectID;
const NotAuthorizedError = require("../../utils/NotAuthorizedError");
const NotFoundError = require("../../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");
const DbUtilFile = require("../../db/utils/fileUtils");
const DbUtilFolder = require("../../db/utils/folderUtils");
const dbUtilsFile = new DbUtilFile();
const dbUtilsFolder = new DbUtilFolder();
const FileService = function () {
this.upload = (user, busboy, req) => {
return new Promise((resolve, reject) => {
const password = user.getEncryptionKey();
let bucketStream;
const initVect = crypto_1.default.randomBytes(16);
const CIPHER_KEY = crypto_1.default.createHash('sha256').update(password).digest();
const cipher = crypto_1.default.createCipheriv('aes256', CIPHER_KEY, initVect);
cipher.on("error", (e) => __awaiter(this, void 0, void 0, function* () {
yield removeChunks(bucketStream);
reject({
message: "File service upload cipher error",
exception: e,
code: 500
});
}));
const formData = new Map();
busboy.on("error", (e) => __awaiter(this, void 0, void 0, function* () {
yield removeChunks(bucketStream);
reject({
message: "File service upload busboy error",
exception: e,
code: 500
});
}));
busboy.on("file", (fieldname, file, filename) => __awaiter(this, void 0, void 0, function* () {
const parent = formData.get("parent") || "/";
const parentList = formData.get("parentList") || "/";
const size = formData.get("size") || "";
let hasThumbnail = false;
let thumbnailID = "";
const isVideo = videoChecker(filename);
const metadata = {
owner: user._id,
parent,
parentList,
hasThumbnail,
thumbnailID,
isVideo,
size,
IV: initVect
};
let bucket = new mongoose.mongo.GridFSBucket(conn.db, {
chunkSizeBytes: 1024 * 255
});
bucketStream = bucket.openUploadStream(filename, { metadata });
bucketStream.on("error", (e) => __awaiter(this, void 0, void 0, function* () {
yield removeChunks(bucketStream);
reject({
message: "Cannot upload file to database",
exception: e,
code: 500
});
}));
req.on("aborted", () => __awaiter(this, void 0, void 0, function* () {
console.log("Upload Request Cancelling...");
yield removeChunks(bucketStream);
}));
file.pipe(cipher).pipe(bucketStream);
bucketStream.on("finish", (file) => __awaiter(this, void 0, void 0, function* () {
const imageCheck = imageChecker(filename);
if (file.length < 15728640 && imageCheck) {
let updatedFile = yield createThumbnail(file, filename, user);
resolve(updatedFile);
}
else {
resolve(file);
}
}));
})).on("field", (field, val) => {
formData.set(field, val);
});
});
};
this.getThumbnail = (user, id) => __awaiter(this, void 0, void 0, function* () {
const password = user.getEncryptionKey();
const thumbnail = yield Thumbnail.findById(id);
if (user._id.toString() !== thumbnail.owner) {
throw new NotAuthorizedError("Thumbnail Unauthorized Error");
}
const iv = thumbnail.data.slice(0, 16);
const chunk = thumbnail.data.slice(16);
const CIPHER_KEY = crypto_1.default.createHash('sha256').update(password).digest();
const decipher = crypto_1.default.createDecipheriv("aes256", CIPHER_KEY, iv);
const decryptedThumbnail = Buffer.concat([decipher.update(chunk), decipher.final()]);
//console.log("decry", decryptedThumbnail);
return decryptedThumbnail;
});
this.getFullThumbnail = (user, fileID, res) => __awaiter(this, void 0, void 0, function* () {
return new Promise((resolve, reject) => {
const userID = user._id;
dbUtilsFile.getFileInfo(fileID, userID).then((file) => __awaiter(this, void 0, void 0, function* () {
if (!file) {
reject({
code: 401,
message: "File For Full Thumbnail Not Found",
exception: undefined
});
}
const bucket = new mongoose.mongo.GridFSBucket(conn.db, {
chunkSizeBytes: 1024 * 255,
});
const password = user.getEncryptionKey();
const IV = file.metadata.IV.buffer;
const readStream = bucket.openDownloadStream(ObjectID(fileID));
readStream.on("error", (e) => {
reject({
code: 500,
message: "File service Full Thumbnail stream error",
exception: e
});
});
const CIPHER_KEY = crypto_1.default.createHash('sha256').update(password).digest();
const decipher = crypto_1.default.createDecipheriv('aes256', CIPHER_KEY, IV);
decipher.on("error", (e) => {
reject({
code: 500,
message: "File service Full Thumbnail decipher error",
exception: e
});
});
res.set('Content-Type', 'binary/octet-stream');
res.set('Content-Disposition', 'attachment; filename="' + file.filename + '"');
res.set('Content-Length', file.metadata.size);
readStream.pipe(decipher).pipe(res).on("finish", () => __awaiter(this, void 0, void 0, function* () {
console.log("Sent Full Thumbnail");
resolve();
}));
}));
});
});
this.publicDownload = (ID, tempToken, res) => {
return new Promise((resolve, reject) => {
dbUtilsFile.getPublicFile(ID).then((file) => __awaiter(this, void 0, void 0, function* () {
if (!file || !file.metadata.link || file.metadata.link !== tempToken) {
reject({
code: 401,
message: "File not public/Not found",
exception: undefined
});
}
else {
const user = yield User.findById(file.metadata.owner);
const bucket = new mongoose.mongo.GridFSBucket(conn.db, {
chunkSizeBytes: 1024 * 255,
});
const password = user.getEncryptionKey();
const IV = file.metadata.IV.buffer;
const readStream = bucket.openDownloadStream(ObjectID(ID));
readStream.on("error", (e) => {
reject({
code: 500,
message: "File service public download decipher error",
exception: e
});
});
const CIPHER_KEY = crypto_1.default.createHash('sha256').update(password).digest();
const decipher = crypto_1.default.createDecipheriv('aes256', CIPHER_KEY, IV);
decipher.on("error", (e) => {
reject({
code: 500,
message: "File service public download decipher error",
exception: e
});
});
res.set('Content-Type', 'binary/octet-stream');
res.set('Content-Disposition', 'attachment; filename="' + file.filename + '"');
res.set('Content-Length', file.metadata.size);
readStream.pipe(decipher).pipe(res).on("finish", () => __awaiter(this, void 0, void 0, function* () {
console.log("removing public link");
yield this.removePublicOneTimeLink(file);
resolve();
}));
}
}));
});
};
this.removePublicOneTimeLink = (currentFile) => __awaiter(this, void 0, void 0, function* () {
const ID = currentFile._id;
if (currentFile.metadata.linkType === "one") {
yield dbUtilsFile.removeOneTimePublicLink(ID);
}
});
this.removeLink = (userID, fileID) => __awaiter(this, void 0, void 0, function* () {
const file = yield dbUtilsFile.removeLink(fileID, userID);
if (!file.lastErrorObject.updatedExisting)
throw new NotFoundError("Remove Link File Not Found Error");
});
this.makePublic = (user, fileID) => __awaiter(this, void 0, void 0, function* () {
const userID = user._id;
const token = yield jwt.sign({ _id: userID.toString() }, env.password);
const file = yield dbUtilsFile.makePublic(fileID, userID, token, "public");
if (!file.lastErrorObject.updatedExisting)
throw new NotFoundError("Make Public File Not Found Error");
return token;
});
this.getPublicInfo = (fileID, tempToken) => __awaiter(this, void 0, void 0, function* () {
const file = yield dbUtilsFile.getPublicInfo(fileID, tempToken);
if (!file || !file.metadata.link || file.metadata.link !== tempToken) {
throw new NotFoundError("Public Info Not Found");
}
else {
return file;
}
});
this.makeOneTimePublic = (userID, fileID) => __awaiter(this, void 0, void 0, function* () {
const token = yield jwt.sign({ _id: userID.toString() }, env.password);
const file = yield dbUtilsFile.makeOneTimePublic(fileID, userID, token);
if (!file.lastErrorObject.updatedExisting)
throw new NotFoundError("Make One Time Public Not Found Error");
return token;
});
this.getFileInfo = (userID, fileID) => __awaiter(this, void 0, void 0, function* () {
let currentFile = yield 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 = yield Folder.findOne({ "owner": userID, "_id": parentID });
if (parentFolder) {
parentName = parentFolder.name;
}
else {
parentName = "Unknown";
}
}
return Object.assign(Object.assign({}, currentFile), { parentName });
});
this.getQuickList = (userID) => __awaiter(this, void 0, void 0, function* () {
const quickList = yield dbUtilsFile.getQuickList(userID);
if (!quickList)
throw new NotFoundError("Quick List Not Found Error");
return quickList;
});
this.getList = (userID, query) => __awaiter(this, void 0, void 0, function* () {
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 = yield dbUtilsFile.getList(queryObj, sortBy, limit);
if (!fileList)
throw new NotFoundError("File List Not Found");
return fileList;
});
this.getDownloadToken = (user) => __awaiter(this, void 0, void 0, function* () {
const tempToken = yield user.generateTempAuthToken();
if (!tempToken)
throw new NotAuthorizedError("Get Download Token Not Authorized Error");
return tempToken;
});
this.getDownloadTokenVideo = (user, cookie) => __awaiter(this, void 0, void 0, function* () {
if (!cookie)
throw new NotAuthorizedError("Get Download Token Video Cookie Not Authorized Error");
const tempToken = yield user.generateTempAuthTokenVideo(cookie);
if (!tempToken)
throw new NotAuthorizedError("Get Download Token Video Not Authorized Error");
return tempToken;
});
this.removeTempToken = (user, tempToken) => __awaiter(this, void 0, void 0, function* () {
const key = user.getEncryptionKey();
const decoded = yield jwt.verify(tempToken, env.password);
const publicKey = decoded.iv;
const encryptedToken = user.encryptToken(tempToken, key, publicKey);
const removedTokenUser = yield dbUtilsFile.removeTempToken(user, encryptedToken);
if (!removedTokenUser)
throw new NotFoundError("Remove Temp Token User Not Found Errors");
yield removedTokenUser.save();
});
this.transcodeVideo = (user, body) => {
return new Promise((resolve, reject) => {
const id = body.file._id;
const userID = user._id;
conn.db.collection("fs.files")
.findOne({ "_id": ObjectID(id), "metadata.owner": userID }).then((currentFile) => {
if (!currentFile) {
reject({
message: "Transcode Video Not Found Error",
exception: undefined,
code: 401
});
}
else {
const password = user.getEncryptionKey(); //env.key;
const IV = currentFile.metadata.IV.buffer;
const bucket = new mongoose.mongo.GridFSBucket(conn.db);
const readStream = bucket.openDownloadStream(ObjectID(id));
readStream.on("error", (e) => {
reject({
message: "File service transcode video stream error",
exception: e,
code: 500
});
});
const CIPHER_KEY = crypto_1.default.createHash('sha256').update(password).digest();
const decipher = crypto_1.default.createDecipheriv('aes256', CIPHER_KEY, IV);
decipher.on("error", (e) => {
reject({
message: "File service transcode video decipher error",
exception: e,
code: 500
});
});
const tempStream = temp.createWriteStream();
tempStream.on("error", (e) => {
reject({
message: "File service transcode video temp error",
exception: e,
code: 500
});
});
readStream.pipe(decipher).pipe(tempStream).on("finish", () => {
const writeBucket = new mongoose.mongo.GridFSBucket(conn.db, {
bucketName: "videos",
});
const gfsWrite = writeBucket.openUploadStream(currentFile.filename, {
_id: id,
});
gfsWrite.on("error", (e) => {
reject({
message: "File service transcode video write stream error",
exception: e,
code: 500
});
});
const initVect = crypto_1.default.randomBytes(16);
const cipher = crypto_1.default.createCipheriv('aes256', CIPHER_KEY, initVect);
cipher.on("error", (e) => {
reject({
message: "File service transcode video cipher write error",
exception: e,
code: 500
});
});
const str = progress({ time: 100 });
str.on("progress", () => {
});
str.on("finish", () => {
});
const tempStream2 = temp.createWriteStream();
tempStream2.on("error", (e) => {
reject({
message: "File service transcode video temp write error",
exception: e,
code: 500
});
});
const ffmpegCommand = ffmpeg()
.input(tempStream.path).outputOptions(['-movflags frag_keyframe+empty_moov', '-movflags +faststart'])
.outputFormat('mp4').on("error", (err, stdout, stderr) => {
console.log('An error occurred: ' + err.message, err, stderr);
reject({
message: "Video Transcode Failed Error",
exception: err.message,
code: 500
});
})
.videoCodec('libx264')
.audioBitrate('128k')
.videoBitrate(8000, true)
.pipe(tempStream2).on("finish", () => {
fs.createReadStream(tempStream2.path).pipe(cipher).pipe(gfsWrite).on("finish", (file) => __awaiter(this, void 0, void 0, function* () {
console.log("transcode finished");
yield conn.db.collection("fs.files")
.findOneAndUpdate({ "_id": ObjectID(id) }, { "$set": { "metadata.transcoded": true, "metadata.transcodedIV": initVect, "metadata.transcoded_size": tempStream2.bytesWritten, "metadata.transcodedID": file._id } });
resolve();
})).on("error", (e) => {
reject({
message: "File service transcode read stream error",
exception: e,
code: 500
});
});
});
ffmpegCommand.on("error", (e) => {
reject({
message: "File service FFMPEG error",
exception: e,
code: 500
});
});
});
}
});
});
};
this.removeTranscodeVideo = (userID, fileID) => __awaiter(this, void 0, void 0, function* () {
const parentFile = yield dbUtilsFile.getFileInfo(fileID, userID);
const transcodedVideoID = parentFile.metadata.transcodedID;
const bucket = new mongoose.mongo.GridFSBucket(conn.db, {
bucketName: "videos"
});
try {
yield bucket.delete(ObjectID(transcodedVideoID));
}
catch (e) {
console.log("Could Not Find Transcoded Video");
}
const file = yield dbUtilsFile.removeTranscodeVideo(fileID, userID);
if (!file)
throw new NotFoundError("Remove Transcode Video Error");
});
this.streamTranscodedVideo = (userID, fileID, headers, res) => {
return new Promise((resolve, reject) => {
dbUtilsFile.getFileInfo(fileID, userID).then((file) => {
if (!file) {
reject({
code: 401,
message: "Stream Transcoded File Not Found",
exception: undefined
});
}
else {
const fileSize = file.metadata.transcoded_size;
const transcodedVideoID = file.metadata.transcodedID;
const password = user.getEncryptionKey(); //env.key;
const range = headers.range;
const parts = range.replace(/bytes=/, "").split("-");
const start = parseInt(parts[0], 10);
const end = parts[1]
? parseInt(parts[1], 10)
: fileSize - 1;
const chunksize = (end - start) + 1;
const IV = file.metadata.transcodedIV.buffer;
let head = {
'Content-Range': 'bytes ' + start + '-' + end + '/' + fileSize,
'Accept-Ranges': 'bytes',
'Content-Length': chunksize,
'Content-Type': 'video/mp4'
};
const bucket = new mongoose.mongo.GridFSBucket(conn.db, {
bucketName: "videos",
chunkSizeBytes: chunksize
});
const readStream = bucket.openDownloadStream(ObjectID(transcodedVideoID), {
start: start,
end: end
});
readStream.on("error", (e) => {
reject({
code: 500,
message: "File service transcode video stream error",
exception: e
});
});
const CIPHER_KEY = crypto_1.default.createHash('sha256').update(password).digest();
const decipher = crypto_1.default.createDecipheriv('aes256', CIPHER_KEY, IV);
decipher.setAutoPadding(false);
decipher.on("error", (e) => {
reject({
code: 500,
message: "File service transcode video decipher error",
exception: e
});
});
res.writeHead(206, head);
readStream.pipe(decipher).pipe(res).on("finish", () => {
resolve();
});
}
});
});
};
this.streamVideo = (user, fileID, headers, res) => {
return new Promise((resolve, reject) => {
const userID = user._id;
dbUtilsFile.getFileInfo(fileID, userID).then((currentFile) => {
if (!currentFile) {
reject({
code: 401,
message: "Video Steam Not Found Error",
exception: undefined
});
}
else {
const password = user.getEncryptionKey();
const fileSize = currentFile.metadata.size;
const range = headers.range;
const parts = range.replace(/bytes=/, "").split("-");
let start = parseInt(parts[0], 10);
let end = parts[1]
? parseInt(parts[1], 10)
: fileSize - 1;
const chunksize = (end - start) + 1;
const IV = currentFile.metadata.IV.buffer;
let head = {
'Content-Range': 'bytes ' + start + '-' + end + '/' + fileSize,
'Accept-Ranges': 'bytes',
'Content-Length': chunksize,
'Content-Type': 'video/mp4'
};
const bucket = new mongoose.mongo.GridFSBucket(conn.db, {
chunkSizeBytes: 1024
});
const readStream = bucket.openDownloadStream(ObjectID(fileID), {
start: start,
end: end.length
});
readStream.on("error", (e) => {
reject({
code: 500,
message: "File service stream video stream error",
exception: e
});
});
const CIPHER_KEY = crypto_1.default.createHash('sha256').update(password).digest();
const decipher = crypto_1.default.createDecipheriv('aes256', CIPHER_KEY, IV);
decipher.on("error", (e) => {
reject({
code: 500,
message: "File service stream video decipher error",
exception: e
});
});
res.writeHead(206, head);
readStream.pipe(decipher).pipe(res).on("finish", () => {
resolve();
});
}
});
});
};
this.downloadFile = (user, fileID, res) => {
return new Promise((resolve, reject) => {
const userID = user._id;
dbUtilsFile.getFileInfo(fileID, userID).then((file) => {
if (!file) {
reject({
code: 401,
message: "Download File Not Found Error",
exception: undefined
});
}
else {
const password = user.getEncryptionKey();
const bucket = new mongoose.mongo.GridFSBucket(conn.db);
const IV = file.metadata.IV.buffer;
const readStream = bucket.openDownloadStream(ObjectID(fileID));
readStream.on("error", (e) => {
reject({
code: 500,
message: "File service download decipher error",
exception: e
});
});
const CIPHER_KEY = crypto_1.default.createHash('sha256').update(password).digest();
const decipher = crypto_1.default.createDecipheriv('aes256', CIPHER_KEY, IV);
decipher.on("error", (e) => {
reject({
code: 500,
message: "File service download decipher error",
exception: e
});
});
res.set('Content-Type', 'binary/octet-stream');
res.set('Content-Disposition', 'attachment; filename="' + file.filename + '"');
res.set('Content-Length', file.metadata.size);
readStream.pipe(decipher).pipe(res).on("finish", () => {
resolve();
});
}
});
});
};
this.getSuggestedList = (userID, searchQuery) => __awaiter(this, void 0, void 0, function* () {
searchQuery = new RegExp(searchQuery, 'i');
const fileList = yield dbUtilsFile.getFileSearchList(userID, searchQuery);
const folderList = yield dbUtilsFolder.getFolderSearchList(userID, searchQuery);
if (!fileList || !folderList)
throw new NotFoundError("Suggested List Not Found Error");
return {
fileList,
folderList
};
});
this.renameFile = (userID, fileID, title) => __awaiter(this, void 0, void 0, function* () {
const file = yield dbUtilsFile.renameFile(fileID, userID, title);
if (!file.lastErrorObject.updatedExisting)
throw new NotFoundError("Rename File Not Found Error");
return file;
});
this.moveFile = (userID, fileID, parentID) => __awaiter(this, void 0, void 0, function* () {
let parentList = ["/"];
if (parentID.length !== 1) {
const parentFile = yield dbUtilsFolder.getFolderInfo(parentID, userID);
if (!parentFile)
throw new NotFoundError("Rename Parent File Not Found Error");
const parentList = parentFile.parentList;
parentList.push(parentID);
}
const file = yield dbUtilsFile.moveFile(fileID, userID, parentID, parentList.toString());
if (!file.lastErrorObject.updatedExisting)
throw new NotFoundError("Rename File Not Found Error");
return file;
});
this.deleteFile = (userID, fileID) => __awaiter(this, void 0, void 0, function* () {
let bucket = new mongoose.mongo.GridFSBucket(conn.db, {
chunkSizeBytes: 1024 * 255,
});
const videoBucket = new mongoose.mongo.GridFSBucket(conn.db, {
bucketName: "videos"
});
const file = yield dbUtilsFile.getFileInfo(fileID, userID);
if (!file)
throw new NotFoundError("Delete File Not Found Error");
if (file.metadata.thumbnailID) {
yield Thumbnail.deleteOne({ _id: file.metadata.thumbnailID });
}
if (file.metadata.isVideo && file.metadata.transcoded) {
try {
yield bucket.delete(ObjectID(file.metadata.transcodedID));
}
catch (e) {
console.log("Could Not Find Transcoded Video");
}
}
yield bucket.delete(ObjectID(fileID));
});
};
module.exports = FileService;
+209
View File
@@ -0,0 +1,209 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const imageChecker = require("../../utils/imageChecker");
const crypto_1 = __importDefault(require("crypto"));
const videoChecker = require("../../utils/videoChecker");
const mongoose = require("../../db/mongoose");
const conn = mongoose.connection;
const createThumbnail = require("../../services/FileService/utils/createThumbnail");
const thumbnail_1 = __importDefault(require("../../models/thumbnail"));
const ObjectID = require('mongodb').ObjectID;
const NotAuthorizedError_1 = __importDefault(require("../../utils/NotAuthorizedError"));
const NotFoundError_1 = __importDefault(require("../../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");
const index_1 = __importDefault(require("../../db/utils/fileUtils/index"));
const DbUtilFolder = require("../../db/utils/folderUtils");
const dbUtilsFile = new index_1.default();
const dbUtilsFolder = new DbUtilFolder();
class MongoFileService {
constructor() {
this.getThumbnail = (user, id) => __awaiter(this, void 0, void 0, function* () {
const password = user.getEncryptionKey();
const thumbnail = yield thumbnail_1.default.findById(id);
if (thumbnail.owner !== user._id.toString()) {
throw new NotAuthorizedError_1.default('Thumbnail Unauthorized Error');
}
const iv = thumbnail.data.slice(0, 16);
const chunk = thumbnail.data.slice(16);
const CIPHER_KEY = crypto_1.default.createHash('sha256').update(password).digest();
const decipher = crypto_1.default.createDecipheriv("aes256", CIPHER_KEY, iv);
const decryptedThumbnail = Buffer.concat([decipher.update(chunk), decipher.final()]);
return decryptedThumbnail;
});
this.removePublicOneTimeLink = (currentFile) => __awaiter(this, void 0, void 0, function* () {
const fileID = currentFile._id;
if (currentFile.metadata.linkType === "one") {
yield dbUtilsFile.removeOneTimePublicLink(fileID);
}
});
this.removeLink = (userID, fileID) => __awaiter(this, void 0, void 0, function* () {
const file = yield dbUtilsFile.removeLink(fileID, userID);
if (!file.lastErrorObject.updatedExisting)
throw new NotFoundError_1.default("Remove Link File Not Found Error");
});
this.makePublic = (user, fileID) => __awaiter(this, void 0, void 0, function* () {
const userID = user._id;
const token = yield jwt.sign({ _id: userID.toString() }, env.password);
const file = yield dbUtilsFile.makePublic(fileID, userID, token);
if (!file.lastErrorObject.updatedExisting)
throw new NotFoundError_1.default("Make Public File Not Found Error");
return token;
});
this.getPublicInfo = (fileID, tempToken) => __awaiter(this, void 0, void 0, function* () {
const file = yield dbUtilsFile.getPublicInfo(fileID, tempToken);
if (!file || !file.metadata.link || file.metadata.link !== tempToken) {
throw new NotFoundError_1.default("Public Info Not Found");
}
else {
return file;
}
});
this.makeOneTimePublic = (userID, fileID) => __awaiter(this, void 0, void 0, function* () {
const token = yield jwt.sign({ _id: userID.toString() }, env.password);
const file = yield dbUtilsFile.makeOneTimePublic(fileID, userID, token);
if (!file.lastErrorObject.updatedExisting)
throw new NotFoundError_1.default("Make One Time Public Not Found Error");
return token;
});
this.getFileInfo = (userID, fileID) => __awaiter(this, void 0, void 0, function* () {
let currentFile = yield dbUtilsFile.getFileInfo(fileID, userID);
if (!currentFile)
throw new NotFoundError_1.default("Get File Info Not Found Error");
const parentID = currentFile.metadata.parent;
let parentName = "";
if (parentID === "/") {
parentName = "Home";
}
else {
const parentFolder = yield Folder.findOne({ "owner": userID, "_id": parentID });
if (parentFolder) {
parentName = parentFolder.name;
}
else {
parentName = "Unknown";
}
}
return Object.assign(Object.assign({}, currentFile), { parentName });
});
this.getQuickList = (userID) => __awaiter(this, void 0, void 0, function* () {
const quickList = yield dbUtilsFile.getQuickList(userID);
if (!quickList)
throw new NotFoundError_1.default("Quick List Not Found Error");
return quickList;
});
this.getList = (userID, query) => __awaiter(this, void 0, void 0, function* () {
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 = yield dbUtilsFile.getList(queryObj, sortBy, limit);
if (!fileList)
throw new NotFoundError_1.default("File List Not Found");
return fileList;
});
this.getDownloadToken = (user) => __awaiter(this, void 0, void 0, function* () {
const tempToken = yield user.generateTempAuthToken();
if (!tempToken)
throw new NotAuthorizedError_1.default("Get Download Token Not Authorized Error");
return tempToken;
});
this.getDownloadTokenVideo = (user, cookie) => __awaiter(this, void 0, void 0, function* () {
if (!cookie)
throw new NotAuthorizedError_1.default("Get Download Token Video Cookie Not Authorized Error");
const tempToken = yield user.generateTempAuthTokenVideo(cookie);
if (!tempToken)
throw new NotAuthorizedError_1.default("Get Download Token Video Not Authorized Error");
return tempToken;
});
this.removeTempToken = (user, tempToken) => __awaiter(this, void 0, void 0, function* () {
const key = user.getEncryptionKey();
const decoded = yield jwt.verify(tempToken, env.password);
const publicKey = decoded.iv;
const encryptedToken = user.encryptToken(tempToken, key, publicKey);
const removedTokenUser = yield dbUtilsFile.removeTempToken(user, encryptedToken);
if (!removedTokenUser)
throw new NotFoundError_1.default("Remove Temp Token User Not Found Errors");
yield removedTokenUser.save();
});
this.getSuggestedList = (userID, searchQuery) => __awaiter(this, void 0, void 0, function* () {
searchQuery = new RegExp(searchQuery, 'i');
const fileList = yield dbUtilsFile.getFileSearchList(userID, searchQuery);
const folderList = yield dbUtilsFolder.getFolderSearchList(userID, searchQuery);
if (!fileList || !folderList)
throw new NotFoundError_1.default("Suggested List Not Found Error");
return {
fileList,
folderList
};
});
this.renameFile = (userID, fileID, title) => __awaiter(this, void 0, void 0, function* () {
const file = yield dbUtilsFile.renameFile(fileID, userID, title);
if (!file.lastErrorObject.updatedExisting)
throw new NotFoundError_1.default("Rename File Not Found Error");
return file;
});
this.moveFile = (userID, fileID, parentID) => __awaiter(this, void 0, void 0, function* () {
let parentList = ["/"];
if (parentID.length !== 1) {
const parentFile = yield dbUtilsFolder.getFolderInfo(parentID, userID);
if (!parentFile)
throw new NotFoundError_1.default("Rename Parent File Not Found Error");
const parentList = parentFile.parentList;
parentList.push(parentID);
}
const file = yield dbUtilsFile.moveFile(fileID, userID, parentID, parentList.toString());
if (!file.lastErrorObject.updatedExisting)
throw new NotFoundError_1.default("Rename File Not Found Error");
return file;
});
this.deleteFile = (userID, fileID) => __awaiter(this, void 0, void 0, function* () {
let bucket = new mongoose.mongo.GridFSBucket(conn.db, {
chunkSizeBytes: 1024 * 255,
});
const file = yield dbUtilsFile.getFileInfo(fileID, userID);
if (!file)
throw new NotFoundError_1.default("Delete File Not Found Error");
if (file.metadata.thumbnailID) {
yield thumbnail_1.default.deleteOne({ _id: file.metadata.thumbnailID });
}
if (file.metadata.isVideo && file.metadata.transcoded) {
try {
yield bucket.delete(ObjectID(file.metadata.transcodedID));
}
catch (e) {
console.log("Could Not Find Transcoded Video");
}
}
yield bucket.delete(ObjectID(fileID));
});
}
}
exports.default = MongoFileService;
+65
View File
@@ -0,0 +1,65 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
const mongoose = require("../../../db/mongoose");
const conn = mongoose.connection;
const crypto = require("crypto");
const env = require("../../../enviroment/env");
const Thumbnail = require("../../../models/thumbnail");
const ObjectID = require('mongodb').ObjectID;
const sharp = require("sharp");
const concat = require("concat-stream");
const createThumbnail = (file, filename, user) => __awaiter(void 0, void 0, void 0, function* () {
return new Promise((resolve) => {
const password = user.getEncryptionKey();
let CIPHER_KEY = crypto.createHash('sha256').update(password).digest();
let bucket = new mongoose.mongo.GridFSBucket(conn.db, {
chunkSizeBytes: 1024 * 255
});
const readStream = bucket.openDownloadStream(ObjectID(file._id));
readStream.on("error", (e) => {
console.log("File service upload thumbnail error", e);
resolve(file);
});
const decipher = crypto.createDecipheriv('aes256', CIPHER_KEY, file.metadata.IV);
decipher.on("error", (e) => {
console.log("File service upload thumbnail decipher error", e);
resolve(file);
});
try {
const concatStream = concat((bufferData) => __awaiter(void 0, void 0, void 0, function* () {
const thumbnailIV = crypto.randomBytes(16);
//CIPHER_KEY = crypto.createHash('sha256').update(process.env.newPassword).digest()
const thumbnailCipher = crypto.createCipheriv("aes256", CIPHER_KEY, thumbnailIV);
bufferData = Buffer.concat([thumbnailIV, thumbnailCipher.update(bufferData), thumbnailCipher.final()]); //thumbnailCipher.update(bufferData)
const thumbnailModel = new Thumbnail({ name: filename, owner: user._id, data: bufferData });
yield thumbnailModel.save();
let updatedFile = yield conn.db.collection("fs.files")
.findOneAndUpdate({ "_id": file._id }, { "$set": { "metadata.hasThumbnail": true, "metadata.thumbnailID": thumbnailModel._id } });
updatedFile = updatedFile.value;
updatedFile = Object.assign(Object.assign({}, updatedFile), { metadata: Object.assign(Object.assign({}, updatedFile.metadata), { hasThumbnail: true, thumbnailID: thumbnailModel._id }) });
resolve(updatedFile);
})).on("error", (e) => {
console.log("File service upload concat stream error", e);
resolve(file);
});
const imageResize = sharp().resize(300).on("error", (e) => {
console.log("resize error", e);
resolve(file);
});
readStream.pipe(decipher).pipe(imageResize).pipe(concatStream);
}
catch (e) {
console.log(e);
resolve(file);
}
});
});
module.exports = createThumbnail;
+27
View File
@@ -0,0 +1,27 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
const DbUtilsFile = require("../../../db/utils/fileUtils");
const dbUtilsFile = new DbUtilsFile();
const removeChunks = (bucketStream) => __awaiter(void 0, void 0, void 0, function* () {
try {
const uploadID = bucketStream.id;
if (!uploadID || uploadID.length === 0) {
console.log("Invalid uploadID for remove chunks");
return;
}
yield dbUtilsFile.removeChunksByID(uploadID);
console.log("Upload Request Cancelled, Chunks Removed");
}
catch (e) {
console.log("Could not remove chunks for canceled upload", uploadID, e);
}
});
module.exports = removeChunks;
+202
View File
@@ -0,0 +1,202 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
const Folder = require("../../models/folder");
const InternalServerError = require("../../utils/InternalServerError");
const NotFoundError = require("../../utils/NotFoundError");
const UtilsFile = require("../../db/utils/fileUtils");
const ObjectID = require('mongodb').ObjectID;
const UtilsFolder = require("../../db/utils/folderUtils");
const mongoose = require("../../db/mongoose");
const conn = mongoose.connection;
const Thumbnail = require("../../models/thumbnail");
const sortBySwitch = require("../../utils/sortBySwitchFolder");
const utilsFile = new UtilsFile();
const utilsFolder = new UtilsFolder();
const FolderService = function () {
this.uploadFolder = (data) => __awaiter(this, void 0, void 0, function* () {
const folder = new Folder(data);
yield folder.save();
if (!folder)
throw new InternalServerError("Upload Folder Error");
return folder;
});
this.deleteFolder = (userID, folderID, parentList) => __awaiter(this, void 0, void 0, function* () {
let bucket = new mongoose.mongo.GridFSBucket(conn.db, {
chunkSizeBytes: 1024 * 255
});
const videoBucket = new mongoose.mongo.GridFSBucket(conn.db, {
bucketName: "videos"
});
const parentListString = parentList.toString();
yield Folder.deleteMany({ "owner": userID, "parentList": { $all: parentList } });
yield Folder.deleteMany({ "owner": userID, "_id": folderID });
const fileList = yield utilsFile.getFileListByParent(userID, parentListString);
if (!fileList)
throw new NotFoundError("Delete File List Not Found");
for (let i = 0; i < fileList.length; i++) {
const currentFile = fileList[i];
try {
if (currentFile.metadata.thumbnailID) {
yield Thumbnail.deleteOne({ _id: currentFile.metadata.thumbnailID });
}
if (currentFile.metadata.isVideo && currentFile.metadata.transcoded) {
try {
yield videoBucket.delete(ObjectID(currentFile.metadata.transcodedID));
}
catch (e) {
console.log("Could Not Find Transcoded Video");
}
}
yield bucket.delete(ObjectID(currentFile._id));
}
catch (e) {
console.log("Could not delete file", currentFile.filename, currentFile._id);
}
}
});
this.deleteAll = (userID) => __awaiter(this, void 0, void 0, function* () {
console.log("remove all request");
let bucket = new mongoose.mongo.GridFSBucket(conn.db, {
chunkSizeBytes: 1024 * 255
});
const videoBucket = new mongoose.mongo.GridFSBucket(conn.db, {
bucketName: "videos"
});
yield Folder.deleteMany({ "owner": userID });
const fileList = yield utilsFile.getFileListByOwner(userID);
if (!fileList)
throw new NotFoundError("Delete All File List Not Found Error");
for (let i = 0; i < fileList.length; i++) {
const currentFile = fileList[i];
try {
if (currentFile.metadata.thumbnailID) {
yield Thumbnail.deleteOne({ _id: currentFile.metadata.thumbnailID });
}
if (currentFile.metadata.isVideo && currentFile.metadata.transcoded) {
try {
yield videoBucket.delete(ObjectID(currentFile.metadata.transcodedID));
}
catch (e) {
console.log("Cannot Find Transcoded Video");
}
}
yield bucket.delete(ObjectID(currentFile._id));
}
catch (e) {
console.log("Could Not Remove File", currentFile.filename, currentFile._id);
}
}
});
this.getFolderInfo = (userID, folderID) => __awaiter(this, void 0, void 0, function* () {
let currentFolder = yield utilsFolder.getFolderInfo(folderID, userID);
if (!currentFolder)
throw new NotFoundError("Folder Info Not Found Error");
const parentID = currentFolder.parent;
let parentName = "";
if (parentID === "/") {
parentName = "Home";
}
else {
const parentFolder = yield utilsFolder.getFolderInfo(parentID, userID);
if (parentFolder) {
parentName = parentFolder.name;
}
else {
parentName = "Unknown";
}
}
const folderName = currentFolder.name;
currentFolder = Object.assign(Object.assign({}, currentFolder._doc), { parentName, folderName });
// Must Use ._doc here, or the destucturing/spreading
// Will add a bunch of unneeded variables to the object.
return currentFolder;
});
this.getFolderSublist = (userID, folderID) => __awaiter(this, void 0, void 0, function* () {
const folder = yield utilsFolder.getFolderInfo(folderID, userID);
if (!folder)
throw new NotFoundError("Folder Sublist Not Found Error");
const subfolderList = folder.parentList;
let folderIDList = [];
let folderNameList = [];
for (let i = 0; i < subfolderList.length; i++) {
const currentSubFolderID = subfolderList[i];
if (currentSubFolderID === "/") {
folderIDList.push("/");
folderNameList.push("Home");
}
else {
const currentFolder = yield utilsFolder.getFolderInfo(currentSubFolderID, userID);
folderIDList.push(currentFolder._id);
folderNameList.push(currentFolder.name);
}
}
folderIDList.push(folderID);
folderNameList.push(folder.name);
return {
folderIDList,
folderNameList
};
});
this.getFolderList = (userID, query) => __awaiter(this, void 0, void 0, function* () {
let searchQuery = query.search || "";
const parent = query.parent || "/";
let sortBy = query.sortby || "DEFAULT";
sortBy = sortBySwitch(sortBy);
if (searchQuery.length === 0) {
const folderList = yield utilsFolder.getFolderListByParent(userID, parent, sortBy);
if (!folderList)
throw new NotFoundError("Folder List Not Found Error");
return folderList;
}
else {
searchQuery = new RegExp(searchQuery, 'i');
const folderList = yield utilsFolder.getFolderListBySearch(userID, searchQuery, sortBy);
if (!folderList)
throw new NotFoundError("Folder List Not Found Error");
return folderList;
}
});
this.renameFolder = (userID, folderID, title) => __awaiter(this, void 0, void 0, function* () {
const folder = yield utilsFolder.renameFolder(folderID, userID, title);
if (!folder)
throw new NotFoundError("Rename Folder Not Found");
});
this.moveFolder = (userID, folderID, parentID) => __awaiter(this, void 0, void 0, function* () {
let parentList = ["/"];
if (parentID.length !== 1) {
const parentFile = yield utilsFolder.getFolderInfo(parentID, userID);
parentList = parentFile.parentList;
parentList.push(parentID);
}
const folder = yield utilsFolder.moveFolder(folderID, userID, parentID, parentList);
if (!folder)
throw new NotFoundError("Move Folder Not Found");
const folderChilden = yield utilsFolder.findAllFoldersByParent(folderID.toString(), userID);
folderChilden.map((currentFolderChild) => __awaiter(this, void 0, void 0, function* () {
let currentFolderChildParentList = currentFolderChild.parentList;
const indexOfFolderID = currentFolderChildParentList.indexOf(folderID.toString());
currentFolderChildParentList = currentFolderChildParentList.splice(indexOfFolderID);
currentFolderChildParentList = [...parentList, ...currentFolderChildParentList];
currentFolderChild.parentList = currentFolderChildParentList;
yield currentFolderChild.save();
}));
const fileChildren = yield utilsFile.getFileListByParent(userID, folderID.toString());
fileChildren.map((currentFileChild) => __awaiter(this, void 0, void 0, function* () {
let currentFileChildParentList = currentFileChild.metadata.parentList;
currentFileChildParentList = currentFileChildParentList.split(",");
const indexOfFolderID = currentFileChildParentList.indexOf(folderID.toString());
currentFileChildParentList = currentFileChildParentList.splice(indexOfFolderID);
currentFileChildParentList = [...parentList, ...currentFileChildParentList];
yield utilsFile.moveFile(currentFileChild._id, userID, currentFileChild.metadata.parent, currentFileChildParentList.toString());
}));
});
};
module.exports = FolderService;
+62
View File
@@ -0,0 +1,62 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
const User = require("../../models/user");
const bcrypt = require("bcrypt");
const crypto = require("crypto");
const NotFoundError = require("../../utils/NotFoundError");
const InternalServerError = require("../../utils/InternalServerError");
const NotAuthorizedError = require("../../utils/NotAuthorizedError");
const UserService = function () {
this.login = (userData) => __awaiter(this, void 0, void 0, function* () {
const email = userData.email;
const password = userData.password;
const user = yield User.findByCreds(email, password);
const token = yield user.generateAuthToken();
if (!user || !token)
throw new NotFoundError("Login User Not Found Error");
return { user, token };
});
this.logout = (user, userToken) => __awaiter(this, void 0, void 0, function* () {
user.tokens = user.tokens.filter((token) => {
return token.token !== userToken;
});
yield user.save();
});
this.logoutAll = (user) => __awaiter(this, void 0, void 0, function* () {
user.tokens = [];
user.tempTokens = [];
yield user.save();
});
this.create = (userData) => __awaiter(this, void 0, void 0, function* () {
console.log("Create");
const user = new User(userData);
yield user.save();
yield user.generateEncryptionKeys();
const token = yield user.generateAuthToken();
if (!user || !token)
throw new InternalServerError("Could Not Create New User Error");
return { user, token };
});
this.changePassword = (user, oldPassword, newPassword) => __awaiter(this, void 0, void 0, function* () {
const isMatch = yield bcrypt.compare(oldPassword, user.password);
if (!isMatch)
throw new NotAuthorizedError("Change Passwords Do Not Match Error");
const encryptionKey = user.getEncryptionKey();
user.password = newPassword;
user.tokens = [];
user.tempTokens = [];
yield user.save();
yield user.changeEncryptionKey(encryptionKey);
const newToken = yield user.generateAuthToken();
return newToken;
});
};
module.exports = UserService;
+1
View File
@@ -0,0 +1 @@
"use strict";
+8
View File
@@ -0,0 +1,8 @@
"use strict";
class InternalServerError extends Error {
constructor(args) {
super(args);
this.code = 500;
}
}
module.exports = InternalServerError;
+8
View File
@@ -0,0 +1,8 @@
"use strict";
class NotAuthorizedError extends Error {
constructor(args) {
super(args);
this.code = 401;
}
}
module.exports = NotAuthorizedError;
+8
View File
@@ -0,0 +1,8 @@
"use strict";
class NotFoundError extends Error {
constructor(args) {
super(args);
this.code = 404;
}
}
module.exports = NotFoundError;
+9
View File
@@ -0,0 +1,9 @@
"use strict";
const createError = (message, code, exception) => {
let error = new Error(message);
error.message = message;
error.code = code;
error.exception = exception;
throw error;
};
module.exports = createError;
+27
View File
@@ -0,0 +1,27 @@
"use strict";
const createQuery = (owner, parent, sortBy, startAt, startAtDate, searchQuery, startAtName) => {
let query = { "metadata.owner": owner };
if (searchQuery !== "") {
searchQuery = new RegExp(searchQuery, 'i');
query = Object.assign(Object.assign({}, query), { filename: searchQuery });
}
else {
query = Object.assign(Object.assign({}, query), { "metadata.parent": parent });
}
if (startAt) {
if (sortBy === "date_desc" || sortBy === "DEFAULT") {
query = Object.assign(Object.assign({}, query), { "uploadDate": { $lt: new Date(startAtDate) } });
}
else if (sortBy === "date_asc") {
query = Object.assign(Object.assign({}, query), { "uploadDate": { $gt: new Date(startAtDate) } });
}
else if (sortBy === "alp_desc") {
query = Object.assign(Object.assign({}, query), { "filename": { $lt: startAtName } });
}
else {
query = Object.assign(Object.assign({}, query), { "filename": { $gt: startAtName } });
}
}
return query;
};
module.exports = createQuery;
+22
View File
@@ -0,0 +1,22 @@
"use strict";
const videoExtList = [
"jpeg",
"jpg",
"png",
"gif",
"svg",
"tiff",
"bmp"
];
const videoChecker = (filename) => {
if (filename.length < 1 || !filename.includes(".")) {
return false;
}
const extSplit = filename.split(".");
if (extSplit < 1) {
return false;
}
const ext = extSplit[extSplit.length - 1];
return videoExtList.includes(ext.toLowerCase());
};
module.exports = videoChecker;
+9
View File
@@ -0,0 +1,9 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const mobilecheck = () => {
var check = false;
(function (a) { if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4)))
check = true; })(navigator.userAgent || navigator.vendor || window.opera);
return check;
};
exports.default = mobilecheck;
+14
View File
@@ -0,0 +1,14 @@
"use strict";
const sortBySwitch = (sortBy) => {
switch (sortBy) {
case "alp_asc":
return { filename: 1 };
case "alp_desc":
return { filename: -1 };
case "date_asc":
return { uploadDate: 1 };
default:
return { uploadDate: -1 };
}
};
module.exports = sortBySwitch;
+14
View File
@@ -0,0 +1,14 @@
"use strict";
const sortBySwitch = (sortBy) => {
switch (sortBy) {
case "alp_asc":
return { name: 1 };
case "alp_desc":
return { name: -1 };
case "date_asc":
return { createdAt: 1 };
default:
return { createdAt: -1 };
}
};
module.exports = sortBySwitch;
+48
View File
@@ -0,0 +1,48 @@
"use strict";
const videoExtList = [
"3g2",
"3gp",
"aaf",
"asf",
"avchd",
"avi",
"drc",
"flv",
"m2v",
"m4p",
"m4v",
"mkv",
"mng",
"mov",
"mp2",
"mp4",
"mpe",
"mpeg",
"mpg",
"mpv",
"mxf",
"nsv",
"ogg",
"ogv",
"qt",
"rm",
"rmvb",
"roq",
"svi",
"vob",
"webm",
"wmv",
"yuv"
];
const videoChecker = (filename) => {
if (filename.length < 1 || !filename.includes(".")) {
return false;
}
const extSplit = filename.split(".");
if (extSplit < 1) {
return false;
}
const ext = extSplit[extSplit.length - 1];
return videoExtList.includes(ext.toLowerCase());
};
module.exports = videoChecker;
+8 -1
View File
@@ -12,7 +12,7 @@
"test": "cross-env NODE_ENV=test env-cmd -f ./config/test.env jest --config=jest.config.json --watchAll --runInBand",
"start:dev": "env-cmd -f ./config/dev.env node server/serverStart.js",
"start": "cross-env NODE_ENV=production env-cmd -f ./config/prod.env node server/serverStart.js --env production",
"start:no-ssl": "cross-env NODE_ENV=production-no-ssl env-cmd -f ./config/prod.env node server/serverStart.js --env production-no-ssl",
"start:no-ssl": "cross-env NODE_ENV=production-no-ssl env-cmd -f ./config/prod.env node dist/server/serverStart.js --env production-no-ssl",
"clean-database": "env-cmd -f ./config/prod.env node serverUtils/cleanDatabase.js",
"clean-database:dev": "env-cmd -f ./config/dev.env node serverUtils/cleanDatabase.js",
"backup-database": "env-cmd -f ./config/prod.env node serverUtils/backupDatabase.js",
@@ -32,10 +32,16 @@
},
"dependencies": {
"@babel/core": "^7.8.4",
"@babel/parser": "^7.9.4",
"@babel/plugin-proposal-class-properties": "^7.8.3",
"@babel/plugin-proposal-object-rest-spread": "^7.8.3",
"@babel/preset-env": "^7.8.4",
"@babel/preset-react": "^7.8.3",
"@babel/types": "^7.9.5",
"@types/express": "^4.17.6",
"@types/mongodb": "^3.5.5",
"@types/mongoose": "^5.7.10",
"@types/node": "^13.11.1",
"axios": "^0.19.2",
"babel-polyfill": "^6.26.0",
"bcrypt": "^3.0.8",
@@ -76,6 +82,7 @@
"sharp": "^0.23.4",
"sweetalert2": "^9.7.2",
"temp": "^0.9.1",
"typescript": "^3.8.3",
"uuid": "^3.4.0",
"validator": "^12.2.0",
"webpack": "^4.41.6"
-1
View File
@@ -1 +0,0 @@
module.exports = __dirname
+74
View File
@@ -0,0 +1,74 @@
{
"compilerOptions": {
/* Basic Options */
// "incremental": true, /* Enable incremental compilation */
"target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
"module": "CommonJS", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
// "lib": [], /* Specify library files to be included in the compilation. */
"allowJs": true, /* Allow javascript files to be compiled. */
// "checkJs": true, /* Report errors in .js files. */
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
// "declaration": true, /* Generates corresponding '.d.ts' file. */
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
// "sourceMap": true, /* Generates corresponding '.map' file. */
// "outFile": "./", /* Concatenate and emit output to single file. */
"outDir": "./dist", /* Redirect output structure to the directory. */
"rootDir": "./backend", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
// "composite": true, /* Enable project compilation */
// "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
// "removeComments": true, /* Do not emit comments to output. */
// "noEmit": true, /* Do not emit outputs. */
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
/* Strict Type-Checking Options */
"strict": true, /* Enable all strict type-checking options. */
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* Enable strict null checks. */
// "strictFunctionTypes": true, /* Enable strict checking of function types. */
// "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
/* Additional Checks */
// "noUnusedLocals": true, /* Report errors on unused locals. */
// "noUnusedParameters": true, /* Report errors on unused parameters. */
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
/* Module Resolution Options */
"moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
// "typeRoots": [], /* List of folders to include type definitions from. */
// "types": [], /* Type declaration files to be included in compilation. */
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
/* Source Map Options */
// "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
// "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
/* Experimental Options */
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
/* Advanced Options */
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
},
"exclude": [
"serverUtils",
"src",
"tests",
"key",
"public",
"node_modules",
"webpack.config.js",
"dist"
]
}