From c0880761403e0162a0e66860a5ad75a4f0d38678 Mon Sep 17 00:00:00 2001 From: subnub Date: Sun, 9 Jun 2024 00:28:42 -0400 Subject: [PATCH] fixed hotloading, fixed _id types, fixed some links, downloading, and started imrpoving db code --- backend/db/utils/fileUtils/index.ts | 39 +- .../middleware/authNoEmailVerificication.ts | 3 +- backend/middleware/authRefresh.ts | 3 +- backend/middleware/authStreamVideo.ts | 3 +- backend/models/file.ts | 4 +- backend/models/user.ts | 992 +++--- .../ChunkService/FileSystemService.ts | 29 +- backend/services/ChunkService/S3Service.ts | 19 +- .../ChunkService/utils/getBusboyData.ts | 59 +- backend/services/FileService/index.ts | 10 +- backend/services/FolderService/index.ts | 4 +- backend/utils/createQuery.ts | 4 +- backend/utils/userUpdateCheck.ts | 51 +- index.html | 24 + nodemon.json | 6 + package.json | 12 +- src/actions/auth.js | 297 +- src/actions/files.js | 964 +++--- src/axiosInterceptor/index.js | 144 +- src/components/Header/Header.js | 117 +- src/components/Header/index.js | 403 ++- src/components/LoginPage/LoginPage.js | 394 ++- src/components/MainSection/index.js | 533 ++-- src/components/QuickAccess/QuickAccess.js | 43 +- src/components/SettingsPage/index.js | 2797 ++++++++++------- src/enviroment/envFrontEnd.js | 26 +- src/utils/reduceQuickItemList.js | 21 +- tsconfig.json | 3 +- vite.config.js | 17 +- 29 files changed, 3893 insertions(+), 3128 deletions(-) create mode 100644 index.html create mode 100644 nodemon.json diff --git a/backend/db/utils/fileUtils/index.ts b/backend/db/utils/fileUtils/index.ts index c3a8fad..f4508b7 100644 --- a/backend/db/utils/fileUtils/index.ts +++ b/backend/db/utils/fileUtils/index.ts @@ -1,6 +1,6 @@ import mongoose from "../../mongoose"; import { ObjectId } from "mongodb"; -import { FileInterface } from "../../../models/file"; +import File, { FileInterface } from "../../../models/file"; import { UserInterface } from "../../../models/user"; import { QueryInterface } from "../../../utils/createQuery"; const conn = mongoose.connection; @@ -19,6 +19,7 @@ class DbUtil { removeOneTimePublicLink = async ( fileID: string | mongoose.Types.ObjectId ) => { + mongoose; const file = (await conn.db.collection("fs.files").findOneAndUpdate( { _id: new ObjectId(fileID) }, { @@ -33,7 +34,7 @@ class DbUtil { const file = (await conn.db .collection("fs.files") .findOneAndUpdate( - { _id: new ObjectId(fileID), "metadata.owner": new ObjectId(userID) }, + { _id: new ObjectId(fileID), "metadata.owner": userID }, { $unset: { "metadata.linkType": "", "metadata.link": "" } } )) as FileInterface; @@ -44,7 +45,7 @@ class DbUtil { const file = (await conn.db .collection("fs.files") .findOneAndUpdate( - { _id: new ObjectId(fileID), "metadata.owner": new ObjectId(userID) }, + { _id: new ObjectId(fileID), "metadata.owner": userID }, { $set: { "metadata.linkType": "public", "metadata.link": token } } )) as FileInterface; @@ -64,7 +65,7 @@ class DbUtil { const file = (await conn.db .collection("fs.files") .findOneAndUpdate( - { _id: new ObjectId(fileID), "metadata.owner": new ObjectId(userID) }, + { _id: new ObjectId(fileID), "metadata.owner": userID }, { $set: { "metadata.linkType": "one", "metadata.link": token } } )) as FileInterface; @@ -72,16 +73,17 @@ class DbUtil { }; getFileInfo = async (fileID: string, userID: string) => { - const file = (await conn.db.collection("fs.files").findOne({ - "metadata.owner": new ObjectId(userID), + console.log("info diff", userID.toString()); + const file = await File.findOne({ + "metadata.owner": userID, _id: new ObjectId(fileID), - })) as FileInterface; + }); return file; }; getQuickList = async (userID: string, s3Enabled: boolean) => { - let query: any = { "metadata.owner": new ObjectId(userID) }; + let query: any = { "metadata.owner": userID }; if (!s3Enabled) { query = { ...query, "metadata.personalFile": null }; @@ -118,7 +120,7 @@ class DbUtil { getFileSearchList = async (userID: string, searchQuery: RegExp) => { let query: any = { - "metadata.owner": new ObjectId(userID), + "metadata.owner": userID, filename: searchQuery, }; @@ -132,14 +134,11 @@ class DbUtil { }; renameFile = async (fileID: string, userID: string, title: string) => { - const file = (await conn.db - .collection("fs.files") - .findOneAndUpdate( - { _id: new ObjectId(fileID), "metadata.owner": new ObjectId(userID) }, - { $set: { filename: title } } - )) as FileInterface; - - return file; + const updateFileResponse = await File.findOneAndUpdate( + { _id: new ObjectId(fileID), "metadata.owner": userID }, + { $set: { filename: title } } + ); + return updateFileResponse; }; moveFile = async ( @@ -149,7 +148,7 @@ class DbUtil { parentList: string ) => { const file = await conn.db.collection("fs.files").findOneAndUpdate( - { _id: new ObjectId(fileID), "metadata.owner": new ObjectId(userID) }, + { _id: new ObjectId(fileID), "metadata.owner": userID }, { $set: { "metadata.parent": parent, @@ -168,7 +167,7 @@ class DbUtil { const fileList = (await conn.db .collection("fs.files") .find({ - "metadata.owner": new ObjectId(userID), + "metadata.owner": userID, "metadata.parentList": { $regex: `.*${parentListString}.*` }, }) .toArray()) as FileInterface[]; @@ -179,7 +178,7 @@ class DbUtil { getFileListByOwner = async (userID: string) => { const fileList = (await conn.db .collection("fs.files") - .find({ "metadata.owner": new ObjectId(userID) }) + .find({ "metadata.owner": userID }) .toArray()) as FileInterface[]; return fileList; diff --git a/backend/middleware/authNoEmailVerificication.ts b/backend/middleware/authNoEmailVerificication.ts index f78fefe..521bfef 100644 --- a/backend/middleware/authNoEmailVerificication.ts +++ b/backend/middleware/authNoEmailVerificication.ts @@ -3,6 +3,7 @@ import User, { UserInterface } from "../models/user"; import env from "../enviroment/env"; import { Request, Response, NextFunction } from "express"; import userUpdateCheck from "../utils/userUpdateCheck"; +import mongoose from "mongoose"; interface RequestType extends Request { user?: userAccessType; @@ -16,7 +17,7 @@ type jwtType = { }; type userAccessType = { - _id: string; + _id: mongoose.Types.ObjectId; emailVerified: boolean; email: string; botChecked: boolean; diff --git a/backend/middleware/authRefresh.ts b/backend/middleware/authRefresh.ts index 9e62ae0..04ec525 100644 --- a/backend/middleware/authRefresh.ts +++ b/backend/middleware/authRefresh.ts @@ -3,6 +3,7 @@ import User, { UserInterface } from "../models/user"; import env from "../enviroment/env"; import { Request, Response, NextFunction } from "express"; import { ObjectId } from "mongodb"; +import mongoose from "mongoose"; interface RequestType extends Request { user?: UserInterface; @@ -17,7 +18,7 @@ type jwtType = { }; const removeOldTokens = async ( - userID: string, + userID: mongoose.Types.ObjectId, uuid: string | undefined, oldTime: number ) => { diff --git a/backend/middleware/authStreamVideo.ts b/backend/middleware/authStreamVideo.ts index 51710b4..5ffe035 100644 --- a/backend/middleware/authStreamVideo.ts +++ b/backend/middleware/authStreamVideo.ts @@ -3,6 +3,7 @@ import User, { UserInterface } from "../models/user"; import env from "../enviroment/env"; import { Request, Response, NextFunction } from "express"; import { ObjectId } from "mongodb"; +import mongoose from "mongoose"; interface RequestType extends Request { user?: UserInterface; @@ -18,7 +19,7 @@ type jwtType = { }; const removeOldTokens = async ( - userID: string, + userID: mongoose.Types.ObjectId, uuid: string | undefined, oldTime: number ) => { diff --git a/backend/models/file.ts b/backend/models/file.ts index 300c03f..24c9ee1 100644 --- a/backend/models/file.ts +++ b/backend/models/file.ts @@ -59,14 +59,14 @@ const fileSchema = new mongoose.Schema({ }); export interface FileInterface - extends mongoose.Document { + extends mongoose.Document { length: number; chunkSize: number; uploadDate: string; filename: string; lastErrorObject: { updatedExisting: any }; metadata: { - owner: string | ObjectId; + owner: string; parent: string; parentList: string; hasThumbnail: boolean; diff --git a/backend/models/user.ts b/backend/models/user.ts index 03acbbe..db3e4a1 100644 --- a/backend/models/user.ts +++ b/backend/models/user.ts @@ -1,610 +1,708 @@ -import mongoose, {Document} from "mongoose"; +import mongoose, { Document } from "mongoose"; import validator from "validator"; import crypto from "crypto"; import bcrypt from "bcrypt"; import jwt from "jsonwebtoken"; import env from "../enviroment/env"; -const userSchema = new mongoose.Schema({ - - name: - { - type:String, - }, - email: { - type: String, - required: true, - trim: true, - unique: true, - lowercase: true, - validate(value: any): any { - if (!validator.isEmail(value)) { - throw new Error("Email is invalid"); - } - } - }, - password: { - type: String, - trim: true, - required: true, - validate(value: any): any { - if (value.length < 6) { - throw new Error("Password Length Not Sufficent"); - } - } +const userSchema = new mongoose.Schema( + { + name: { + type: String, }, - tokens:[{ + email: { + type: String, + required: true, + trim: true, + unique: true, + lowercase: true, + validate(value: any): any { + if (!validator.isEmail(value)) { + throw new Error("Email is invalid"); + } + }, + }, + password: { + type: String, + trim: true, + required: true, + validate(value: any): any { + if (value.length < 6) { + throw new Error("Password Length Not Sufficent"); + } + }, + }, + tokens: [ + { token: { - type: String, - required: true + type: String, + required: true, }, uuid: { - type: String, - required: true, + type: String, + required: true, }, time: { - type: Number, - required: true - } - }], - tempTokens: [{ + type: Number, + required: true, + }, + }, + ], + tempTokens: [ + { token: { - type: String, - required: true + type: String, + required: true, }, uuid: { - type: String, - required: true, + type: String, + required: true, }, time: { - type: Number, - required: true - } - }], + type: Number, + required: true, + }, + }, + ], privateKey: { - type: String, + type: String, }, publicKey: { - type: String, + type: String, }, emailVerified: { - type: Boolean + type: Boolean, }, emailToken: { - type: String, + type: String, }, passwordResetToken: { - type: String + type: String, }, googleDriveEnabled: { - type: Boolean + type: Boolean, }, googleDriveData: { - - id: { - type: String - }, - key: { - type: String - }, - iv: { - type: Buffer - }, - token: { - type: String - } + id: { + type: String, + }, + key: { + type: String, + }, + iv: { + type: Buffer, + }, + token: { + type: String, + }, }, s3Enabled: { - type: Boolean + type: Boolean, }, s3Data: { - id: { - type: String - }, - key: { - type: String - }, - bucket: { - type: String - }, - iv: { - type: Buffer - } + id: { + type: String, + }, + key: { + type: String, + }, + bucket: { + type: String, + }, + iv: { + type: Buffer, + }, }, personalStorageCanceledDate: Number, storageData: { - storageSize: Number, - storageLimit: Number, - failed: Boolean, + storageSize: Number, + storageLimit: Number, + failed: Boolean, }, storageDataPersonal: { - storageSize: Number, - failed: Boolean, + storageSize: Number, + failed: Boolean, }, storageDataGoogle: { - storageSize: Number, - storageLimit: Number, - failed: Boolean, + storageSize: Number, + storageLimit: Number, + failed: Boolean, }, activeSubscription: Boolean, planID: String, passwordLastModified: Number, lastSubscriptionCheckTime: Number, - lastSubscriptionStatus: Boolean -}, { - timestamps: true -}) + lastSubscriptionStatus: Boolean, + }, + { + 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, - emailVerified?: boolean, - emailToken?: string, - passwordResetToken?: string, - googleDriveEnabled?: boolean, - googleDriveData?: { - id?: string, - key?: string, - iv?: Buffer, - token?: string, - }, - s3Enabled?: boolean, - s3Data?: { - id?: string, - key?: string, - bucket?: string, - iv?: Buffer, - }, - storageData?: { - storageSize?: number, - storageLimit?: number, - failed?: boolean, - }, - storageDataPersonal?: { - storageSize?: number, - failed?: boolean, - }, - storageDataGoogle?: { - storageSize?: number, - storageLimit?: number, - failed?: boolean, - }, - activeSubscription?: boolean, - passwordLastModified?: number, - personalStorageCanceledDate?: number, - planID?: string, - lastSubscriptionCheckTime?: number, - lastSubscriptionStatus?: boolean, + _id: mongoose.Types.ObjectId; + name: string; + email: string; + password: string; + tokens: any[]; + tempTokens: any[]; + privateKey?: string; + publicKey?: string; + token?: string; + emailVerified?: boolean; + emailToken?: string; + passwordResetToken?: string; + googleDriveEnabled?: boolean; + googleDriveData?: { + id?: string; + key?: string; + iv?: Buffer; + token?: string; + }; + s3Enabled?: boolean; + s3Data?: { + id?: string; + key?: string; + bucket?: string; + iv?: Buffer; + }; + storageData?: { + storageSize?: number; + storageLimit?: number; + failed?: boolean; + }; + storageDataPersonal?: { + storageSize?: number; + failed?: boolean; + }; + storageDataGoogle?: { + storageSize?: number; + storageLimit?: number; + failed?: boolean; + }; + activeSubscription?: boolean; + passwordLastModified?: number; + personalStorageCanceledDate?: number; + planID?: string; + lastSubscriptionCheckTime?: number; + lastSubscriptionStatus?: boolean; - getEncryptionKey: () => Buffer | undefined; - generateTempAuthToken: () => Promise; - encryptToken: (tempToken: any, key: any, publicKey: any) => any; - decryptToken: (encryptedToken: any, key: any, publicKey: any) => any; - findByCreds: (email: string, password: string) => Promise; - generateAuthToken: (uuid: string | undefined) => Promise<{accessToken: string, refreshToken: string}> - generateAuthTokenStreamVideo: (uuid: string | undefined) => Promise - generateEncryptionKeys: () => Promise; - changeEncryptionKey: (randomKey: Buffer) => Promise; - generateEmailVerifyToken: () => Promise; - generatePasswordResetToken: () => Promise; - encryptDriveIDandKey: (ID:string, key: string) => Promise; - decryptDriveIDandKey: () => Promise<{clientID: string, clientKey: string}>; - encryptDriveTokenData: (token: Object) => Promise; - decryptDriveTokenData: () => Promise; - encryptS3Data: (id: string, key: string, bucket: string) => Promise; - decryptS3Data: () => Promise<{id: string, key: string, bucket: string}> + getEncryptionKey: () => Buffer | undefined; + generateTempAuthToken: () => Promise; + encryptToken: (tempToken: any, key: any, publicKey: any) => any; + decryptToken: (encryptedToken: any, key: any, publicKey: any) => any; + findByCreds: (email: string, password: string) => Promise; + generateAuthToken: ( + uuid: string | undefined + ) => Promise<{ accessToken: string; refreshToken: string }>; + generateAuthTokenStreamVideo: (uuid: string | undefined) => Promise; + generateEncryptionKeys: () => Promise; + changeEncryptionKey: (randomKey: Buffer) => Promise; + generateEmailVerifyToken: () => Promise; + generatePasswordResetToken: () => Promise; + encryptDriveIDandKey: (ID: string, key: string) => Promise; + decryptDriveIDandKey: () => Promise<{ clientID: string; clientKey: string }>; + encryptDriveTokenData: (token: Object) => Promise; + decryptDriveTokenData: () => Promise; + encryptS3Data: (id: string, key: string, bucket: string) => Promise; + decryptS3Data: () => Promise<{ id: string; key: string; bucket: string }>; } -const maxAgeAccess = 60 * 1000 * 20 + (1000 * 60); -const maxAgeRefresh = 60 * 1000 * 60 * 24 * 30 + (1000 * 60); +const maxAgeAccess = 60 * 1000 * 20 + 1000 * 60; +const maxAgeRefresh = 60 * 1000 * 60 * 24 * 30 + 1000 * 60; const maxAgeAccessStreamVideo = 60 * 1000 * 60 * 24; -userSchema.pre("save", async function(this: any, next: any) { - - const user = this; +userSchema.pre("save", async function (this: any, next: any) { + const user = this; - if (user.isModified("password")) { - user.password = await bcrypt.hash(user.password, 8); - } + if (user.isModified("password")) { + user.password = await bcrypt.hash(user.password, 8); + } - next(); -}) + next(); +}); -userSchema.statics.findByCreds = async(email: string, password: string) => { +userSchema.statics.findByCreds = async (email: string, password: string) => { + const user = await User.findOne({ email }); - const user = await User.findOne({email}); + if (!user) { + throw new Error("User not found"); + } - if (!user) { + const isMatch = await bcrypt.compare(password, user.password); - throw new Error("User not found") - } + if (!isMatch) { + throw new Error("Incorrect password"); + } - const isMatch = await bcrypt.compare(password, user.password); + return user; +}; - if (!isMatch) { - throw new Error("Incorrect password"); - } +userSchema.methods.toJSON = function () { + const user = this; - return user; -} + const userObject = user.toObject(); -userSchema.methods.toJSON = function() { + delete userObject.password; + delete userObject.tokens; + delete userObject.tempTokens; + delete userObject.privateKey; + delete userObject.publicKey; - const user = this; + return userObject; +}; - const userObject = user.toObject(); +userSchema.methods.generateAuthTokenStreamVideo = async function ( + uuid: string | undefined +) { + const iv = crypto.randomBytes(16); - delete userObject.password; - delete userObject.tokens; - delete userObject.tempTokens; - delete userObject.privateKey; - delete userObject.publicKey; + const user = this; - return userObject; -} + const date = new Date(); + const time = date.getTime(); -userSchema.methods.generateAuthTokenStreamVideo = async function(uuid: string | undefined) { + let accessTokenStreamVideo = jwt.sign( + { _id: user._id.toString(), iv, time }, + env.passwordAccess!, + { expiresIn: maxAgeAccessStreamVideo.toString() } + ); - const iv = crypto.randomBytes(16); + const encryptionKey = user.getEncryptionKey(); - const user = this; + const encryptedToken = user.encryptToken( + accessTokenStreamVideo, + encryptionKey, + iv + ); - const date = new Date(); - const time = date.getTime(); - - let accessTokenStreamVideo = jwt.sign({_id:user._id.toString(), iv, time}, env.passwordAccess!, {expiresIn: maxAgeAccessStreamVideo.toString()}); + uuid = uuid ? uuid : "unknown"; - const encryptionKey = user.getEncryptionKey(); + await User.updateOne( + { _id: user._id }, + { $push: { tempTokens: { token: encryptedToken, uuid, time } } } + ); - const encryptedToken = user.encryptToken(accessTokenStreamVideo, encryptionKey, iv); + return accessTokenStreamVideo; +}; - uuid = uuid ? uuid : "unknown"; +userSchema.methods.generateAuthToken = async function ( + uuid: string | undefined +) { + const iv = crypto.randomBytes(16); - await User.updateOne({_id: user._id}, {$push: {"tempTokens": {token: encryptedToken, uuid, time}}}); + const user = this; - return accessTokenStreamVideo; -} + const date = new Date(); + const time = date.getTime(); -userSchema.methods.generateAuthToken = async function(uuid: string | undefined) { + const userObj = { + _id: user._id, + emailVerified: user.emailVerified || env.disableEmailVerification, + email: user.email, + s3Enabled: user.s3Enabled, + googleDriveEnabled: user.googleDriveEnabled, + }; - const iv = crypto.randomBytes(16); + let accessToken = jwt.sign({ user: userObj, iv }, env.passwordAccess!, { + expiresIn: maxAgeAccess.toString(), + }); + let refreshToken = jwt.sign( + { _id: user._id.toString(), iv, time }, + env.passwordRefresh!, + { expiresIn: maxAgeRefresh.toString() } + ); - const user = this; + const encryptionKey = user.getEncryptionKey(); - const date = new Date(); - const time = date.getTime(); + const encryptedToken = user.encryptToken(refreshToken, encryptionKey, iv); - const userObj = {_id: user._id, emailVerified: user.emailVerified || env.disableEmailVerification, email: user.email, s3Enabled: user.s3Enabled, googleDriveEnabled: user.googleDriveEnabled} - - let accessToken = jwt.sign({user: userObj, iv}, env.passwordAccess!, {expiresIn: maxAgeAccess.toString()}); - let refreshToken = jwt.sign({_id:user._id.toString(), iv, time}, env.passwordRefresh!, {expiresIn: maxAgeRefresh.toString()}); + //user.tokens = user.tokens.concat({token: encryptedToken}); - const encryptionKey = user.getEncryptionKey(); + uuid = uuid ? uuid : "unknown"; - const encryptedToken = user.encryptToken(refreshToken, encryptionKey, iv); + await User.updateOne( + { _id: user._id }, + { $push: { tokens: { token: encryptedToken, uuid, time } } } + ); - //user.tokens = user.tokens.concat({token: encryptedToken}); + // console.log("saving user") + // console.log("user saved") + return { accessToken, refreshToken }; - uuid = uuid ? uuid : "unknown"; + // const iv = crypto.randomBytes(16); - await User.updateOne({_id: user._id}, {$push: {"tokens": {token: encryptedToken, uuid, time}}}) + // const user = this; + // let token = jwt.sign({_id:user._id.toString(), iv}, env.passwordAccess!); - // console.log("saving user") - // console.log("user saved") - return {accessToken, refreshToken}; + // const encryptionKey = user.getEncryptionKey(); - // const iv = crypto.randomBytes(16); + // const encryptedToken = user.encryptToken(token, encryptionKey, iv); - // const user = this; - // let token = jwt.sign({_id:user._id.toString(), iv}, env.passwordAccess!); + // user.tokens = user.tokens.concat({token: encryptedToken}); - // const encryptionKey = user.getEncryptionKey(); + // await user.save(); + // return token; +}; - // const encryptedToken = user.encryptToken(token, encryptionKey, iv); +userSchema.methods.encryptToken = function ( + token: string, + key: string, + iv: any +) { + iv = Buffer.from(iv, "hex"); - // user.tokens = user.tokens.concat({token: encryptedToken}); + const TOKEN_CIPHER_KEY = crypto.createHash("sha256").update(key).digest(); + const cipher = crypto.createCipheriv("aes-256-cbc", TOKEN_CIPHER_KEY, iv); + const encryptedText = cipher.update(token); - // await user.save(); - // return token; -} + return Buffer.concat([encryptedText, cipher.final()]).toString("hex"); +}; -userSchema.methods.encryptToken = function(token: string, key: string, iv: any) { +userSchema.methods.decryptToken = function ( + encryptedToken: any, + key: string, + iv: any +) { + encryptedToken = Buffer.from(encryptedToken, "hex"); + iv = Buffer.from(iv, "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); - const TOKEN_CIPHER_KEY = crypto.createHash('sha256').update(key).digest(); - const cipher = crypto.createCipheriv('aes-256-cbc', TOKEN_CIPHER_KEY, iv); - const encryptedText = cipher.update(token); + const tokenDecrypted = decipher.update(encryptedToken); - return Buffer.concat([encryptedText, cipher.final()]).toString("hex");; -} + return Buffer.concat([tokenDecrypted, decipher.final()]).toString(); +}; -userSchema.methods.decryptToken = function(encryptedToken: any, key: string, iv: any) { +userSchema.methods.generateEncryptionKeys = async function () { + const user = this; + const userPassword = user.password; + const masterPassword = env.key!; - encryptedToken = Buffer.from(encryptedToken, "hex"); - iv = Buffer.from(iv, "hex") + const randomKey = crypto.randomBytes(32); - const TOKEN_CIPHER_KEY = crypto.createHash('sha256').update(key).digest(); - const decipher = crypto.createDecipheriv('aes-256-cbc', TOKEN_CIPHER_KEY, iv) - - const tokenDecrypted = decipher.update(encryptedToken); + 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()]); - return Buffer.concat([tokenDecrypted, decipher.final()]).toString(); -} + const MASTER_CIPHER_KEY = crypto + .createHash("sha256") + .update(masterPassword) + .digest(); + const masterCipher = crypto.createCipheriv( + "aes-256-cbc", + MASTER_CIPHER_KEY, + iv + ); + const masterEncryptedText = masterCipher.update(encryptedText); -userSchema.methods.generateEncryptionKeys = async function() { + user.privateKey = Buffer.concat([ + masterEncryptedText, + masterCipher.final(), + ]).toString("hex"); + user.publicKey = iv.toString("hex"); + await user.save(); +}; + +userSchema.methods.getEncryptionKey = function () { + try { 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; + } catch (e) { + console.log("Get Encryption Key Error", e); + return undefined; + } +}; + +userSchema.methods.changeEncryptionKey = async function (randomKey: Buffer) { + 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 + ); + const masterEncryptedText = masterCipher.update(encryptedText); + + user.privateKey = Buffer.concat([ + masterEncryptedText, + masterCipher.final(), + ]).toString("hex"); + user.publicKey = iv.toString("hex"); + + await user.save(); +}; + +userSchema.methods.generateTempAuthToken = async function () { + const iv = crypto.randomBytes(16); + + const user = this as UserInterface; + const token = jwt.sign( + { _id: user._id.toString(), iv }, + env.passwordAccess!, + { expiresIn: "3000ms" } + ); + + const encryptionKey = user.getEncryptionKey(); + const encryptedToken = user.encryptToken(token, encryptionKey, iv); + + user.tempTokens = user.tempTokens.concat({ token: encryptedToken }); + + await user.save(); + return token; +}; + +userSchema.methods.generateEmailVerifyToken = async function () { + const iv = crypto.randomBytes(16); - const randomKey = crypto.randomBytes(32); + const user = this as UserInterface; + const token = jwt.sign( + { _id: user._id.toString(), iv }, + env.passwordAccess!, + { expiresIn: "1d" } + ); + + const encryptionKey = user.getEncryptionKey(); + const encryptedToken = user.encryptToken(token, encryptionKey, iv); + + user.emailToken = encryptedToken; - 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()]); + await user.save(); + return token; +}; + +userSchema.methods.encryptDriveIDandKey = async function ( + ID: string, + key: string +) { + const iv = crypto.randomBytes(16); - const MASTER_CIPHER_KEY = crypto.createHash('sha256').update(masterPassword).digest(); - const masterCipher = crypto.createCipheriv('aes-256-cbc', MASTER_CIPHER_KEY, iv); - const masterEncryptedText = masterCipher.update(encryptedText); + const user = this as UserInterface; - user.privateKey = Buffer.concat([masterEncryptedText, masterCipher.final()]).toString("hex"); - user.publicKey = iv.toString("hex"); + const encryptedKey = user.getEncryptionKey(); - await user.save(); -} + const encryptedDriveID = user.encryptToken(ID, encryptedKey, iv); + const encryptedDriveKey = user.encryptToken(key, encryptedKey, iv); -userSchema.methods.getEncryptionKey = function() { + if (!user.googleDriveData) user.googleDriveData = {}; - try { - const user = this; - const userPassword = user.password; - const masterEncryptedText = user.privateKey; - const masterPassword = env.key!; - const iv = Buffer.from(user.publicKey, "hex"); + user.googleDriveData!.id = encryptedDriveID; + user.googleDriveData!.key = encryptedDriveKey; + user.googleDriveData!.iv = iv; - const USER_CIPHER_KEY = crypto.createHash('sha256').update(userPassword).digest(); - const MASTER_CIPHER_KEY = crypto.createHash('sha256').update(masterPassword).digest(); + await user.save(); +}; - 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()]) +userSchema.methods.decryptDriveIDandKey = async function () { + const user = this as UserInterface; - let decipher = crypto.createDecipheriv('aes-256-cbc', USER_CIPHER_KEY, iv); - let decrypted = decipher.update(masterDecrypted); - decrypted = Buffer.concat([decrypted, decipher.final()]); + const iv = user.googleDriveData!.iv; - return decrypted; + const encryptedKey = user.getEncryptionKey(); - } catch (e) { + const encryptedDriveID = user.googleDriveData?.id; + const encryptedDriveKey = user.googleDriveData?.key; - console.log("Get Encryption Key Error", e); - return undefined; - } -} + const decryptedDriveID = user.decryptToken( + encryptedDriveID, + encryptedKey, + iv + ); + const decryptedDriveKey = user.decryptToken( + encryptedDriveKey, + encryptedKey, + iv + ); -userSchema.methods.changeEncryptionKey = async function(randomKey: Buffer) { + return { + clientID: decryptedDriveID, + clientKey: decryptedDriveKey, + }; +}; - const user = this; - const userPassword = user.password; - const masterPassword = env.key!; +userSchema.methods.encryptDriveTokenData = async function (token: Object) { + const user = this as UserInterface; + const iv = user.googleDriveData?.iv; - 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 tokenToString = JSON.stringify(token); - const MASTER_CIPHER_KEY = crypto.createHash('sha256').update(masterPassword).digest(); - const masterCipher = crypto.createCipheriv('aes-256-cbc', MASTER_CIPHER_KEY, iv); - const masterEncryptedText = masterCipher.update(encryptedText); + const encryptedKey = user.getEncryptionKey(); - user.privateKey = Buffer.concat([masterEncryptedText, masterCipher.final()]).toString("hex"); - user.publicKey = iv.toString("hex"); + const encryptedDriveToken = user.encryptToken( + tokenToString, + encryptedKey, + iv + ); - await user.save(); -} + if (!user.googleDriveData) user.googleDriveData = {}; -userSchema.methods.generateTempAuthToken = async function() { + user.googleDriveData.token = encryptedDriveToken; + user.googleDriveEnabled = true; - const iv = crypto.randomBytes(16); + await user.save(); +}; - const user = this as UserInterface; - const token = jwt.sign({_id:user._id.toString(), iv}, env.passwordAccess!, {expiresIn: "3000ms"}); +userSchema.methods.decryptDriveTokenData = async function () { + const user = this as UserInterface; - const encryptionKey = user.getEncryptionKey(); - const encryptedToken = user.encryptToken(token, encryptionKey, iv); + const iv = user.googleDriveData!.iv; - user.tempTokens = user.tempTokens.concat({token: encryptedToken}); + const encryptedKey = user.getEncryptionKey(); - await user.save(); - return token; -} + const encryptedToken = user.googleDriveData?.token; -userSchema.methods.generateEmailVerifyToken = async function() { + const decryptedToken = user.decryptToken(encryptedToken, encryptedKey, iv); - const iv = crypto.randomBytes(16); + const tokenToObj = JSON.parse(decryptedToken); - const user = this as UserInterface; - const token = jwt.sign({_id:user._id.toString(), iv}, env.passwordAccess!, {expiresIn: "1d"}); + return tokenToObj; +}; - const encryptionKey = user.getEncryptionKey(); - const encryptedToken = user.encryptToken(token, encryptionKey, iv); +userSchema.methods.encryptS3Data = async function ( + ID: string, + key: string, + bucket: string +) { + const iv = crypto.randomBytes(16); - user.emailToken = encryptedToken; + const user = this as UserInterface; - await user.save(); - return token; -} + const encryptedKey = user.getEncryptionKey(); -userSchema.methods.encryptDriveIDandKey = async function(ID: string, key: string) { + const encryptedS3ID = user.encryptToken(ID, encryptedKey, iv); + const encryptedS3Key = user.encryptToken(key, encryptedKey, iv); + const encryptedS3Bucket = user.encryptToken(bucket, encryptedKey, iv); - const iv = crypto.randomBytes(16); + if (!user.s3Data) user.s3Data = {}; - const user = this as UserInterface; - - const encryptedKey = user.getEncryptionKey(); + user.s3Data!.id = encryptedS3ID; + user.s3Data!.key = encryptedS3Key; + user.s3Data!.bucket = encryptedS3Bucket; + user.s3Data!.iv = iv; + user.s3Enabled = true; - const encryptedDriveID = user.encryptToken(ID, encryptedKey, iv); - const encryptedDriveKey = user.encryptToken(key, encryptedKey, iv); - - if (!user.googleDriveData) user.googleDriveData = {}; + await user.save(); +}; - user.googleDriveData!.id = encryptedDriveID; - user.googleDriveData!.key = encryptedDriveKey; - user.googleDriveData!.iv = iv; +userSchema.methods.decryptS3Data = async function () { + const user = this as UserInterface; - await user.save(); -} + const iv = user.s3Data?.iv; -userSchema.methods.decryptDriveIDandKey = async function() { - - const user = this as UserInterface; - - const iv = user.googleDriveData!.iv; + const encryptedKey = user.getEncryptionKey(); - const encryptedKey = user.getEncryptionKey(); + const encrytpedS3ID = user.s3Data?.id; + const encryptedS3Key = user.s3Data?.key; + const encryptedS3Bucket = user.s3Data?.bucket; - const encryptedDriveID = user.googleDriveData?.id; - const encryptedDriveKey = user.googleDriveData?.key; + const decrytpedS3ID = user.decryptToken(encrytpedS3ID, encryptedKey, iv); + const decryptedS3Key = user.decryptToken(encryptedS3Key, encryptedKey, iv); + const decryptedS3Bucket = user.decryptToken( + encryptedS3Bucket, + encryptedKey, + iv + ); - const decryptedDriveID = user.decryptToken(encryptedDriveID, encryptedKey, iv) - const decryptedDriveKey = user.decryptToken(encryptedDriveKey, encryptedKey, iv); - - return { - clientID: decryptedDriveID, - clientKey: decryptedDriveKey - } -} + //console.log("decrypted keys", decrytpedS3ID, decryptedS3Key, decryptedS3Bucket); -userSchema.methods.encryptDriveTokenData = async function(token: Object) { - - const user = this as UserInterface; - const iv = user.googleDriveData?.iv; + return { + id: decrytpedS3ID, + key: decryptedS3Key, + bucket: decryptedS3Bucket, + }; +}; - const tokenToString = JSON.stringify(token); - - const encryptedKey = user.getEncryptionKey(); +userSchema.methods.generatePasswordResetToken = async function () { + const iv = crypto.randomBytes(16); - const encryptedDriveToken = user.encryptToken(tokenToString, encryptedKey, iv);; - - if (!user.googleDriveData) user.googleDriveData = {}; + const user = this as UserInterface; + const token = jwt.sign( + { _id: user._id.toString(), iv }, + env.passwordAccess!, + { expiresIn: "1h" } + ); - user.googleDriveData.token = encryptedDriveToken; - user.googleDriveEnabled = true; + const encryptionKey = user.getEncryptionKey(); + const encryptedToken = user.encryptToken(token, encryptionKey, iv); - await user.save(); -} + user.passwordResetToken = encryptedToken; -userSchema.methods.decryptDriveTokenData = async function() { - - const user = this as UserInterface; - - const iv = user.googleDriveData!.iv; + await user.save(); + return token; +}; - const encryptedKey = user.getEncryptionKey(); +userSchema.methods.generateTempAuthTokenVideo = async function ( + cookie: string +) { + const iv = crypto.randomBytes(16); - const encryptedToken = user.googleDriveData?.token; + const user = this; + const token = jwt.sign( + { _id: user._id.toString(), cookie, iv }, + env.passwordAccess!, + { expiresIn: "5h" } + ); - const decryptedToken = user.decryptToken(encryptedToken, encryptedKey, iv); + const encryptionKey = user.getEncryptionKey(); + const encryptedToken = user.encryptToken(token, encryptionKey, iv); - const tokenToObj = JSON.parse(decryptedToken); - - return tokenToObj; -} + user.tempTokens = user.tempTokens.concat({ token: encryptedToken }); -userSchema.methods.encryptS3Data = async function(ID: string, key: string, bucket: string) { - - const iv = crypto.randomBytes(16); - - const user = this as UserInterface; - - const encryptedKey = user.getEncryptionKey(); - - const encryptedS3ID = user.encryptToken(ID, encryptedKey, iv); - const encryptedS3Key = user.encryptToken(key, encryptedKey, iv); - const encryptedS3Bucket = user.encryptToken(bucket, encryptedKey, iv); - - if (!user.s3Data) user.s3Data = {}; - - user.s3Data!.id = encryptedS3ID; - user.s3Data!.key = encryptedS3Key; - user.s3Data!.bucket = encryptedS3Bucket; - user.s3Data!.iv = iv; - user.s3Enabled = true; - - await user.save(); -} - -userSchema.methods.decryptS3Data = async function() { - - const user = this as UserInterface; - - const iv = user.s3Data?.iv; - - const encryptedKey = user.getEncryptionKey(); - - const encrytpedS3ID = user.s3Data?.id; - const encryptedS3Key = user.s3Data?.key; - const encryptedS3Bucket = user.s3Data?.bucket; - - const decrytpedS3ID = user.decryptToken(encrytpedS3ID, encryptedKey, iv); - const decryptedS3Key = user.decryptToken(encryptedS3Key, encryptedKey, iv); - const decryptedS3Bucket = user.decryptToken(encryptedS3Bucket, encryptedKey, iv); - - //console.log("decrypted keys", decrytpedS3ID, decryptedS3Key, decryptedS3Bucket); - - return { - id: decrytpedS3ID, - key: decryptedS3Key, - bucket: decryptedS3Bucket, - } -} - -userSchema.methods.generatePasswordResetToken = async function() { - - const iv = crypto.randomBytes(16); - - const user = this as UserInterface; - const token = jwt.sign({_id:user._id.toString(), iv}, env.passwordAccess!, {expiresIn: "1h"}); - - const encryptionKey = user.getEncryptionKey(); - const encryptedToken = user.encryptToken(token, encryptionKey, iv); - - user.passwordResetToken = encryptedToken; - - await user.save(); - return token; -} - -userSchema.methods.generateTempAuthTokenVideo = async function(cookie: string) { - - const iv = crypto.randomBytes(16); - - const user = this; - const token = jwt.sign({_id:user._id.toString(), cookie, iv}, env.passwordAccess!, {expiresIn:"5h"}); - - const encryptionKey = user.getEncryptionKey(); - const encryptedToken = user.encryptToken(token, encryptionKey, iv); - - user.tempTokens = user.tempTokens.concat({token: encryptedToken}); - - await user.save(); - return token; -} + await user.save(); + return token; +}; const User = mongoose.model("User", userSchema); export default User; -module.exports = User; \ No newline at end of file +module.exports = User; diff --git a/backend/services/ChunkService/FileSystemService.ts b/backend/services/ChunkService/FileSystemService.ts index 82aa068..01c5a36 100644 --- a/backend/services/ChunkService/FileSystemService.ts +++ b/backend/services/ChunkService/FileSystemService.ts @@ -35,6 +35,7 @@ class FileSystemService implements ChunkInterface { constructor() {} uploadFile = async (user: UserInterface, busboy: any, req: Request) => { + console.log("upeload file"); const password = user.getEncryptionKey(); if (!password) throw new ForbiddenError("Invalid Encryption Key"); @@ -45,7 +46,11 @@ class FileSystemService implements ChunkInterface { const cipher = crypto.createCipheriv("aes256", CIPHER_KEY, initVect); - const { file, filename, formData } = await getBusboyData(busboy); + const { file, filename: fileInfo, formData } = await getBusboyData(busboy); + + const filename = fileInfo.filename; + + console.log("1filename", filename); const parent = formData.get("parent") || "/"; const parentList = formData.get("parentList") || "/"; @@ -84,6 +89,8 @@ class FileSystemService implements ChunkInterface { const date = new Date(); const encryptedFileSize = await getFileSize(metadata.filePath); + console.log("filtnamed", filename); + const currentFile = new File({ filename, uploadDate: date.toISOString(), @@ -95,6 +102,8 @@ class FileSystemService implements ChunkInterface { await addToStoageSize(user, size, personalFile); + console.log("current file", currentFile); + const imageCheck = imageChecker(currentFile.filename); if (currentFile.length < 15728640 && imageCheck) { @@ -150,11 +159,11 @@ class FileSystemService implements ChunkInterface { }; downloadFile = async (user: UserInterface, fileID: string, res: Response) => { - const currentFile: FileInterface = await dbUtilsFile.getFileInfo( + const currentFile = await dbUtilsFile.getFileInfo( fileID, - user._id + user._id.toString() ); - + console.log(fileID, user._id); if (!currentFile) throw new NotFoundError("Download File Not Found"); const password = user.getEncryptionKey(); @@ -184,9 +193,9 @@ class FileSystemService implements ChunkInterface { }; getFileReadStream = async (user: UserInterface, fileID: string) => { - const currentFile: FileInterface = await dbUtilsFile.getFileInfo( + const currentFile = await dbUtilsFile.getFileInfo( fileID, - user._id + user._id.toString() ); if (!currentFile) throw new NotFoundError("Download File Not Found"); @@ -246,7 +255,7 @@ class FileSystemService implements ChunkInterface { ) => { const userID = user._id; - const file: FileInterface = await dbUtilsFile.getFileInfo(fileID, userID); + const file = await dbUtilsFile.getFileInfo(fileID, userID.toString()); if (!file) throw new NotFoundError("File Thumbnail Not Found"); @@ -291,9 +300,9 @@ class FileSystemService implements ChunkInterface { // Is safari going to be the next internet explorer? const userID = user._id; - const currentFile: FileInterface = await dbUtilsFile.getFileInfo( + const currentFile = await dbUtilsFile.getFileInfo( fileID, - userID + userID.toString() ); if (!currentFile) throw new NotFoundError("Video File Not Found"); @@ -435,7 +444,7 @@ class FileSystemService implements ChunkInterface { }; deleteFile = async (userID: string, fileID: string) => { - const file: FileInterface = await dbUtilsFile.getFileInfo(fileID, userID); + const file = await dbUtilsFile.getFileInfo(fileID, userID); if (!file) throw new NotFoundError("Delete File Not Found Error"); diff --git a/backend/services/ChunkService/S3Service.ts b/backend/services/ChunkService/S3Service.ts index 5c98078..8559478 100644 --- a/backend/services/ChunkService/S3Service.ts +++ b/backend/services/ChunkService/S3Service.ts @@ -44,7 +44,8 @@ class S3Service implements ChunkInterface { const cipher = crypto.createCipheriv("aes256", CIPHER_KEY, initVect); - const { file, filename, formData } = await getBusboyData(busboy); + const { file, filename: fileInfo, formData } = await getBusboyData(busboy); + const filename = fileInfo.filename; const parent = formData.get("parent") || "/"; const parentList = formData.get("parentList") || "/"; @@ -166,9 +167,9 @@ class S3Service implements ChunkInterface { }; downloadFile = async (user: UserInterface, fileID: string, res: Response) => { - const currentFile: FileInterface = await dbUtilsFile.getFileInfo( + const currentFile = await dbUtilsFile.getFileInfo( fileID, - user._id + user._id.toString() ); if (!currentFile) throw new NotFoundError("Download File Not Found"); @@ -202,9 +203,9 @@ class S3Service implements ChunkInterface { }; getFileReadStream = async (user: UserInterface, fileID: string) => { - const currentFile: FileInterface = await dbUtilsFile.getFileInfo( + const currentFile = await dbUtilsFile.getFileInfo( fileID, - user._id + user._id.toString() ); if (!currentFile) throw new NotFoundError("Download File Not Found"); @@ -246,9 +247,9 @@ class S3Service implements ChunkInterface { // Is safari going to be the next internet explorer? const userID = user._id; - const currentFile: FileInterface = await dbUtilsFile.getFileInfo( + const currentFile = await dbUtilsFile.getFileInfo( fileID, - userID + userID.toString() ); if (!currentFile) throw new NotFoundError("Video File Not Found"); @@ -416,7 +417,7 @@ class S3Service implements ChunkInterface { ) => { const userID = user._id; - const file: FileInterface = await dbUtilsFile.getFileInfo(fileID, userID); + const file = await dbUtilsFile.getFileInfo(fileID, userID.toString()); if (!file) throw new NotFoundError("File Thumbnail Not Found"); @@ -489,7 +490,7 @@ class S3Service implements ChunkInterface { }; deleteFile = async (userID: string, fileID: string) => { - const file: FileInterface = await dbUtilsFile.getFileInfo(fileID, userID); + const file = await dbUtilsFile.getFileInfo(fileID, userID); if (!file) throw new NotFoundError("Delete File Not Found Error"); diff --git a/backend/services/ChunkService/utils/getBusboyData.ts b/backend/services/ChunkService/utils/getBusboyData.ts index 0166e6f..598d2e6 100644 --- a/backend/services/ChunkService/utils/getBusboyData.ts +++ b/backend/services/ChunkService/utils/getBusboyData.ts @@ -1,33 +1,40 @@ import { Stream } from "stream"; const getBusboyData = (busboy: any) => { + type dataType = { + file: Stream; + filename: { + filename: string; + }; + formData: Map; + }; - type dataType = { + return new Promise((resolve, reject) => { + const formData = new Map(); + + busboy.on("field", (field: any, val: any) => { + console.log("field", field, val); + + formData.set(field, val); + }); + + busboy.on( + "file", + async ( + _: string, file: Stream, - filename: string, - formData: Map - } - - return new Promise((resolve, reject) => { - - const formData = new Map(); - - busboy.on("field", (field: any, val: any) => { - - formData.set(field, val) - + filename: { + filename: string; + } + ) => { + resolve({ + file, + filename, + formData, }); + } + ); + }); +}; - busboy.on("file", async(_: string, file: Stream, filename: string) => { - - resolve({ - file, - filename, - formData - }) - }) - - }) -} - -export default getBusboyData; \ No newline at end of file +export default getBusboyData; diff --git a/backend/services/FileService/index.ts b/backend/services/FileService/index.ts index 7d8728f..360d0b3 100644 --- a/backend/services/FileService/index.ts +++ b/backend/services/FileService/index.ts @@ -106,7 +106,10 @@ class MongoFileService { const userID = user._id; const s3Enabled = user.s3Enabled ? true : false; - const quickList = await dbUtilsFile.getQuickList(userID, s3Enabled); + const quickList = await dbUtilsFile.getQuickList( + userID.toString(), + s3Enabled + ); if (!quickList) throw new NotFoundError("Quick List Not Found Error"); @@ -131,7 +134,7 @@ class MongoFileService { const s3Enabled = user.s3Enabled ? true : false; const queryObj = createQuery( - userID, + userID.toString(), parent, query.sortby, startAt, @@ -219,8 +222,7 @@ class MongoFileService { 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"); + if (!file) throw new NotFoundError("Rename File Not Found Error"); return file; }; diff --git a/backend/services/FolderService/index.ts b/backend/services/FolderService/index.ts index 3de3fcd..2b30d65 100644 --- a/backend/services/FolderService/index.ts +++ b/backend/services/FolderService/index.ts @@ -109,7 +109,7 @@ class FolderService { if (searchQuery.length === 0) { const folderList = await utilsFolder.getFolderListByParent( - userID, + userID.toString(), parent, sortBy, s3Enabled, @@ -124,7 +124,7 @@ class FolderService { } else { searchQuery = new RegExp(searchQuery, "i"); const folderList = await utilsFolder.getFolderListBySearch( - userID, + userID.toString(), searchQuery, sortBy, type, diff --git a/backend/utils/createQuery.ts b/backend/utils/createQuery.ts index 40bcfbc..16d66a7 100644 --- a/backend/utils/createQuery.ts +++ b/backend/utils/createQuery.ts @@ -2,7 +2,7 @@ import s3 from "../db/s3"; import { ObjectId } from "mongodb"; export interface QueryInterface { - "metadata.owner": ObjectId; + "metadata.owner": ObjectId | string; "metadata.parent"?: string; filename?: | string @@ -30,7 +30,7 @@ const createQuery = ( storageType: string, folderSearch: boolean ) => { - let query: QueryInterface = { "metadata.owner": new ObjectId(owner) }; + let query: QueryInterface = { "metadata.owner": owner }; if (searchQuery !== "") { searchQuery = new RegExp(searchQuery, "i"); diff --git a/backend/utils/userUpdateCheck.ts b/backend/utils/userUpdateCheck.ts index 4170b68..22d829e 100644 --- a/backend/utils/userUpdateCheck.ts +++ b/backend/utils/userUpdateCheck.ts @@ -1,6 +1,6 @@ -import User, {UserInterface} from "../models/user"; - -import {Request, Response, NextFunction} from "express"; +import User, { UserInterface } from "../models/user"; +import mongoose from "mongoose"; +import { Request, Response, NextFunction } from "express"; import NotFoundError from "./NotFoundError"; import { createLoginCookie } from "../cookies/createCookies"; @@ -11,27 +11,36 @@ import { createLoginCookie } from "../cookies/createCookies"; // } type userAccessType = { - _id: string, - emailVerified: boolean, - email: string, - botChecked: boolean, -} + _id: mongoose.Types.ObjectId; + emailVerified: boolean; + email: string; + botChecked: boolean; +}; -const userUpdateCheck = async(res: Response, id: string, uuid: string | undefined) => { +const userUpdateCheck = async ( + res: Response, + id: mongoose.Types.ObjectId, + uuid: string | undefined +) => { + const updatedUser = await User.findById(id); - const updatedUser = await User.findById(id); + if (!updatedUser) throw new NotFoundError("Cannot find updated user auth"); - if (!updatedUser) throw new NotFoundError("Cannot find updated user auth"); + if (updatedUser.emailVerified) { + const { accessToken, refreshToken } = await updatedUser.generateAuthToken( + uuid + ); + createLoginCookie(res, accessToken, refreshToken); + } - if (updatedUser.emailVerified) { + let strippedUser: userAccessType = { + _id: updatedUser._id, + emailVerified: updatedUser.emailVerified!, + email: updatedUser.email, + botChecked: false, + }; - const {accessToken, refreshToken} = await updatedUser.generateAuthToken(uuid); - createLoginCookie(res, accessToken, refreshToken); - } + return strippedUser; +}; - let strippedUser: userAccessType = {_id: updatedUser._id, emailVerified: updatedUser.emailVerified!, email: updatedUser.email, botChecked: false} - - return strippedUser; -} - -export default userUpdateCheck; \ No newline at end of file +export default userUpdateCheck; diff --git a/index.html b/index.html new file mode 100644 index 0000000..363a288 --- /dev/null +++ b/index.html @@ -0,0 +1,24 @@ + + + + + myDrive + + + + + + + + + + + + + + +
+ + + + diff --git a/nodemon.json b/nodemon.json new file mode 100644 index 0000000..2f7d144 --- /dev/null +++ b/nodemon.json @@ -0,0 +1,6 @@ +{ + "watch": ["dist/"], + "ignore": ["src", "node_modules"], + "ext": "js,json", + "exec": "node dist/server/serverStart.js" +} diff --git a/package.json b/package.json index 67793fc..d692ccb 100755 --- a/package.json +++ b/package.json @@ -30,7 +30,12 @@ "remove-old-subscription-data": "node serverUtils/removeOldSubscriptionData.js", "remove-old-personal-data": "node serverUtils/removeOldPersonalData.js", "remove-tokens": "node serverUtils/removeTokens.js --env production", - "remove-tokens:dev": "NODE_ENV=development node serverUtils/removeTokens.js" + "remove-tokens:dev": "NODE_ENV=development node serverUtils/removeTokens.js", + "vite-test": "vite", + "dev-test": "concurrently \"vite\" \"nodemon server.js\"", + "watch:backend": "tsc -w", + "dev-hot": "concurrently \"vite\" \"tsc -w\" \"npm run dev:backend\"", + "dev:backend": "nodemon dist/server/serverStart.js" }, "dependencies": { "@babel/core": "^7.8.4", @@ -66,7 +71,7 @@ "cli-progress": "^3.6.0", "compression": "^1.7.4", "concat-stream": "^2.0.0", - "connect-busboy": "0.0.2", + "connect-busboy": "^1.0.0", "cookie-parser": "^1.4.6", "copy-text-to-clipboard": "^2.1.1", "core-js": "^3.6.4", @@ -100,7 +105,7 @@ "sharp": "^0.33.4", "stream-skip": "^1.0.3", "supertest-session": "^4.1.0", - "sweetalert2": "^9.17.4", + "sweetalert2": "^11.11.1", "temp": "^0.9.1", "typescript": "^5.4.5", "uuid": "^3.4.0", @@ -129,6 +134,7 @@ "live-server": "^1.2.1", "nodemon": "^3.1.3", "react-test-renderer": "^16.12.0", + "sass": "^1.77.4", "sass-loader": "^8.0.2", "style-loader": "^1.1.3", "superagent-binary-parser": "^1.0.1", diff --git a/src/actions/auth.js b/src/actions/auth.js index 5484f80..8522207 100755 --- a/src/actions/auth.js +++ b/src/actions/auth.js @@ -1,189 +1,178 @@ -import {setLoginFailed} from "./main"; -import {history} from "../routers/AppRouter" -import {resetUpload} from "./uploads" +import { setLoginFailed } from "./main"; +import { history } from "../routers/AppRouter"; +import { resetUpload } from "./uploads"; import axios from "../axiosInterceptor"; import env from "../enviroment/envFrontEnd"; -import {setCreateNewAccount} from "./main"; +import { setCreateNewAccount } from "./main"; export const login = (id) => ({ - type: "LOGIN", - id -}) + type: "LOGIN", + id, +}); export const logout = () => ({ - type: "LOGOUT" -}) + type: "LOGOUT", +}); export const startLogin = (email, password, currentRoute) => { + return (dispatch) => { + const dt = { email, password }; - return (dispatch) => { + axios + .post("/user-service/login", dt) + .then((response) => { + // console.log("USER SERVICE LOGIN RESPONSE") - const dt = {email, password}; + const id = response.data.user._id; + const emailVerified = response.data.user.emailVerified; - axios.post("/user-service/login", dt).then((response) => { + env.googleDriveEnabled = response.data.user.googleDriveEnabled; + env.s3Enabled = response.data.user.s3Enabled; + env.activeSubscription = response.data.user.activeSubscription; + env.emailAddress = response.data.user.email; + env.name = response.data.user.name || ""; - // console.log("USER SERVICE LOGIN RESPONSE") + //window.localStorage.setItem("token", token); - const id = response.data.user._id; - const emailVerified = response.data.user.emailVerified; - - env.googleDriveEnabled = response.data.user.googleDriveEnabled; - env.s3Enabled = response.data.user.s3Enabled; - env.activeSubscription = response.data.user.activeSubscription; - env.emailAddress = response.data.user.email; - env.name = response.data.user.name || "" - - //window.localStorage.setItem("token", token); - - if (emailVerified) { - - dispatch(setLoginFailed(false)) - dispatch(login(id)); - history.push(currentRoute); - } else { - console.log("Email Not Verified") - dispatch(setLoginFailed("Unverified Email", 404)) - } - - }).catch((err) => { - console.log("USER SERVICE LOGIN ERROR") - const code = err.response.status; - dispatch(setLoginFailed("Incorrect Email or Password", code)) - console.log(err); - }) - } -} + if (emailVerified) { + dispatch(setLoginFailed(false)); + dispatch(login(id)); + history.push(currentRoute); + } else { + console.log("Email Not Verified"); + dispatch(setLoginFailed("Unverified Email", 404)); + } + }) + .catch((err) => { + console.log("USER SERVICE LOGIN ERROR", err); + const code = err.response?.status; + dispatch(setLoginFailed("Incorrect Email or Password", code)); + console.log(err); + }); + }; +}; export const startCreateAccount = (email, password) => { + return (dispatch) => { + const dt = { email, password }; + axios + .post("/user-service/create", dt) + .then((response) => { + const token = response.data.token; + const id = response.data.user._id; + const emailVerified = response.data.user.emailVerified; - return (dispatch) => { + // window.localStorage.setItem("token", token); - const dt = {email, password}; - axios.post("/user-service/create", dt).then((response) => { - - const token = response.data.token; - const id = response.data.user._id; - const emailVerified = response.data.user.emailVerified; + if (emailVerified) { + dispatch(setLoginFailed(false)); + dispatch(login(id)); + history.push("/home"); + } else { + console.log("Email Not Verified"); + dispatch(setLoginFailed("Unverified Email", 404)); + dispatch(setCreateNewAccount(true)); + } + }) + .catch((err) => { + console.log(err); - // window.localStorage.setItem("token", token); - - if (emailVerified) { - dispatch(setLoginFailed(false)) - dispatch(login(id)); - history.push("/home"); - } else { - console.log("Email Not Verified") - dispatch(setLoginFailed("Unverified Email", 404)) - dispatch(setCreateNewAccount(true)) - } + if (err.response) { + const errStatus = err.response.status; - }).catch((err) => { - - console.log(err); - - if (err.response) { - - const errStatus = err.response.status; - - if (errStatus === 401) { - - dispatch(setLoginFailed("Create Blocked By Admin")) - - } else { - - dispatch(setLoginFailed("Duplicate Email, or Invalid Password")) - } - - } else { - - dispatch(setLoginFailed("Duplicate Email, or Invalid Password")) - } - }) - } -} + if (errStatus === 401) { + dispatch(setLoginFailed("Create Blocked By Admin")); + } else { + dispatch(setLoginFailed("Duplicate Email, or Invalid Password")); + } + } else { + dispatch(setLoginFailed("Duplicate Email, or Invalid Password")); + } + }); + }; +}; const reload = () => { - setTimeout(() => { - window.location.reload(true); - }, 3000); -} + setTimeout(() => { + window.location.reload(true); + }, 3000); +}; export const startLoginCheck = (currentRoute) => { + return (dispatch) => { + axios + .get("/user-service/user") + .then((response) => { + const emailVerified = response.data.emailVerified; - return (dispatch) => { + const id = response.data._id; - axios.get("/user-service/user").then((response) => { - - const emailVerified = response.data.emailVerified; + env.googleDriveEnabled = response.data.googleDriveEnabled; + env.s3Enabled = response.data.s3Enabled; + env.activeSubscription = response.data.activeSubscription; + env.emailAddress = response.data.email; + env.name = response.data.name || ""; - const id = response.data._id; + if (emailVerified) { + dispatch(setLoginFailed(false)); + dispatch(login(id)); + history.push(currentRoute); + } else { + console.log("Email Not Verified"); + dispatch(setLoginFailed("Unverified Email", 404)); + } - env.googleDriveEnabled = response.data.googleDriveEnabled; - env.s3Enabled = response.data.s3Enabled; - env.activeSubscription = response.data.activeSubscription; - env.emailAddress = response.data.email; - env.name = response.data.name || "" - - if (emailVerified) { - dispatch(setLoginFailed(false)) - dispatch(login(id)) - history.push(currentRoute); - } else { - console.log("Email Not Verified") - dispatch(setLoginFailed("Unverified Email", 404)) - } - - //reload(); - - }).catch((err) => { - - console.log("login check error", err, err.response.data, err.data, err.response); - // window.localStorage.removeItem("token") - dispatch(setLoginFailed("Login Expired")) - // history.push("/login") - }) - } -} + //reload(); + }) + .catch((err) => { + console.log( + "login check error", + err, + err.response?.data, + err.data, + err.response + ); + // window.localStorage.removeItem("token") + dispatch(setLoginFailed("Login Expired")); + // history.push("/login") + }); + }; +}; export const startLogoutAll = () => { + return (dispatch) => { + axios + .post("/user-service/logout-all") + .then(() => { + window.localStorage.removeItem("token"); - return (dispatch) => { + dispatch(resetUpload()); + dispatch(setLoginFailed(false)); + dispatch(logout()); - axios.post("/user-service/logout-all").then(() => { - - window.localStorage.removeItem("token") - - dispatch(resetUpload()) - dispatch(setLoginFailed(false)) - dispatch(logout()) - - history.push("/") - - }).catch((err) => { - console.log(err); - }) - - } - -} + history.push("/"); + }) + .catch((err) => { + console.log(err); + }); + }; +}; export const startLogout = () => { + return (dispatch) => { + axios + .post("/user-service/logout") + .then(() => { + window.localStorage.removeItem("token"); - return (dispatch) => { + dispatch(resetUpload()); + dispatch(setLoginFailed(false)); + dispatch(logout()); - axios.post("/user-service/logout").then(() => { - - window.localStorage.removeItem("token") - - dispatch(resetUpload()) - dispatch(setLoginFailed(false)) - dispatch(logout()) - - history.push("/") - - }).catch((err) => { - console.log(err); - }) - - } -} \ No newline at end of file + history.push("/"); + }) + .catch((err) => { + console.log(err); + }); + }; +}; diff --git a/src/actions/files.js b/src/actions/files.js index 27c0b2f..476754a 100644 --- a/src/actions/files.js +++ b/src/actions/files.js @@ -1,511 +1,545 @@ -import {addUpload, editUpload, cancelUpload} from "./uploads"; -import {loadMoreItems, setLoading, setLoadingMoreItems} from "./main" -import {resetSelected} from "./selectedItem"; -import {addQuickFile, startSetQuickFiles, setQuickFiles} from "./quickFiles"; -import {startSetStorage} from "./storage" +import { addUpload, editUpload, cancelUpload } from "./uploads"; +import { loadMoreItems, setLoading, setLoadingMoreItems } from "./main"; +import { resetSelected } from "./selectedItem"; +import { addQuickFile, startSetQuickFiles, setQuickFiles } from "./quickFiles"; +import { startSetStorage } from "./storage"; import uuid from "uuid"; import axios from "../axiosInterceptor"; import axiosNonInterceptor from "axios"; import env from "../enviroment/envFrontEnd"; import Swal from "sweetalert2"; -import mobileCheck from "../utils/mobileCheck"; import { setFolders } from "./folders"; import reduceQuickItemList from "../utils/reduceQuickItemList"; -const http = require('http'); -const https = require('https'); +import http from "http"; +import https from "https"; -let cachedResults = {} +let cachedResults = {}; export const setFiles = (files) => ({ - type: "SET_FILES", - files -}) + type: "SET_FILES", + files, +}); export const editFile = (id, file) => ({ - type: "EDIT_FILE", - id, - file -}) + type: "EDIT_FILE", + id, + file, +}); export const editFileMetadata = (id, metadata) => ({ - type: "EDIT_FILE_METADATA", - id, - metadata -}) + type: "EDIT_FILE_METADATA", + id, + metadata, +}); -export const startSetFileAndFolderItems = (historyKey, parent="/", sortby="DEFAULT", search="", isGoogle=false, storageType="DEFAULT", folderSearch=false) => { +export const startSetFileAndFolderItems = ( + historyKey, + parent = "/", + sortby = "DEFAULT", + search = "", + isGoogle = false, + storageType = "DEFAULT", + folderSearch = false +) => { + return (dispatch) => { + if (cachedResults[historyKey]) { + const { fileList, folderList } = cachedResults[historyKey]; - return (dispatch) => { + dispatch(setFiles(fileList)); + dispatch(setFolders(folderList)); + dispatch(setLoading(false)); - if (cachedResults[historyKey]) { - - const {fileList, folderList} = cachedResults[historyKey]; + if (fileList.length === limit) { + dispatch(loadMoreItems(true)); + } else { + dispatch(loadMoreItems(false)); + } - dispatch(setFiles(fileList)); - dispatch(setFolders(folderList)); - dispatch(setLoading(false)) + delete cachedResults[historyKey]; - if (fileList.length === limit) { - dispatch(loadMoreItems(true)) - } else { - dispatch(loadMoreItems(false)) - } + return; + } - delete cachedResults[historyKey]; + //isGoogle = env.googleDriveEnabled; - return; - } + let limit = window.localStorage.getItem("list-size") || 50; + limit = parseInt(limit); - //isGoogle = env.googleDriveEnabled; - - let limit = window.localStorage.getItem("list-size") || 50 - limit = parseInt(limit); - - let fileURL = ""; - let folderURL = ""; + let fileURL = ""; + let folderURL = ""; - if (search && search !== "") { + if (search && search !== "") { + if (env.googleDriveEnabled) { + fileURL = `/file-service-google-mongo/list?search=${search}`; + folderURL = `/folder-service-google-mongo/list?search=${search}`; + } else { + fileURL = `/file-service/list?search=${search}`; + folderURL = `/folder-service/list?search=${search}`; + } + } else { + fileURL = isGoogle + ? `/file-service-google/list?parent=${parent}&sortby=${sortby}&search=${search}&limit=${limit}&storageType=${storageType}` + : env.googleDriveEnabled && parent === "/" + ? `/file-service-google-mongo/list?parent=${parent}&sortby=${sortby}&search=${search}&limit=${limit}&storageType=${storageType}` + : `/file-service/list?parent=${parent}&sortby=${sortby}&search=${search}&limit=${limit}&storageType=${storageType}`; - if (env.googleDriveEnabled) { - fileURL = `/file-service-google-mongo/list?search=${search}`; - folderURL = `/folder-service-google-mongo/list?search=${search}`; - } else { - fileURL = `/file-service/list?search=${search}`; - folderURL = `/folder-service/list?search=${search}`; - } + folderURL = isGoogle + ? `/folder-service-google/list?parent=${parent}&sortby=${sortby}&search=${search}&storageType=${storageType}` + : env.googleDriveEnabled && parent === "/" + ? `/folder-service-google-mongo/list?parent=${parent}&sortby=${sortby}&search=${search}&storageType=${storageType}` + : `/folder-service/list?parent=${parent}&sortby=${sortby}&search=${search}&storageType=${storageType}`; + } + dispatch(setFiles([])); + dispatch(setFolders([])); + dispatch(setLoading(true)); + const itemList = [axios.get(fileURL), axios.get(folderURL)]; + + Promise.all(itemList) + .then((values) => { + const fileList = values[0].data; + const folderList = values[1].data; + + dispatch(setFiles(fileList)); + dispatch(setFolders(folderList)); + dispatch(setLoading(false)); + + if (fileList.length === limit) { + dispatch(loadMoreItems(true)); } else { - - fileURL = - isGoogle ? `/file-service-google/list?parent=${parent}&sortby=${sortby}&search=${search}&limit=${limit}&storageType=${storageType}` : - (env.googleDriveEnabled && parent === "/") ? `/file-service-google-mongo/list?parent=${parent}&sortby=${sortby}&search=${search}&limit=${limit}&storageType=${storageType}` : - `/file-service/list?parent=${parent}&sortby=${sortby}&search=${search}&limit=${limit}&storageType=${storageType}` - - folderURL = isGoogle ? `/folder-service-google/list?parent=${parent}&sortby=${sortby}&search=${search}&storageType=${storageType}` : - (env.googleDriveEnabled && parent === "/") ? `/folder-service-google-mongo/list?parent=${parent}&sortby=${sortby}&search=${search}&storageType=${storageType}` : - `/folder-service/list?parent=${parent}&sortby=${sortby}&search=${search}&storageType=${storageType}`; - + dispatch(loadMoreItems(false)); } - dispatch(setFiles([])) - dispatch(setFolders([])) - dispatch(setLoading(true)) - - const itemList = [axios.get(fileURL), axios.get(folderURL)]; - - Promise.all(itemList).then((values) => { - - const fileList = values[0].data; - const folderList = values[1].data; + cachedResults[historyKey] = { fileList, folderList }; + }) + .catch((e) => { + console.log("Get All Items Error", e); + }); + }; +}; - dispatch(setFiles(fileList)); - dispatch(setFolders(folderList)); - dispatch(setLoading(false)) +export const startSetAllItems = ( + clearCache, + parent = "/", + sortby = "DEFAULT", + search = "", + isGoogle = false, + storageType = "DEFAULT" +) => { + return (dispatch) => { + if (clearCache) cachedResults = {}; - if (fileList.length === limit) { - dispatch(loadMoreItems(true)) - } else { - dispatch(loadMoreItems(false)) - } - - cachedResults[historyKey] = {fileList, folderList} + //isGoogle = env.googleDriveEnabled; + let limit = window.localStorage.getItem("list-size") || 50; + limit = parseInt(limit); - }).catch((e) => { - console.log("Get All Items Error", e); - }) + if (cachedResults[parent]) { + const { fileList, folderList, quickItemList } = cachedResults[parent]; + + dispatch(setFiles(fileList)); + dispatch(setFolders(folderList)); + dispatch(setQuickFiles(quickItemList)); + dispatch(setLoading(false)); + + if (fileList.length === limit) { + dispatch(loadMoreItems(true)); + } else { + dispatch(loadMoreItems(false)); + } + + cachedResults = {}; + cachedResults[parent] = { fileList, folderList, quickItemList }; + + return; } -} -export const startSetAllItems = (clearCache, parent="/", sortby="DEFAULT", search="", isGoogle=false, storageType="DEFAULT") => { + const fileURL = isGoogle + ? `/file-service-google/list?parent=${parent}&sortby=${sortby}&search=${search}&limit=${limit}&storageType=${storageType}` + : env.googleDriveEnabled && parent === "/" + ? `/file-service-google-mongo/list?parent=${parent}&sortby=${sortby}&search=${search}&limit=${limit}&storageType=${storageType}` + : `/file-service/list?parent=${parent}&sortby=${sortby}&search=${search}&limit=${limit}&storageType=${storageType}`; - return (dispatch) => { + const folderURL = isGoogle + ? `/folder-service-google/list?parent=${parent}&sortby=${sortby}&search=${search}&storageType=${storageType}` + : env.googleDriveEnabled && parent === "/" + ? `/folder-service-google-mongo/list?parent=${parent}&sortby=${sortby}&search=${search}&storageType=${storageType}` + : `/folder-service/list?parent=${parent}&sortby=${sortby}&search=${search}&storageType=${storageType}`; - if (clearCache) cachedResults = {}; + const quickItemsURL = !env.googleDriveEnabled + ? `/file-service/quick-list` + : `/file-service-google-mongo/quick-list`; - //isGoogle = env.googleDriveEnabled; + dispatch(setFiles([])); + dispatch(setFolders([])); + dispatch(setQuickFiles([])); + dispatch(setLoading(true)); - if (cachedResults[parent]) { + const itemList = [ + axios.get(fileURL), + axios.get(folderURL), + axios.get(quickItemsURL), + ]; - const {fileList, folderList, quickItemList} = cachedResults[parent]; + Promise.all(itemList) + .then((values) => { + const fileList = values[0].data; + const folderList = values[1].data; + const quickItemList = reduceQuickItemList(values[2].data); - dispatch(setFiles(fileList)); - dispatch(setFolders(folderList)); - dispatch(setQuickFiles(quickItemList)); - dispatch(setLoading(false)) + dispatch(setFiles(fileList)); + dispatch(setFolders(folderList)); + dispatch(setQuickFiles(quickItemList)); + dispatch(setLoading(false)); - if (fileList.length === limit) { - dispatch(loadMoreItems(true)) - } else { - dispatch(loadMoreItems(false)) - } - - cachedResults = {} - cachedResults[parent] = {fileList, folderList, quickItemList} - - return; - } - - let limit = window.localStorage.getItem("list-size") || 50 - limit = parseInt(limit) - - const fileURL = - isGoogle ? `/file-service-google/list?parent=${parent}&sortby=${sortby}&search=${search}&limit=${limit}&storageType=${storageType}` : - (env.googleDriveEnabled && parent === "/") ? `/file-service-google-mongo/list?parent=${parent}&sortby=${sortby}&search=${search}&limit=${limit}&storageType=${storageType}` : - `/file-service/list?parent=${parent}&sortby=${sortby}&search=${search}&limit=${limit}&storageType=${storageType}` - - const folderURL = isGoogle ? `/folder-service-google/list?parent=${parent}&sortby=${sortby}&search=${search}&storageType=${storageType}` : - (env.googleDriveEnabled && parent === "/") ? `/folder-service-google-mongo/list?parent=${parent}&sortby=${sortby}&search=${search}&storageType=${storageType}` : - `/folder-service/list?parent=${parent}&sortby=${sortby}&search=${search}&storageType=${storageType}`; - - const quickItemsURL = !env.googleDriveEnabled ? `/file-service/quick-list` : `/file-service-google-mongo/quick-list`; - - dispatch(setFiles([])) - dispatch(setFolders([])) - dispatch(setQuickFiles([])) - dispatch(setLoading(true)) - - const itemList = [axios.get(fileURL), axios.get(folderURL), axios.get(quickItemsURL)]; - - Promise.all(itemList).then((values) => { - - const fileList = values[0].data; - const folderList = values[1].data; - const quickItemList = reduceQuickItemList(values[2].data); - - dispatch(setFiles(fileList)); - dispatch(setFolders(folderList)); - dispatch(setQuickFiles(quickItemList)); - dispatch(setLoading(false)) - - if (fileList.length === limit) { - dispatch(loadMoreItems(true)) - } else { - dispatch(loadMoreItems(false)) - } - - cachedResults = {} - cachedResults[parent] = {fileList, folderList, quickItemList} - - }).catch((e) => { - console.log("Get All Items Error", e); - }) - } -} - -export const startSetFiles = (parent="/", sortby="DEFAULT", search="", isGoogle=false, storageType="DEFAULT") => { - - return (dispatch) => { - - let limit = window.localStorage.getItem("list-size") || 50 - limit = parseInt(limit) - - dispatch(setFiles([])) - dispatch(setLoading(true)) - - if (env.googleDriveEnabled) { - - axios.get(`/file-service-google/list?parent=${parent}&sortby=${sortby}&search=${search}&limit=${limit}&storageType=${storageType}`).then((results) => { - - const googleList = results.data; - //dispatch(loadMoreFiles(googleList)) - dispatch(setFiles(googleList)) - dispatch(setLoading(false)) - - if (googleList.length === limit) { - dispatch(loadMoreItems(true)) - } else { - dispatch(loadMoreItems(false)) - } - - }).catch((err) => { - console.log(err) - }) - } else if (env.googleDriveEnabled && parent === "/") { - - // Temp Google Drive API - axios.get(`/file-service-google-mongo/list?parent=${parent}&sortby=${sortby}&search=${search}&limit=${limit}&storageType=${storageType}`).then((results) => { - // console.log("Google Data", results.data.data.files); - // const convertedList = convertDriveListToMongoList(results.data.data.files); - // console.log("Converted List", convertedList); - const googleMongoList = results.data; - //dispatch(loadMoreFiles(googleList)) - //dispatch(setLoading(true)) - dispatch(setFiles(googleMongoList)) - dispatch(setLoading(false)) - - if (results.data.length === limit) { - dispatch(loadMoreItems(true)) - } else { - dispatch(loadMoreItems(false)) - } - - }).catch((err) => { - console.log(err) - }) + if (fileList.length === limit) { + dispatch(loadMoreItems(true)); } else { - - axios.get(`/file-service/list?parent=${parent}&sortby=${sortby}&search=${search}&limit=${limit}&storageType=${storageType}`).then((results) => { - - const mongoData = results.data; - //dispatch(setLoading(true)) - dispatch(setFiles(mongoData)) - dispatch(setLoading(false)) - - if (results.data.length === limit) { - dispatch(loadMoreItems(true)) - } else { - dispatch(loadMoreItems(false)) - } - - }).catch((err) => { - console.log(err) - }) + dispatch(loadMoreItems(false)); } - } -} - -export const loadMoreFiles = (files) => ({ - type: "LOAD_MORE_FILES", - files -}) - -export const startLoadMoreFiles = (parent="/", sortby="DEFAULT", search="", startAtDate, startAtName, pageToken, isGoogle=false) => { - - return (dispatch) => { - - dispatch(setLoadingMoreItems(true)); - - let limit = window.localStorage.getItem("list-size") || 50 - limit = parseInt(limit) - - if (isGoogle) { - - // Temp Google Drive API - axios.get(`/file-service-google/list?limit=${limit}&parent=${parent}&sortby=${sortby}&search=${search}&startAt=${true}&startAtDate=${startAtDate}&startAtName=${startAtName}&pageToken=${pageToken}`).then((results) => { - - dispatch(loadMoreFiles(results.data)) - - if (results.data.length !== limit) { - - dispatch(loadMoreItems(false)) - - } else { - dispatch(loadMoreItems(true)) - } - - dispatch(setLoadingMoreItems(false)); - //dispatch(setLoading(false)) - - }).catch((err) => { - console.log(err) - }) - - } else { - - axios.get(`/file-service/list?limit=${limit}&parent=${parent}&sortby=${sortby}&search=${search}&startAt=${true}&startAtDate=${startAtDate}&startAtName=${startAtName}`).then((results) => { - - //console.log("load more files result", results.data.length) - - dispatch(loadMoreFiles(results.data)) - - if (results.data.length !== limit) { - - dispatch(loadMoreItems(false)) - - } else { - dispatch(loadMoreItems(true)) - } - - // dispatch(setLoading(false)) - dispatch(setLoadingMoreItems(false)); - - }).catch((err) => { - console.log(err) - }) - } - } -} - -export const addFile = (file) => ({ - type: "ADD_FILE", - file -}) - -export const startAddFile = (uploadInput, parent, parentList, storageSwitcherType) => { - - return (dispatch, getState) => { - - if (env.uploadMode === '') { - console.log("No Storage Accounts!"); - Swal.fire({ - icon: 'error', - title: 'No Storage Accounts Active', - text: 'Go to settings to add a storage account', - }) - return; - } - - // Store the parent, incase it changes. - const prevParent = getState().parent.parent; - - for (let i = 0; i < uploadInput.files.length; i++) { - const currentFile = uploadInput.files[i]; - const currentID = uuid(); - - const CancelToken = axiosNonInterceptor.CancelToken; - const source = CancelToken.source(); - - const httpAgent = new http.Agent({ keepAlive: true }); - const httpsAgent = new https.Agent({ keepAlive: true }); - - const config = { - headers: { - httpAgent, - httpsAgent, - 'Content-Type': 'multipart/form-data', - 'Transfere-Encoding': "chunked", - }, - onUploadProgress: (progressEvent) => { - - const currentProgress = Math.round(((progressEvent.loaded / progressEvent.total) * 100)); - - if (currentProgress !== 100) { - - dispatch(editUpload(currentID, currentProgress)) - } - }, - cancelToken: source.token, - }; - - dispatch(addUpload({id: currentID, progress: 0, name: currentFile.name, completed: false, source, canceled: false, size: currentFile.size})) - - const storageType = env.uploadMode; - - const data = new FormData(); - - data.append('filename', currentFile.name); - data.append("parent", parent) - data.append("parentList", parentList) - data.append("currentID", currentID) - data.append("size", currentFile.size) - if (storageType === "s3") data.append("personal-file", true); - data.append('file', currentFile); - - - const url = storageType === "drive" ? '/file-service-google/upload' : storageType === "s3" ? '/file-service-personal/upload' : '/file-service/upload'; - - axios.post(url, data, config) - .then(function (response) { - - const currentParent = getState().parent.parent; - // This can change by the time the file uploads - if (prevParent === currentParent) { - dispatch(addFile(response.data)); - } - - dispatch(addQuickFile(response.data)) - dispatch(editUpload(currentID, 100, true)) - dispatch(resetSelected()) - dispatch(startSetStorage()) - - cachedResults = {}; - - }) - .catch(function (error) { - console.log(error); - dispatch(cancelUpload(currentID)) - }); - - } - } -} - -export const removeFile = (id) => ({ - type: "REMOVE_FILE", - id -}) - -export const startRemoveFile = (id, isGoogle=false, isPersonal=false) => { - - return (dispatch) => { - - const data = {id} - - if (isGoogle) { - - axios.delete("/file-service-google/remove", { - data - }).then(() => { - dispatch(removeFile(id)) - dispatch(startSetStorage()) - dispatch(startSetQuickFiles()); - - cachedResults = {}; - - }).catch((err) => { - console.log(err) - }) - - } else { - - const url = !isPersonal ? "/file-service/remove" : "/file-service-personal/remove"; - - axios.delete(url, { - data - }).then(() => { - dispatch(removeFile(id)) - dispatch(startSetStorage()) - dispatch(startSetQuickFiles()); - - cachedResults = {}; - - }).catch((err) => { - console.log(err) - }) - } - } -} - - -export const startRenameFile = (id, title, isGoogle=false) => { - - return (dispatch) => { - - const data = {id, title} - - if (isGoogle) { - - axios.patch("/file-service-google/rename", data).then(() => { - - dispatch(editFile(id, {filename: title})) - - cachedResults = {}; - - }).catch((err) => { - console.log(err) - }) - } else { - - axios.patch("/file-service/rename", data).then(() => { - - dispatch(editFile(id, {filename: title})) - - cachedResults = {}; - - }).catch((err) => { - console.log(err) - }) - } - - } -} - -export const startResetCache = () => { - - return (dispatch) => { - cachedResults = {}; + cachedResults[parent] = { fileList, folderList, quickItemList }; + }) + .catch((e) => { + console.log("Get All Items Error", e); + }); + }; +}; + +export const startSetFiles = ( + parent = "/", + sortby = "DEFAULT", + search = "", + isGoogle = false, + storageType = "DEFAULT" +) => { + return (dispatch) => { + let limit = window.localStorage.getItem("list-size") || 50; + limit = parseInt(limit); + + dispatch(setFiles([])); + dispatch(setLoading(true)); + + if (env.googleDriveEnabled) { + axios + .get( + `/file-service-google/list?parent=${parent}&sortby=${sortby}&search=${search}&limit=${limit}&storageType=${storageType}` + ) + .then((results) => { + const googleList = results.data; + //dispatch(loadMoreFiles(googleList)) + dispatch(setFiles(googleList)); + dispatch(setLoading(false)); + + if (googleList.length === limit) { + dispatch(loadMoreItems(true)); + } else { + dispatch(loadMoreItems(false)); + } + }) + .catch((err) => { + console.log(err); + }); + } else if (env.googleDriveEnabled && parent === "/") { + // Temp Google Drive API + axios + .get( + `/file-service-google-mongo/list?parent=${parent}&sortby=${sortby}&search=${search}&limit=${limit}&storageType=${storageType}` + ) + .then((results) => { + // console.log("Google Data", results.data.data.files); + // const convertedList = convertDriveListToMongoList(results.data.data.files); + // console.log("Converted List", convertedList); + const googleMongoList = results.data; + //dispatch(loadMoreFiles(googleList)) + //dispatch(setLoading(true)) + dispatch(setFiles(googleMongoList)); + dispatch(setLoading(false)); + + if (results.data.length === limit) { + dispatch(loadMoreItems(true)); + } else { + dispatch(loadMoreItems(false)); + } + }) + .catch((err) => { + console.log(err); + }); + } else { + axios + .get( + `/file-service/list?parent=${parent}&sortby=${sortby}&search=${search}&limit=${limit}&storageType=${storageType}` + ) + .then((results) => { + const mongoData = results.data; + //dispatch(setLoading(true)) + dispatch(setFiles(mongoData)); + dispatch(setLoading(false)); + + if (results.data.length === limit) { + dispatch(loadMoreItems(true)); + } else { + dispatch(loadMoreItems(false)); + } + }) + .catch((err) => { + console.log(err); + }); } -} + }; +}; + +export const loadMoreFiles = (files) => ({ + type: "LOAD_MORE_FILES", + files, +}); + +export const startLoadMoreFiles = ( + parent = "/", + sortby = "DEFAULT", + search = "", + startAtDate, + startAtName, + pageToken, + isGoogle = false +) => { + return (dispatch) => { + dispatch(setLoadingMoreItems(true)); + + let limit = window.localStorage.getItem("list-size") || 50; + limit = parseInt(limit); + + if (isGoogle) { + // Temp Google Drive API + axios + .get( + `/file-service-google/list?limit=${limit}&parent=${parent}&sortby=${sortby}&search=${search}&startAt=${true}&startAtDate=${startAtDate}&startAtName=${startAtName}&pageToken=${pageToken}` + ) + .then((results) => { + dispatch(loadMoreFiles(results.data)); + + if (results.data.length !== limit) { + dispatch(loadMoreItems(false)); + } else { + dispatch(loadMoreItems(true)); + } + + dispatch(setLoadingMoreItems(false)); + //dispatch(setLoading(false)) + }) + .catch((err) => { + console.log(err); + }); + } else { + axios + .get( + `/file-service/list?limit=${limit}&parent=${parent}&sortby=${sortby}&search=${search}&startAt=${true}&startAtDate=${startAtDate}&startAtName=${startAtName}` + ) + .then((results) => { + //console.log("load more files result", results.data.length) + + dispatch(loadMoreFiles(results.data)); + + if (results.data.length !== limit) { + dispatch(loadMoreItems(false)); + } else { + dispatch(loadMoreItems(true)); + } + + // dispatch(setLoading(false)) + dispatch(setLoadingMoreItems(false)); + }) + .catch((err) => { + console.log(err); + }); + } + }; +}; + +export const addFile = (file) => ({ + type: "ADD_FILE", + file, +}); + +export const startAddFile = ( + uploadInput, + parent, + parentList, + storageSwitcherType +) => { + return (dispatch, getState) => { + if (env.uploadMode === "") { + console.log("No Storage Accounts!"); + Swal.fire({ + icon: "error", + title: "No Storage Accounts Active", + text: "Go to settings to add a storage account", + }); + return; + } + + // Store the parent, incase it changes. + const prevParent = getState().parent.parent; + + for (let i = 0; i < uploadInput.files.length; i++) { + const currentFile = uploadInput.files[i]; + const currentID = uuid(); + + const CancelToken = axiosNonInterceptor.CancelToken; + const source = CancelToken.source(); + + const config = { + headers: { + "Content-Type": "multipart/form-data", + "Transfere-Encoding": "chunked", + }, + onUploadProgress: (progressEvent) => { + const currentProgress = Math.round( + (progressEvent.loaded / progressEvent.total) * 100 + ); + + if (currentProgress !== 100) { + dispatch(editUpload(currentID, currentProgress)); + } + }, + cancelToken: source.token, + }; + + dispatch( + addUpload({ + id: currentID, + progress: 0, + name: currentFile.name, + completed: false, + source, + canceled: false, + size: currentFile.size, + }) + ); + + const storageType = env.uploadMode; + + const data = new FormData(); + + data.append("filename", currentFile.name); + data.append("parent", parent); + data.append("parentList", parentList); + data.append("currentID", currentID); + data.append("size", currentFile.size); + if (storageType === "s3") data.append("personal-file", true); + data.append("file", currentFile); + + const url = + storageType === "drive" + ? "/file-service-google/upload" + : storageType === "s3" + ? "/file-service-personal/upload" + : "/file-service/upload"; + + axios + .post(url, data, config) + .then(function (response) { + const currentParent = getState().parent.parent; + // This can change by the time the file uploads + if (prevParent === currentParent) { + dispatch(addFile(response.data)); + } + + dispatch(addQuickFile(response.data)); + dispatch(editUpload(currentID, 100, true)); + dispatch(resetSelected()); + dispatch(startSetStorage()); + + cachedResults = {}; + }) + .catch(function (error) { + console.log(error); + dispatch(cancelUpload(currentID)); + }); + } + }; +}; + +export const removeFile = (id) => ({ + type: "REMOVE_FILE", + id, +}); + +export const startRemoveFile = (id, isGoogle = false, isPersonal = false) => { + return (dispatch) => { + const data = { id }; + + if (isGoogle) { + axios + .delete("/file-service-google/remove", { + data, + }) + .then(() => { + dispatch(removeFile(id)); + dispatch(startSetStorage()); + dispatch(startSetQuickFiles()); + + cachedResults = {}; + }) + .catch((err) => { + console.log(err); + }); + } else { + const url = !isPersonal + ? "/file-service/remove" + : "/file-service-personal/remove"; + + axios + .delete(url, { + data, + }) + .then(() => { + dispatch(removeFile(id)); + dispatch(startSetStorage()); + dispatch(startSetQuickFiles()); + + cachedResults = {}; + }) + .catch((err) => { + console.log(err); + }); + } + }; +}; + +export const startRenameFile = (id, title, isGoogle = false) => { + return (dispatch) => { + const data = { id, title }; + + if (isGoogle) { + axios + .patch("/file-service-google/rename", data) + .then(() => { + dispatch(editFile(id, { filename: title })); + + cachedResults = {}; + }) + .catch((err) => { + console.log(err); + }); + } else { + axios + .patch("/file-service/rename", data) + .then(() => { + dispatch(editFile(id, { filename: title })); + + cachedResults = {}; + }) + .catch((err) => { + console.log(err); + }); + } + }; +}; + +export const startResetCache = () => { + return (dispatch) => { + cachedResults = {}; + }; +}; diff --git a/src/axiosInterceptor/index.js b/src/axiosInterceptor/index.js index caabee9..b942033 100644 --- a/src/axiosInterceptor/index.js +++ b/src/axiosInterceptor/index.js @@ -1,4 +1,4 @@ -import axios from 'axios'; +import axios from "axios"; import uuid from "uuid"; let browserIDCheck = localStorage.getItem("browser-id"); @@ -8,88 +8,90 @@ const sleep = () => { setTimeout(() => { resolve(); }, 150); - }) -} + }); +}; -const axiosRetry = axios.create(); -const axiosNoRetry = axios.create(); -const axios3 = axios.create(); - -axiosRetry.interceptors.request.use((config) => { - - if (!browserIDCheck) { - browserIDCheck = uuid.v4(); - localStorage.setItem("browser-id", browserIDCheck); - }; - - config.headers.uuid = browserIDCheck; - - return config; - -}, (error) => { - - return Promise.reject(error); - -}) - -axiosRetry.interceptors.response.use((response) => { - //console.log("axios interceptor successful") - return response; -}, (error) => { - - return new Promise((resolve, reject) => { - - //console.log("request interceptor failed", error.config.url); - - let originalRequest = error.config; - - if (error.response.status !== 401) { - //console.log("error does not equal 401"); - return reject(error); - } - - if (originalRequest.ran === true) { - //console.log("original request ran", error.config.url); - return reject(error); - } - - if (error.config.url === "/user-service/get-token") { - //console.log("error url equal to refresh token route") - return reject(); - } +const axiosRetry = axios.create({ baseURL: "http://localhost:5173/api" }); +const axiosNoRetry = axios.create({ baseURL: "http://localhost:5173/api" }); +const axios3 = axios.create({ baseURL: "http://localhost:5173/api" }); +axiosRetry.interceptors.request.use( + (config) => { if (!browserIDCheck) { browserIDCheck = uuid.v4(); localStorage.setItem("browser-id", browserIDCheck); - }; - - axiosNoRetry.post("/user-service/get-token", {}, {headers: { - "uuid" : browserIDCheck - }}).then((cookieResponse) => { - - // We need to sleep before requesting again, if not I believe - // The old request will still be open and it will not make a - // Brand new request sometimes, so it will log users out - // But adding a sleep function seems to fix this. - return sleep("sleepy boi"); + } - }).then((sleepres) => { + config.headers.uuid = browserIDCheck; - return axios3(originalRequest); + return config; + }, + (error) => { + return Promise.reject(error); + } +); - }).then((response) => { +axiosRetry.interceptors.response.use( + (response) => { + //console.log("axios interceptor successful") + return response; + }, + (error) => { + return new Promise((resolve, reject) => { + //console.log("request interceptor failed", error.config.url); - resolve(response) + let originalRequest = error.config; - }).catch((e) => { + if (error.response.status !== 401) { + //console.log("error does not equal 401"); + return reject(error); + } - //console.log("error"); - return reject(error); + if (originalRequest.ran === true) { + //console.log("original request ran", error.config.url); + return reject(error); + } - }) - }) + if (error.config.url === "/user-service/get-token") { + //console.log("error url equal to refresh token route") + return reject(); + } -}) + if (!browserIDCheck) { + browserIDCheck = uuid.v4(); + localStorage.setItem("browser-id", browserIDCheck); + } + + axiosNoRetry + .post( + "/user-service/get-token", + {}, + { + headers: { + uuid: browserIDCheck, + }, + } + ) + .then((cookieResponse) => { + // We need to sleep before requesting again, if not I believe + // The old request will still be open and it will not make a + // Brand new request sometimes, so it will log users out + // But adding a sleep function seems to fix this. + return sleep("sleepy boi"); + }) + .then((sleepres) => { + return axios3(originalRequest); + }) + .then((response) => { + resolve(response); + }) + .catch((e) => { + //console.log("error"); + return reject(error); + }); + }); + } +); // axios.interceptors.response.use( (response) => { @@ -148,7 +150,7 @@ axiosRetry.interceptors.response.use((response) => { // // console.log("cookieError", cookieError); // // return Promise.reject(error); // // }) - + // }); export default axiosRetry; diff --git a/src/components/Header/Header.js b/src/components/Header/Header.js index 0be62e7..eb78b4f 100644 --- a/src/components/Header/Header.js +++ b/src/components/Header/Header.js @@ -1,53 +1,72 @@ import React from "react"; const Header = (props) => ( +
+ +
+); -
-
-
- - -
-
-
-) - -export default Header \ No newline at end of file +export default Header; diff --git a/src/components/Header/index.js b/src/components/Header/index.js index a8057ee..e37f7d0 100644 --- a/src/components/Header/index.js +++ b/src/components/Header/index.js @@ -1,224 +1,213 @@ import Header from "./Header"; -import {startLogout} from "../../actions/auth" -import {showSettings} from "../../actions/settings"; -import {setSearch} from "../../actions/filter" -import {loadMoreItems} from "../../actions/main"; -import {setParent, resetParentList} from "../../actions/parent"; -import {startSetFiles} from "../../actions/files"; -import {startSetFolders} from "../../actions/folders"; +import { startLogout } from "../../actions/auth"; +import { showSettings } from "../../actions/settings"; +import { setSearch } from "../../actions/filter"; +import { loadMoreItems } from "../../actions/main"; +import { setParent, resetParentList } from "../../actions/parent"; +import { startSetFiles } from "../../actions/files"; +import { startSetFolders } from "../../actions/folders"; import env from "../../enviroment/envFrontEnd"; -import {history} from "../../routers/AppRouter"; +import { history } from "../../routers/AppRouter"; import axios from "../../axiosInterceptor"; -import {connect} from "react-redux"; +import { connect } from "react-redux"; import React from "react"; const currentURL = env.url; class HeaderContainer extends React.Component { + constructor(props) { + super(props); - constructor(props) { - super(props); + this.searchValue = ""; - this.searchValue = ""; + this.state = { + focused: false, + suggestedList: { + fileList: [], + folderList: [], + }, + }; + } - this.state = { - focused: false, - suggestedList: { - fileList: [], - folderList: [] - } - } + searchEvent = (e) => { + e.preventDefault(); + + const value = this.props.search; + + // console.log("Search value". value) + + const parent = "/"; + this.props.dispatch(setParent(parent)); + this.props.dispatch(loadMoreItems(true)); + this.props.dispatch(startSetFiles(undefined, undefined, value)); + this.props.dispatch(startSetFolders(undefined, undefined, value)); + this.props.dispatch(resetParentList()); + }; + + searchOnChange = (e) => { + const value = e.target.value; + this.searchValue = value; + + this.props.dispatch(setSearch(value)); + this.searchSuggested(); + }; + + showSuggested = () => { + this.setState(() => { + return { + ...this.state, + focused: true, + }; + }); + }; + + hideSuggested = () => { + this.setState(() => { + return { + ...this.state, + focused: false, + }; + }); + }; + + selectSuggested = () => { + history.push(`/search/${this.searchValue}`); + + this.searchValue = ""; + + this.setState(() => { + return { + ...this.state, + suggestedList: { + fileList: [], + folderList: [], + }, + }; + }); + }; + + searchSuggested = () => { + return; + + // if (this.searchValue === "") { + + // return this.setState(() => { + // return { + // ...this.state, + // suggestedList: { + // fileList: [], + // folderList: [] + // } + // } + // }) + // } + + // const url = !env.googleDriveEnabled ? currentURL +`/file-service/suggested-list?search=${this.searchValue}` : currentURL +`/file-service-google-mongo/suggested-list?search=${this.searchValue}` + + // axios.get(url).then((results) => { + + // this.setState(() => { + // return { + // ...this.state, + // suggestedList: results.data + // } + // }) + + // }).catch((err) => { + // console.log(err) + // }) + }; + + showSettings = () => { + this.props.dispatch(showSettings()); + }; + + logoutUser = () => { + this.props.dispatch(startLogout()); + }; + + itemClick = () => { + console.log("item click"); + }; + + selectSuggestedByParent = () => { + // const parent = this.props.parent === "/" ? "home" : this.props.parent; + + const parent = this.props.parent; + + history.push( + `/search/${this.searchValue}?parent=${parent}&folder_search=true` + ); + + this.searchValue = ""; + + this.setState(() => { + return { + ...this.state, + suggestedList: { + fileList: [], + folderList: [], + }, + }; + }); + }; + + selectSuggestedByStorageType = () => { + history.push(`/search/${this.searchValue}?storageType=stripe`); + + this.searchValue = ""; + + this.setState(() => { + return { + ...this.state, + suggestedList: { + fileList: [], + folderList: [], + }, + }; + }); + }; + + goToSettings = () => { + history.push("/settings"); + }; + + getProfilePic = () => { + if (env.name && env.name.length !== 0) { + return env.name.substring(0, 1).toUpperCase(); + } else if (env.emailAddress && env.emailAddress.length !== 0) { + return env.emailAddress.substring(0, 1).toUpperCase(); + } else { + return "?"; } - - searchEvent = (e) => { - e.preventDefault(); + }; - const value = this.props.search; - - // console.log("Search value". value) - - const parent = "/" - this.props.dispatch(setParent(parent)) - this.props.dispatch(loadMoreItems(true)) - this.props.dispatch(startSetFiles(undefined, undefined, value)); - this.props.dispatch(startSetFolders(undefined, undefined, value)); - this.props.dispatch(resetParentList()) - - - } - - searchOnChange = (e) => { - - const value = e.target.value; - this.searchValue = value; - - this.props.dispatch(setSearch(value)) - this.searchSuggested() - } - - showSuggested = () => { - - this.setState(() => { - return { - ...this.state, - focused: true - } - }) - } - - hideSuggested = () => { - - this.setState(() => { - return { - ...this.state, - focused: false - } - }) - } - - selectSuggested = () => { - - history.push(`/search/${this.searchValue}`) - - this.searchValue = '' - - this.setState(() => { - return { - ...this.state, - suggestedList: { - fileList: [], - folderList: [] - } - } - }) - } - - searchSuggested = () => { - - return; - - // if (this.searchValue === "") { - - // return this.setState(() => { - // return { - // ...this.state, - // suggestedList: { - // fileList: [], - // folderList: [] - // } - // } - // }) - // } - - // const url = !env.googleDriveEnabled ? currentURL +`/file-service/suggested-list?search=${this.searchValue}` : currentURL +`/file-service-google-mongo/suggested-list?search=${this.searchValue}` - - // axios.get(url).then((results) => { - - // this.setState(() => { - // return { - // ...this.state, - // suggestedList: results.data - // } - // }) - - // }).catch((err) => { - // console.log(err) - // }) - } - - showSettings = () => { - - this.props.dispatch(showSettings()) - } - - logoutUser = () => { - - this.props.dispatch(startLogout()) - } - - itemClick = () => { - console.log("item click") - } - - selectSuggestedByParent = () => { - - // const parent = this.props.parent === "/" ? "home" : this.props.parent; - - const parent = this.props.parent; - - history.push(`/search/${this.searchValue}?parent=${parent}&folder_search=true`) - - this.searchValue = '' - - this.setState(() => { - return { - ...this.state, - suggestedList: { - fileList: [], - folderList: [] - } - } - }) - } - - selectSuggestedByStorageType = () => { - - history.push(`/search/${this.searchValue}?storageType=stripe`) - - this.searchValue = '' - - this.setState(() => { - return { - ...this.state, - suggestedList: { - fileList: [], - folderList: [] - } - } - }) - } - - goToSettings = () => { - - window.location.assign(env.url+"/settings") - } - - getProfilePic = () => { - - if (env.name && env.name.length !== 0) { - return env.name.substring(0, 1).toUpperCase(); - } else if (env.emailAddress && env.emailAddress.length !== 0) { - return env.emailAddress.substring(0,1).toUpperCase(); - } else { - return "?" - } - } - - render() { - - return
- } + render() { + return ( +
+ ); + } } const connectPropToStore = (state) => ({ - search: state.filter.search, - parentNameList: state.parent.parentNameList, - parent: state.parent.parent, -}) + search: state.filter.search, + parentNameList: state.parent.parentNameList, + parent: state.parent.parent, +}); -export default connect(connectPropToStore)(HeaderContainer); \ No newline at end of file +export default connect(connectPropToStore)(HeaderContainer); diff --git a/src/components/LoginPage/LoginPage.js b/src/components/LoginPage/LoginPage.js index 85bbf80..a727fc5 100755 --- a/src/components/LoginPage/LoginPage.js +++ b/src/components/LoginPage/LoginPage.js @@ -3,181 +3,239 @@ import React from "react"; import env from "../../enviroment/envFrontEnd"; const LoginPage = (props) => { - - return ( - + return ( +
+ {!props.loginFailed ? (
- - {(!props.loginFailed) ? - -
- -
- -
- -
-
- - -
- - : - -
- - {(props.loginFailed && props.loginFailedCode === 404) ? - -
- -
- - + ) : ( +
+
+
+ logo
- } + {/* */} +
+

+ {props.state.loginMode + ? "Login to your account" + : "Create an account"} +

+
+
+ +
+ {!props.state.resetPasswordMode ? ( +
+ + {props.state.loginMode ? ( + Forgot? + ) : undefined} +
+ ) : undefined} + {props.state.loginMode ? undefined : ( +
+ { + props.passwordInput = ref; + }} + /> +
+ )} +
+ +
+ {!props.state.resetPasswordMode ? ( +
+ {props.state.loginMode ? ( +

+ Don't have an account?{" "} + + Create account + +

+ ) : ( +

+ Back to Login +

+ )} +
+ ) : ( +
+

+ Back to{" "} + Login +

+
+ )} + + {props.loginFailed ? ( + props.loginFailedCode === 404 ? ( +
+
+ +

Email Not Verified

+
+
+

+ Resend Email Verification +

+

+ Logout +

+
+
+ ) : ( +
+ +

{props.loginFailed}

+
+ ) + ) : undefined} +
+
+ + {/* */} +
+

Forgot your password?

+

+ Type in your email address and we’ll send you instructions + to reset your password. +

+
+
+ +
+
+ +
+
+
+ +
+

Check your email

+

+ If the email address matches any in our database, we’ll send + you an email with instructions on how to reset your password +

+
+
+
+ )} + + {/* */} + {/*
+

Copyright © 2020 myDrive. All Rights Reserved.

+
*/}
+ )} +
+ ); +}; - - - ) - -} - -export default LoginPage \ No newline at end of file +export default LoginPage; diff --git a/src/components/MainSection/index.js b/src/components/MainSection/index.js index f7fe9a0..abf3fbe 100644 --- a/src/components/MainSection/index.js +++ b/src/components/MainSection/index.js @@ -1,287 +1,312 @@ - -import {startLoadMoreFiles} from "../../actions/files"; -import {startSetSelectedItem, setLastSelected} from "../../actions/selectedItem"; -import {setLoading, setLeftSectionMode, setRightSectionMode} from "../../actions/main"; -import {setPopupFile} from "../../actions/popupFile"; -import mobileCheck from "../../utils/mobileCheck" +import { startLoadMoreFiles } from "../../actions/files"; +import { + startSetSelectedItem, + setLastSelected, +} from "../../actions/selectedItem"; +import { + setLoading, + setLeftSectionMode, + setRightSectionMode, +} from "../../actions/main"; +import { setPopupFile } from "../../actions/popupFile"; +import mobileCheck from "../../utils/mobileCheck"; import MainSection from "./MainSection"; import env from "../../enviroment/envFrontEnd"; import axios from "../../axiosInterceptor"; -import {connect} from "react-redux"; -import {history} from "../../routers/AppRouter"; +import { connect } from "react-redux"; +import { history } from "../../routers/AppRouter"; import React from "react"; import { getUpdateSettingsID } from "../../utils/updateSettings"; class MainSectionContainer extends React.Component { + constructor(props) { + super(props); - constructor(props) { - super(props); + this.doubleClickFoldersMobile = false; + this.lastSettingsUpdateID = ""; + } - this.doubleClickFoldersMobile = false; - this.lastSettingsUpdateID = ""; + folderClick = (id, folder, bypass = false) => { + const currentDate = Date.now(); + const mobile = mobileCheck(); + const selectedID = this.props.selected; + + const doubleClickMobile = + localStorage.getItem("double-click-folders") || false; + + if ( + (currentDate - this.props.lastSelected < 1500 && selectedID === id) || + (mobile && !doubleClickMobile) || + bypass + ) { + const folderPush = folder.drive + ? `/folder-google/${id}` + : folder.personalFolder + ? `/folder-personal/${id}` + : `/folder/${id}`; + history.push(folderPush); + } else { + const isGoogleDrive = folder.drive; + + this.props.dispatch( + startSetSelectedItem(id, false, false, isGoogleDrive) + ); + } + }; + + fileClick = (fileID, file, fromQuickItems = false, bypass = false) => { + const currentDate = Date.now(); + + let selectedFileID = fileID; + + if (fromQuickItems) { + selectedFileID = "quick-" + fileID; } - folderClick = (id, folder, bypass=false) => { + const isMobile = mobileCheck(); - const currentDate = Date.now(); - const mobile = mobileCheck(); - const selectedID = this.props.selected; + if ( + (currentDate - this.props.lastSelected < 1500 && + selectedFileID === this.props.selected) || + bypass + ) { + this.props.dispatch(setPopupFile({ showPopup: true, ...file })); + } else { + const isGoogleDrive = file.metadata.drive; - const doubleClickMobile = localStorage.getItem("double-click-folders") || false; + this.props.dispatch( + startSetSelectedItem(fileID, true, fromQuickItems, isGoogleDrive) + ); + } + }; - if ((currentDate - this.props.lastSelected < 1500 && selectedID === id) || (mobile && !doubleClickMobile)|| bypass) { + scrollEvent = (e) => { + //if (!mobileCheck()) return; - const folderPush = folder.drive ? `/folder-google/${id}` : folder.personalFolder ? `/folder-personal/${id}` : `/folder/${id}`; - history.push(folderPush) + return; - } else { + const scrollY = window.pageYOffset; + const windowY = document.documentElement.scrollHeight; - const isGoogleDrive = folder.drive; + let limit = window.localStorage.getItem("list-size") || 50; + limit = parseInt(limit); - this.props.dispatch(startSetSelectedItem(id, false, false, isGoogleDrive)); - } - + if (this.props.loading) return; + + if (windowY / 2 < scrollY && this.props.allowLoadMoreItems) { + console.log("load more main"); + + if (this.props.files.length >= limit) { + const parent = this.props.parent; + const search = this.props.filter.search; + const sortBy = this.props.filter.sortBy; + const lastFileDate = + this.props.files[this.props.files.length - 1].uploadDate; + const lastFileName = + this.props.files[this.props.files.length - 1].filename; + + this.props.dispatch(setLoading(true)); + this.props.dispatch( + startLoadMoreFiles(parent, sortBy, search, lastFileDate, lastFileName) + ); + } + } + }; + + componentDidMount = () => { + window.addEventListener("scroll", this.scrollEvent); + window.addEventListener("resize", this.resizeEvent); + + this.getSettings(); + }; + + componentDidUpdate = () => { + console.log("main updated"); + + // console.log("update ID main", getUpdateSettingsID()); + + // if (this.lastSettingsUpdateID !== getUpdateSettingsID()) { + // console.log("Settings Update!"); + // this.getSettings(); + // } + + // this.lastSettingsUpdateID = getUpdateSettingsID(); + + // console.log("update settings id", updateSettingsID); + + // console.log("Main Section Updated", this.props.resetSettingsMain); + + // if (this.lastSettingsUpdateID !== this.props.resetSettingsMain) { + // console.log("Settings Update!"); + // this.getSettings(); + // } + + // this.lastSettingsUpdateID = this.props.resetSettingsMain; + }; + + getSettings = () => { + this.doubleClickFoldersMobile = + localStorage.getItem("double-click-folders") || false; + }; + + componentWillUnmount = () => { + window.removeEventListener("scroll", this.scrollEvent); + }; + + resizeEvent = () => { + if (this.props.leftSectionMode === "open") + this.props.dispatch(setLeftSectionMode("")); + if (this.props.rightSectionMode === "open") + this.props.dispatch(setRightSectionMode("")); + }; + + downloadFile = (fileID, file) => { + const isGoogle = file.metadata.drive; + const isGoogleDoc = file.metadata.googleDoc; + const isPersonal = file.metadata.personalFile; + + this.props.dispatch(setLastSelected(0)); + + axios + .post("/user-service/get-token") + .then((response) => { + let finalUrl = isGoogle + ? !isGoogleDoc + ? `/file-service-google/download/${fileID}` + : `/file-service-google-doc/download/${fileID}` + : !isPersonal + ? `/file-service/download/${fileID}` + : `/file-service-personal/download/${fileID}`; + + finalUrl = `http://localhost:3000${finalUrl}`; + + console.log("download file", finalUrl); + + const link = document.createElement("a"); + document.body.appendChild(link); + link.href = finalUrl; + link.setAttribute("type", "hidden"); + link.setAttribute("download", true); + link.click(); + }) + .catch((e) => { + console.log("Download file get refresh token error", e); + }); + + // axios.get(currentURL +'/file-service/download/get-token') + // .then((response) => { + + // const tempToken = response.data.tempToken; + + // const finalUrl = + // isGoogle ? !isGoogleDoc ? currentURL + `/file-service-google/download/${fileID}` : currentURL + `/file-service-google-doc/download/${fileID}` + // : !isPersonal ? currentURL + `/file-service/download/${fileID}` : currentURL + `/file-service-personal/download/${fileID}` + + // const link = document.createElement('a'); + // document.body.appendChild(link); + // link.href = finalUrl; + // link.setAttribute('type', 'hidden'); + // link.setAttribute("download", true); + // link.click(); + + // }).catch((err) => { + // console.log(err) + // }) + }; + + loadMoreItems = () => { + return; + + console.log("load more main"); + + if (mobileCheck()) return; + + let limit = window.localStorage.getItem("list-size") || 50; + limit = parseInt(limit); + + if (this.props.loading) { + return; } - fileClick = (fileID, file, fromQuickItems=false, bypass=false) => { - - const currentDate = Date.now(); - - let selectedFileID = fileID; - - if (fromQuickItems) { - selectedFileID = "quick-" + fileID; - } - - const isMobile = mobileCheck(); - - if ((currentDate - this.props.lastSelected < 1500 && selectedFileID === this.props.selected) || bypass) { - - this.props.dispatch(setPopupFile({showPopup: true, ...file})) - - } else { - - const isGoogleDrive = file.metadata.drive - - this.props.dispatch(startSetSelectedItem(fileID, true, fromQuickItems, isGoogleDrive)) - - } + if (this.props.files.length >= limit) { + const parent = this.props.parent; + const search = this.props.filter.search; + const sortBy = this.props.filter.sortBy; + const lastFileDate = + this.props.files[this.props.files.length - 1].uploadDate; + const lastFileName = + this.props.files[this.props.files.length - 1].filename; + const lastPageToken = + this.props.files[this.props.files.length - 1].pageToken; + const isGoogle = this.props.filter.isGoogle; + this.props.dispatch( + startLoadMoreFiles( + parent, + sortBy, + search, + lastFileDate, + lastFileName, + lastPageToken, + isGoogle + ) + ); } + }; - scrollEvent = (e) => { + switchLeftSectionMode = () => { + const leftSectionMode = this.props.leftSectionMode; - //if (!mobileCheck()) return; - - return; - - const scrollY = window.pageYOffset; - const windowY = document.documentElement.scrollHeight; - - let limit = window.localStorage.getItem("list-size") || 50 - limit = parseInt(limit) - - if (this.props.loading) return; - - if ((windowY / 2) < scrollY && this.props.allowLoadMoreItems) { - - console.log("load more main") - - if (this.props.files.length >= limit) { - const parent = this.props.parent; - const search = this.props.filter.search; - const sortBy = this.props.filter.sortBy; - const lastFileDate = this.props.files[this.props.files.length - 1].uploadDate - const lastFileName = this.props.files[this.props.files.length - 1].filename - - this.props.dispatch(setLoading(true)); - this.props.dispatch(startLoadMoreFiles(parent, sortBy, search, lastFileDate, lastFileName)); - - } - } + if (leftSectionMode === "" || leftSectionMode === "close") { + this.props.dispatch(setLeftSectionMode("open")); + } else { + this.props.dispatch(setLeftSectionMode("close")); } + }; - componentDidMount = () => { - window.addEventListener("scroll", this.scrollEvent); - window.addEventListener("resize", this.resizeEvent); + switchRightSectionMode = () => { + const rightSectionMode = this.props.rightSectionMode; - this.getSettings(); - } - - componentDidUpdate = () => { - - console.log("main updated"); - - // console.log("update ID main", getUpdateSettingsID()); - - // if (this.lastSettingsUpdateID !== getUpdateSettingsID()) { - // console.log("Settings Update!"); - // this.getSettings(); - // } - - // this.lastSettingsUpdateID = getUpdateSettingsID(); - - // console.log("update settings id", updateSettingsID); - - // console.log("Main Section Updated", this.props.resetSettingsMain); - - // if (this.lastSettingsUpdateID !== this.props.resetSettingsMain) { - // console.log("Settings Update!"); - // this.getSettings(); - // } - - // this.lastSettingsUpdateID = this.props.resetSettingsMain; - } - - getSettings = () => { - - this.doubleClickFoldersMobile = localStorage.getItem("double-click-folders") || false; - } - - componentWillUnmount = () => { - - window.removeEventListener("scroll", this.scrollEvent); - } - - resizeEvent = () => { - if (this.props.leftSectionMode === 'open') this.props.dispatch(setLeftSectionMode('')) - if (this.props.rightSectionMode === 'open') this.props.dispatch(setRightSectionMode('')) - } - - downloadFile = (fileID, file) => { - - const isGoogle = file.metadata.drive; - const isGoogleDoc = file.metadata.googleDoc; - const isPersonal = file.metadata.personalFile; - - this.props.dispatch(setLastSelected(0)); - - axios.post("/user-service/get-token").then((response) => { - - - - const finalUrl = - isGoogle ? !isGoogleDoc ? `/file-service-google/download/${fileID}` : `/file-service-google-doc/download/${fileID}` - : !isPersonal ? `/file-service/download/${fileID}` : `/file-service-personal/download/${fileID}` - - console.log("download file", finalUrl); - - const link = document.createElement('a'); - document.body.appendChild(link); - link.href = finalUrl; - link.setAttribute('type', 'hidden'); - link.setAttribute("download", true); - link.click(); - - }).catch((e) => { - console.log("Download file get refresh token error", e); - }) - - // axios.get(currentURL +'/file-service/download/get-token') - // .then((response) => { - - // const tempToken = response.data.tempToken; - - // const finalUrl = - // isGoogle ? !isGoogleDoc ? currentURL + `/file-service-google/download/${fileID}` : currentURL + `/file-service-google-doc/download/${fileID}` - // : !isPersonal ? currentURL + `/file-service/download/${fileID}` : currentURL + `/file-service-personal/download/${fileID}` - - // const link = document.createElement('a'); - // document.body.appendChild(link); - // link.href = finalUrl; - // link.setAttribute('type', 'hidden'); - // link.setAttribute("download", true); - // link.click(); - - // }).catch((err) => { - // console.log(err) - // }) - } - - loadMoreItems = () => { - - return; - - console.log("load more main") - - if (mobileCheck()) return; - - let limit = window.localStorage.getItem("list-size") || 50 - limit = parseInt(limit) - - if (this.props.loading) { - - return; - } - - if (this.props.files.length >= limit) { - - const parent = this.props.parent; - const search = this.props.filter.search; - const sortBy = this.props.filter.sortBy; - const lastFileDate = this.props.files[this.props.files.length - 1].uploadDate - const lastFileName = this.props.files[this.props.files.length - 1].filename - const lastPageToken = this.props.files[this.props.files.length - 1].pageToken - const isGoogle = this.props.filter.isGoogle; - - this.props.dispatch(startLoadMoreFiles(parent, sortBy, search, lastFileDate, lastFileName, lastPageToken, isGoogle)) - } - } - - switchLeftSectionMode = () => { - - const leftSectionMode = this.props.leftSectionMode; - - if (leftSectionMode === '' || leftSectionMode === 'close') { - this.props.dispatch(setLeftSectionMode('open')) - } else { - this.props.dispatch(setLeftSectionMode('close')) - } - } - - switchRightSectionMode = () => { - - const rightSectionMode = this.props.rightSectionMode; - - if (rightSectionMode === '' || rightSectionMode === 'close') { - this.props.dispatch(setRightSectionMode('open')) - } else { - this.props.dispatch(setRightSectionMode('close')) - } - } - - render() { - - return + if (rightSectionMode === "" || rightSectionMode === "close") { + this.props.dispatch(setRightSectionMode("open")); + } else { + this.props.dispatch(setRightSectionMode("close")); } + }; + render() { + return ( + + ); + } } const connectPropToState = (state) => ({ - filter: state.filter, - files: state.files, - folders: state.folders, - allowLoadMoreItems: state.main.loadMoreItems, - loading: state.main.loading, - showPopup: state.popupFile.showPopup, - quickFiles: state.quickFiles, - selected: state.selectedItem.selected, - lastSelected: state.selectedItem.lastSelected, - parent: state.parent.parent, - parentNameList: state.parent.parentNameList, - moverID: state.mover.id, - routeType: state.main.currentRouteType, - cachedSearch: state.main.cachedSearch, - leftSectionMode: state.main.leftSectionMode, - rightSectionMode: state.main.rightSectionMode, - // resetSettingsMain: state.main.resetSettingsMain -}) + filter: state.filter, + files: state.files, + folders: state.folders, + allowLoadMoreItems: state.main.loadMoreItems, + loading: state.main.loading, + showPopup: state.popupFile.showPopup, + quickFiles: state.quickFiles, + selected: state.selectedItem.selected, + lastSelected: state.selectedItem.lastSelected, + parent: state.parent.parent, + parentNameList: state.parent.parentNameList, + moverID: state.mover.id, + routeType: state.main.currentRouteType, + cachedSearch: state.main.cachedSearch, + leftSectionMode: state.main.leftSectionMode, + rightSectionMode: state.main.rightSectionMode, + // resetSettingsMain: state.main.resetSettingsMain +}); -export default connect(connectPropToState)(MainSectionContainer); \ No newline at end of file +export default connect(connectPropToState)(MainSectionContainer); diff --git a/src/components/QuickAccess/QuickAccess.js b/src/components/QuickAccess/QuickAccess.js index 1e89608..68afb56 100644 --- a/src/components/QuickAccess/QuickAccess.js +++ b/src/components/QuickAccess/QuickAccess.js @@ -2,26 +2,29 @@ import QuickAccessItem from ".././QuickAccessItem"; import React from "react"; const QuickAccess = (props) => ( - -
- -
-

Quick Access

-
- -
- - {props.quickFiles - .map((file) => )} - -
- +
+
+

Quick Access

-) +
+ {props.quickFiles.map((file) => ( + + ))} +
+
+); -export default QuickAccess; \ No newline at end of file +export default QuickAccess; diff --git a/src/components/SettingsPage/index.js b/src/components/SettingsPage/index.js index 036be04..822e5fc 100644 --- a/src/components/SettingsPage/index.js +++ b/src/components/SettingsPage/index.js @@ -1,10 +1,10 @@ import React from "react"; import Header from "../Header/index"; -import axios from "../../axiosInterceptor" +import axios from "../../axiosInterceptor"; import env from "../../enviroment/envFrontEnd"; -import Swal from "sweetalert2" +import Swal from "sweetalert2"; import bytes from "bytes"; -import moment from "moment" +import moment from "moment"; import capitalize from "../../utils/capitalize"; import { resetCurrentRoute } from "../../actions/routes"; import { setFolders } from "../../actions/folders"; @@ -12,306 +12,303 @@ import { setQuickFiles } from "../../actions/quickFiles"; import { hideSettings } from "../../actions/settings"; import { startLogout, startLogoutAll } from "../../actions/auth"; import { setFiles, startResetCache } from "../../actions/files"; -import {connect} from "react-redux" +import { connect } from "react-redux"; import { setParent } from "../../actions/parent"; -import uuid from "uuid" +import uuid from "uuid"; import InvoiceItem from "../InvoiceItem"; -import {setUpdateSettingsID} from "../../utils/updateSettings"; +import { setUpdateSettingsID } from "../../utils/updateSettings"; import HomepageSpinner from "../HomepageSpinner"; import { setLoading } from "../../actions/main"; +import { history } from "../../routers/AppRouter"; // import {updateSettingsID} from "../MainSection" // import { resetSettingsMain } from "../../actions/main"; class SettingsPageContainer extends React.Component { - - constructor(props) { - super(props); + constructor(props) { + super(props); - this.state = { - sideBarOpen: false, - mode: "general", - loaded: false, - userDetails: {}, - addS3AccountOpen: false, - s3ID: "", - s3Key: "", - s3Bucket: "", - addGoogleAccountOpen: false, - googleID: "", - googleSecret: "", - invoiceData: {}, - invoices: [], - invoicesLoaded: false, - showChangePassword: false, - oldPassword: "", - newPassword: "", - verifyNewPassword: "", - showAddName: false, - name: "", - listView: true, - dateSort: true, - descendingSort: true, - dropToUpload: true, - doubleClickFolders: false, - hideFolderTree: false, - showFolderTreeScrollBars: false - } + this.state = { + sideBarOpen: false, + mode: "general", + loaded: false, + userDetails: {}, + addS3AccountOpen: false, + s3ID: "", + s3Key: "", + s3Bucket: "", + addGoogleAccountOpen: false, + googleID: "", + googleSecret: "", + invoiceData: {}, + invoices: [], + invoicesLoaded: false, + showChangePassword: false, + oldPassword: "", + newPassword: "", + verifyNewPassword: "", + showAddName: false, + name: "", + listView: true, + dateSort: true, + descendingSort: true, + dropToUpload: true, + doubleClickFolders: false, + hideFolderTree: false, + showFolderTreeScrollBars: false, + }; - this.uploadReference = React.createRef() - } + this.uploadReference = React.createRef(); + } - getUserDetails = () => { + getUserDetails = () => { + this.props.dispatch(setLoading(true)); - this.props.dispatch(setLoading(true)); + axios + .get("/user-service/user-detailed") + .then((response) => { + env.name = response.data.name; + env.emailAddress = response.data.email; + this.props.dispatch(setParent(uuid.v4())); - axios.get("/user-service/user-detailed").then((response) => { - - env.name = response.data.name; - env.emailAddress = response.data.email - this.props.dispatch(setParent(uuid.v4())) + this.setState( + () => { + return { + ...this.state, + loaded: true, + userDetails: response.data, + }; + }, + () => { + // this.getInvoiceData(); + this.props.dispatch(setLoading(false)); + } + ); + }) + .catch((err) => { + console.log("Loading user details error", err); - this.setState(() => { - return { - ...this.state, - loaded: true, - userDetails: response.data - } - }, () => { + Swal.fire({ + title: "Error loading user account", + text: "There was an error loading your account, would you like to logout?", + icon: "warning", + showCancelButton: true, + confirmButtonText: "Yes, logout", + cancelButtonText: "No", + }).then((result) => { + if (result.value) { + console.log("Confirm logout"); - // this.getInvoiceData(); - this.props.dispatch(setLoading(false)) - - }) - }).catch((err) => { - - console.log("Loading user details error", err); - - Swal.fire({ - title: 'Error loading user account', - text: 'There was an error loading your account, would you like to logout?', - icon: 'warning', - showCancelButton: true, - confirmButtonText: 'Yes, logout', - cancelButtonText: 'No' - }).then((result) => { - - if (result.value) { - console.log("Confirm logout"); - - axios.post("/user-service/logout").then(() => { - window.location.assign(env.url); - }).catch((e) => { + axios + .post("/user-service/logout") + .then(() => { window.location.assign(env.url); }) - } - - }) - }) - - } + .catch((e) => { + window.location.assign(env.url); + }); + } + }); + }); + }; - componentDidMount = () => { - this.getUserDetails(); - this.setSettings(); + componentDidMount = () => { + this.getUserDetails(); + this.setSettings(); - //console.log("env sub", this.state.userDetails.activeSubscription) - } + //console.log("env sub", this.state.userDetails.activeSubscription) + }; - setSettings = () => { + setSettings = () => { + const gridMode = window.localStorage.getItem("grid-mode"); + const nameMode = window.localStorage.getItem("name-mode"); + const ascMode = window.localStorage.getItem("asc-mode"); + const dropToUpload = window.localStorage.getItem("non_drop-mode"); + const doubleClickFolders = window.localStorage.getItem( + "double-click-folders" + ); + const hideFolderTree = window.localStorage.getItem("hide-folder-tree"); + const showFolderTreeScrollBars = window.localStorage.getItem( + "show-folder-tree-scroll-bars" + ); - const gridMode = window.localStorage.getItem("grid-mode"); - const nameMode = window.localStorage.getItem("name-mode"); - const ascMode = window.localStorage.getItem("asc-mode"); - const dropToUpload = window.localStorage.getItem("non_drop-mode"); - const doubleClickFolders = window.localStorage.getItem("double-click-folders"); - const hideFolderTree = window.localStorage.getItem("hide-folder-tree"); - const showFolderTreeScrollBars = window.localStorage.getItem("show-folder-tree-scroll-bars") + this.setState(() => { + return { + ...this.state, + listView: !gridMode, + dateSort: !nameMode, + descendingSort: !ascMode, + dropToUpload: !dropToUpload, + doubleClickFolders: doubleClickFolders, + hideFolderTree: hideFolderTree, + showFolderTreeScrollBars, + }; + }); + }; - this.setState(() => { + showSideBar = () => { + this.setState(() => { + return { + ...this.state, + sideBarOpen: !this.state.sideBarOpen, + }; + }); + }; + + modeChangeFullScreen = (type) => { + this.setState(() => { + return { + ...this.state, + mode: type, + }; + }); + }; + + modeChange = (type) => { + this.setState( + () => { return { ...this.state, - listView: !gridMode, - dateSort: !nameMode, - descendingSort: !ascMode, - dropToUpload: !dropToUpload, - doubleClickFolders: doubleClickFolders, - hideFolderTree: hideFolderTree, - showFolderTreeScrollBars - } + mode: type, + }; + }, + () => { + this.showSideBar(); + } + ); + //this.showSideBar() + }; + + getProfilePicName = () => { + if (!this.state.loaded) return "?"; + + if (this.state.userDetails.name) { + if (this.state.userDetails.name.length >= 1) { + return this.state.userDetails.name.substring(0, 1).toUpperCase(); + } else { + return "?"; + } + } else if (this.state.userDetails.email.length >= 1) { + return this.state.userDetails.email.substring(0, 1).toUpperCase(); + } else { + return "?"; + } + }; + + onChangeS3ID = (e) => { + const value = e.target.value; + + this.setState(() => { + return { + ...this.state, + s3ID: value, + }; + }); + }; + + onChangeS3Bucket = (e) => { + const value = e.target.value; + + this.setState(() => { + return { + ...this.state, + s3Bucket: value, + }; + }); + }; + + onChangeS3Key = (e) => { + const value = e.target.value; + + this.setState(() => { + return { + ...this.state, + s3Key: value, + }; + }); + }; + + onChangeGoogleID = (e) => { + const value = e.target.value; + + this.setState(() => { + return { + ...this.state, + googleID: value, + }; + }); + }; + + onChangeGoogleSecret = (e) => { + const value = e.target.value; + + this.setState(() => { + return { + ...this.state, + googleSecret: value, + }; + }); + }; + + showS3Account = () => { + this.setState(() => { + return { + ...this.state, + addS3AccountOpen: !this.state.addS3AccountOpen, + }; + }); + }; + + showGoogleAccount = () => { + this.setState(() => { + return { + ...this.state, + addGoogleAccountOpen: !this.state.addGoogleAccountOpen, + }; + }); + }; + + submitS3Account = (e) => { + e.preventDefault(); + + const data = { + id: this.state.s3ID, + bucket: this.state.s3Bucket, + key: this.state.s3Key, + }; + + axios + .post("/user-service/add-s3-storage", data) + .then((response) => { + Swal.fire( + "S3 Account Added", + "Amazon S3 Account has been linked with myDrive", + "success" + ).then(() => { + //window.location.assign(env.url); + env.s3Enabled = true; + + this.getUserDetails(); + this.showS3Account(); + // let newUser = this.state.userDetails; + // newUser = {...newUser, s3Enabled: true} + }); }) - } + .catch((err) => { + Swal.fire({ + icon: "error", + title: "Add S3 Account Error", + text: "Invalid S3 Credentials", + }); + }); + }; - showSideBar = () => { + getInvoiceData = () => { + if (!env.commercialMode || !this.state.userDetails.activeSubscription) + return; - this.setState(() => { - return { - ...this.state, - sideBarOpen: !this.state.sideBarOpen - } - }) - } - - modeChangeFullScreen = (type) => { - - this.setState(() => { - return { - ...this.state, - mode: type - } - }) - } - - modeChange = (type) => { - - this.setState(() => { - return { - ...this.state, - mode: type - } - }, () => { - this.showSideBar() - }) - //this.showSideBar() - } - - getProfilePicName = () => { - - if (!this.state.loaded) return "?"; - - if (this.state.userDetails.name) { - if (this.state.userDetails.name.length >= 1) { - return this.state.userDetails.name.substring(0, 1).toUpperCase(); - } else { - return "?" - } - } else if (this.state.userDetails.email.length >= 1) { - return this.state.userDetails.email.substring(0,1).toUpperCase(); - } else { - return "?" - } - } - - onChangeS3ID = (e) => { - - const value = e.target.value; - - this.setState(() => { - return { - ...this.state, - s3ID: value - } - }) - } - - onChangeS3Bucket = (e) => { - - const value = e.target.value; - - this.setState(() => { - return { - ...this.state, - s3Bucket: value - } - }) - } - - onChangeS3Key = (e) => { - - const value = e.target.value; - - this.setState(() => { - return { - ...this.state, - s3Key: value - } - }) - } - - onChangeGoogleID = (e) => { - - const value = e.target.value; - - this.setState(() => { - return { - ...this.state, - googleID: value - } - }) - } - - onChangeGoogleSecret = (e) => { - - const value = e.target.value; - - this.setState(() => { - return { - ...this.state, - googleSecret: value - } - }) - } - - showS3Account = () => { - - this.setState(() => { - return { - ...this.state, - addS3AccountOpen: !this.state.addS3AccountOpen - } - }) - } - - showGoogleAccount = () => { - - this.setState(() => { - return { - ...this.state, - addGoogleAccountOpen: !this.state.addGoogleAccountOpen - } - }) - } - - submitS3Account = (e) => { - - e.preventDefault() - - const data = { - id: this.state.s3ID, - bucket: this.state.s3Bucket, - key: this.state.s3Key - } - - axios.post("/user-service/add-s3-storage", data).then((response) => { - - Swal.fire( - 'S3 Account Added', - 'Amazon S3 Account has been linked with myDrive', - 'success' - ).then(() => { - //window.location.assign(env.url); - env.s3Enabled = true; - - this.getUserDetails() - this.showS3Account() - // let newUser = this.state.userDetails; - // newUser = {...newUser, s3Enabled: true} - }) - - }).catch((err) => { - Swal.fire({ - icon: 'error', - title: 'Add S3 Account Error', - text: 'Invalid S3 Credentials', - }) - }) - } - - getInvoiceData = () => { - - if (!env.commercialMode || !this.state.userDetails.activeSubscription) return; - - axios.get("/user-service/payments").then((response) => { - + axios + .get("/user-service/payments") + .then((response) => { const invoices = response.data.invoices; let invoiceDetails = response.data; @@ -319,282 +316,275 @@ class SettingsPageContainer extends React.Component { this.setState(() => { return { - ...this.state, + ...this.state, invoiceData: invoiceDetails, - invoices, - invoicesLoaded: true} - }) - - }).catch((e) => { - console.log("invoice err", e) + invoices, + invoicesLoaded: true, + }; + }); }) + .catch((e) => { + console.log("invoice err", e); + }); + }; - } + removeS3Account = (e) => { + if (e) e.preventDefault(); - removeS3Account = (e) => { + Swal.fire({ + title: "Remove S3 Account?", + text: "This will unlink your Amazon S3 Account from myDrive.", + icon: "warning", + showCancelButton: true, + confirmButtonColor: "#3085d6", + cancelButtonColor: "#d33", + confirmButtonText: "Yes, remove account", + }).then((result) => { + if (result.value) { + axios + .delete("/user-service/remove-s3-storage") + .then((response) => { + let newUser = this.state.userDetails; + delete newUser.s3Enabled; - if (e) e.preventDefault(); + env.s3Enabled = undefined; + this.setState(() => { + return { + ...this.state, + userDetails: newUser, + }; + }); - Swal.fire({ - title: 'Remove S3 Account?', - text: "This will unlink your Amazon S3 Account from myDrive.", - icon: 'warning', - showCancelButton: true, - confirmButtonColor: '#3085d6', - cancelButtonColor: '#d33', - confirmButtonText: 'Yes, remove account' - }).then((result) => { - if (result.value) { - - axios.delete('/user-service/remove-s3-storage').then((response) => { - - let newUser = this.state.userDetails; - delete newUser.s3Enabled; - - env.s3Enabled = undefined; - this.setState(() => { - return { - ...this.state, - userDetails: newUser - } - }) - - this.showS3Account() - Swal.fire( - 'S3 Account Removed', - 'Your Amazon S3 Account has been unlinked from myDrive', - 'success' - ) - - }).catch((err) => { - console.log("could not remove google account", err); - }) - - - } + this.showS3Account(); + Swal.fire( + "S3 Account Removed", + "Your Amazon S3 Account has been unlinked from myDrive", + "success" + ); }) - } - - refreshStorageSize = () => { - - axios.patch("/user-service/refresh-storage-size", undefined).then((response) => { - - this.getUserDetails() - - }).catch((err) => { - console.log("refresh storage error") - }) - } - - submitGoogleAccount = (e) => { - - e.preventDefault() - - const clientID = this.state.googleID; - const clientKey = this.state.googleSecret; - const clientRedirect = "/add-google-account" - - const data = { - clientID, - clientKey, - clientRedirect + .catch((err) => { + console.log("could not remove google account", err); + }); } + }); + }; - axios.post("/user-service/create-google-storage-url", data).then((response) => { - - const googleURL = response.data - - window.location.assign(googleURL) - - }).catch((err) => { - console.log("create url error", err) - }) - } - - removeGoogleAccount = (e) => { - - e.preventDefault(); - - axios.delete('/user-service/remove-google-storage').then((response) => { - - env.googleDriveEnable = undefined; - this.showGoogleAccount(); + refreshStorageSize = () => { + axios + .patch("/user-service/refresh-storage-size", undefined) + .then((response) => { this.getUserDetails(); - Swal.fire( - 'Google Account Removed', - 'Your Google Account has been unlinked from myDrive', - 'success' - ).then(() => { - // window.location.assign(env.url) - - }) }) - } + .catch((err) => { + console.log("refresh storage error"); + }); + }; - getStoragePercentage = () => { + submitGoogleAccount = (e) => { + e.preventDefault(); - let value = Math.floor((this.state.userDetails.storageData.storageSize / this.state.userDetails.storageData.storageLimit) * 100); + const clientID = this.state.googleID; + const clientKey = this.state.googleSecret; + const clientRedirect = "/add-google-account"; - if (value < 0) value = 0; - if (value > 100) value = 100; + const data = { + clientID, + clientKey, + clientRedirect, + }; - return value; - } + axios + .post("/user-service/create-google-storage-url", data) + .then((response) => { + const googleURL = response.data; - getStoragePercentageGoogle = () => { - let value = Math.floor((this.state.userDetails.storageDataGoogle.storageSize / this.state.userDetails.storageDataGoogle.storageLimit) * 100); + window.location.assign(googleURL); + }) + .catch((err) => { + console.log("create url error", err); + }); + }; - if (value < 0) value = 0; - if (value > 100) value = 100; + removeGoogleAccount = (e) => { + e.preventDefault(); - return value; - } + axios.delete("/user-service/remove-google-storage").then((response) => { + env.googleDriveEnable = undefined; + this.showGoogleAccount(); + this.getUserDetails(); + Swal.fire( + "Google Account Removed", + "Your Google Account has been unlinked from myDrive", + "success" + ).then(() => { + // window.location.assign(env.url) + }); + }); + }; - launchStoragePage = () => { + getStoragePercentage = () => { + let value = Math.floor( + (this.state.userDetails.storageData.storageSize / + this.state.userDetails.storageData.storageLimit) * + 100 + ); - window.location.assign(env.url+"/add-storage") - } + if (value < 0) value = 0; + if (value > 100) value = 100; - logout = () => { + return value; + }; - this.props.dispatch(resetCurrentRoute()) - this.props.dispatch(setFolders([])); - this.props.dispatch(setFiles([])); - this.props.dispatch(setQuickFiles([])); - this.props.dispatch(hideSettings()) - this.props.dispatch(startLogout()) - } + getStoragePercentageGoogle = () => { + let value = Math.floor( + (this.state.userDetails.storageDataGoogle.storageSize / + this.state.userDetails.storageDataGoogle.storageLimit) * + 100 + ); + + if (value < 0) value = 0; + if (value > 100) value = 100; + + return value; + }; + + launchStoragePage = () => { + window.location.assign(env.url + "/add-storage"); + }; + + logout = () => { + this.props.dispatch(resetCurrentRoute()); + this.props.dispatch(setFolders([])); + this.props.dispatch(setFiles([])); + this.props.dispatch(setQuickFiles([])); + this.props.dispatch(hideSettings()); + this.props.dispatch(startLogout()); + }; logoutAll = () => { - - this.props.dispatch(resetCurrentRoute()) - this.props.dispatch(setFolders([])); - this.props.dispatch(setFiles([])); - this.props.dispatch(setQuickFiles([])); - this.props.dispatch(hideSettings()); - this.props.dispatch(startLogoutAll()); - } + this.props.dispatch(resetCurrentRoute()); + this.props.dispatch(setFolders([])); + this.props.dispatch(setFiles([])); + this.props.dispatch(setQuickFiles([])); + this.props.dispatch(hideSettings()); + this.props.dispatch(startLogoutAll()); + }; changeShowChangePassword = () => { - this.setState(() => { return { ...this.state, showChangePassword: !this.state.showChangePassword, oldPassword: "", newPassword: "", - verifyNewPassword: "" - } - }) - } + verifyNewPassword: "", + }; + }); + }; goHome = () => { - window.location.assign(env.url) - } + history.push("/"); + }; onChangeOldPassword = (e) => { - const value = e.target.value; this.setState(() => { - return { - ...this.state, - oldPassword: value - } - }) - } + return { + ...this.state, + oldPassword: value, + }; + }); + }; onChangeNewPassword = (e) => { - const value = e.target.value; this.setState(() => { - return { - ...this.state, - newPassword: value - } - }) - } + return { + ...this.state, + newPassword: value, + }; + }); + }; onChangeVerifyNewPassword = (e) => { - const value = e.target.value; this.setState(() => { - return { - ...this.state, - verifyNewPassword: value - } - }) - } + return { + ...this.state, + verifyNewPassword: value, + }; + }); + }; submitPasswordChange = (e) => { + e.preventDefault(); - e.preventDefault() - - if (this.state.oldPassword.length === 0 || this.state.newPassword.length === 0 || this.state.verifyNewPassword.length === 0) { + if ( + this.state.oldPassword.length === 0 || + this.state.newPassword.length === 0 || + this.state.verifyNewPassword.length === 0 + ) { Swal.fire({ - icon: 'error', - title: 'Error', - text: 'Enter All Required Fields', - }) + icon: "error", + title: "Error", + text: "Enter All Required Fields", + }); } if (this.state.verifyNewPassword !== this.state.newPassword) { - Swal.fire({ - icon: 'error', - title: 'Error', - text: 'New passwords do not match', - }) + icon: "error", + title: "Error", + text: "New passwords do not match", + }); return; } const data = { newPassword: this.state.newPassword, - oldPassword: this.state.oldPassword - } + oldPassword: this.state.oldPassword, + }; - axios.post(`/user-service/change-password/`, data).then((results) => { - - //const newToken = results.data; - // window.localStorage.setItem("token", newToken); + axios + .post(`/user-service/change-password/`, data) + .then((results) => { + //const newToken = results.data; + // window.localStorage.setItem("token", newToken); - this.changeShowChangePassword() - //this.getUserDetails() + this.changeShowChangePassword(); + //this.getUserDetails() - Swal.fire( - 'Password Changed', - 'All other sessions have been logged out', - 'success' - ) - - - }).catch((err) => { - console.log(err) + Swal.fire( + "Password Changed", + "All other sessions have been logged out", + "success" + ); + }) + .catch((err) => { + console.log(err); Swal.fire({ - icon: 'error', - title: 'Error', - text: 'Error changing password', - }) - }) - - } + icon: "error", + title: "Error", + text: "Error changing password", + }); + }); + }; onChangeAddName = (e) => { - const value = e.target.value; this.setState(() => { - return { - ...this.state, - name: value - } - }) - } + return { + ...this.state, + name: value, + }; + }); + }; doubleClickOnChange = (e) => { - if (this.state.doubleClickFolders) { localStorage.removeItem("double-click-folders"); } else { @@ -604,150 +594,146 @@ class SettingsPageContainer extends React.Component { this.setState(() => { return { ...this.state, - doubleClickFolders: !this.state.doubleClickFolders - } - }) + doubleClickFolders: !this.state.doubleClickFolders, + }; + }); //this.props.dispatch(resetSettingsMain(uuid.v4())); // updateSettingsID = uuid.v4(); // setUpdateSettingsID(uuid.v4()); - } + }; changeShowAddName = () => { - this.setState(() => { return { ...this.state, showAddName: !this.state.showAddName, - name: "" - } - }) - } + name: "", + }; + }); + }; submitAddName = (e) => { - - e.preventDefault() + e.preventDefault(); if (this.state.name.length === 0) return; const data = { - name: this.state.name - } + name: this.state.name, + }; - axios.patch("/user-service/add-name", data).then((response) => { - - this.changeShowAddName(); - this.getUserDetails() - Swal.fire( - 'Name Updated', - 'Your name has been sucessfully updated', - 'success' - ) - - }).catch(() => { - console.log("could not change name") - Swal.fire({ - icon: 'error', - title: 'Error', - text: 'Error changing name', + axios + .patch("/user-service/add-name", data) + .then((response) => { + this.changeShowAddName(); + this.getUserDetails(); + Swal.fire( + "Name Updated", + "Your name has been sucessfully updated", + "success" + ); }) - }) - } + .catch(() => { + console.log("could not change name"); + Swal.fire({ + icon: "error", + title: "Error", + text: "Error changing name", + }); + }); + }; goHome = () => { - window.location.assign(env.url) - } + history.push("/"); + }; downloadPersonalFileList = (e) => { - - e.preventDefault() - - axios.post('/user-service/get-token').then((response) => { - - const finalUrl = `/user-service/download-personal-file-list`; - - const link = document.createElement('a'); - document.body.appendChild(link); - link.href = finalUrl; - link.setAttribute('type', 'hidden'); - link.setAttribute("download", true); - link.click(); - }) - } - - uploadPersonalFileList = (e) => { - e.preventDefault(); - if (this.uploadReference.current.files && this.uploadReference.current.files[0]) { + axios.post("/user-service/get-token").then((response) => { + const finalUrl = `/user-service/download-personal-file-list`; + const link = document.createElement("a"); + document.body.appendChild(link); + link.href = finalUrl; + link.setAttribute("type", "hidden"); + link.setAttribute("download", true); + link.click(); + }); + }; + + uploadPersonalFileList = (e) => { + e.preventDefault(); + + if ( + this.uploadReference.current.files && + this.uploadReference.current.files[0] + ) { const currentFile = this.uploadReference.current.files[0]; const config = { headers: { - 'Content-Type': 'application/json' - } - } - - axios.post('/user-service/upload-personal-file-list', currentFile, config).then((response) => { - - this.uploadReference.current.value = '' + "Content-Type": "application/json", + }, + }; - Swal.fire( - 'Personal Data Uploaded', - 'Your Peronsal Metadata has been uploaded to myDrive successfully', - 'success' - ) + axios + .post("/user-service/upload-personal-file-list", currentFile, config) + .then((response) => { + this.uploadReference.current.value = ""; - }).catch((err) => { - console.log("upload personal file list error", err); - Swal.fire({ - icon: 'error', - title: 'Error', - text: 'Error uploading personal file list', + Swal.fire( + "Personal Data Uploaded", + "Your Peronsal Metadata has been uploaded to myDrive successfully", + "success" + ); }) - }) - + .catch((err) => { + console.log("upload personal file list error", err); + Swal.fire({ + icon: "error", + title: "Error", + text: "Error uploading personal file list", + }); + }); } - - } + }; removeS3Metadata = (e) => { e.preventDefault(); Swal.fire({ - title: 'Remove S3 Metadata?', + title: "Remove S3 Metadata?", text: "This will remove all S3 Metadata from myDrive, please download your metadata list before removing.", - icon: 'warning', + icon: "warning", showCancelButton: true, - confirmButtonColor: '#3085d6', - cancelButtonColor: '#d33', - confirmButtonText: 'Yes, remove metadata' + confirmButtonColor: "#3085d6", + cancelButtonColor: "#d33", + confirmButtonText: "Yes, remove metadata", }).then((result) => { if (result.value) { - - axios.delete("/user-service/remove-s3-metadata").then((response) => { - - Swal.fire( - 'S3 Metadata removed', - 'Your S3 metadata has been removed from myDrive successfully.', - 'success' - ) - }).catch((err) => { - console.log("delete s3 data err", err); - Swal.fire({ - icon: 'error', - title: 'Error', - text: 'Error deleting S3 metadata', + axios + .delete("/user-service/remove-s3-metadata") + .then((response) => { + Swal.fire( + "S3 Metadata removed", + "Your S3 metadata has been removed from myDrive successfully.", + "success" + ); }) - }) - + .catch((err) => { + console.log("delete s3 data err", err); + Swal.fire({ + icon: "error", + title: "Error", + text: "Error deleting S3 metadata", + }); + }); } - }) - } + }); + }; listViewOnChange = (e) => { - if (this.state.listView) { window.localStorage.setItem("grid-mode", true); } else { @@ -757,49 +743,46 @@ class SettingsPageContainer extends React.Component { this.setState(() => { return { ...this.state, - listView: !this.state.listView - } - }) + listView: !this.state.listView, + }; + }); // this.setSettings(); - } + }; sortByDateChange = () => { - if (this.state.dateSort) { window.localStorage.setItem("name-mode", true); } else { - window.localStorage.removeItem("name-mode") + window.localStorage.removeItem("name-mode"); } this.setState(() => { return { ...this.state, - dateSort: !this.state.dateSort - } - }) - } + dateSort: !this.state.dateSort, + }; + }); + }; sortByDescendingChange = () => { - if (this.state.descendingSort) { window.localStorage.setItem("asc-mode", true); } else { - window.localStorage.removeItem("asc-mode") + window.localStorage.removeItem("asc-mode"); } this.setState(() => { return { ...this.state, - descendingSort: !this.state.descendingSort - } - }) - } + descendingSort: !this.state.descendingSort, + }; + }); + }; dropOnChange = () => { - if (this.state.dropToUpload) { - window.localStorage.setItem("non_drop-mode", true) + window.localStorage.setItem("non_drop-mode", true); } else { window.localStorage.removeItem("non_drop-mode"); } @@ -807,228 +790,331 @@ class SettingsPageContainer extends React.Component { this.setState(() => { return { ...this.state, - dropToUpload: !this.state.dropToUpload - } - }) - } - - hideFolderTreeOnChange = () =>{ + dropToUpload: !this.state.dropToUpload, + }; + }); + }; + hideFolderTreeOnChange = () => { if (this.state.hideFolderTree) { - window.localStorage.removeItem("hide-folder-tree"); - } else { - - console.log("setting hide folder tree to true") + console.log("setting hide folder tree to true"); window.localStorage.setItem("hide-folder-tree", true); } - + this.setState(() => ({ ...this.state, - hideFolderTree: !this.state.hideFolderTree - })) - - } + hideFolderTree: !this.state.hideFolderTree, + })); + }; showFolderTreeScrollBarsOnChange = () => { - if (this.state.showFolderTreeScrollBars) { - window.localStorage.removeItem("show-folder-tree-scroll-bars"); - } else { - window.localStorage.setItem("show-folder-tree-scroll-bars", true); } this.setState(() => ({ ...this.state, - showFolderTreeScrollBars: !this.state.showFolderTreeScrollBars - })) - - } + showFolderTreeScrollBars: !this.state.showFolderTreeScrollBars, + })); + }; render() { - if (this.props.loading) { - return + return ; } return ( +
+
+
-
+
-
- -
- -
- -
- - - -
-
- - - - {/* - - */} -
-
-
-
-
-

Personal info

-
-
-
-

Profile picture

-
-
- -
-
-

Security

-
-
-
-

Logout Account

-
-
-

-
-
- Logout -
-
-
-
-

Email

-
-
-

{this.state.loaded ? this.state.userDetails.email : "Loading..."}

-
-
- {/* Change */} -
-
-
-
-

Password

-
-
-

{this.state.loaded ? this.state.userDetails.passwordLastModified ? `Updated ${moment(this.state.userDetails.passwordLastModified).calendar()}` : "Password Not Updated Yet" : "Loading..."}

-
- -
+
+
+ + + + {/* + + */} +
+
+
+
+
+

Personal info

+
+
+
+

Profile picture

+
+
+
+

+ + {this.getProfilePicName()} + +

+
+
+
+ {/* Upload */} +
+
+
+
+

Name

+
+
+

+ {this.state.loaded + ? this.state.userDetails.name + ? capitalize(this.state.userDetails.name) + : "No Name Set" + : "Loading..."} +

+
+
+ Change +
+
+
+
+
+

Security

+
+
+
+

Logout Account

+
+
+

+
+
+ Logout +
+
+
+
+

Email

+
+
+

+ {this.state.loaded + ? this.state.userDetails.email + : "Loading..."} +

+
+
+ {/* Change */} +
+
-
-
-

Logout All Accounts

-
-
-

-
- -
- {/*
+
+
+

Password

+
+
+

+ {this.state.loaded + ? this.state.userDetails.passwordLastModified + ? `Updated ${moment( + this.state.userDetails.passwordLastModified + ).calendar()}` + : "Password Not Updated Yet" + : "Loading..."} +

+
+ +
+ +
+
+

Logout All Accounts

+
+
+

+
+ +
+ {/*

Two factor authentication

@@ -1039,230 +1125,382 @@ class SettingsPageContainer extends React.Component { Enable
*/} -
- -
-
-

Preferences

-
-
-
-

Language

-
-
-

English

-
-
- Change -
-
-
-
-

Date format

-
-
-

MM / DD / YYYY

-
-
- Change -
-
- -
-
-

Date Time zone

-
-
-

GMT +7

-
-
- Change -
-
-
-
-
-
-
-

Storage Accounts

-
-
-
-
-
-

{env.commercialMode ? "myDrive" : "Local Storage"}

- {!this.state.loaded ? "Loading..." : (env.commercialMode && this.state.userDetails.activeSubscription) ? "Plan Type" : ""} -
-
-
-
-
-
- {!this.state.loaded ? "Loading..." : - (env.commercialMode && this.state.userDetails.activeSubscription) ? - `${bytes(this.state.userDetails.storageData.storageSize)} of - ${bytes(this.state.userDetails.storageData.storageLimit)} used` : !env.commercialMode ? `${bytes(this.state.userDetails.storageData.storageSize)} used` : ''} + +
+
+

Preferences

+
+
+
+

Language

+
+
+

English

+
+
+ Change +
+
+
+
+

Date format

+
+
+

MM / DD / YYYY

+
+
+ Change +
+
+ +
+
+

Date Time zone

+
+
+

GMT +7

+
+
+ Change +
+
+
-
- -
-
-

- star{" "} - Earn more free space. Get an additional - 10GB of storage for every friend you invite. -

- Invite Friends -
-
-
-
-
-

Google Drive

- {!this.state.loaded ? "Loading..." : this.state.userDetails.googleDriveEnabled ? this.state.userDetails.googleDriveData.id : "No Google Account"} -
-
-
-
-
+
+
+
+

Storage Accounts

+
+
+
+
+
+

+ {env.commercialMode ? "myDrive" : "Local Storage"} +

+ + {!this.state.loaded + ? "Loading..." + : env.commercialMode && + this.state.userDetails.activeSubscription + ? "Plan Type" + : ""} + +
+
+
+
+
+
+
+ + {!this.state.loaded + ? "Loading..." + : env.commercialMode && + this.state.userDetails.activeSubscription + ? `${bytes( + this.state.userDetails.storageData + .storageSize + )} of + ${bytes( + this.state.userDetails.storageData.storageLimit + )} used` + : !env.commercialMode + ? `${bytes( + this.state.userDetails.storageData + .storageSize + )} used` + : ""} + +
+
+ +
+
+

+ star{" "} + Earn more free space. Get an additional + 10GB of storage for every friend you invite. +

+ Invite Friends +
+
+
+
+
+

Google Drive

+ + {!this.state.loaded + ? "Loading..." + : this.state.userDetails.googleDriveEnabled + ? this.state.userDetails.googleDriveData.id + : "No Google Account"} + +
+
+
+
+
+
+
+ + {this.state.userDetails.googleDriveEnabled + ? !this.state.userDetails.storageDataGoogle.failed + ? `${bytes( + this.state.userDetails.storageDataGoogle + .storageSize + )} of + ${bytes( + this.state.userDetails.storageDataGoogle.storageLimit + )} used` + : "Failed" + : ""} + +
+
+ +
+ +
+
+
+

Amazon S3

+ + {!this.state.loaded + ? "Loading..." + : this.state.userDetails.s3Enabled + ? this.state.userDetails.s3Data.bucket + : "S3 Not Enabled"} + +
+
+
+
+
+
+
+ + {this.state.userDetails.s3Enabled + ? !this.state.userDetails.storageDataPersonal + .failed + ? `${bytes( + this.state.userDetails.storageDataPersonal + .storageSize + )} used` + : "Failed" + : ""} + +
+
+ +
+
+ class="elem__settings more__accounts" + style={{ display: "none" }} + > +
+

Add more accounts

+
+
+

More Storage Options Coming Soon!

+
+
+
+

BackBlaze

+
+
+ Enable +
+
+
+
+

Sia Network

+
+
+ Enable +
+
+
+
+

Localhost

+
+
+ Enable +
+
+
- {this.state.userDetails.googleDriveEnabled ? !this.state.userDetails.storageDataGoogle.failed ? `${bytes(this.state.userDetails.storageDataGoogle.storageSize)} of - ${bytes(this.state.userDetails.storageDataGoogle.storageLimit)} used` : "Failed" : ""} - -
-
- -
- -
-
-
-

Amazon S3

- {!this.state.loaded ? "Loading..." : this.state.userDetails.s3Enabled ? this.state.userDetails.s3Data.bucket : "S3 Not Enabled"} -
-
-
-
-
-
-
- {this.state.userDetails.s3Enabled ? !this.state.userDetails.storageDataPersonal.failed ? - `${bytes(this.state.userDetails.storageDataPersonal.storageSize)} used` : "Failed" : ""} -
-
- -
-
-
-
-

Add more accounts

-
-
-

More Storage Options Coming Soon!

-
-
-
-

BackBlaze

-
-
- Enable -
-
-
-
-

Sia Network

-
-
- Enable -
-
-
-
-

Localhost

-
-
- Enable -
-
-
-
-
-
-
-

Payment

-
-
-
-

Payment method

-
-
-

{(this.state.loaded && this.state.invoicesLoaded) ? - !this.state.invoiceData.card ? "No Payment Method" : - `${this.state.invoiceData.card.brand} ending in ${this.state.invoiceData.card.last4}` : "No Payment Method"}

-
-
- Change -
-
-
-
-

Billing cycle

-
-
-

{(this.state.loaded && this.state.invoicesLoaded) ? - !this.state.invoiceData.subscription ? "No Subscription" : - capitalize(this.state.invoiceData.subscription.plan.interval) : "No Subscription"}

-
-
- Change -
-
-
-
-
-

History

-
-
- +
+
+
+

Payment

+
+
+
+

Payment method

+
+
+

+ {this.state.loaded && this.state.invoicesLoaded + ? !this.state.invoiceData.card + ? "No Payment Method" + : `${this.state.invoiceData.card.brand} ending in ${this.state.invoiceData.card.last4}` + : "No Payment Method"} +

+
+
+ Change +
+
+
+
+

Billing cycle

+
+
+

+ {this.state.loaded && this.state.invoicesLoaded + ? !this.state.invoiceData.subscription + ? "No Subscription" + : capitalize( + this.state.invoiceData.subscription.plan + .interval + ) + : "No Subscription"} +

+
+
+ Change +
+
+
+
+
+

History

+
+
+
+ + + + + + + - - - - - - - - - {(!this.state.loaded || !this.state.invoicesLoaded) ? undefined : this.state.invoices.map((currentInvoice) => { - - return - - })} - {/* + {!this.state.loaded || !this.state.invoicesLoaded + ? undefined + : this.state.invoices.map((currentInvoice) => { + return ( + + ); + })} + {/* @@ -1289,57 +1527,94 @@ class SettingsPageContainer extends React.Component { Receipt */} -
DATEPLANAMOUNTSTATUS
DATEPLANAMOUNTSTATUS
May 1, 2020 myDrive Standard Plan $9.99
-
-
-
+ +
+
+
-
-
-
-

Customization

-
-
- Set Defaults -

- - -

-

- - -

-

- - -

-

- - -

-

- - -

-

- - -

-

- - -

-
-
+
+
+
+

Customization

+
+
+ Set Defaults +

+ + +

+

+ + +

+

+ + +

+

+ + +

+

+ + +

+

+ + +

+

+ + +

+
+
- {/*
+ {/*

Marketing

@@ -1361,111 +1636,158 @@ class SettingsPageContainer extends React.Component {

*/} -
-
-
-
-
- - +
- - -