├── drive ├── .dockerignore ├── Dockerfile ├── src │ ├── routes │ │ ├── trashRoutes.ts │ │ ├── folderRoute.ts │ │ └── fileRoutes.ts │ ├── utils │ │ ├── cloudinary.ts │ │ ├── producer.ts │ │ ├── awsS3Bucket.ts │ │ └── consummer.ts │ ├── controllers │ │ ├── trashController.ts │ │ ├── folderController.ts │ │ └── fileController.ts │ ├── model │ │ ├── Share.ts │ │ ├── Folder.ts │ │ ├── User.ts │ │ └── File.ts │ ├── middleware │ │ └── verifyJWT.ts │ └── app.ts ├── docker-compose.yaml ├── .vscode │ └── launch.json ├── package.json └── tsconfig.json ├── authentication ├── .dockerignore ├── Dockerfile ├── src │ ├── routes │ │ ├── refresh.ts │ │ ├── authRoute.ts │ │ └── userRouter.ts │ ├── utils │ │ ├── producer.ts │ │ └── consummer.ts │ ├── middleware │ │ └── verifyJWT.ts │ ├── index.ts │ ├── model │ │ └── User.ts │ └── controllers │ │ ├── googleAuthController.ts │ │ ├── authController.ts │ │ ├── refreshTokenController.ts │ │ └── userController.ts ├── .vscode │ └── launch.json ├── package.json └── tsconfig.json └── .gitignore /drive/.dockerignore: -------------------------------------------------------------------------------- 1 | .vscode/ 2 | node_modules/ -------------------------------------------------------------------------------- /authentication/.dockerignore: -------------------------------------------------------------------------------- 1 | 2 | .vscode/ 3 | node_modules/ -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | authentication/node_modules 2 | authentication/.env 3 | authentication/.eslintrc.json 4 | drive/node_modules 5 | drive/.env 6 | drive/.eslintrc.json -------------------------------------------------------------------------------- /drive/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:alpine 2 | WORKDIR /usr/src/app 3 | COPY package*.json ./ 4 | RUN npm install 5 | COPY . . 6 | EXPOSE 4007 7 | CMD ["npm","start"] -------------------------------------------------------------------------------- /authentication/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:alpine 2 | WORKDIR /usr/src/app 3 | COPY package*.json ./ 4 | RUN npm install 5 | COPY . . 6 | EXPOSE 4000 7 | CMD ["npm","start"] -------------------------------------------------------------------------------- /drive/src/routes/trashRoutes.ts: -------------------------------------------------------------------------------- 1 | import { Router } from "express" 2 | import { getAllFiles } from "../controllers/trashController"; 3 | const router = Router(); 4 | 5 | router.get('/', getAllFiles) 6 | 7 | export default router; -------------------------------------------------------------------------------- /drive/docker-compose.yaml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | app1: 4 | image: alfasareekkan/auth:2 5 | ports: 6 | - "4000:4000" 7 | app2: 8 | image: alfasareekkan/drive:1 9 | ports: 10 | - "4007:4007" 11 | 12 | -------------------------------------------------------------------------------- /authentication/src/routes/refresh.ts: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | const router = express.Router(); 3 | import {handleRefreshToken} from "../controllers/refreshTokenController"; 4 | 5 | router.post('/', handleRefreshToken); 6 | 7 | export default router -------------------------------------------------------------------------------- /drive/src/utils/cloudinary.ts: -------------------------------------------------------------------------------- 1 | import { v2 as cloudinary } from "cloudinary" 2 | import {config} from "dotenv" 3 | config() 4 | 5 | cloudinary.config({ 6 | cloud_name: process.env.CLOUDINARY_CLOUD_NAME, 7 | api_key:process.env.CLOUDINARY_API_KEY, 8 | api_secret: process.env.CLOUDINARY_API_SECRET, 9 | // secure: true 10 | }) 11 | 12 | export default cloudinary; -------------------------------------------------------------------------------- /drive/src/routes/folderRoute.ts: -------------------------------------------------------------------------------- 1 | import express from 'express'; 2 | import {isCreateFolder, isGetFolder, getAllFolders, isUserShareFolder} from '../controllers/folderController' 3 | const router = express.Router() 4 | 5 | 6 | router.post('/create-folder', isCreateFolder) 7 | router.post('/get-folder', isGetFolder) 8 | router.post('/get-all-folders', getAllFolders) 9 | router.post('/share-folder',isUserShareFolder ) 10 | 11 | 12 | 13 | export default router; -------------------------------------------------------------------------------- /drive/src/controllers/trashController.ts: -------------------------------------------------------------------------------- 1 | import { Request, Response } from "express" 2 | import File from "../model/File"; 3 | 4 | 5 | export const getAllFiles = async(req: Request, res: Response) => { 6 | // console.log(req.headers.userId); 7 | const userId = req.headers.userId; 8 | try { 9 | const files = await File.find({ userId, recordStatus: 3 }); 10 | res.status(200).json(files); 11 | 12 | } catch (error) { 13 | 14 | } 15 | 16 | } -------------------------------------------------------------------------------- /drive/src/model/Share.ts: -------------------------------------------------------------------------------- 1 | import mongoose, { model, Schema, Types } from "mongoose"; 2 | 3 | export interface IShare{ 4 | userId: Types.ObjectId; 5 | shares: Types.Array 6 | } 7 | 8 | const shareSchema = new Schema({ 9 | userId: { 10 | 11 | type:Schema.Types.ObjectId, 12 | }, 13 | shares: { 14 | type:[Schema.Types.ObjectId] 15 | } 16 | }) 17 | 18 | const Share = model('share', shareSchema) 19 | export default Share; -------------------------------------------------------------------------------- /authentication/src/routes/authRoute.ts: -------------------------------------------------------------------------------- 1 | import express from 'express'; 2 | import { signUpPost, loginPost } from '../controllers/authController' 3 | import { googleSignUp } from '../controllers/googleAuthController'; 4 | import {handleRefreshToken} from '../controllers/refreshTokenController' 5 | 6 | const router = express.Router() 7 | 8 | 9 | router.post('/signup',signUpPost) 10 | 11 | 12 | router.post('/login', loginPost) 13 | router.post('/google-signup', googleSignUp) 14 | router.post('/refresh-token',handleRefreshToken) 15 | // router.get('/logout') 16 | 17 | 18 | export default router -------------------------------------------------------------------------------- /authentication/src/routes/userRouter.ts: -------------------------------------------------------------------------------- 1 | import { Router } from "express"; 2 | import { getUserDetails,sendOtp ,submitOtp, changePassword, forgotOtp, updateNewPassword, isSubmitOtp} from "../controllers/userController"; 3 | import verifyJWT from "../middleware/verifyJWT"; 4 | const router = Router(); 5 | 6 | router.get("/get-user", verifyJWT, getUserDetails) 7 | router.post("/send-otp", verifyJWT, sendOtp) 8 | router.post("/submit-otp", verifyJWT, submitOtp) 9 | router.post("/change-password", verifyJWT, changePassword) 10 | router.post("/forgot-password", forgotOtp); 11 | router.post("/new-password", updateNewPassword); 12 | router.post("/otp-password", isSubmitOtp); 13 | 14 | 15 | 16 | 17 | 18 | 19 | export default router -------------------------------------------------------------------------------- /drive/src/routes/fileRoutes.ts: -------------------------------------------------------------------------------- 1 | import { Router } from "express"; 2 | import { 3 | isFileUpload, getFileSize, isGetFile,addToFavorite, 4 | iGetSharedWithMe, getAllFiles, deleteFile,isGetFavorite 5 | } from "./../controllers/fileController" 6 | const router = Router(); 7 | 8 | router.post('/upload', isFileUpload) 9 | router.get('/get-file-size', getFileSize) 10 | router.post('/get-file', isGetFile) 11 | router.get('/get-shared-files', iGetSharedWithMe) 12 | router.get('/get-all-file', getAllFiles) 13 | router.delete('/delete-file/:id', deleteFile) 14 | router.delete('/delete-file/:id',deleteFile) 15 | router.patch('/add-to-favourite/:id', addToFavorite) 16 | router.get('/get-all-favorite', isGetFavorite) 17 | 18 | 19 | 20 | 21 | export default router; -------------------------------------------------------------------------------- /drive/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "node", 9 | "request": "launch", 10 | "name": "Debug Typescript", 11 | "skipFiles": [ 12 | "/**" 13 | ], 14 | "program": "${workspaceFolder}\\src\\app.ts", 15 | "runtimeArgs": ["-r","ts-node/register","-r","tsconfig-paths/register"], 16 | "console": "integratedTerminal", 17 | "outFiles": [ 18 | "${workspaceFolder}/**/*.js" 19 | ] 20 | } 21 | ] 22 | } -------------------------------------------------------------------------------- /authentication/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "node", 9 | "request": "launch", 10 | "name": "Debug Typescript", 11 | "skipFiles": [ 12 | "/**" 13 | ], 14 | "program": "${workspaceFolder}\\src\\index.ts", 15 | "runtimeArgs": ["-r","ts-node/register","-r","tsconfig-paths/register"], 16 | "console": "integratedTerminal", 17 | "outFiles": [ 18 | "${workspaceFolder}/**/*.js" 19 | ] 20 | } 21 | ] 22 | } -------------------------------------------------------------------------------- /drive/src/model/Folder.ts: -------------------------------------------------------------------------------- 1 | import mongoose, { model, Schema, Types } from "mongoose"; 2 | 3 | export interface IFolder{ 4 | folderName: string; 5 | parentFolderId?: Types.ObjectId; 6 | userId: Types.ObjectId; 7 | recordStatus: number, 8 | folderLevel:number 9 | 10 | } 11 | 12 | const folderSchema = new Schema({ 13 | folderName: { 14 | type: String, 15 | required: true, 16 | }, 17 | parentFolderId: { 18 | type: Schema.Types.ObjectId, 19 | }, 20 | userId: { 21 | type: Schema.Types.ObjectId 22 | 23 | }, 24 | recordStatus: { 25 | type: Number, 26 | default: 0, 27 | required:true 28 | }, 29 | folderLevel: { 30 | type:Number, 31 | } 32 | 33 | }, { timestamps: true }) 34 | 35 | const Folder = model('Folder', folderSchema) 36 | export default Folder -------------------------------------------------------------------------------- /drive/src/utils/producer.ts: -------------------------------------------------------------------------------- 1 | import amqp, { Connection } from 'amqplib/callback_api' 2 | export let amqbConnection: Connection; 3 | 4 | 5 | const createMQProducer = (amqpUrl: string, queueName: string) => { 6 | console.log('Connecting to RabbitMQ...') 7 | let ch: any 8 | amqp.connect(amqpUrl, (errorConnect: Error, connection: Connection) => { 9 | if (errorConnect) { 10 | console.log('Error connecting to RabbitMQ: ', errorConnect) 11 | amqbConnection = connection; 12 | 13 | return 14 | } 15 | 16 | connection.createChannel((errorChannel, channel) => { 17 | if (errorChannel) { 18 | console.log('Error creating channel: ', errorChannel) 19 | return 20 | } 21 | 22 | ch = channel 23 | console.log('Connected to RabbitMQ') 24 | }) 25 | }) 26 | return (msg: string) => { 27 | console.log('Produce message to RabbitMQ...') 28 | ch.sendToQueue(queueName, Buffer.from(msg)) 29 | } 30 | } 31 | 32 | export default createMQProducer -------------------------------------------------------------------------------- /authentication/src/utils/producer.ts: -------------------------------------------------------------------------------- 1 | import amqp, { Connection,Channel } from 'amqplib/callback_api' 2 | export let amqbConnection: Connection; 3 | 4 | const createMQProducer = (amqpUrl: string, queueName: string) => { 5 | console.log('Connecting to RabbitMQ...') 6 | let ch: Channel 7 | amqp.connect(amqpUrl, (errorConnect: Error, connection: Connection) => { 8 | if (errorConnect) { 9 | console.log('Error connecting to RabbitMQ: ', errorConnect) 10 | amqbConnection = connection; 11 | return 12 | } 13 | 14 | connection.createChannel((errorChannel, channel) => { 15 | if (errorChannel) { 16 | console.log('Error creating channel: ', errorChannel) 17 | return 18 | } 19 | 20 | ch = channel 21 | console.log('Connected to RabbitMQ') 22 | }) 23 | }) 24 | return (msg: string) => { 25 | console.log('Produce message to RabbitMQ...') 26 | ch.sendToQueue(queueName, Buffer.from(msg)) 27 | } 28 | } 29 | 30 | export default createMQProducer -------------------------------------------------------------------------------- /authentication/src/utils/consummer.ts: -------------------------------------------------------------------------------- 1 | import amqp, { Message } from 'amqplib/callback_api' 2 | 3 | const createMQConsumer = (amqpURl: string, queueName: string) => { 4 | console.log('Connecting to RabbitMQ...') 5 | return () => { 6 | amqp.connect(amqpURl, (errConn, conn) => { 7 | if (errConn) { 8 | throw errConn 9 | } 10 | 11 | conn.createChannel((errChan, chan) => { 12 | if (errChan) { 13 | throw errChan 14 | } 15 | 16 | console.log('Connected to RabbitMQ') 17 | chan.assertQueue(queueName, { durable: true }) 18 | chan.consume(queueName, (msg: Message | null) => { 19 | if (msg) { 20 | const parsed = JSON.parse(msg.content.toString()) 21 | switch (parsed.action) { 22 | case 'REGISTER': 23 | console.log('Consuming REGISTER action', parsed.data) 24 | break 25 | default: 26 | break 27 | } 28 | } 29 | }, { noAck: true }) 30 | }) 31 | }) 32 | } 33 | } 34 | 35 | export default createMQConsumer -------------------------------------------------------------------------------- /drive/src/middleware/verifyJWT.ts: -------------------------------------------------------------------------------- 1 | import jwt, { JwtPayload } from "jsonwebtoken"; 2 | import { Request, Response, NextFunction } from "express"; 3 | 4 | const JWT_SECRET: string | undefined = process.env.JWTKEY; 5 | 6 | const verifyJWT = (req: Request, res: Response, next: NextFunction) => { 7 | const authHeader = req.headers.authorization || req.headers.Authorization; 8 | if (typeof authHeader === "string") { 9 | if (!authHeader?.startsWith("Bearer ")) return res.sendStatus(401); 10 | const token = authHeader.split(" ")[1]; 11 | jwt.verify(token, process.env.JWTKEY, (err, decoded) => { 12 | if (err) return res.sendStatus(403); //invalid token 13 | // req.body.user = decoded.UserInfo.username; 14 | 15 | let userInfo: JwtPayload | string = jwt.decode(token); 16 | if (typeof userInfo !== "string") { 17 | let id = userInfo.UserInfo.id; 18 | req.headers.userId=id; 19 | } else { 20 | let userObject = JSON.parse(userInfo); 21 | req.headers.userId= userObject.UserInfo.id; 22 | } 23 | next(); 24 | }); 25 | } 26 | }; 27 | 28 | export default verifyJWT; 29 | -------------------------------------------------------------------------------- /authentication/src/middleware/verifyJWT.ts: -------------------------------------------------------------------------------- 1 | import jwt, { JwtPayload } from "jsonwebtoken"; 2 | import { Request, Response, NextFunction } from "express"; 3 | 4 | const JWT_SECRET: string | undefined = process.env.JWTKEY; 5 | 6 | const verifyJWT = (req: Request, res: Response, next: NextFunction) => { 7 | const authHeader = req.headers.authorization || req.headers.Authorization; 8 | if (typeof authHeader === "string") { 9 | if (!authHeader?.startsWith("Bearer ")) return res.sendStatus(401); 10 | const token = authHeader.split(" ")[1]; 11 | jwt.verify(token, process.env.JWTKEY, (err, decoded) => { 12 | if (err) return res.sendStatus(403); //invalid token 13 | // req.body.user = decoded.UserInfo.username; 14 | 15 | const userInfo: JwtPayload | string = jwt.decode(token); 16 | if (typeof userInfo !== "string") { 17 | const id = userInfo.UserInfo.id; 18 | req.headers.userId=id; 19 | } else { 20 | const userObject = JSON.parse(userInfo); 21 | req.headers.userId= userObject.UserInfo.id; 22 | } 23 | next(); 24 | }); 25 | } 26 | }; 27 | 28 | export default verifyJWT; 29 | -------------------------------------------------------------------------------- /authentication/src/index.ts: -------------------------------------------------------------------------------- 1 | import express from "express" 2 | import cors from "cors"; 3 | import dotenv from "dotenv"; 4 | import mongoose from "mongoose"; 5 | 6 | import authRoute from "./routes/authRoute"; 7 | // import refresh from "./routes/refresh"; 8 | import userRouter from "./routes/userRouter"; 9 | // import createMQProducer,{amqbConnection} from "./utils/producer"; 10 | dotenv.config(); 11 | // export const producer=createMQProducer(process.env.RABITMQURI,process.env.RABITQUEUE) 12 | export interface ProcessEnv { 13 | [key: string]: string | undefined; 14 | } 15 | 16 | 17 | const app = express(); 18 | app.use(express.json()); 19 | app.use(cors({ 20 | credentials: true, 21 | origin: process.env.ORIGIN 22 | })); 23 | 24 | app.use("/", authRoute); 25 | app.use("/user",userRouter) 26 | mongoose.connect(process.env.DATABASE).then(() => { 27 | app.listen(4000, () => { 28 | console.log('listening on port 4000'); 29 | }) 30 | // process.on('beforeExit', () => { 31 | // console.log('closing connection'); 32 | // amqbConnection.close() 33 | // }) 34 | }); -------------------------------------------------------------------------------- /drive/src/model/User.ts: -------------------------------------------------------------------------------- 1 | import { Schema, model, ObjectId ,Types} from 'mongoose'; 2 | 3 | 4 | export interface IUser { 5 | _id?: ObjectId 6 | userId: Types.ObjectId; 7 | firstName: string; 8 | lastName: string; 9 | email: string; 10 | password: string; 11 | refreshToken?:string[] |undefined 12 | // phoneNumber: number; 13 | } 14 | 15 | // interface UserModel extends Model { 16 | // save(result: resultType): unknown; 17 | // login(email:string,password:string): IUser; 18 | // } 19 | const userSchema = new Schema({ 20 | userId: { 21 | type:Schema.Types.ObjectId 22 | }, 23 | firstName: { 24 | type: String, 25 | required: true, 26 | 27 | }, 28 | lastName: { 29 | type: String, 30 | required:true, 31 | }, 32 | email: { 33 | type: String, 34 | required: [true,"Please enter an email"], 35 | 36 | }, 37 | password: { 38 | type: String, 39 | required: [true,"Please enter password"], 40 | }, 41 | refreshToken: [String] 42 | }) 43 | 44 | const User = model('User', userSchema); 45 | export default User; 46 | -------------------------------------------------------------------------------- /authentication/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "authentication", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "ts-node-dev src/index.ts" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "@types/bcrypt": "^5.0.0", 14 | "@types/cors": "^2.8.12", 15 | "@types/dotenv": "^8.2.0", 16 | "@types/express": "^4.17.14", 17 | "@types/jsonwebtoken": "^8.5.9", 18 | "@types/mongoose": "^5.11.97", 19 | "@types/nodemailer": "^6.4.7", 20 | "@types/validator": "^13.7.10", 21 | "amqplib": "^0.10.3", 22 | "bcrypt": "^5.1.0", 23 | "cors": "^2.8.5", 24 | "dotenv": "^16.0.3", 25 | "express": "^4.18.2", 26 | "jsonwebtoken": "^8.5.1", 27 | "mongoose": "^6.7.4", 28 | "nodemailer": "^6.9.0", 29 | "ts-node-dev": "^2.0.0", 30 | "typescript": "^4.9.3", 31 | "validator": "^13.7.0" 32 | }, 33 | "devDependencies": { 34 | "@types/amqplib": "^0.10.0", 35 | "@typescript-eslint/eslint-plugin": "^5.45.0", 36 | "@typescript-eslint/parser": "^5.45.0", 37 | "eslint": "^8.29.0", 38 | "ts-node": "^10.9.1", 39 | "tsconfig-paths": "^4.1.1" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /drive/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "drive", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "ts-node-dev ./src/app.ts" 8 | }, 9 | "author": "alfas", 10 | "license": "ISC", 11 | "dependencies": { 12 | "@types/amqplib": "^0.10.0", 13 | "@types/cors": "^2.8.13", 14 | "@types/express": "^4.17.14", 15 | "@types/jsonwebtoken": "^8.5.9", 16 | "@types/mongoose": "^5.11.97", 17 | "amqplib": "^0.10.3", 18 | "aws-sdk": "^2.1284.0", 19 | "cloudinary": "^1.33.0", 20 | "cors": "^2.8.5", 21 | "dotenv": "^16.0.3", 22 | "express": "^4.18.2", 23 | "jsonwebtoken": "^8.5.1", 24 | "mongoose": "^6.8.0", 25 | "morgan": "^1.10.0", 26 | "nodemon": "^2.0.20", 27 | "pdf-image": "^2.0.0", 28 | "ts-node-dev": "^2.0.0" 29 | }, 30 | "devDependencies": { 31 | "@types/morgan": "^1.9.3", 32 | "@types/node": "^18.11.18", 33 | "@types/pdf-image": "^2.0.1", 34 | "@typescript-eslint/eslint-plugin": "^5.46.0", 35 | "eslint": "^8.29.0", 36 | "eslint-config-standard-with-typescript": "^23.0.0", 37 | "eslint-plugin-import": "^2.26.0", 38 | "eslint-plugin-n": "^15.6.0", 39 | "eslint-plugin-promise": "^6.1.1", 40 | "typescript": "^4.9.4" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /drive/src/utils/awsS3Bucket.ts: -------------------------------------------------------------------------------- 1 | import S3 from "aws-sdk/clients/s3"; 2 | import dotenv from "dotenv"; 3 | dotenv.config() 4 | 5 | const bucketName = process.env.AWS_BUCKET_NAME 6 | const region = process.env.AWS_BUCKET_REGION 7 | const accessKeyId = process.env.AWS_ACCESS_KEY 8 | const secretAccessKey = process.env.AWS_SECRET_KEY 9 | 10 | // AWS.config.update({ 11 | // region, 12 | // accessKeyId, 13 | // secretAccessKey 14 | // }) 15 | 16 | const s3 = new S3({ 17 | region, 18 | accessKeyId, 19 | secretAccessKey 20 | }) 21 | 22 | export const uploadFile = (fileStream:Buffer, fileName: string) => { 23 | 24 | const uploadParams = { 25 | Bucket: bucketName, 26 | Key: fileName, 27 | Body:fileStream 28 | } 29 | return s3.upload(uploadParams).promise() 30 | } 31 | 32 | export const getFile = async (key:string) => { 33 | const getParams = { 34 | Bucket: bucketName, 35 | Key: key, 36 | // Expires:60, 37 | 38 | } 39 | // const data = await s3.getSignedUrl('getObject',getParams) 40 | const data = await s3.getSignedUrl('getObject', getParams) 41 | 42 | console.log(data); 43 | 44 | // const url = data.Body.toString('utf-8'); 45 | // console.log(url); 46 | 47 | return data; 48 | 49 | } -------------------------------------------------------------------------------- /drive/src/app.ts: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | import dotenv from "dotenv"; 3 | import cors from "cors"; 4 | import mongoose from "mongoose"; 5 | import morgan from "morgan"; 6 | import verifyJWT from "./middleware/verifyJWT"; 7 | import folderRouter from "./routes/folderRoute"; 8 | import fileRouter from "./routes/fileRoutes" 9 | import trashRouter from "./routes/trashRoutes" 10 | import amqp, { Channel } from "amqplib/callback_api"; 11 | import User from "./model/User"; 12 | import createMQConsumer, { amqbConnection } from "./utils/consummer"; 13 | 14 | dotenv.config(); 15 | // export const consumer = createMQConsumer( 16 | // process.env.RABITMQURI, 17 | // process.env.RABITQUEUE 18 | // ); 19 | const app = express(); 20 | app.use(cors({ 21 | credentials: true, 22 | origin: process.env.ORIGIN 23 | })); 24 | app.use(express.json({ limit: '100mb' })); 25 | app.use(express.urlencoded({ limit: '100mb', extended: true })) 26 | app.use(morgan(':method :url :status :res[content-length] - :response-time ms')) 27 | const port = process.env.PORT; 28 | app.use(verifyJWT) 29 | app.use('/', folderRouter); 30 | app.use('/files', fileRouter); 31 | app.use('/trash',trashRouter) 32 | // consumer(); 33 | mongoose.connect(process.env.DATABASE, { 34 | // strictQuery:false, 35 | // useNewUrlParser: true 36 | }).then(() => { 37 | app.listen(port, () => { 38 | return console.log(`Express is listening at http://localhost:${port}`); 39 | }); 40 | }); 41 | // process.on('beforeExit', () => { 42 | // console.log('closing connection'); 43 | // amqbConnection.close() 44 | // }) 45 | -------------------------------------------------------------------------------- /drive/src/model/File.ts: -------------------------------------------------------------------------------- 1 | import { Schema, model, Types } from "mongoose"; 2 | 3 | export interface IFile{ 4 | fileName: string; 5 | fileType: string; 6 | parentFolderId?: Types.ObjectId; 7 | userId: Types.ObjectId; 8 | recordStatus: number; 9 | folderLevel: number; 10 | fileSize: number; 11 | AWSEtag: string; 12 | AWSLocation: string; 13 | AWSKey: string; 14 | AWSBucket: string; 15 | cludinaryUrl: string; 16 | favourite: boolean; 17 | 18 | } 19 | 20 | const fileSchema = new Schema({ 21 | fileName: { type: String, required: true }, 22 | fileType: { type: String, required: true }, 23 | parentFolderId: { 24 | type: Schema.Types.ObjectId, 25 | ref: "Folder", 26 | }, 27 | userId: { 28 | type: Schema.Types.ObjectId, 29 | ref: "User", 30 | }, 31 | recordStatus: { 32 | type: Number, 33 | default: 0, 34 | }, 35 | folderLevel: { 36 | type: Number, 37 | default:0, 38 | }, 39 | fileSize: { 40 | type: Number, 41 | required:true, 42 | }, 43 | AWSEtag: { 44 | type: String, 45 | }, 46 | AWSLocation: { 47 | type: String, 48 | }, 49 | AWSKey: { 50 | type: String, 51 | }, 52 | AWSBucket: { 53 | type: String, 54 | }, 55 | cludinaryUrl: { 56 | type: String, 57 | }, 58 | favourite: { 59 | type: Boolean, 60 | default:false, 61 | } 62 | }, { timestamps: true }) 63 | 64 | const File = model('file', fileSchema); 65 | export default File; -------------------------------------------------------------------------------- /drive/src/utils/consummer.ts: -------------------------------------------------------------------------------- 1 | import amqp, { Message,Connection } from 'amqplib/callback_api' 2 | import User from '../model/User' 3 | export let amqbConnection: Connection; 4 | 5 | 6 | 7 | const createMQConsumer = (amqpURl: string, queueName: string) => { 8 | console.log('Connecting to RabbitMQ...') 9 | return () => { 10 | amqp.connect(amqpURl, (errConn, conn) => { 11 | if (errConn) { 12 | throw errConn 13 | } 14 | amqbConnection = conn; 15 | 16 | 17 | conn.createChannel((errChan, chan) => { 18 | if (errChan) { 19 | throw errChan 20 | } 21 | 22 | console.log('Connected to RabbitMQ') 23 | chan.assertQueue(queueName, { durable: true }) 24 | chan.consume(queueName, (msg: Message | null) => { 25 | if (msg) { 26 | const parsed = JSON.parse(msg.content.toString()) 27 | switch (parsed.action) { 28 | case 'REGISTER': 29 | User.create({ 30 | userId: parsed.data._id, 31 | firstName: parsed.data.firstName, 32 | lastName: parsed.data.lastName, 33 | email: parsed.data.email, 34 | password: parsed.data.password, 35 | refreshToken:parsed.data.refreshToken 36 | }).then((re) => { 37 | console.log(re); 38 | 39 | 40 | }) 41 | break 42 | case 'LOGIN': 43 | console.log('Consuming LOGIN action', parsed.data) 44 | break 45 | default: 46 | break 47 | } 48 | } 49 | }, { noAck: true }) 50 | }) 51 | }) 52 | } 53 | } 54 | 55 | export default createMQConsumer -------------------------------------------------------------------------------- /authentication/src/model/User.ts: -------------------------------------------------------------------------------- 1 | import { Schema, model, connect, ObjectId,Model } from 'mongoose'; 2 | import validator from 'validator' 3 | import bcrypt from 'bcrypt'; 4 | 5 | 6 | export interface IUser { 7 | _id?:ObjectId 8 | firstName: string; 9 | lastName: string; 10 | email: string; 11 | password: string; 12 | otp?: string; 13 | otpVerify?: boolean; 14 | profile?:string 15 | // phoneNumber: number; 16 | } 17 | 18 | interface UserModel extends Model { 19 | login(email: string, password: string): IUser; 20 | findOneUser(email: string): IUser; 21 | 22 | } 23 | const userSchema = new Schema({ 24 | firstName: { 25 | type: String, 26 | required: true, 27 | 28 | }, 29 | lastName: { 30 | type: String, 31 | required:true, 32 | }, 33 | email: { 34 | type: String, 35 | required: [true,"Please enter an email"], 36 | unique: true, 37 | lowercase: true, 38 | validate: [validator.isEmail,'Please enter a valid email'] 39 | }, 40 | password: { 41 | type: String, 42 | required: [true,"Please enter password"], 43 | minlength:[6,'Minimum password length is 6 characters'] 44 | }, 45 | profile: { 46 | type:String 47 | }, 48 | otp: { 49 | type:String, 50 | }, 51 | otpVerify: { 52 | type: Boolean, 53 | default:false 54 | } 55 | 56 | // phoneNumber: { 57 | // type: Number, 58 | // unique: true, 59 | // // validate:[validator.isMobilePhone('enter a valid number')] 60 | // } 61 | }) 62 | 63 | userSchema.static('login',async function login(email, password) { 64 | const user = await this.findOne({ email }) 65 | if (user) { 66 | const auth = await bcrypt.compare(password, user.password) 67 | if (auth) { 68 | return user 69 | } 70 | throw Error('incorrect password') 71 | 72 | } 73 | throw Error('incorrect email') 74 | }) 75 | userSchema.static('findOneUser', async function findOneUser(email) { 76 | const user = await this.findOne({ email }) 77 | return user 78 | }) 79 | const User = model('User', userSchema); 80 | export default User; 81 | -------------------------------------------------------------------------------- /authentication/src/controllers/googleAuthController.ts: -------------------------------------------------------------------------------- 1 | import { Request, Response } from "express" 2 | import { decode, JwtPayload } from "jsonwebtoken" 3 | import {hash,compare} from "bcrypt" 4 | import User from "../model/User"; 5 | import { createToken,handleErrors } from "./authController"; 6 | 7 | 8 | const jwtDecode = (token: string):JwtPayload=> { 9 | const userInfo: JwtPayload | string = decode(token); 10 | if (typeof userInfo !== "string") { 11 | return userInfo 12 | } else { 13 | const userObject = JSON.parse(userInfo); 14 | return userObject 15 | } 16 | }; 17 | 18 | 19 | 20 | export const googleSignUp = async (req: Request, res: Response) => { 21 | try { 22 | const payload = jwtDecode(req.body.credentials) 23 | const password = payload.email + process.env.REFRESH_TOKEN_SECRET 24 | 25 | 26 | 27 | const user = await User.findOne({ email: payload.email }) 28 | if (!user) { 29 | const hashPassword =await hash(password,20) 30 | const result=await User.create({ 31 | email: payload.email, 32 | firstName: payload.given_name, 33 | lastName: payload.family_name, 34 | profile: payload.picture, 35 | password: hashPassword 36 | 37 | }) 38 | const token = createToken(result,'15s') 39 | const refresh = createToken(user,'15s') 40 | 41 | res.status(201).json({ user:{ 42 | firstName: result.firstName, 43 | lastName: result.lastName, 44 | email: result.email, 45 | profile: result.profile, 46 | otpVerify: result.otpVerify, 47 | }, accessToken:token,refreshToken:refresh }); 48 | } 49 | if (user) { 50 | const match = compare(password, user.password) 51 | if (match) { 52 | 53 | const token = createToken(user,'7d'); 54 | const refresh = createToken(user,'15s') 55 | 56 | res.status(201).json({ user:{ 57 | firstName: user.firstName, 58 | lastName: user.lastName, 59 | email: user.email, 60 | profile: user.profile, 61 | otpVerify:user.otpVerify 62 | }, accessToken:token,refreshToken:refresh}) 63 | } else { 64 | res.status(401) 65 | } 66 | } 67 | } catch (error) { 68 | console.log(error); 69 | 70 | const err = handleErrors(error) 71 | res.status(401).json({err}) 72 | } 73 | 74 | 75 | 76 | 77 | } -------------------------------------------------------------------------------- /drive/src/controllers/folderController.ts: -------------------------------------------------------------------------------- 1 | import { Request, Response } from "express"; 2 | import jwt, { JwtPayload } from "jsonwebtoken"; 3 | import Folder, { IFolder } from "../model/Folder"; 4 | import File from "../model/File"; 5 | import mongoose, { Schema, Types } from "mongoose"; 6 | import User from "../model/User"; 7 | import Share from "../model/Share"; 8 | 9 | 10 | const jwtDecode = (token: string): Types.ObjectId => { 11 | let userInfo: JwtPayload | string = jwt.decode(token); 12 | if (typeof userInfo !== "string") { 13 | let id = userInfo.UserInfo.id; 14 | return id; 15 | } else { 16 | let userObject = JSON.parse(userInfo); 17 | return userObject.UserInfo.id; 18 | } 19 | }; 20 | 21 | export const isCreateFolder = async (req: Request, res: Response) => { 22 | const { userId, folderName, folderId, level } = req.body; 23 | 24 | try { 25 | let user = req.headers.userId 26 | console.log(user); 27 | 28 | if (level === 1) { 29 | 30 | let folder = await Folder.create({ 31 | userId: user, 32 | folderLevel: level, 33 | folderName, 34 | }); 35 | res.status(200).json(folder); 36 | } else { 37 | let folder = await Folder.create({ 38 | userId: user, 39 | folderLevel: level, 40 | folderName, 41 | parentFolderId: folderId, 42 | }); 43 | res.status(200).json(folder); 44 | } 45 | } catch (error) { 46 | console.log(error); 47 | } 48 | }; 49 | 50 | export const isGetFolder = async (req: Request, res: Response) => { 51 | try { 52 | console.log(req.body); 53 | 54 | let folder: IFolder = await Folder.findById(req.body.folderId); 55 | console.log(folder); 56 | 57 | res.status(200).json(folder); 58 | } catch (error) { 59 | console.log(error); 60 | } 61 | }; 62 | 63 | export const getAllFolders = async (req: Request, res: Response) => { 64 | const { user, level, folderId } = req.body; 65 | 66 | try { 67 | let userId = jwtDecode(user); 68 | if (!folderId && level === 1) { 69 | let folders = await Folder.find({ userId: userId, folderLevel: 1 }); 70 | let files = await File.find({ userId, folderLevel: level, recordStatus: 0 }) 71 | 72 | 73 | 74 | res.status(200).json({ folders ,files}); 75 | } else if (folderId && level !== 1) { 76 | let folders = await Folder.find({ 77 | userId: userId, 78 | parentFolderId: folderId, 79 | recordStatus:0 80 | }); 81 | console.log(folders); 82 | let files = await File.find({ userId, parentFolderId: folderId, recordStatus: 0 }) 83 | 84 | 85 | 86 | res.status(200).json({ folders ,files}); 87 | } 88 | } catch (error) {} 89 | }; 90 | 91 | export const isUserShareFolder = async (req: Request, res: Response) => { 92 | 93 | try { 94 | const user = await User.findOne({ email: req.body.email }) 95 | console.log(user); 96 | if (!user) return res.sendStatus(404) 97 | const userShare = await Share.findOne({ userId: user._id }) 98 | if (!userShare) { 99 | let shareArray=[req.body.folderId] 100 | let share = await Share.create({ userId: user._id, shares: shareArray }) 101 | console.log(share); 102 | 103 | } else { 104 | userShare.shares.push(req.body.folderId); 105 | let er = await userShare.save() 106 | 107 | res.status(200).json("success") 108 | 109 | } 110 | } catch (error) { 111 | 112 | } 113 | 114 | 115 | 116 | } 117 | -------------------------------------------------------------------------------- /authentication/src/controllers/authController.ts: -------------------------------------------------------------------------------- 1 | import { Request, Response } from "express"; 2 | import { ObjectId } from "mongoose"; 3 | import User, { IUser } from "../model/User"; 4 | import bcrypt from "bcrypt"; 5 | import jwt from "jsonwebtoken"; 6 | import dotenv from "dotenv"; 7 | // import { producer } from "../index"; 8 | 9 | 10 | dotenv.config(); 11 | 12 | const JWTKEY: string | undefined = process.env.JWTKEY; 13 | 14 | export const handleErrors = (err: any) => { 15 | // err.code is for duplicate exists 16 | interface errorType { 17 | email: string, password: string, 18 | [key: string]: any 19 | } 20 | const error : errorType = { email: "", password: "", }; 21 | if (err.code === 11000) { 22 | error.email = "email already in use"; 23 | return error; 24 | } 25 | if (err.message.includes("User validation failed")) { 26 | // to take values only form object 27 | Object.values(err.errors).forEach(({ properties }: any) => { 28 | 29 | error[properties.path]= properties.message; 30 | }); 31 | } 32 | if (err.message === "incorrect email") { 33 | error.email = "incorrect email"; 34 | } 35 | if (err.message === "incorrect password") { 36 | error.password = "incorrect password"; 37 | } 38 | return error; 39 | }; 40 | 41 | export const createToken = (result:IUser,time:string) => { 42 | if (JWTKEY) { 43 | return jwt.sign( 44 | { 45 | UserInfo: { 46 | username: result.email, 47 | id: result._id, 48 | }, 49 | }, 50 | JWTKEY, 51 | { expiresIn: time } 52 | ); 53 | } 54 | }; 55 | interface resultType extends IUser { 56 | [x: string]: any; 57 | _id: ObjectId; 58 | } 59 | 60 | export const signUpPost = async (req: Request, res: Response) => { 61 | const { firstName, lastName, email, password }: IUser = req.body; 62 | if (!email || !password) 63 | return res 64 | .status(400) 65 | .json({ message: "Username and password are required." }); 66 | 67 | try { 68 | //encrypt the password 69 | const hashedPwd = await bcrypt.hash(password, 10); 70 | const result: resultType = await User.create({ 71 | firstName, 72 | lastName, 73 | email, 74 | password: hashedPwd, 75 | }); 76 | const user = await result.save() 77 | // const msg = { 78 | // action: 'REGISTER', 79 | // data:user 80 | // } 81 | // ch.sendToQueue('user_created',Buffer.from(JSON.stringify(user))) 82 | // producer(JSON.stringify(msg)) 83 | const token = createToken(result,'15s'); 84 | const refresh = createToken(user,'15s'); 85 | 86 | res.status(201).json({ 87 | user: { 88 | firstName: result.firstName, 89 | lastName: result.lastName, 90 | email: result.email, 91 | profile: result.profile, 92 | otpVerify: result.otpVerify, 93 | }, accessToken:token,refreshToken:refresh }); 94 | } catch (err: any) { 95 | const errors = handleErrors(err); 96 | 97 | res.status(400).json({ errors}); 98 | } 99 | }; 100 | 101 | export const loginPost = async (req: Request, res: Response) => { 102 | const { email, password } = req.body; 103 | try { 104 | const user =await User.login(email, password) 105 | 106 | const token = createToken(user,'7d'); 107 | const refresh = createToken(user,'15s'); 108 | res.status(200).json({user:{ 109 | firstName: user.firstName, 110 | lastName: user.lastName, 111 | email: user.email, 112 | profile: user.profile, 113 | otpVerify:user.otpVerify, 114 | },accessToken:token,refreshToken:refresh}) 115 | } catch (error) { 116 | const errors = handleErrors(error); 117 | 118 | res.status(400).json({ errors }); 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /authentication/src/controllers/refreshTokenController.ts: -------------------------------------------------------------------------------- 1 | import { Request, Response, json } from 'express' 2 | import jwt, { JwtPayload } from 'jsonwebtoken' 3 | import User, { IUser } from '../model/User'; 4 | import { createToken } from './authController'; 5 | 6 | 7 | 8 | export const handleRefreshToken = async (req: Request, res: Response) => { 9 | 10 | const authHeader = req.headers.authorization || req.headers.Authorization; 11 | try { 12 | 13 | if(!authHeader) throw new Error 14 | if (typeof authHeader === 'string') { 15 | if (!authHeader?.startsWith('Bearer ')) return res.sendStatus(403); 16 | const token = authHeader.split(' ')[1]; 17 | jwt.verify( 18 | token, 19 | process.env.JWTKEY, 20 | async (err, decoded) => { 21 | if (err) return res.sendStatus(403); 22 | let userToken 23 | if (typeof decoded === 'string') { 24 | 25 | userToken=JSON.parse(decoded) 26 | } else { 27 | userToken=decoded 28 | } 29 | 30 | 31 | const user =await User.findOneUser(userToken.UserInfo.username) 32 | 33 | if (!user) return res.sendStatus(403); 34 | const refreshToken = createToken(user, '15s') 35 | 36 | res.status(200).json({refreshToken}) 37 | 38 | } 39 | ); 40 | } 41 | } catch (error) { 42 | res.sendStatus(403); 43 | 44 | } 45 | 46 | } 47 | 48 | 49 | // const cookies = req.cookies; 50 | // if (!cookies?.jwt) return res.sendStatus(401); 51 | // const refreshToken = cookies.jwt; 52 | // res.clearCookie('jwt', { httpOnly: true, sameSite: 'none', secure: true }); 53 | 54 | // const foundUser = await User.findOne({ refreshToken }).exec(); 55 | // // if (REFRESH_TOKEN_SECRET) { 56 | 57 | // // Detected refresh token reuse! 58 | // if (!foundUser) { 59 | // jwt.verify( 60 | // refreshToken, 61 | // process.env.REFRESH_TOKEN_SECRET, 62 | // async (err:any, decoded:any) => { 63 | // if (err) return res.sendStatus(403); //Forbidden 64 | // // Delete refresh tokens of hacked user 65 | // const hackedUser = await User.findOne({ email: decoded.email }).exec(); 66 | // hackedUser.refreshToken = []; 67 | // const result = await hackedUser.save(); 68 | // } 69 | // ) 70 | // return res.sendStatus(403); //Forbidden 71 | // } 72 | 73 | // const newRefreshTokenArray = foundUser.refreshToken.filter(rt => rt !== refreshToken); 74 | 75 | // // evaluate jwt 76 | // jwt.verify( 77 | // refreshToken, 78 | // process.env.REFRESH_TOKEN_SECRET, 79 | // async (err:any, decoded:any) => { 80 | // if (err) { 81 | // // expired refresh token 82 | // foundUser.refreshToken = [...newRefreshTokenArray]; 83 | // const result = await foundUser.save(); 84 | // } 85 | // if (err || foundUser.email !== decoded.username) return res.sendStatus(403); 86 | 87 | // // Refresh token was still valid 88 | // const accessToken = jwt.sign( 89 | // { 90 | // UserInfo: { 91 | // username: foundUser.email, 92 | // id: foundUser._id, 93 | 94 | // } 95 | // }, 96 | // process.env.JWTKEY, 97 | // { expiresIn: '10s' } 98 | // ); 99 | 100 | // const newRefreshToken = jwt.sign( 101 | // { "username": foundUser.email }, 102 | // process.env.REFRESH_TOKEN_SECRET, 103 | // { expiresIn: '15s' } 104 | // ); 105 | // // Saving refreshToken with current user 106 | // foundUser.refreshToken = [...newRefreshTokenArray, newRefreshToken]; 107 | // const result = await foundUser.save(); 108 | 109 | // // Creates Secure Cookie with refresh token 110 | // res.cookie('jwt', newRefreshToken, { httpOnly: true, secure: true, sameSite: 'none', maxAge: 24 * 60 * 60 * 1000 }); 111 | 112 | // res.json({ accessToken,user:foundUser.email }) 113 | 114 | // } 115 | // ); 116 | // // } 117 | // } -------------------------------------------------------------------------------- /authentication/src/controllers/userController.ts: -------------------------------------------------------------------------------- 1 | import { Request, Response } from "express"; 2 | import nodemailer from "nodemailer"; 3 | import { hash, compare } from "bcrypt"; 4 | 5 | import User from "../model/User"; 6 | 7 | const transporter = nodemailer.createTransport({ 8 | service: "gmail", 9 | auth: { 10 | user: process.env.EMAIL_ID, 11 | pass: process.env.EMAIL_PASSWORD, 12 | }, 13 | }); 14 | interface MailOptions { 15 | from: string; 16 | to: string; 17 | subject: string; 18 | text?: string; 19 | html?: string; 20 | } 21 | 22 | export const getUserDetails = async (req: Request, res: Response) => { 23 | const userId = req.headers.userId; 24 | try { 25 | const user = await User.findById(userId, { 26 | firstName: 1, 27 | lastName: 1, 28 | email: 1, 29 | _id: 0, 30 | profile: 1, 31 | otpVerify: 1, 32 | }); 33 | res.status(200).json(user); 34 | } catch (error: any) { 35 | res.status(404).json({ message: error.message }); 36 | } 37 | }; 38 | 39 | export const sendOtp = async (req: Request, res: Response) => { 40 | const otp = Math.floor(100000 + Math.random() * 900000); 41 | try { 42 | const hashedOtp = await hash(otp.toString(), 10); 43 | const user = await User.updateOne( 44 | { email: req.body.email, _id: req.headers.userId }, 45 | { $set: { otp: hashedOtp } } 46 | ); 47 | if (user.modifiedCount === 1) { 48 | const mailOptions: MailOptions = { 49 | from: '"Cloud-Box" ', 50 | to: req.body.email, 51 | subject: "Email Verification", 52 | text: `Your otp is`, 53 | html: `
54 |

55 | ${otp} 56 |

57 |
`, 58 | }; 59 | transporter.sendMail(mailOptions, (error, info) => { 60 | if (error) { 61 | return console.log(error); 62 | } 63 | console.log("Message sent: %s", info.messageId); 64 | }); 65 | } 66 | } catch (error: any) { 67 | res.status(404).json({ message: error.message }); 68 | } 69 | }; 70 | 71 | export const submitOtp = async (req: Request, res: Response) => { 72 | try { 73 | const user = await User.findById(req.headers.userId); 74 | 75 | if (user) { 76 | const isCheck = await compare(req.body.otp, user.otp); 77 | if (!isCheck) throw new Error("Incorrect otp"); 78 | user.otpVerify = true; 79 | 80 | await user.save(); 81 | res.status(200).json("success");`` 82 | } else throw new Error("User not found"); 83 | } catch (error: any) { 84 | 85 | res.status(404).json({ message: error.message }); 86 | } 87 | }; 88 | 89 | export const changePassword = async (req: Request, res: Response) => { 90 | const { oldPassword, newPassword } = req.body; 91 | const userId=req.headers.userId 92 | try { 93 | const user = await User.findById(userId); 94 | if (!user) throw new Error("User not found"); 95 | const isCheck = await compare(oldPassword, user.password); 96 | if (!isCheck) throw new Error("Incorrect password"); 97 | const oldCheck = await compare(newPassword, user.password) 98 | if (oldCheck) throw new Error("Give another password"); 99 | user.password =await hash(newPassword,10); 100 | await user.save(); 101 | res.status(200).json("success"); 102 | } catch (error:any) { 103 | res.status(404).json({message:error.message}); 104 | } 105 | }; 106 | 107 | 108 | 109 | export const forgotOtp = async (req: Request, res: Response) => { 110 | console.log(req.body); 111 | 112 | const otp = Math.floor(100000 + Math.random() * 900000); 113 | try { 114 | const hashedOtp = await hash(otp.toString(), 10); 115 | const user = await User.updateOne( 116 | { email: req.body.email}, 117 | { $set: { otp: hashedOtp } } 118 | ); 119 | if(user.modifiedCount === 0) throw new Error("Invalid Email") 120 | if (user.modifiedCount === 1) { 121 | const mailOptions: MailOptions = { 122 | from: '"Cloud-Box" ', 123 | to: req.body.email, 124 | subject: "Email Verification", 125 | text: `Your otp is`, 126 | html: `
127 |

128 | ${otp} 129 |

130 |
`, 131 | }; 132 | transporter.sendMail(mailOptions, (error, info) => { 133 | if (error) { 134 | return console.log(error); 135 | } 136 | console.log("Message sent: %s", info.messageId); 137 | res.status(200).json("success") 138 | }); 139 | } 140 | } catch (error: any) { 141 | res.status(404).json({ message: error.message }); 142 | } 143 | }; 144 | 145 | 146 | export const updateNewPassword = async (req: Request, res: Response) => { 147 | const { email, password, otp } = req.body; 148 | try { 149 | const user = await User.findOne({ email: email }); 150 | if (!user) throw new Error(`User ${email} not found`); 151 | const isCheck = await compare(otp, user.otp); 152 | if (!isCheck) throw new Error("OTP in not verified"); 153 | user.password = await hash(password, 10); 154 | await user.save(); 155 | res.status(200).json("success") 156 | } catch (error:any) { 157 | res.status(404).json({message:error.message}) 158 | } 159 | 160 | } 161 | 162 | 163 | export const isSubmitOtp = async (req: Request, res: Response)=>{ 164 | const { email, otp } = req.body; 165 | try { 166 | const user = await User.findOne({ email: email }); 167 | if (!user) throw new Error(`User ${email} not found`); 168 | const isCheck = await compare(otp, user.otp); 169 | if (!isCheck) throw new Error("Incorrect OTP"); 170 | res.status(200).json("success"); 171 | 172 | 173 | } catch (error:any) { 174 | res.status(404).json({ message: error.message }); 175 | } 176 | 177 | } -------------------------------------------------------------------------------- /drive/src/controllers/fileController.ts: -------------------------------------------------------------------------------- 1 | import { Request, Response } from "express"; 2 | import crypto, { createHash } from "crypto"; 3 | import {Types} from "mongoose"; 4 | import { uploadFile, getFile } from "../utils/awsS3Bucket"; 5 | import Folder from "./../model/Folder" 6 | import Share from "../model/Share"; 7 | import File from "./../model/File"; 8 | import cloudinary from "../utils/cloudinary"; 9 | 10 | export const isFileUpload = async (req: Request, res: Response) => { 11 | const { 12 | fileContents, 13 | previewImage, 14 | // enc, 15 | folderId, level, fileName, fileSize, 16 | fileType,} = req.body; 17 | const userId=req.headers.userId 18 | 19 | try { 20 | // console.log(enc); 21 | 22 | // const uni8Array: Array = Object.values(fileContents) 23 | // const buffer = Buffer.from(uni8Array); 24 | // const hash = createHash('sha256'); 25 | // hash.update(buffer) 26 | // console.log(buffer); 27 | 28 | // const fileHash2 = hash.digest('hex'); 29 | // if (fileHash2 === fileHash) { 30 | // console.log(fileHash2); 31 | 32 | let isFileExist = await File.findOne({ userId, parentFolderId: folderId, fileName,folderLevel:level }) 33 | if (isFileExist) res.sendStatus(409) 34 | 35 | let previewImageData=await cloudinary.uploader.upload(previewImage, 36 | { 37 | folder: "PreviewImages", 38 | width: 150, 39 | crop: "scale", 40 | }, 41 | ) 42 | 43 | 44 | // let s3Result = await uploadFile(buffer, req.body.fileName) 45 | 46 | 47 | let file= await File.create({ 48 | userId, 49 | parentFolderId: folderId, 50 | fileName, 51 | folderLevel: level, 52 | fileSize, 53 | fileType, 54 | // fileHash: fileHash2, 55 | cludinaryUrl: previewImageData.secure_url, 56 | AWSBucket: fileContents.Bucket, 57 | AWSKey: fileContents.Key, 58 | AWSEtag: fileContents.ETag, 59 | AWSLocation:fileContents.Location 60 | 61 | }) 62 | console.log(file); 63 | 64 | res.status(200).json(file); 65 | 66 | 67 | // } 68 | // else { 69 | // res.sendStatus(406) 70 | // } 71 | 72 | 73 | } catch (error) { 74 | console.log(error); 75 | 76 | } 77 | 78 | 79 | 80 | } 81 | 82 | export const getFileSize = async (req: Request, res: Response) => { 83 | let userId = req.headers.userId; 84 | if(typeof userId === 'string') 85 | try { 86 | let fileSize=await File.aggregate([{ 87 | $match: { 88 | userId:new Types.ObjectId(userId), 89 | recordStatus: { 90 | $lte: 2 91 | } 92 | } 93 | }, { 94 | $group: { 95 | _id: null, 96 | fileSize: { 97 | $sum: '$fileSize' 98 | } 99 | } 100 | }]) 101 | res.status(200).json({fileSize:fileSize[0].fileSize}) 102 | 103 | } catch (error) { 104 | 105 | 106 | } 107 | 108 | } 109 | 110 | export const isGetFile =async (req: Request, res: Response) => { 111 | try { 112 | let data = await getFile(req.body.key) 113 | res.json({url:data}) 114 | } catch (error) { 115 | console.log(error); 116 | 117 | } 118 | } 119 | 120 | export const iGetSharedWithMe =async (req:Request, res:Response) => { 121 | let userId = req.headers.userId; 122 | if (typeof userId === 'string') 123 | try { 124 | let result= await Share.aggregate([ 125 | { 126 | '$match': { 127 | 'userId': new Types.ObjectId(userId) 128 | } 129 | }, { 130 | '$lookup': { 131 | 'from': 'files', 132 | 'localField': 'shares', 133 | 'foreignField': '_id', 134 | 'as': 'res' 135 | } 136 | }, { 137 | '$project': { 138 | 'res': 1, 139 | '_id': 0 140 | } 141 | }, { 142 | '$unwind': { 143 | 'path': '$res' 144 | } 145 | }, { 146 | '$replaceRoot': { 147 | 'newRoot': '$res' 148 | } 149 | } 150 | ]) 151 | res.status(200).json(result) 152 | 153 | } catch (error) { 154 | res.sendStatus(404) 155 | } 156 | } 157 | 158 | export const getAllFiles = async(req: Request, res: Response) => { 159 | let userId = req.headers.userId; 160 | if (typeof userId === 'string') 161 | try { 162 | const result = await File.aggregate([{ 163 | $match: { 164 | userId:new Types.ObjectId(userId), 165 | recordStatus: { 166 | $lte: 2 167 | } 168 | } 169 | }]) 170 | res.status(200).json(result) 171 | } catch (error) { 172 | res.sendStatus(404) 173 | } 174 | } 175 | 176 | export const deleteFile = async(req: Request, res: Response) => { 177 | const userId = req.headers.userId; 178 | const fileId = req.params.id; 179 | try { 180 | const file = await File.findOne({ userId, _id: fileId }); 181 | if (!file) throw new Error("server error"); 182 | file.recordStatus = 3; 183 | await file.save(); 184 | res.status(200).json("success"); 185 | } catch (error:any) { 186 | 187 | res.status(404).json({message:error.message}) 188 | } 189 | 190 | } 191 | 192 | 193 | export const addToFavorite = async(req: Request, res: Response) => { 194 | const userId = req.headers.userId; 195 | const fileId = req.params.id; 196 | try { 197 | const file = await File.updateOne({ userId, _id: fileId }, { 198 | $set: { 199 | favourite:true 200 | } 201 | }); 202 | if (file.modifiedCount === 0) throw new Error("server error"); 203 | res.status(200).json("success"); 204 | 205 | } catch (error:any) { 206 | res.status(404).json({ message:error.message}) 207 | } 208 | } 209 | 210 | export const isGetFavorite =async (req: Request, res: Response) => { 211 | const userId = req.headers.userId; 212 | 213 | try { 214 | const files = await File.find({ userId, favourite: true }); 215 | res.status(200).json(files); 216 | } catch (error:any) { 217 | res.status(404).json({ message:error.message}) 218 | 219 | } 220 | } -------------------------------------------------------------------------------- /drive/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Visit https://aka.ms/tsconfig to read more about this file */ 4 | 5 | /* Projects */ 6 | // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ 7 | // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ 8 | // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ 9 | // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ 10 | // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ 11 | // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ 12 | 13 | /* Language and Environment */ 14 | "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ 15 | // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ 16 | // "jsx": "preserve", /* Specify what JSX code is generated. */ 17 | // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ 18 | // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ 19 | // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ 20 | // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ 21 | // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ 22 | // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ 23 | // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ 24 | // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ 25 | // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ 26 | 27 | /* Modules */ 28 | "module": "commonjs", /* Specify what module code is generated. */ 29 | // "rootDir": "./", /* Specify the root folder within your source files. */ 30 | // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ 31 | // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ 32 | // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ 33 | // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ 34 | // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ 35 | // "types": [], /* Specify type package names to be included without being referenced in a source file. */ 36 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 37 | // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ 38 | // "resolveJsonModule": true, /* Enable importing .json files. */ 39 | // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ 40 | 41 | /* JavaScript Support */ 42 | // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ 43 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ 44 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ 45 | 46 | /* Emit */ 47 | // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ 48 | // "declarationMap": true, /* Create sourcemaps for d.ts files. */ 49 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ 50 | // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ 51 | // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ 52 | // "outDir": "./", /* Specify an output folder for all emitted files. */ 53 | // "removeComments": true, /* Disable emitting comments. */ 54 | // "noEmit": true, /* Disable emitting files from a compilation. */ 55 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ 56 | // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ 57 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ 58 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ 59 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 60 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ 61 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ 62 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ 63 | // "newLine": "crlf", /* Set the newline character for emitting files. */ 64 | // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ 65 | // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ 66 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ 67 | // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ 68 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ 69 | // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ 70 | 71 | /* Interop Constraints */ 72 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ 73 | // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ 74 | "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ 75 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ 76 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ 77 | 78 | /* Type Checking */ 79 | "strict": true, /* Enable all strict type-checking options. */ 80 | // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ 81 | "strictNullChecks": false, /* When type checking, take into account 'null' and 'undefined'. */ 82 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ 83 | // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ 84 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ 85 | // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ 86 | // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ 87 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ 88 | // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ 89 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ 90 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ 91 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ 92 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ 93 | // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ 94 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ 95 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ 96 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ 97 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ 98 | 99 | /* Completeness */ 100 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ 101 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /authentication/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Visit https://aka.ms/tsconfig to read more about this file */ 4 | 5 | /* Projects */ 6 | // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ 7 | // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ 8 | // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ 9 | // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ 10 | // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ 11 | // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ 12 | 13 | /* Language and Environment */ 14 | "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ 15 | // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ 16 | // "jsx": "preserve", /* Specify what JSX code is generated. */ 17 | // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ 18 | // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ 19 | // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ 20 | // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ 21 | // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ 22 | // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ 23 | // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ 24 | // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ 25 | // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ 26 | 27 | /* Modules */ 28 | "module": "commonjs", /* Specify what module code is generated. */ 29 | // "rootDir": "./", /* Specify the root folder within your source files. */ 30 | // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ 31 | // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ 32 | // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ 33 | // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ 34 | // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ 35 | // "types": [], /* Specify type package names to be included without being referenced in a source file. */ 36 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 37 | // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ 38 | // "resolveJsonModule": true, /* Enable importing .json files. */ 39 | // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ 40 | 41 | /* JavaScript Support */ 42 | // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ 43 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ 44 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ 45 | 46 | /* Emit */ 47 | // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ 48 | // "declarationMap": true, /* Create sourcemaps for d.ts files. */ 49 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ 50 | // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ 51 | // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ 52 | // "outDir": "./", /* Specify an output folder for all emitted files. */ 53 | // "removeComments": true, /* Disable emitting comments. */ 54 | // "noEmit": true, /* Disable emitting files from a compilation. */ 55 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ 56 | // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ 57 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ 58 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ 59 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 60 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ 61 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ 62 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ 63 | // "newLine": "crlf", /* Set the newline character for emitting files. */ 64 | // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ 65 | // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ 66 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ 67 | // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ 68 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ 69 | // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ 70 | 71 | /* Interop Constraints */ 72 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ 73 | // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ 74 | "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ 75 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ 76 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ 77 | 78 | /* Type Checking */ 79 | "strict": true, /* Enable all strict type-checking options. */ 80 | // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ 81 | "strictNullChecks": false, /* When type checking, take into account 'null' and 'undefined'. */ 82 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ 83 | // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ 84 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ 85 | // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ 86 | // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ 87 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ 88 | // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ 89 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ 90 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ 91 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ 92 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ 93 | // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ 94 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ 95 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ 96 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ 97 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ 98 | 99 | /* Completeness */ 100 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ 101 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 102 | } 103 | } 104 | --------------------------------------------------------------------------------