From 30293c2c1e4861bc41fb22c7e1e6373dfede1793 Mon Sep 17 00:00:00 2001 From: geeknk Date: Sat, 9 Dec 2023 19:38:27 +0530 Subject: [PATCH] fixed bug in typescript and applied raw query --- app.js | 19 - app.ts | 19 + build/app.js | 15 + build/config/constant.js | 24 + build/config/dbconnect.js | 35 + build/config/redisconfig.js | 20 + build/controllers/userController.js | 144 ++++ build/interfaces.td.js | 1 + build/middleware/usermiddle.js | 69 ++ {routes => build/routes}/userRoute.js | 7 +- build/services/userservices.js | 171 ++++ config/{constant.js => constant.ts} | 0 config/{dbconnect.js => dbconnect.ts} | 0 config/{redisconfig.js => redisconfig.ts} | 2 +- .../{userController.js => userController.ts} | 112 ++- interfaces.td.ts | 40 + middleware/usermiddle.js | 56 -- middleware/usermiddle.ts | 98 +++ nodemon.json | 4 + package-lock.json | 763 +++++------------- package.json | 21 +- routes/userRoute.ts | 16 + services/userservices.js | 310 ------- services/userservices.ts | 225 ++++++ tsconfig.json | 8 +- 25 files changed, 1145 insertions(+), 1034 deletions(-) delete mode 100644 app.js create mode 100644 app.ts create mode 100644 build/app.js create mode 100644 build/config/constant.js create mode 100644 build/config/dbconnect.js create mode 100644 build/config/redisconfig.js create mode 100644 build/controllers/userController.js create mode 100644 build/interfaces.td.js create mode 100644 build/middleware/usermiddle.js rename {routes => build/routes}/userRoute.js (72%) create mode 100644 build/services/userservices.js rename config/{constant.js => constant.ts} (100%) rename config/{dbconnect.js => dbconnect.ts} (100%) rename config/{redisconfig.js => redisconfig.ts} (83%) rename controllers/{userController.js => userController.ts} (58%) create mode 100644 interfaces.td.ts delete mode 100644 middleware/usermiddle.js create mode 100644 middleware/usermiddle.ts create mode 100644 nodemon.json create mode 100644 routes/userRoute.ts delete mode 100644 services/userservices.js create mode 100644 services/userservices.ts diff --git a/app.js b/app.js deleted file mode 100644 index bdfa860..0000000 --- a/app.js +++ /dev/null @@ -1,19 +0,0 @@ -import express from "express" -import service from "./config/constant.js" -import cookieparser from "cookie-parser" -import {router} from"./routes/userRoute.js" -import {redisconnect} from"./config/redisconfig.js" -import {dbConnection} from "./config/dbconnect.js" - -const app = express(); - -app.use(express.json()) -app.use(cookieparser()) -app.use("/user", router) - -dbConnection(); -redisconnect(); - -app.listen(service.PORT, () => { - console.log("server is running"); -}); diff --git a/app.ts b/app.ts new file mode 100644 index 0000000..4c864b0 --- /dev/null +++ b/app.ts @@ -0,0 +1,19 @@ +import express,{Application} from "express" +import service from "./config/constant" +import cookieparser from "cookie-parser" +import {router} from"./routes/userRoute" +import {redisconnect} from"./config/redisconfig" +import {dbConnection} from "./config/dbconnect" + +const app: Application = express(); + +app.use(express.json()) +app.use(cookieparser()) +app.use("/user", router) + +dbConnection(); +redisconnect(); + +app.listen(service.PORT, () => { + console.log("server is running"); +}); diff --git a/build/app.js b/build/app.js new file mode 100644 index 0000000..16e8ef4 --- /dev/null +++ b/build/app.js @@ -0,0 +1,15 @@ +import express from "express"; +import service from "./config/constant"; +import cookieparser from "cookie-parser"; +import { router } from "./routes/userRoute"; +import { redisconnect } from "./config/redisconfig"; +import { dbConnection } from "./config/dbconnect"; +const app = express(); +app.use(express.json()); +app.use(cookieparser()); +app.use("/user", router); +dbConnection(); +redisconnect(); +app.listen(service.PORT, () => { + console.log("server is running"); +}); diff --git a/build/config/constant.js b/build/config/constant.js new file mode 100644 index 0000000..06a0b33 --- /dev/null +++ b/build/config/constant.js @@ -0,0 +1,24 @@ +import dotenv from "dotenv"; +dotenv.config(); +export default { + PORT: process.env.PORT_NO, + ACCESS_TOKEN_SECRET: process.env.ACCESS_TOKEN_SECRET, + REFRESH_TOKEN_SECRET: process.env.REFRESH_TOKEN_SECRET, + db_url: process.env.DB_URL, + ACCESS_TOKEN_EXPIRES: process.env.JWT_EXPIRY, + FPASS_EXPIRESIN: process.env.FPASS_EXPIRY, + API_KEY: process.env.APIKEY, + EMAIL_FROM: process.env.emailFrom, + URL: process.env.url, + URL1: process.env.url1, + snapURL: process.env.snapurl, + EMAIL_PASS: process.env.pass, + DB: process.env.database, + PASS: process.env.password, + CLIENT_ID: process.env.CLIENT_ID, + CLIENT_SECERET: process.env.CLIENT_SECERET, + REDIRECT_URI: process.env.REDIRECT_URI, + REFRESH_TOKEN: process.env.REFRESH_TOKEN, + USER: process.env.USER, +}; +//export const port : pr diff --git a/build/config/dbconnect.js b/build/config/dbconnect.js new file mode 100644 index 0000000..6ec9a93 --- /dev/null +++ b/build/config/dbconnect.js @@ -0,0 +1,35 @@ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +import mysql from 'mysql2'; +import config from './constant.js'; +export const con = mysql.createConnection({ + host: "localhost", + user: "root", + database: config.DB, + password: config.PASS +}); +export const dbConnection = () => __awaiter(void 0, void 0, void 0, function* () { + try { + yield con.connect(); + const userTable = `CREATE TABLE IF NOT EXISTS users ( + username VARCHAR(255), + firstname VARCHAR(255), + lastname VARCHAR(255), + email VARCHAR(255), + mobile VARCHAR(255), + password VARCHAR(255) + )`; + con.query(userTable); + console.log("db connected"); + } + catch (error) { + console.log(error); + } +}); diff --git a/build/config/redisconfig.js b/build/config/redisconfig.js new file mode 100644 index 0000000..0b0df5d --- /dev/null +++ b/build/config/redisconfig.js @@ -0,0 +1,20 @@ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +import { createClient } from 'redis'; +export const client = createClient(); +export const redisconnect = () => __awaiter(void 0, void 0, void 0, function* () { + try { + yield client.connect(); + console.log("redis connected"); + } + catch (error) { + console.log(error); + } +}); diff --git a/build/controllers/userController.js b/build/controllers/userController.js new file mode 100644 index 0000000..7075d3d --- /dev/null +++ b/build/controllers/userController.js @@ -0,0 +1,144 @@ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +import * as userServices from "../services/userservices"; +export const signup = (req, res) => __awaiter(void 0, void 0, void 0, function* () { + const data = yield userServices.usersignup(req.body); + if (data) { + res.status(201).send({ success: true, msg: "User registered successfully", data: data }); + } +}); +export const signin = (req, res) => __awaiter(void 0, void 0, void 0, function* () { + const loggedin = yield userServices.userlogin(req.body); + if (!loggedin) { + return res.status(401).send({ success: false, msg: "Email or Password is wrong" }); + } + else { + // Assigning refresh token in http-only cookie + res.cookie('refresh_token', loggedin.refreshToken, { httpOnly: true, + sameSite: 'none', secure: true, + maxAge: 24 * 60 * 60 * 1000 + }); + res.status(200).send(loggedin.accessToken); + } +}); +export const changePass = (req, res) => __awaiter(void 0, void 0, void 0, function* () { + const validpass = yield userServices.matchpass(req.body); + if (!validpass) { + return res.status(401).send({ success: "failed", message: "password doesn't match" }); + } + try { + userServices.modifyPass(req.data.email, req.body.password); + res.status(201).send({ success: "true", message: "password changed" }); + } + catch (error) { + res.status(401).send({ success: "false", message: "password is not changed" }); + } +}); +export const verifyuser = (req, res) => __awaiter(void 0, void 0, void 0, function* () { + const validuser = yield userServices.verifyemail(req.body.email); + if (!validuser) { + res.status(401).send({ success: "false", message: "user doesn't exist" }); + } + else { + res.status(201).send({ success: "true", message: "user exist", token: validuser }); + } +}); +export const forgetPass = (req, res) => __awaiter(void 0, void 0, void 0, function* () { + const validpass = yield userServices.matchpass(req.body); + if (!validpass) { + return res.status(401).send({ success: "failed", message: "password doesn't match" }); + } + try { + userServices.modifyPass(req.data.email, req.body.password); + res.status(201).send({ success: "true", message: "password updated" }); + } + catch (error) { + res.status(401).send({ success: "false", message: "password is not updated" }); + } +}); +export const updateuser = (req, res) => __awaiter(void 0, void 0, void 0, function* () { + try { + const response = yield userServices.updateuser1(req.data.email, req.body); + res.status(201).send({ success: "true", message: "user updated successfully", response }); + } + catch (error) { + res.status(402).send({ success: "false", message: "user not updated" }); + } +}); +//get user data with the help of token (without body) +export const getuser = (req, res) => __awaiter(void 0, void 0, void 0, function* () { + try { + const userData = yield userServices.getdata(req.data.id); + res.send(userData); + } + catch (error) { + console.log(error); + res.status(402).send(error); + } +}); +//get user data with the help of token (without email) +export const deluser = (req, res) => __awaiter(void 0, void 0, void 0, function* () { + try { + yield userServices.deleteuser(req.data.id); + res.status(201).send({ success: "true", message: "user deleted" }); + } + catch (error) { + console.log(error); + res.status(402).send(error); + } +}); +// get user in the form of list (page wise) +export const userlist = (req, res) => __awaiter(void 0, void 0, void 0, function* () { + try { + const data = yield userServices.user_list(+req.params.page); + if (data) { + res.status(201).send({ success: "true", message: data }); + } + } + catch (error) { + res.status(401).send({ success: "false", message: "userdata not found", error }); + } +}); +// user address +export const user_address = (req, res) => __awaiter(void 0, void 0, void 0, function* () { + try { + const data = yield userServices.useraddress(req.body, req.data.id); + if (data) { + res.status(201).send({ success: "true", message: "address saved" }); + } + else { + res.status(401).send({ success: "false", message: "address not saved" }); + } + } + catch (error) { + res.status(401).send({ success: "false", message: error }); + } +}); +export const profileImg = (req, res) => __awaiter(void 0, void 0, void 0, function* () { + if (req.file) { + res.status(201).send({ success: "true", message: "image uploaded" }); + } + else { + res.status(401).send({ success: "false", message: "failed" }); + } +}); +export const refreshuser = (req, res) => __awaiter(void 0, void 0, void 0, function* () { + try { + const token = yield userServices.generateToken(req.data); + res.cookie('refresh_token', token.refreshToken, { httpOnly: true, + sameSite: 'none', secure: true, + maxAge: 24 * 60 * 60 * 1000 + }); + res.status(200).send(token.accessToken); + } + catch (error) { + res.status(401).send({ success: "false", error }); + } +}); diff --git a/build/interfaces.td.js b/build/interfaces.td.js new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/build/interfaces.td.js @@ -0,0 +1 @@ +export {}; diff --git a/build/middleware/usermiddle.js b/build/middleware/usermiddle.js new file mode 100644 index 0000000..044f2fa --- /dev/null +++ b/build/middleware/usermiddle.js @@ -0,0 +1,69 @@ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +import config from "../config/constant"; +import multer from "multer"; +import { con } from "../config/dbconnect"; +import { client } from "../config/redisconfig"; +import jwt from "jsonwebtoken"; +export const verifyEmail = (req, res, next) => __awaiter(void 0, void 0, void 0, function* () { + con.query(`SELECT * FROM users WHERE email ='${req.body.email}'`, (err, result) => { + if (err) { + res.send(err); + } + else if (result == null) { + console.log("email does not exist "); + next(); + } + else { + console.log(result); + return res.status(409).send({ success: false, msg: "Email already exist" }); + } + }); +}); +export const checkAuth = (req, res, next) => __awaiter(void 0, void 0, void 0, function* () { + const bearerHeader = req.headers["authorization"]; + if (typeof bearerHeader !== "undefined") { + const bearer = bearerHeader.split(" "); + const token = bearer[1]; + const { email, id } = jwt.verify(token, config.ACCESS_TOKEN_SECRET); + req.data = { email, token, id }; + next(); + } + else { + return res.status(409).send({ success: false, msg: "invalid token" }); + } +}); +export const verifyRT = (req, res, next) => __awaiter(void 0, void 0, void 0, function* () { + var _a; + if ((_a = req.cookies) === null || _a === void 0 ? void 0 : _a.refresh_token) { + // Destructuring refreshToken from cookie + const refreshToken = req.cookies.refresh_token; + // Verifying refresh token + const tokenData = yield client.hGetAll(refreshToken); + req.data = tokenData; + client.del(refreshToken); + next(); + } + else { + return res + .status(406) + .json({ message: "Unauthorized ! Refresh token not found" }); + } +}); +export const upload = multer({ + storage: multer.diskStorage({ + destination: function (req, file, cb) { + cb(null, "uploads"); + }, + filename: function (req, file, cb) { + cb(null, file.fieldname + "-" + Date.now() + ".jpg"); + }, + }), +}).single("user_file"); diff --git a/routes/userRoute.js b/build/routes/userRoute.js similarity index 72% rename from routes/userRoute.js rename to build/routes/userRoute.js index bcd61bb..ff91148 100644 --- a/routes/userRoute.js +++ b/build/routes/userRoute.js @@ -2,8 +2,7 @@ import express from "express"; export const router = express.Router(); import * as mid from "../middleware/usermiddle.js"; import * as controller from "../controllers/userController.js"; - -router.get("/register", controller.signup); +router.get("/register", mid.verifyEmail, controller.signup); router.get("/get", mid.checkAuth, controller.getuser); router.get("/list/:page", controller.userlist); router.post("/auth/signin", controller.signin); @@ -14,7 +13,3 @@ router.put("/updateuser", mid.checkAuth, controller.updateuser); router.put("/delete", mid.checkAuth, controller.deluser); router.post("/forgot-password", controller.verifyuser); router.put("/profile-image", mid.upload, controller.profileImg); -router.post("/fetch/flipkart/mobile", controller.flipkartMob); -router.post("/fetch/flipkart/mobile/all", controller.flipkartAllMob); -router.post("/fetch/snapdeal/t-shirt", controller.snapdealTshirt); -router.get("/aggregate", controller.aggregate); diff --git a/build/services/userservices.js b/build/services/userservices.js new file mode 100644 index 0000000..b93a653 --- /dev/null +++ b/build/services/userservices.js @@ -0,0 +1,171 @@ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +import config from "../config/constant.js"; +import { con } from "../config/dbconnect.js"; +import { client } from "../config/redisconfig.js"; +import { google } from "googleapis"; +import jwt from "jsonwebtoken"; +import bcrypt from "bcryptjs"; +import nodemailer from "nodemailer"; +import randToken from "rand-token"; +const oAuth2Client = new google.auth.OAuth2(config.CLIENT_ID, config.CLIENT_SECERET, config.REDIRECT_URI); +oAuth2Client.setCredentials({ refresh_token: config.REFRESH_TOKEN }); +const accessToken = () => __awaiter(void 0, void 0, void 0, function* () { + const accesstoken = yield oAuth2Client.getAccessToken(); + return accesstoken; +}); +const transport = nodemailer.createTransport({ + service: "gmail", + auth: { + type: 'OAuth2', + user: config.USER, + clientId: config.CLIENT_ID, + clientSecret: config.CLIENT_SECERET, + refreshToken: config.REFRESH_TOKEN, + accessToken: accessToken() + }, +}); +export const getdata = (id) => __awaiter(void 0, void 0, void 0, function* () { + try { + return yield con.findOne({ include: address }, { where: { id } }); + } + catch (error) { + console.error("Error retrieving data:", error); + throw error; + } +}); +export const deleteuser = (id) => __awaiter(void 0, void 0, void 0, function* () { + // const data = await User.destroy({where:{id: id}},{ + // include: [{ + // model: address, + // where: { user_id: id }, + // }] + // });/ + const data = yield address.destroy({ where: { user_id: id } }, { + include: [{ + model: User, + where: { id: id }, + }] + }); + yield User.destroy({ where: { id: id } }); + if (data) { + return true; + } +}); +export const updateuser1 = (email, body_data) => __awaiter(void 0, void 0, void 0, function* () { + yield User.update(body_data, { where: { email } }); +}); +export const matchpass = (data) => __awaiter(void 0, void 0, void 0, function* () { + return data.password === data.new_password; +}); +export const verifyemail = (email) => __awaiter(void 0, void 0, void 0, function* () { + const emailexist = yield User.findOne({ where: { email } }); + if (emailexist) { + const token = jwt.sign({ email: emailexist.email, id: emailexist._id, username: emailexist.username }, config.ACCESS_TOKEN_SECRET, { expiresIn: config.FPASS_EXPIRESIN }); + const mailOption = { + from: config.EMAIL_FROM, + to: "ernitish26@gmail.com", + subject: "Password Reset Link", + html: `${token}`, + }; + transport.sendMail(mailOption); + return token; + } + else { + return false; + } +}); +export const modifyPass = (email, password) => __awaiter(void 0, void 0, void 0, function* () { + yield User.update({ password }, { + where: { email } + }); + const mailOption = { + from: config.EMAIL_FROM, + to: "ernitish26@gmail.com", + subject: "Password Reset", + text: "Password Reset successfully", + }; + transport.sendMail(mailOption); +}); +export const userlogin = (data) => __awaiter(void 0, void 0, void 0, function* () { + const userData = yield User.findOne({ where: { email: data.email } }); + const pass = yield bcrypt.compare(userData.password, data.password); + if (pass && userData) { + const accessToken = jwt.sign({ email: userData.email, id: userData.id }, config.ACCESS_TOKEN_SECRET, { expiresIn: config.ACCESS_TOKEN_EXPIRES }); + const refreshToken = randToken.uid(256); + yield client.hSet(refreshToken, { + id: userData.id, + email: userData.email, + username: userData.username + }); + return { accessToken, refreshToken }; + } + else { + return false; + } +}); +export const usersignup = (data) => { + let user; + const sql = `INSERT INTO users VALUES(?)`; + con.query(sql, data, (err, result) => { + if (err) { + return err; + } + else { + user = result; + } + }); + if (user) { + const mailOption = { + from: config.EMAIL_FROM, + to: 'rajaryan232326@gmail.com', + subject: "Registration", + text: "Registeration successful", + }; + transport.sendMail(mailOption); + return user; + } + else { + return false; + } +}; +export const user_list = (page) => __awaiter(void 0, void 0, void 0, function* () { + const firstindex = (page - 1) * 10; + const lastindex = page * 10; + const data = yield User.findAll(); + const sliced_data = data.slice(firstindex, lastindex); + return sliced_data; +}); +export const useraddress = (data, ID) => __awaiter(void 0, void 0, void 0, function* () { + try { + let userAdd = yield address.create({ + user_id: ID, + address: data.address, + city: data.city, + state: data.state, + pin_code: data.pin_code, + phone: data.phone, + }); + return userAdd; + } + catch (error) { + console.error(error); + } +}); +export const generateToken = (userData) => __awaiter(void 0, void 0, void 0, function* () { + const accessToken = jwt.sign({ email: userData.email, id: userData.id }, config.ACCESS_TOKEN_SECRET, { expiresIn: config.ACCESS_TOKEN_EXPIRES }); + const refreshToken = randToken.uid(256); + yield client.hSet(refreshToken, { + id: userData.id, + email: userData.email, + username: userData.username + }); + return { accessToken, refreshToken }; +}); diff --git a/config/constant.js b/config/constant.ts similarity index 100% rename from config/constant.js rename to config/constant.ts diff --git a/config/dbconnect.js b/config/dbconnect.ts similarity index 100% rename from config/dbconnect.js rename to config/dbconnect.ts diff --git a/config/redisconfig.js b/config/redisconfig.ts similarity index 83% rename from config/redisconfig.js rename to config/redisconfig.ts index 7838a29..a4195f9 100644 --- a/config/redisconfig.js +++ b/config/redisconfig.ts @@ -5,7 +5,7 @@ export const client = createClient(); export const redisconnect = async () =>{ try { await client.connect(); - console.log("redis connected"); + console.log("redis connected") } catch (error) { console.log(error); } diff --git a/controllers/userController.js b/controllers/userController.ts similarity index 58% rename from controllers/userController.js rename to controllers/userController.ts index 8bfa4db..ebe3d09 100644 --- a/controllers/userController.js +++ b/controllers/userController.ts @@ -1,40 +1,66 @@ -import * as userServices from "../services/userservices.js" +import * as userServices from "../services/userservices" +import {Request,Response} from "express" -export const signup = async (req, res) => { - const data = await userServices.usersignup(req.body) - if(data){ - res.status(201).send({ success: true, msg:"User registered successfully", data: data }); +interface reqInterface extends Request{ + data:{ + email:string + id:string + page:string } +} + +export const signup = async (req:Request, res:Response) => { + try { + await userServices.usersignup(req.body) + userServices.sendEmail({ + to:req.body.email, + subject: "Registration", + text:"user registered successfully", + link:"", + url:"" + }) + res.status(201).send({ success: true, msg:"User registered successfully"}) + } catch (error) { + + } + }; -export const signin = async (req, res) => { - const loggedin = await userServices.userlogin(req.body) +export const signin = async (req:Request, res:Response) => { + const loggedin = await userServices.token(req.body) if (!loggedin) { return res.status(401).send({ success: false, msg: "Email or Password is wrong" }); } else { // Assigning refresh token in http-only cookie res.cookie('refresh_token', loggedin.refreshToken, { httpOnly: true, - sameSite: 'None', secure: true, + sameSite: 'none', secure: true, maxAge: 24 * 60 * 60 * 1000 }); res.status(200).send(loggedin.accessToken); } }; - export const changePass = async (req, res) => { + export const changePass = async (req:Request, res:Response) => { const validpass = await userServices.matchpass(req.body) if(!validpass){ return res.status(401).send({success: "failed", message: "password doesn't match" }); }try { - userServices.modifyPass(req.data.email,req.body); + userServices.modifyPass(req.data.email, req.body.password); + userServices.sendEmail({ + to: "ernitish26@gmail.com", + subject: "Password Reset", + text: "Password Reset successfully", + link:"", + url:"" + }) res.status(201).send({success: "true", message: "password changed" }); } catch (error) { res.status(401).send({success: "false", message: "password is not changed" }); } }; - export const verifyuser = async(req,res) => { - const validuser = await userServices.verifyemail(req.body) + export const verifyuser = async(req:Request, res:Response) => { + const validuser = await userServices.verifyemail(req.body.email) if(!validuser){ res.status(401).send({success: "false", message: "user doesn't exist" }); }else{ @@ -42,19 +68,19 @@ export const signin = async (req, res) => { } }; - export const forgetPass = async (req, res) => { + export const forgetPass = async (req:Request, res:Response) => { const validpass = await userServices.matchpass(req.body) if(!validpass){ return res.status(401).send({success: "failed", message: "password doesn't match" }); }try { - userServices.modifyPass(req.data.email,req.body); + userServices.modifyPass(req.data.email,req.body.password); res.status(201).send({success: "true", message: "password updated" }); } catch (error) { res.status(401).send({success: "false", message: "password is not updated" }); } }; - export const updateuser = async (req, res) => { + export const updateuser = async (req:Request, res:Response) => { try { const response = await userServices.updateuser1(req.data.email , req.body); res.status(201).send({success: "true", message: "user updated successfully", response }); @@ -65,7 +91,7 @@ export const signin = async (req, res) => { //get user data with the help of token (without body) - export const getuser = async (req, res) => { + export const getuser = async (req:Request, res:Response) => { try { const userData = await userServices.getdata(req.data.id); res.send(userData) @@ -77,7 +103,7 @@ export const signin = async (req, res) => { //get user data with the help of token (without email) - export const deluser = async (req, res) => { + export const deluser = async (req:Request, res:Response) => { try { await userServices.deleteuser(req.data.id); res.status(201).send({success: "true", message: "user deleted" }); @@ -89,9 +115,9 @@ export const signin = async (req, res) => { // get user in the form of list (page wise) - export const userlist = async (req, res) => { + export const userlist = async (req:Request, res:Response) => { try{ - const data = await userServices.user_list(req.params.page) + const data = await userServices.user_list(+req.params.page) if(data){ res.status(201).send({success: "true", message: data }); } @@ -102,7 +128,7 @@ export const signin = async (req, res) => { // user address - export const user_address = async (req,res)=>{ + export const user_address = async (req:Request, res:Response)=>{ try{ const data = await userServices.useraddress(req.body,req.data.id) if(data){ @@ -115,7 +141,7 @@ export const signin = async (req, res) => { } }; - export const profileImg = async (req,res)=>{ + export const profileImg = async (req:Request, res:Response)=>{ if(req.file){ res.status(201).send({success: "true", message: "image uploaded" }); }else{ @@ -123,51 +149,11 @@ export const signin = async (req, res) => { } }; - export const flipkartMob = async (req,res)=>{ - try{ - const fkart = await userServices.flipkart() - if(fkart){ - res.status(201).send({success: "true", message: "userdata found", Data : fkart }); - } - }catch(error){ - res.status(401).send({success: "false", message: "userdata not found" ,error}); - } -}; - - export const flipkartAllMob = async (req,res)=>{ - try{ - const fkart = await userServices.flipkartAll() - if(fkart){ - res.status(201).send({success: "true", message: "userdata found", Data : fkart }); - } - }catch(error){ - res.status(401).send({success: "false", message: "userdata not found" ,error}); - } -}; - export const snapdealTshirt = async (req,res)=>{ - try{ - const sdeal = await userServices.snapdeal() - if(sdeal){ - res.status(201).send({success: "true", message: "userdata found", Data : sdeal }); - } - }catch(error){ - res.status(401).send({success: "false", message: "userdata not found" ,error}); - } -}; - export const aggregate = async (req,res) => { - try { - const data = await userServices.findByAggregate() - res.status(201).send({success: "true", message: "userdata found", Data : data }); - } catch (error) { - res.status(401).send({success: "false",error}); - } -} - - export const refreshuser = async (req,res) => { + export const refreshuser = async (req:reqInterface, res:Response) => { try { const token = await userServices.generateToken(req.data) res.cookie('refresh_token', token.refreshToken, { httpOnly: true, - sameSite: 'None', secure: true, + sameSite: 'none', secure: true, maxAge: 24 * 60 * 60 * 1000 }); res.status(200).send(token.accessToken); diff --git a/interfaces.td.ts b/interfaces.td.ts new file mode 100644 index 0000000..c8a90bb --- /dev/null +++ b/interfaces.td.ts @@ -0,0 +1,40 @@ +import {Request,Response} from 'express' +import { SignOptions } from 'jsonwebtoken'; + +export interface user { + id?: number; + username: string; + firstname: string; + lastname: string; + email: string; + mobile: number; + password: string; +} +export interface user_address { + user_id: number; + address: string; + city: string; + state: string; + pin_code: number; + phone: number; +} +export interface tokenRequest extends Request { + data: { + email?: string, + token?: string, + id?: number, + }; +} +export interface reqInterface extends Request{ + data?: { + [x: string]: string; + }; +} + +export interface mailInterface{ + to:string, + subject: string, + text:string, + link:string, + url:string +} \ No newline at end of file diff --git a/middleware/usermiddle.js b/middleware/usermiddle.js deleted file mode 100644 index 52ae6af..0000000 --- a/middleware/usermiddle.js +++ /dev/null @@ -1,56 +0,0 @@ -import jwt from "jsonwebtoken"; -import config from "../config/constant.js"; -import multer from "multer"; -import { dbConnection } from "../config/dbconnect.js"; -import { client } from "../config/redisconfig.js"; - -export const verifyEmail = async (req, res, next) => { - const userData = await dbConnection.findOne({ where: { email: req.body.email } }); - - if (userData) { - return res.status(409).send({ success: false, msg: "Email already exist" }); - } else { - next(); - } -}; - -export const checkAuth = async (req, res, next) => { - const bearerHeader = req.headers["authorization"]; - if (typeof bearerHeader !== "undefined") { - const bearer = bearerHeader.split(" "); - const token = bearer[1]; - const { email, id } = jwt.verify(token, config.ACCESS_TOKEN_SECRET); - req.data = { email, token, id }; - next(); - } else { - next(); - } -}; - -export const verifyRT = async (req, res, next) => { - if (req.cookies?.refresh_token) { - // Destructuring refreshToken from cookie - const refreshToken = req.cookies.refresh_token; - - // Verifying refresh token - const tokenData = await client.hGetAll(refreshToken); - req.data = tokenData; - client.del(refreshToken); - next(); - } else { - return res - .status(406) - .json({ message: "Unauthorized ! Refresh token not found" }); - } -}; - -export const upload = multer({ - storage: multer.diskStorage({ - destination: function (req, file, cb) { - cb(null, "uploads"); - }, - filename: function (req, file, cb) { - cb(null, file.fieldname + "-" + Date.now() + ".jpg"); - }, - }), -}).single("user_file"); diff --git a/middleware/usermiddle.ts b/middleware/usermiddle.ts new file mode 100644 index 0000000..16a2f3d --- /dev/null +++ b/middleware/usermiddle.ts @@ -0,0 +1,98 @@ +import { Request, Response, NextFunction, RequestHandler } from "express"; +import config from "../config/constant"; +import multer from "multer"; +import { con } from "../config/dbconnect"; +import { client } from "../config/redisconfig"; +import jwt, { Secret, JwtPayload } from "jsonwebtoken"; +import { reqInterface, user } from "../interfaces.td"; +import { fetchUserData } from "../services/userservices"; +import bcrypt from "bcryptjs" + +export const verifyEmail = async ( + req: Request, + res: Response, + next: NextFunction +) => { + con.query( + `SELECT * FROM users WHERE email ='${req.body.email}'`, + (err, result) => { + if (err) { + res.send(err); + } else if (result == null) { + console.log("email does not exist "); + next(); + } else { + console.log(result); + return res + .status(409) + .send({ success: false, msg: "Email already exist" }); + } + } + ); +}; + +export const checkAuth = async ( + req: reqInterface, + res: Response, + next: NextFunction +) => { + const bearerHeader = req.headers["authorization"]; + if (typeof bearerHeader !== "undefined") { + const bearer = bearerHeader.split(" "); + const token = bearer[1]; + const { email,id } = jwt.verify( + token, + config.ACCESS_TOKEN_SECRET as Secret + ) as JwtPayload; + // req["data" as key of typeof Request] = { email, token, id }; + req.data = {email,token,id} + next(); + } else { + return res.status(409).send({ success: false, msg: "invalid token" }); + } +}; + +export const verifyRT = async ( + req: reqInterface, + res: Response, + next: NextFunction +) => { + if (req.cookies?.refresh_token) { + // Destructuring refreshToken from cookie + const refreshToken = req.cookies.refresh_token; + + // Verifying refresh token + const tokenData = await client.hGetAll(refreshToken); + req.data = tokenData; + client.del(refreshToken); + next(); + } else { + return res + .status(406) + .json({ message: "Unauthorized ! Refresh token not found" }); + } +}; + +export const upload = multer({ + storage: multer.diskStorage({ + destination: function (req, file, cb) { + cb(null, "uploads"); + }, + filename: function (req, file, cb) { + cb(null, file.fieldname + "-" + Date.now() + ".jpg"); + }, + }), +}).single("user_file"); + +export const loginMiddileware =async (req:Request, res:Response, next:NextFunction) => { + const userData = await fetchUserData(req.body.email); + + if(userData==null) return res.status(403).send("user not found please register first") + + if(! await bcrypt.compare(req.body.password , userData.password)) + res.status(404).send("email or password does not match") + req.body.id = userData.id + req.body.username = userData.username + + next() +} diff --git a/nodemon.json b/nodemon.json new file mode 100644 index 0000000..f1843a2 --- /dev/null +++ b/nodemon.json @@ -0,0 +1,4 @@ +{ + "ext":".ts, .js", + "ignore":[] +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index f35d12e..40616e9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,25 +9,26 @@ "version": "1.0.0", "license": "ISC", "dependencies": { + "@types/bcryptjs": "^2.4.6", + "@types/cookie-parser": "^1.4.6", + "@types/dotenv": "^8.2.0", + "@types/jsonwebtoken": "^9.0.5", + "@types/multer": "^1.4.11", + "@types/nodemailer": "^6.4.14", "axios": "^1.6.2", - "bcryptjs": "^2.4.3", "cheerio": "^1.0.0-rc.12", - "cookie-parser": "^1.4.6", - "dotenv": "^16.3.1", "express": "^4.18.2", "googleapis": "^129.0.0", - "jsonwebtoken": "^9.0.2", - "multer": "^1.4.5-lts.1", "mysql2": "^3.6.5", - "nodemailer": "^6.9.7", - "nodemon": "^3.0.2", "rand-token": "^1.0.1", "redis": "^4.6.11" }, "devDependencies": { "@types/express": "^4.17.21", "@types/node": "^20.10.3", - "ts-node": "^10.9.1" + "nodemon": "^3.0.2", + "ts-node": "^10.9.1", + "typescript": "^5.3.2" } }, "node_modules/@cspotcode/source-map-support": { @@ -144,11 +145,15 @@ "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", "dev": true }, + "node_modules/@types/bcryptjs": { + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/@types/bcryptjs/-/bcryptjs-2.4.6.tgz", + "integrity": "sha512-9xlo6R2qDs5uixm0bcIqCeMCE6HiQsIyel9KQySStiyqNl2tnj2mP3DX1Nf56MD6KMenNNlBBsy3LJ7gUEQPXQ==" + }, "node_modules/@types/body-parser": { "version": "1.19.5", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", - "dev": true, "dependencies": { "@types/connect": "*", "@types/node": "*" @@ -158,16 +163,31 @@ "version": "3.4.38", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", - "dev": true, "dependencies": { "@types/node": "*" } }, + "node_modules/@types/cookie-parser": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/@types/cookie-parser/-/cookie-parser-1.4.6.tgz", + "integrity": "sha512-KoooCrD56qlLskXPLGUiJxOMnv5l/8m7cQD2OxJ73NPMhuSz9PmvwRD6EpjDyKBVrdJDdQ4bQK7JFNHnNmax0w==", + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/dotenv": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/@types/dotenv/-/dotenv-8.2.0.tgz", + "integrity": "sha512-ylSC9GhfRH7m1EUXBXofhgx4lUWmFeQDINW5oLuS+gxWdfUeW4zJdeVTYVkexEW+e2VUvlZR2kGnGGipAWR7kw==", + "deprecated": "This is a stub types definition. dotenv provides its own type definitions, so you do not need this installed.", + "dependencies": { + "dotenv": "*" + } + }, "node_modules/@types/express": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", - "dev": true, "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.33", @@ -179,7 +199,6 @@ "version": "4.17.41", "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz", "integrity": "sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==", - "dev": true, "dependencies": { "@types/node": "*", "@types/qs": "*", @@ -190,41 +209,59 @@ "node_modules/@types/http-errors": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", - "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", - "dev": true + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" + }, + "node_modules/@types/jsonwebtoken": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.5.tgz", + "integrity": "sha512-VRLSGzik+Unrup6BsouBeHsf4d1hOEgYWTm/7Nmw1sXoN1+tRly/Gy/po3yeahnP4jfnQWWAhQAqcNfH7ngOkA==", + "dependencies": { + "@types/node": "*" + } }, "node_modules/@types/mime": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", - "dev": true + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" + }, + "node_modules/@types/multer": { + "version": "1.4.11", + "resolved": "https://registry.npmjs.org/@types/multer/-/multer-1.4.11.tgz", + "integrity": "sha512-svK240gr6LVWvv3YGyhLlA+6LRRWA4mnGIU7RcNmgjBYFl6665wcXrRfxGp5tEPVHUNm5FMcmq7too9bxCwX/w==", + "dependencies": { + "@types/express": "*" + } }, "node_modules/@types/node": { "version": "20.10.3", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.3.tgz", "integrity": "sha512-XJavIpZqiXID5Yxnxv3RUDKTN5b81ddNC3ecsA0SoFXz/QU8OGBwZGMomiq0zw+uuqbL/krztv/DINAQ/EV4gg==", - "dev": true, "dependencies": { "undici-types": "~5.26.4" } }, + "node_modules/@types/nodemailer": { + "version": "6.4.14", + "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-6.4.14.tgz", + "integrity": "sha512-fUWthHO9k9DSdPCSPRqcu6TWhYyxTBg382vlNIttSe9M7XfsT06y0f24KHXtbnijPGGRIcVvdKHTNikOI6qiHA==", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/qs": { "version": "6.9.10", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.10.tgz", - "integrity": "sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw==", - "dev": true + "integrity": "sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw==" }, "node_modules/@types/range-parser": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", - "dev": true + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" }, "node_modules/@types/send": { "version": "0.17.4", "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", - "dev": true, "dependencies": { "@types/mime": "^1", "@types/node": "*" @@ -234,7 +271,6 @@ "version": "1.15.5", "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", - "dev": true, "dependencies": { "@types/http-errors": "*", "@types/mime": "*", @@ -244,7 +280,8 @@ "node_modules/abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true }, "node_modules/accepts": { "version": "1.3.8", @@ -315,6 +352,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -323,11 +361,6 @@ "node": ">= 8" } }, - "node_modules/append-field": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", - "integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==" - }, "node_modules/arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", @@ -357,7 +390,8 @@ "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true }, "node_modules/base64-js": { "version": "1.5.1", @@ -378,11 +412,6 @@ } ] }, - "node_modules/bcryptjs": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", - "integrity": "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==" - }, "node_modules/bignumber.js": { "version": "9.1.2", "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", @@ -395,6 +424,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, "engines": { "node": ">=8" } @@ -431,6 +461,7 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -440,6 +471,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, "dependencies": { "fill-range": "^7.0.1" }, @@ -452,22 +484,6 @@ "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" - }, - "node_modules/busboy": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", - "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", - "dependencies": { - "streamsearch": "^1.1.0" - }, - "engines": { - "node": ">=10.16.0" - } - }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -529,6 +545,7 @@ "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, "funding": [ { "type": "individual", @@ -573,21 +590,8 @@ "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" - }, - "node_modules/concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "engines": [ - "node >= 0.8" - ], - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true }, "node_modules/content-disposition": { "version": "0.5.4", @@ -616,36 +620,11 @@ "node": ">= 0.6" } }, - "node_modules/cookie-parser": { - "version": "1.4.6", - "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.6.tgz", - "integrity": "sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA==", - "dependencies": { - "cookie": "0.4.1", - "cookie-signature": "1.0.6" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/cookie-parser/node_modules/cookie": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", - "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==", - "engines": { - "node": ">= 0.6" - } - }, "node_modules/cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" - }, "node_modules/create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", @@ -898,6 +877,7 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, "dependencies": { "to-regex-range": "^5.0.1" }, @@ -974,6 +954,7 @@ "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, "hasInstallScript": true, "optional": true, "os": [ @@ -1051,6 +1032,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, "dependencies": { "is-glob": "^4.0.1" }, @@ -1167,6 +1149,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, "engines": { "node": ">=4" } @@ -1295,7 +1278,8 @@ "node_modules/ignore-by-default": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", - "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==" + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", + "dev": true }, "node_modules/inherits": { "version": "2.0.4", @@ -1314,6 +1298,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, "dependencies": { "binary-extensions": "^2.0.0" }, @@ -1325,6 +1310,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -1333,6 +1319,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, "dependencies": { "is-extglob": "^2.1.1" }, @@ -1344,6 +1331,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, "engines": { "node": ">=0.12.0" } @@ -1364,11 +1352,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" - }, "node_modules/json-bigint": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", @@ -1377,86 +1360,6 @@ "bignumber.js": "^9.0.0" } }, - "node_modules/jsonwebtoken": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", - "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", - "dependencies": { - "jws": "^3.2.2", - "lodash.includes": "^4.3.0", - "lodash.isboolean": "^3.0.3", - "lodash.isinteger": "^4.0.4", - "lodash.isnumber": "^3.0.3", - "lodash.isplainobject": "^4.0.6", - "lodash.isstring": "^4.0.1", - "lodash.once": "^4.0.0", - "ms": "^2.1.1", - "semver": "^7.5.4" - }, - "engines": { - "node": ">=12", - "npm": ">=6" - } - }, - "node_modules/jsonwebtoken/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "node_modules/jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", - "dependencies": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "dependencies": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/lodash.includes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", - "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" - }, - "node_modules/lodash.isboolean": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", - "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" - }, - "node_modules/lodash.isinteger": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", - "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" - }, - "node_modules/lodash.isnumber": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", - "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" - }, - "node_modules/lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" - }, - "node_modules/lodash.isstring": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" - }, - "node_modules/lodash.once": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" - }, "node_modules/long": { "version": "5.2.3", "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", @@ -1466,6 +1369,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, "dependencies": { "yallist": "^4.0.0" }, @@ -1534,6 +1438,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -1541,47 +1446,11 @@ "node": "*" } }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, "node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, - "node_modules/multer": { - "version": "1.4.5-lts.1", - "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.5-lts.1.tgz", - "integrity": "sha512-ywPWvcDMeH+z9gQq5qYHCCy+ethsk4goepZ45GLD63fOu0YcNecQxi64nDs3qluZB+murG3/D4dJ7+dGctcCQQ==", - "dependencies": { - "append-field": "^1.0.0", - "busboy": "^1.0.0", - "concat-stream": "^1.5.2", - "mkdirp": "^0.5.4", - "object-assign": "^4.1.1", - "type-is": "^1.6.4", - "xtend": "^4.0.0" - }, - "engines": { - "node": ">= 6.0.0" - } - }, "node_modules/mysql2": { "version": "3.6.5", "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.6.5.tgz", @@ -1665,18 +1534,11 @@ } } }, - "node_modules/nodemailer": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.7.tgz", - "integrity": "sha512-rUtR77ksqex/eZRLmQ21LKVH5nAAsVicAtAYudK7JgwenEDZ0UIQ1adUGqErz7sMkWYxWTTU1aeP2Jga6WQyJw==", - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/nodemon": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.0.2.tgz", "integrity": "sha512-9qIN2LNTrEzpOPBaWHTm4Asy1LxXLSickZStAQ4IZe7zsoIpD/A7LWxhZV3t4Zu352uBcqVnRsDXSMR2Sc3lTA==", + "dev": true, "dependencies": { "chokidar": "^3.5.2", "debug": "^4", @@ -1704,6 +1566,7 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, "dependencies": { "ms": "2.1.2" }, @@ -1719,12 +1582,14 @@ "node_modules/nodemon/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true }, "node_modules/nopt": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", + "dev": true, "dependencies": { "abbrev": "1" }, @@ -1739,6 +1604,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -1754,14 +1620,6 @@ "url": "https://github.com/fb55/nth-check?sponsor=1" } }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/object-inspect": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", @@ -1821,6 +1679,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, "engines": { "node": ">=8.6" }, @@ -1828,11 +1687,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -1853,7 +1707,8 @@ "node_modules/pstree.remy": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", - "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==" + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true }, "node_modules/qs": { "version": "6.11.0", @@ -1899,29 +1754,11 @@ "node": ">= 0.8" } }, - "node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/readable-stream/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, "dependencies": { "picomatch": "^2.2.1" }, @@ -1970,6 +1807,7 @@ "version": "7.5.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, "dependencies": { "lru-cache": "^6.0.0" }, @@ -2063,6 +1901,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", + "dev": true, "dependencies": { "semver": "^7.5.3" }, @@ -2086,31 +1925,11 @@ "node": ">= 0.8" } }, - "node_modules/streamsearch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", - "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/string_decoder/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, "dependencies": { "has-flag": "^3.0.0" }, @@ -2122,6 +1941,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, "dependencies": { "is-number": "^7.0.0" }, @@ -2141,6 +1961,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dev": true, "dependencies": { "nopt": "~1.0.10" }, @@ -2208,17 +2029,11 @@ "node": ">= 0.6" } }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" - }, "node_modules/typescript": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.2.tgz", "integrity": "sha512-6l+RyNy7oAHDfxC4FzSJcz9vnjTKxrLpDG5M2Vu4SHRVNg6xzqZp6LYSR9zjqQTu8DU/f5xwxUdADOkbrIX2gQ==", "dev": true, - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -2230,13 +2045,13 @@ "node_modules/undefsafe": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", - "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==" + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "dev": true }, "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" }, "node_modules/unpipe": { "version": "1.0.0", @@ -2251,11 +2066,6 @@ "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", "integrity": "sha512-XdVKMF4SJ0nP/O7XIPB0JwAEuT9lDIYnNsK8yGVe43y0AWoKeJNdv3ZNWh7ksJ6KqQFjOO6ox/VEitLnaVNufw==" }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", @@ -2304,14 +2114,6 @@ "webidl-conversions": "^3.0.0" } }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "engines": { - "node": ">=0.4" - } - }, "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", @@ -2423,11 +2225,15 @@ "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", "dev": true }, + "@types/bcryptjs": { + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/@types/bcryptjs/-/bcryptjs-2.4.6.tgz", + "integrity": "sha512-9xlo6R2qDs5uixm0bcIqCeMCE6HiQsIyel9KQySStiyqNl2tnj2mP3DX1Nf56MD6KMenNNlBBsy3LJ7gUEQPXQ==" + }, "@types/body-parser": { "version": "1.19.5", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", - "dev": true, "requires": { "@types/connect": "*", "@types/node": "*" @@ -2437,16 +2243,30 @@ "version": "3.4.38", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", - "dev": true, "requires": { "@types/node": "*" } }, + "@types/cookie-parser": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/@types/cookie-parser/-/cookie-parser-1.4.6.tgz", + "integrity": "sha512-KoooCrD56qlLskXPLGUiJxOMnv5l/8m7cQD2OxJ73NPMhuSz9PmvwRD6EpjDyKBVrdJDdQ4bQK7JFNHnNmax0w==", + "requires": { + "@types/express": "*" + } + }, + "@types/dotenv": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/@types/dotenv/-/dotenv-8.2.0.tgz", + "integrity": "sha512-ylSC9GhfRH7m1EUXBXofhgx4lUWmFeQDINW5oLuS+gxWdfUeW4zJdeVTYVkexEW+e2VUvlZR2kGnGGipAWR7kw==", + "requires": { + "dotenv": "*" + } + }, "@types/express": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", - "dev": true, "requires": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.33", @@ -2458,7 +2278,6 @@ "version": "4.17.41", "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz", "integrity": "sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==", - "dev": true, "requires": { "@types/node": "*", "@types/qs": "*", @@ -2469,41 +2288,59 @@ "@types/http-errors": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", - "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", - "dev": true + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" + }, + "@types/jsonwebtoken": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.5.tgz", + "integrity": "sha512-VRLSGzik+Unrup6BsouBeHsf4d1hOEgYWTm/7Nmw1sXoN1+tRly/Gy/po3yeahnP4jfnQWWAhQAqcNfH7ngOkA==", + "requires": { + "@types/node": "*" + } }, "@types/mime": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", - "dev": true + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" + }, + "@types/multer": { + "version": "1.4.11", + "resolved": "https://registry.npmjs.org/@types/multer/-/multer-1.4.11.tgz", + "integrity": "sha512-svK240gr6LVWvv3YGyhLlA+6LRRWA4mnGIU7RcNmgjBYFl6665wcXrRfxGp5tEPVHUNm5FMcmq7too9bxCwX/w==", + "requires": { + "@types/express": "*" + } }, "@types/node": { "version": "20.10.3", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.3.tgz", "integrity": "sha512-XJavIpZqiXID5Yxnxv3RUDKTN5b81ddNC3ecsA0SoFXz/QU8OGBwZGMomiq0zw+uuqbL/krztv/DINAQ/EV4gg==", - "dev": true, "requires": { "undici-types": "~5.26.4" } }, + "@types/nodemailer": { + "version": "6.4.14", + "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-6.4.14.tgz", + "integrity": "sha512-fUWthHO9k9DSdPCSPRqcu6TWhYyxTBg382vlNIttSe9M7XfsT06y0f24KHXtbnijPGGRIcVvdKHTNikOI6qiHA==", + "requires": { + "@types/node": "*" + } + }, "@types/qs": { "version": "6.9.10", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.10.tgz", - "integrity": "sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw==", - "dev": true + "integrity": "sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw==" }, "@types/range-parser": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", - "dev": true + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" }, "@types/send": { "version": "0.17.4", "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", - "dev": true, "requires": { "@types/mime": "^1", "@types/node": "*" @@ -2513,7 +2350,6 @@ "version": "1.15.5", "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", - "dev": true, "requires": { "@types/http-errors": "*", "@types/mime": "*", @@ -2523,7 +2359,8 @@ "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true }, "accepts": { "version": "1.3.8", @@ -2573,16 +2410,12 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, "requires": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, - "append-field": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", - "integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==" - }, "arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", @@ -2612,18 +2445,14 @@ "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true }, "base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" }, - "bcryptjs": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", - "integrity": "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==" - }, "bignumber.js": { "version": "9.1.2", "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", @@ -2632,7 +2461,8 @@ "binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true }, "body-parser": { "version": "1.20.1", @@ -2662,6 +2492,7 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -2671,6 +2502,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, "requires": { "fill-range": "^7.0.1" } @@ -2680,19 +2512,6 @@ "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" - }, - "busboy": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", - "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", - "requires": { - "streamsearch": "^1.1.0" - } - }, "bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -2739,6 +2558,7 @@ "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, "requires": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -2766,18 +2586,8 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true }, "content-disposition": { "version": "0.5.4", @@ -2797,32 +2607,11 @@ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" }, - "cookie-parser": { - "version": "1.4.6", - "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.6.tgz", - "integrity": "sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA==", - "requires": { - "cookie": "0.4.1", - "cookie-signature": "1.0.6" - }, - "dependencies": { - "cookie": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", - "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==" - } - } - }, "cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, - "core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" - }, "create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", @@ -3008,6 +2797,7 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, "requires": { "to-regex-range": "^5.0.1" } @@ -3055,6 +2845,7 @@ "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, "optional": true }, "function-bind": { @@ -3110,6 +2901,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, "requires": { "is-glob": "^4.0.1" } @@ -3211,7 +3003,8 @@ "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true }, "has-property-descriptors": { "version": "1.0.1", @@ -3297,7 +3090,8 @@ "ignore-by-default": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", - "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==" + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", + "dev": true }, "inherits": { "version": "2.0.4", @@ -3313,6 +3107,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, "requires": { "binary-extensions": "^2.0.0" } @@ -3320,12 +3115,14 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true }, "is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, "requires": { "is-extglob": "^2.1.1" } @@ -3333,7 +3130,8 @@ "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true }, "is-property": { "version": "1.0.2", @@ -3345,11 +3143,6 @@ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==" }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" - }, "json-bigint": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", @@ -3358,84 +3151,6 @@ "bignumber.js": "^9.0.0" } }, - "jsonwebtoken": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", - "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", - "requires": { - "jws": "^3.2.2", - "lodash.includes": "^4.3.0", - "lodash.isboolean": "^3.0.3", - "lodash.isinteger": "^4.0.4", - "lodash.isnumber": "^3.0.3", - "lodash.isplainobject": "^4.0.6", - "lodash.isstring": "^4.0.1", - "lodash.once": "^4.0.0", - "ms": "^2.1.1", - "semver": "^7.5.4" - }, - "dependencies": { - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - } - } - }, - "jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "requires": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "lodash.includes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", - "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" - }, - "lodash.isboolean": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", - "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" - }, - "lodash.isinteger": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", - "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" - }, - "lodash.isnumber": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", - "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" - }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" - }, - "lodash.isstring": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" - }, - "lodash.once": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" - }, "long": { "version": "5.2.3", "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", @@ -3445,6 +3160,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, "requires": { "yallist": "^4.0.0" } @@ -3492,42 +3208,16 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, "requires": { "brace-expansion": "^1.1.7" } }, - "minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==" - }, - "mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "requires": { - "minimist": "^1.2.6" - } - }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, - "multer": { - "version": "1.4.5-lts.1", - "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.5-lts.1.tgz", - "integrity": "sha512-ywPWvcDMeH+z9gQq5qYHCCy+ethsk4goepZ45GLD63fOu0YcNecQxi64nDs3qluZB+murG3/D4dJ7+dGctcCQQ==", - "requires": { - "append-field": "^1.0.0", - "busboy": "^1.0.0", - "concat-stream": "^1.5.2", - "mkdirp": "^0.5.4", - "object-assign": "^4.1.1", - "type-is": "^1.6.4", - "xtend": "^4.0.0" - } - }, "mysql2": { "version": "3.6.5", "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.6.5.tgz", @@ -3586,15 +3276,11 @@ "whatwg-url": "^5.0.0" } }, - "nodemailer": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.7.tgz", - "integrity": "sha512-rUtR77ksqex/eZRLmQ21LKVH5nAAsVicAtAYudK7JgwenEDZ0UIQ1adUGqErz7sMkWYxWTTU1aeP2Jga6WQyJw==" - }, "nodemon": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.0.2.tgz", "integrity": "sha512-9qIN2LNTrEzpOPBaWHTm4Asy1LxXLSickZStAQ4IZe7zsoIpD/A7LWxhZV3t4Zu352uBcqVnRsDXSMR2Sc3lTA==", + "dev": true, "requires": { "chokidar": "^3.5.2", "debug": "^4", @@ -3612,6 +3298,7 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, "requires": { "ms": "2.1.2" } @@ -3619,7 +3306,8 @@ "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true } } }, @@ -3627,6 +3315,7 @@ "version": "1.0.10", "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", + "dev": true, "requires": { "abbrev": "1" } @@ -3634,7 +3323,8 @@ "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true }, "nth-check": { "version": "2.1.1", @@ -3644,11 +3334,6 @@ "boolbase": "^1.0.0" } }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" - }, "object-inspect": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", @@ -3692,12 +3377,8 @@ "picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true }, "proxy-addr": { "version": "2.0.7", @@ -3716,7 +3397,8 @@ "pstree.remy": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", - "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==" + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true }, "qs": { "version": "6.11.0", @@ -3747,31 +3429,11 @@ "unpipe": "1.0.0" } }, - "readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - } - } - }, "readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, "requires": { "picomatch": "^2.2.1" } @@ -3803,6 +3465,7 @@ "version": "7.5.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, "requires": { "lru-cache": "^6.0.0" } @@ -3880,6 +3543,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", + "dev": true, "requires": { "semver": "^7.5.3" } @@ -3894,30 +3558,11 @@ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" }, - "streamsearch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", - "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==" - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - } - } - }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, "requires": { "has-flag": "^3.0.0" } @@ -3926,6 +3571,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, "requires": { "is-number": "^7.0.0" } @@ -3939,6 +3585,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dev": true, "requires": { "nopt": "~1.0.10" } @@ -3978,28 +3625,22 @@ "mime-types": "~2.1.24" } }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" - }, "typescript": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.2.tgz", "integrity": "sha512-6l+RyNy7oAHDfxC4FzSJcz9vnjTKxrLpDG5M2Vu4SHRVNg6xzqZp6LYSR9zjqQTu8DU/f5xwxUdADOkbrIX2gQ==", - "dev": true, - "peer": true + "dev": true }, "undefsafe": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", - "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==" + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "dev": true }, "undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" }, "unpipe": { "version": "1.0.0", @@ -4011,11 +3652,6 @@ "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", "integrity": "sha512-XdVKMF4SJ0nP/O7XIPB0JwAEuT9lDIYnNsK8yGVe43y0AWoKeJNdv3ZNWh7ksJ6KqQFjOO6ox/VEitLnaVNufw==" }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, "utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", @@ -4051,11 +3687,6 @@ "webidl-conversions": "^3.0.0" } }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" - }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", diff --git a/package.json b/package.json index e979728..580109d 100644 --- a/package.json +++ b/package.json @@ -6,29 +6,32 @@ "type": "module", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", - "start": "nodemon app.js" + "dev": "nodemon app.ts", + "type": "ts-node --esm app.ts", + "start": "node ./build/app.js" }, "author": "", "license": "ISC", "dependencies": { + "@types/bcryptjs": "^2.4.6", + "@types/cookie-parser": "^1.4.6", + "@types/dotenv": "^8.2.0", + "@types/jsonwebtoken": "^9.0.5", + "@types/multer": "^1.4.11", + "@types/nodemailer": "^6.4.14", "axios": "^1.6.2", - "bcryptjs": "^2.4.3", "cheerio": "^1.0.0-rc.12", - "cookie-parser": "^1.4.6", - "dotenv": "^16.3.1", "express": "^4.18.2", "googleapis": "^129.0.0", - "jsonwebtoken": "^9.0.2", - "multer": "^1.4.5-lts.1", "mysql2": "^3.6.5", - "nodemailer": "^6.9.7", - "nodemon": "^3.0.2", "rand-token": "^1.0.1", "redis": "^4.6.11" }, "devDependencies": { "@types/express": "^4.17.21", "@types/node": "^20.10.3", - "ts-node": "^10.9.1" + "nodemon": "^3.0.2", + "ts-node": "^10.9.1", + "typescript": "^5.3.2" } } diff --git a/routes/userRoute.ts b/routes/userRoute.ts new file mode 100644 index 0000000..ca5f5c9 --- /dev/null +++ b/routes/userRoute.ts @@ -0,0 +1,16 @@ +import express from "express"; +export const router = express.Router(); +import * as mid from "../middleware/usermiddle.js"; +import * as controller from "../controllers/userController.js"; + +router.get("/register",mid.verifyEmail, controller.signup); +router.get("/get", mid.checkAuth, controller.getuser); +router.get("/list/:page", controller.userlist); +router.post("/auth/signin",mid.loginMiddileware, controller.signin); +router.post("/address", mid.checkAuth, controller.user_address); +router.put("/changePassword", mid.checkAuth, controller.changePass); +router.put("/verify-reset-password", mid.checkAuth, controller.forgetPass); +router.put("/updateuser", mid.checkAuth, controller.updateuser); +router.put("/delete", mid.checkAuth, controller.deluser); +router.post("/forgot-password", controller.verifyuser); +router.put("/profile-image", mid.upload, controller.profileImg); \ No newline at end of file diff --git a/services/userservices.js b/services/userservices.js deleted file mode 100644 index 84f9d3a..0000000 --- a/services/userservices.js +++ /dev/null @@ -1,310 +0,0 @@ -import config from "../config/constant.js"; -// const { User,userToken,address } = require("../models"); -import {con} from "../config/dbconnect.js" -import { client } from "../config/redisconfig.js" -import { google } from "googleapis" -import jwt from "jsonwebtoken" -import bcrypt from "bcryptjs" -import nodemailer from "nodemailer" -import axios from "axios" -import Cheerio from "cheerio" -import randToken from "rand-token" - -const oAuth2Client = new google.auth.OAuth2(config.CLIENT_ID,config.CLIENT_SECERET,config.REDIRECT_URI) -oAuth2Client.setCredentials({ refresh_token:config.REFRESH_TOKEN }) - -const accessToken = async () => { - const accesstoken = await oAuth2Client.getAccessToken(); - return accesstoken -} - -const transport = nodemailer.createTransport({ - service:'gmail', - auth: { - type: 'OAuth2', - user: config.USER, - clientId: config.CLIENT_ID, - clientSecret: config.CLIENT_SECERET, - refreshToken: config.REFRESH_TOKEN, - accessToken: accessToken() - }, -}); - -export const getdata = async (id) => { - try { - return await con.findOne({ include: address }, { where: { id: id } }); - } catch (error) { - console.error("Error retrieving data:", error); - throw error; - } -}; - -export const deleteuser = async (id) => { -// const data = await User.destroy({where:{id: id}},{ -// include: [{ -// model: address, -// where: { user_id: id }, -// }] -// });/ -const data = await address.destroy({where:{user_id: id}},{ - include: [{ - model: User, - where: { id: id }, -}] -}); - -await User.destroy({where:{id: id}}) - if (data) { - return true; - } -}; - -export const updateuser1 = async (email, body_data) => { - await User.update(body_data,{where:{email}}); -}; - -export const matchpass = async (data) => { - return data.password === data.new_password; -}; - -export const verifyemail = async (data) => { - const emailexist = await User.findOne({where: {email: data.email}}); - - if (emailexist) { - const token = jwt.sign( - { email: emailexist.email,id:emailexist._id,username:emailexist.username }, - config.ACCESS_TOKEN_SECRET, - { expiresIn: config.FPASS_EXPIRESIN } - ); - - const mailOption = { - from: config.EMAIL_FROM, - to: "ernitish26@gmail.com", - subject: "Password Reset Link", - html: `${token}`, - }; - transport.sendMail(mailOption); - return token; - } else { - return false; - } -}; - -export const modifyPass = async (email, data) => { - await User.update({password: data.password}, - { - where:{email} - } - ); - const mailOption = { - from: config.EMAIL_FROM, - to: "ernitish26@gmail.com", - subject: "Password Reset", - text: "Password Reset successfully", - }; - transport.sendMail(mailOption); -}; - -export const userlogin = async (data) => { - const userData = await User.findOne({ where: { email: data.email } }); - const pass = bcrypt.compare(userData.password, data.password); - - if (pass && userData) { - const accessToken = jwt.sign( - { email: userData.email, id: userData.id }, - config.ACCESS_TOKEN_SECRET, - { expiresIn: config.ACCESS_TOKEN_EXPIRES } - ); - const refreshToken = randToken.uid(256); - - await userToken.create({ - user_id: userData.id, - token: accessToken, - expiry: config.JWT_EXPIRES_IN, - }); - - await client.hSet(refreshToken, { - id: userData.id, - email: userData.email, - username:userData.username - }); - return { accessToken, refreshToken }; - } else { - return false; - } -}; - -export const usersignup = async (data) => { - - const user = await con.query(`INSERT INTO users VALUES(data)`); - - if (user) { - const mailOption = { - from: config.EMAIL_FROM, - to: 'rajaryan232326@gmail.com', - subject: "Registration", - text: "Registeration successful", - }; - transport.sendMail(mailOption); - return user; - } else { - return false; - } -}; - -export const user_list = async (page) => { - const firstindex = (page - 1) * 10; - const lastindex = page * 10; - const data = await User.findAll(); - const sliced_data = data.slice(firstindex, lastindex); - return sliced_data; -}; - -export const useraddress = async (data, ID) => { - try { - address.sync(); - let userAdd = await address.create({ - user_id: ID, - address: data.address, - city: data.city, - state: data.state, - pin_code: data.pin_code, - phone: data.phone, - }); - return userAdd; - } catch (error) { - console.error(error); - } -}; - -export const flipkart = async () => { - const movie = []; - try { - await axios.get(config.URL).then((response) => { - let $ = Cheerio.load(response.data); - $("._2n7i6c").each(function (el, index) { - const name = $(this).find("a._2rpwqI").attr("title"); - const price = $(this).find("div._30jeq3").text(); - const link = $(this).find("a.s1Q9rs").attr("href"); - const rating = $(this).find("div._3LWZlK").text(); - const discount = $(this).find("div._3Ay6Sb").text().split(" ")[0]; - - movie.push({ - product_name: name, - price: price, - rating: rating, - discount: discount, - link: link, - }); - }); - }); - } catch (error) { - console.log(error); - } - return movie; -}; - -// Function to scrape the category page and get product URLs -export async function scrapeCategoryPage(categoryUrl) { - try { - const response = await axios.get(categoryUrl); - const productUrls = []; - - const $ = Cheerio.load(response.data); - - $("a.s1Q9rs").each((index, element) => { - const productUrl = $(element).attr("href"); - productUrls.push(productUrl); - console.log(productUrls); - }); - - return productUrls; - } catch (error) { - console.error("Error scraping category page:", error.message); - throw error; - } -} - -export const flipkartAll = async () => { - const movie = []; - try { - await axios.get(config.URL1).then((response) => { - let $ = Cheerio.load(response.data); - $("._2kHMtA").each(function (el, index) { - const name = $(this).find("._4rR01T").text(); - const productUrl = $(this).find("a._1fQZEK").attr("href"); - - movie.push({ product_name: name, link: productUrl }); - }); - }); - } catch (error) { - console.log(error); - } - return movie; -}; - -export const snapdeal = async () => { - const Tshirt = []; - try { - await axios.get(config.snapURL).then((response) => { - let $ = Cheerio.load(response.data); - $(".favDp.product-tuple-listing.js-tuple").each(function (el, index) { - const name = $(this).find("p.product-title").attr("title"); - const price = $(this).find("span.product-price").text(); - const link = $(this).find("a.dp-widget-link").attr("href"); - const image = $(this).find("img.product-image").attr("src"); - const discount = $(this) - .find(".product-discount span") - .text() - .split(" ")[0]; - Tshirt.push({ - product_name: name, - image: image, - price: price, - discount: discount, - link: link, - }); - console.log(Tshirt); - }); - }); - } catch (error) { - console.log(error); - } - return Tshirt; -}; -export const findByAggregate = async () => { - //projection - const data = await DummyData.aggregate([ - { $match: { country: "Vietnam" } }, - { $project: { _id: 0, name: 1, email: 1 } }, - ]); - - /* Skip & Sort Aggregate - const d = await DummyData.aggregate([ - {$group: { _id: '$country'}}, - {$sort: { _id:1 }} // 1 for ascending and 2 for descending - ]) - - const data = await DummyData.aggregate([ - {$count:'total'} - ]) -*/ - return data; -}; - -export const generateToken = async (userData) => { - - const accessToken = jwt.sign( - { email: userData.email, id: userData.id }, - config.ACCESS_TOKEN_SECRET, - { expiresIn: config.ACCESS_TOKEN_EXPIRES } - ); - const refreshToken = randToken.uid(256); - await client.hSet(refreshToken, { - id: userData.id, - email: userData.email, - username:userData.username - }); - - return { accessToken, refreshToken }; -}; \ No newline at end of file diff --git a/services/userservices.ts b/services/userservices.ts new file mode 100644 index 0000000..21b1993 --- /dev/null +++ b/services/userservices.ts @@ -0,0 +1,225 @@ +import config from "../config/constant.js"; +import { con } from "../config/dbconnect.js"; +import { client } from "../config/redisconfig.js"; +import { google } from "googleapis"; +import jwt, { Secret } from "jsonwebtoken"; +import nodemailer from "nodemailer"; +import randToken from "rand-token"; +import { mailInterface, user, user_address } from "../interfaces.td.js"; +import { RowDataPacket } from "mysql2"; + +function verifyEmailF(email: string) { + return new Promise((res, rej) => { + con.query( + `SELECT * FROM users WHERE email=${email}`, + function (err, result) { + if (err) rej(err); + res(result); + } + ); + }); +} + +const oAuth2Client = new google.auth.OAuth2( + config.CLIENT_ID, + config.CLIENT_SECERET, + config.REDIRECT_URI +); +oAuth2Client.setCredentials({ refresh_token: config.REFRESH_TOKEN }); + +const accessToken = async () => { + const accesstoken = await oAuth2Client.getAccessToken(); + return accesstoken; +}; + +const transport = nodemailer.createTransport({ + service: "gmail", + auth: { + type: "OAUTH2", + user: config.USER, + clientId: config.CLIENT_ID, + clientSecret: config.CLIENT_SECERET, + refreshToken: config.REFRESH_TOKEN, + accessToken: accessToken as unknown as string, + }, +}); + +export const sendEmail = (option:mailInterface)=>{ + const mailOption = { + from: config.EMAIL_FROM, + to: option.to, + subject: option.subject, + text: option.text, + html: `${option.link}`, + }; + transport.sendMail(mailOption); +} + +export const getdata = async (id: string) => { + try { + return await con.query( + "SELECT * FROM addresses INNER JOIN users ON addresses.user_id=?", + id, + function (err, result) { + if (err) { + console.error(err); + } else { + return result; + } + } + ); + } catch (error) { + console.error("Error retrieving data:", error); + } +}; + +export const deleteuser = async (id: string) => { + con.query(`DELETE * FROM users WHERE id='${id}'`); +}; + +export const updateuser1 = async (email: string, body_data: user) => { + await con.query(`UPDATE users SET '${body_data}' WHERE email='${email}'`); +}; + +export const matchpass = async (data: { + password: string; + new_password: string; +}) => { + return data.password === data.new_password; +}; + +export const verifyemail = async (email: string) => { + // con.query(`SELECT * FROM users WHERE email=${email}`, function (err, result) { + // if (err) throw err; + // console.log("Result: " + result); + // emailexist = result; + // }); + + const emailexist: any = verifyEmailF(email).catch(console.error); + console.log(emailexist, "emailexistemailexist"); + if (emailexist) { + const token = jwt.sign( + { + email: emailexist.email, + id: emailexist.id, + username: emailexist.username, + }, + config.ACCESS_TOKEN_SECRET as jwt.Secret, + { expiresIn: config.FPASS_EXPIRESIN } + ); + + return token; + } else { + return false; + } +}; + + +export const modifyPass = async (email: string, password: string) => { + con.query("UPDATE users SET password= ? WHERE email = ?", [password, email]); +}; + +export const fetchUserData = async (email: string): Promise => { + try { + const userData: user = await new Promise((rej, res) => { + con.query( + `SELECT * FROM users WHERE email= '${email}'`, + (err: any, result: RowDataPacket) => { + if (err) rej(err); + res(result ? result[0] : null); + } + ); + }); + console.log(userData); + return userData as user; + } catch (error) { + console.log(error); + return null; + } +}; + +export const token = async (userData: { + id: string; + username: string; + email: string; +}) => { + const accessToken = jwt.sign( + { email: userData.email, id: userData.id, username: userData.username }, + config.ACCESS_TOKEN_SECRET as jwt.Secret, + { expiresIn: config.ACCESS_TOKEN_EXPIRES } + ); + const refreshToken = randToken.uid(256); + + // code for redis to store refresh token + + await client.hSet(refreshToken, { + id: userData.id, + email: userData.email, + username: userData.username, + }); + return { accessToken, refreshToken }; +}; + +export const usersignup = (data: user) => { + try { + con.query(`INSERT INTO users VALUES('${data}')`, data, (err, result) => { + if (err) throw err; + console.log(result); + }); + + const mailOption = { + from: config.EMAIL_FROM, + to: "rajaryan232326@gmail.com", + subject: "Registration", + text: "Registeration successful", + }; + transport.sendMail(mailOption); + + } catch (error) { + return error; + } +}; + +export const user_list = async (page: number) => { + const firstindex = (page - 1) * 10; + const lastindex = page * 10; + await con.query("SELECT * FROM users", function (err, result) { + if (err) { + console.error(err); + } else { + let data = result; + } + }); +}; + +export const useraddress = async (data: user_address, ID: string) => { + try { + con.query(`INSERT INTO addresses VALUES( + ${ID}, + ${data.address}, + ${data.city}, + ${data.state}, + ${data.pin_code}, + ${data.phone}, + )`) + + } catch (error) { + console.error(error); + } +}; + +export const generateToken = async (userData:{email:string,id:string,username:string}) => { + const accessToken = jwt.sign( + { email: userData.email, id: userData.id }, + config.ACCESS_TOKEN_SECRET as jwt.Secret, + { expiresIn: config.ACCESS_TOKEN_EXPIRES } + ); + const refreshToken = randToken.uid(256); + await client.hSet(refreshToken, { + id: userData.id, + email: userData.email, + username: userData.username, + }); + + return { accessToken, refreshToken }; +}; diff --git a/tsconfig.json b/tsconfig.json index e075f97..34eaebd 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -25,9 +25,9 @@ // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ /* Modules */ - "module": "commonjs", /* Specify what module code is generated. */ - // "rootDir": "./", /* Specify the root folder within your source files. */ - // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ + "module": "ES6", /* Specify what module code is generated. */ + "rootDir": "", /* Specify the root folder within your source files. */ + "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ @@ -55,7 +55,7 @@ // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ // "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. */ - // "outDir": "./", /* Specify an output folder for all emitted files. */ + "outDir": "./build", /* Specify an output folder for all emitted files. */ // "removeComments": true, /* Disable emitting comments. */ // "noEmit": true, /* Disable emitting files from a compilation. */ // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */