chore: add otp based login
This commit is contained in:
@@ -13,7 +13,7 @@ jobs:
|
||||
DANAK_SERVER: "https://captain.run.danakcorp.com"
|
||||
APP_TOKEN: 5a2526d13383aa8c4c3e6019352b96cf81e84b7b781e80c2b8012eaf5e2e69fd
|
||||
CAPROVER_APP_NAME: ostandari
|
||||
GITHUB_TOKEN: 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
|
||||
GITHUB_TOKEN: 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
|
||||
|
||||
steps:
|
||||
- name: Check out repositorys
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
# Use the official Node.js image as a base
|
||||
FROM node:20-alpine
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY package*.json ./
|
||||
|
||||
RUN npm install
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN mkdir -p /app/.nuxt && chown -R node:node /app
|
||||
|
||||
USER node
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
CMD ["npm", "run", "dev"]
|
||||
@@ -0,0 +1,18 @@
|
||||
services:
|
||||
app:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.dev
|
||||
container_name: ostandari-dev
|
||||
# working_dir: /app
|
||||
volumes:
|
||||
- .:/app
|
||||
- /app/node_modules
|
||||
ports:
|
||||
- "3000:3000"
|
||||
command: ["npm", "run", "dev"]
|
||||
environment:
|
||||
NODE_ENV: development
|
||||
|
||||
volumes:
|
||||
mongo_data:
|
||||
Generated
+41
-3
@@ -29,6 +29,7 @@
|
||||
"element-ui": "^2.15.1",
|
||||
"express": "^4.17.1",
|
||||
"express-fileupload": "^1.2.1",
|
||||
"express-rate-limit": "^7.4.1",
|
||||
"express-validator": "^6.10.1",
|
||||
"gsap": "^3.6.1",
|
||||
"jquery": "^3.7.1",
|
||||
@@ -39,6 +40,7 @@
|
||||
"mongoose": "^5.12.5",
|
||||
"mongoose-paginate-v2": "^1.3.18",
|
||||
"morgan": "^1.10.0",
|
||||
"node-cache": "^5.1.2",
|
||||
"nodemailer": "^6.6.0",
|
||||
"nodemon": "^3.1.2",
|
||||
"nuxt": "^2.15.3",
|
||||
@@ -7333,6 +7335,15 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/clone": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
|
||||
"integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/code-point-at": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
|
||||
@@ -8840,9 +8851,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/elliptic": {
|
||||
"version": "6.5.7",
|
||||
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.7.tgz",
|
||||
"integrity": "sha512-ESVCtTwiA+XhY3wyh24QqRGBoP3rEdDUl3EDUUo9tft074fi19IrdpH7hLCMMP3CIj7jb3W96rn8lt/BqIlt5Q==",
|
||||
"version": "6.6.1",
|
||||
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.1.tgz",
|
||||
"integrity": "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"bn.js": "^4.11.9",
|
||||
@@ -9379,6 +9390,21 @@
|
||||
"node": ">=12.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/express-rate-limit": {
|
||||
"version": "7.4.1",
|
||||
"resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.4.1.tgz",
|
||||
"integrity": "sha512-KS3efpnpIDVIXopMc65EMbWbUht7qvTCdtCR2dD/IZmi9MIkopYESwyRqLgv8Pfu589+KqDqOdzJWW7AHoACeg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/express-rate-limit"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"express": "4 || 5 || ^5.0.0-beta.1"
|
||||
}
|
||||
},
|
||||
"node_modules/express-validator": {
|
||||
"version": "6.15.0",
|
||||
"resolved": "https://registry.npmjs.org/express-validator/-/express-validator-6.15.0.tgz",
|
||||
@@ -13547,6 +13573,18 @@
|
||||
"devOptional": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/node-cache": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/node-cache/-/node-cache-5.1.2.tgz",
|
||||
"integrity": "sha512-t1QzWwnk4sjLWaQAS8CHgOJ+RAfmHpxFWmc36IWTiWHQfs0w5JDMBS1b1ZxQteo0vVVuWJvIUKHDkkeK7vIGCg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"clone": "2.x"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/node-fetch": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
"element-ui": "^2.15.1",
|
||||
"express": "^4.17.1",
|
||||
"express-fileupload": "^1.2.1",
|
||||
"express-rate-limit": "^7.4.1",
|
||||
"express-validator": "^6.10.1",
|
||||
"gsap": "^3.6.1",
|
||||
"jquery": "^3.7.1",
|
||||
@@ -42,6 +43,7 @@
|
||||
"mongoose": "^5.12.5",
|
||||
"mongoose-paginate-v2": "^1.3.18",
|
||||
"morgan": "^1.10.0",
|
||||
"node-cache": "^5.1.2",
|
||||
"nodemailer": "^6.6.0",
|
||||
"nodemon": "^3.1.2",
|
||||
"nuxt": "^2.15.3",
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
const { validationResult, query } = require("express-validator");
|
||||
const Logger = require("../models/Logger");
|
||||
const { paginationOptions } = require("../plugins/pagination");
|
||||
|
||||
// get admin login logs with optional filtering and pagination
|
||||
module.exports.getAdminLoginLogs = [
|
||||
[
|
||||
query("page")
|
||||
.optional()
|
||||
.isInt({ min: 1 })
|
||||
.withMessage("Page must be a positive integer."),
|
||||
query("limit")
|
||||
.optional()
|
||||
.isInt({ min: 1 })
|
||||
.withMessage("Limit must be a positive integer."),
|
||||
query("sort")
|
||||
.optional()
|
||||
.isIn(["asc", "desc"])
|
||||
.withMessage('Sort must be either "asc" or "desc".'),
|
||||
query("fromDate")
|
||||
.optional()
|
||||
.isISO8601()
|
||||
.withMessage("From date must be a valid date."),
|
||||
query("toDate")
|
||||
.optional()
|
||||
.isISO8601()
|
||||
.withMessage("To date must be a valid date."),
|
||||
],
|
||||
async (req, res) => {
|
||||
const errors = validationResult(req);
|
||||
if (!errors.isEmpty())
|
||||
return res.status(422).json({ validation: errors.mapped() });
|
||||
|
||||
try {
|
||||
const {
|
||||
page = 1,
|
||||
limit = 1000,
|
||||
sort = "desc",
|
||||
fromDate,
|
||||
toDate,
|
||||
} = req?.query;
|
||||
|
||||
const filters = {};
|
||||
if (fromDate) filters.LastLogin = { $gte: new Date(fromDate) };
|
||||
if (toDate)
|
||||
filters.LastLogin = { ...filters.LastLogin, $lte: new Date(toDate) };
|
||||
|
||||
const options = paginationOptions({ page, limit, sort });
|
||||
const logs = await Logger.find(filters)
|
||||
.populate({ path: "user", select: { password: 0 } })
|
||||
.sort({ updated_at: sort === "desc" ? -1 : 1 })
|
||||
.skip(options.skip)
|
||||
.limit(options.limit);
|
||||
|
||||
const totalLogs = await Logger.countDocuments(filters);
|
||||
const totalPages = Math.ceil(totalLogs / options.limit);
|
||||
|
||||
return res.status(200).json({
|
||||
logs: logs.map((log) => {
|
||||
log.LastLogin = new Date(log.LastLogin).toLocaleString("fa-IR", {
|
||||
timeZone: "Asia/Tehran",
|
||||
// hour: "2-digit",
|
||||
// minute: "2-digit",
|
||||
// day: "2-digit",
|
||||
// month: "2-digit",
|
||||
// weekday: "short",
|
||||
// year: "2-digit",
|
||||
// timeZoneName: "long",
|
||||
});
|
||||
return log;
|
||||
}),
|
||||
page: options.page,
|
||||
totalPages,
|
||||
totalLogs,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Error fetching admin login logs:", error);
|
||||
return res.status(500).json({ message: "Server error occurred." });
|
||||
}
|
||||
},
|
||||
];
|
||||
@@ -1,5 +1,6 @@
|
||||
const User = require("../models/User");
|
||||
const { body, validationResult } = require("express-validator");
|
||||
const { rateLimit } = require("express-rate-limit");
|
||||
const bcrypt = require("bcryptjs");
|
||||
const jwt = require("jsonwebtoken");
|
||||
const crypto = require("crypto");
|
||||
@@ -17,6 +18,9 @@ const fs = require("fs");
|
||||
const nodemailer = require("nodemailer");
|
||||
const Category = require("../models/Category");
|
||||
const Logger = require("../models/Logger");
|
||||
const cacheService = require("../plugins/cache");
|
||||
const { sms } = require("../plugins/sms");
|
||||
|
||||
////// variables
|
||||
const profileWidth = 500;
|
||||
const profileHeight = 500;
|
||||
@@ -25,11 +29,19 @@ const hostURL = "localhost:6688";
|
||||
const limit = 20;
|
||||
const select = "-password -token";
|
||||
|
||||
const limiter = rateLimit({
|
||||
windowMs: 10 * 60 * 1000, // 10 minutes
|
||||
limit: 10,
|
||||
standardHeaders: "draft-7",
|
||||
legacyHeaders: false,
|
||||
});
|
||||
|
||||
/** @todo add private to query */
|
||||
|
||||
/** auth --------------------------------------------- */
|
||||
/////////////////////////////////////////////////////////////////////// login
|
||||
module.exports.login = [
|
||||
limiter,
|
||||
[
|
||||
body("username")
|
||||
.if((value, { req }) => {
|
||||
@@ -138,6 +150,170 @@ module.exports.login = [
|
||||
}
|
||||
},
|
||||
];
|
||||
/** otp --------------------------------------------- */
|
||||
/////////////////////////////////////////////////////////////////////// otp
|
||||
module.exports.otp = [
|
||||
limiter,
|
||||
[
|
||||
body("phone")
|
||||
.notEmpty()
|
||||
.withMessage(_sr["fa"].required.phone_number)
|
||||
.bail()
|
||||
.isMobilePhone("fa-IR")
|
||||
.withMessage(_sr["fa"].required.phone_number),
|
||||
// .isLength({ min: 4 })
|
||||
// .withMessage(_sr["fa"].min_char.min4),
|
||||
],
|
||||
async (req, res) => {
|
||||
try {
|
||||
const errors = validationResult(req);
|
||||
if (!errors.isEmpty())
|
||||
return res.status(422).json({ validation: errors.mapped() });
|
||||
|
||||
const { phone } = req.body;
|
||||
const user = await User.findOne({ mobileNumber: phone });
|
||||
if (!user)
|
||||
return res.status(406).json({
|
||||
message: "شماره موبایل نامعتبر می باشد",
|
||||
});
|
||||
const existOtp = cacheService.get(`OTP:LOGIN:${phone}`);
|
||||
if (existOtp)
|
||||
return res.status(400).json({
|
||||
message: "کد به شماره موبایل شما ارسال شده است",
|
||||
ttl: (cacheService.getTtl(`OTP:LOGIN:${phone}`) - Date.now()) / 1000,
|
||||
});
|
||||
const otp = crypto.randomInt(10000, 99999);
|
||||
const message = `کد ورود شما ${otp} میباشد. استانداری لغو11`;
|
||||
/** save otp in cache */
|
||||
cacheService.set(`OTP:LOGIN:${phone}`, otp, 120);
|
||||
/** send sms to user */
|
||||
const smsResult = await sms(phone, message);
|
||||
|
||||
if (!smsResult.IsSuccessful) {
|
||||
console.log(smsResult);
|
||||
return res500(res, `مشکلی در ارسال پیامک پیش آمده است`);
|
||||
}
|
||||
|
||||
return res.status(200).json({
|
||||
message: "کد به شماره موبایل شما ارسال شد",
|
||||
});
|
||||
} catch (error) {
|
||||
return res500(res, error?.message);
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
/////////////////////////////////////////////////////////////////////// verify otp
|
||||
module.exports.verifyOtp = [
|
||||
limiter,
|
||||
[
|
||||
body("phone")
|
||||
.notEmpty()
|
||||
.withMessage(_sr["fa"].required.phone_number)
|
||||
.bail()
|
||||
.isMobilePhone("fa-IR")
|
||||
.withMessage(_sr["fa"].required.phone_number),
|
||||
|
||||
body("code")
|
||||
.notEmpty()
|
||||
.withMessage(_sr["fa"].required.otp_code)
|
||||
.bail()
|
||||
.isLength({ min: 5, max: 5 })
|
||||
.withMessage(_sr["fa"].format.otp_length),
|
||||
],
|
||||
async (req, res) => {
|
||||
try {
|
||||
const errors = validationResult(req);
|
||||
if (!errors.isEmpty())
|
||||
return res.status(422).json({ validation: errors.mapped() });
|
||||
|
||||
const { phone, code } = req.body;
|
||||
|
||||
// Check if the OTP exists in the cache
|
||||
const cachedOtp = cacheService.get(`OTP:LOGIN:${phone}`);
|
||||
if (!cachedOtp) {
|
||||
return res.status(400).json({
|
||||
message: "کد وارد شده منقضی شده است یا نامعتبر میباشد",
|
||||
});
|
||||
}
|
||||
|
||||
// Verify if the provided OTP matches the cached OTP
|
||||
if (cachedOtp.toString() !== code.trim()) {
|
||||
return res.status(422).json({
|
||||
validation: { code: { msg: "کد وارد شده نامعتبر میباشد" } },
|
||||
});
|
||||
}
|
||||
|
||||
// Find the user by phone number
|
||||
const user = await User.findOne({ mobileNumber: phone });
|
||||
if (!user) {
|
||||
return res.status(406).json({
|
||||
message: "شماره موبایل نامعتبر می باشد",
|
||||
});
|
||||
}
|
||||
|
||||
// Check if the user's registration is complete
|
||||
if (!user.registration_done) {
|
||||
return res.status(403).json({
|
||||
message: `اکانت شما غیرفعال می باشد لطفا با ادمین تماس بگیرید`,
|
||||
});
|
||||
}
|
||||
|
||||
// Create or update login logger
|
||||
const logger = await Logger.findOne({ user: user._id });
|
||||
if (logger) {
|
||||
await Logger.findOneAndUpdate(
|
||||
{ user: user._id },
|
||||
{ $set: { LastLogin: new Date() } },
|
||||
{ new: true }
|
||||
);
|
||||
} else {
|
||||
const newLogger = new Logger({
|
||||
user: user,
|
||||
LastLogin: new Date(),
|
||||
});
|
||||
await newLogger.save();
|
||||
}
|
||||
|
||||
// Check if the user already has a valid token
|
||||
if (user.token) {
|
||||
jwt.verify(
|
||||
user.token.replace(/^Bearer\s/, ""),
|
||||
secretKey,
|
||||
async (err, decoded) => {
|
||||
if (err || !decoded) {
|
||||
// Generate a new token if the existing one is invalid
|
||||
const token = await jwt.sign({ _id: user._id }, secretKey, {
|
||||
expiresIn: "2h",
|
||||
});
|
||||
user.token = token;
|
||||
await user.save();
|
||||
// Remove the OTP from the cache
|
||||
cacheService.del(`OTP:LOGIN:${phone}`);
|
||||
return res.json({ token: user.token });
|
||||
} else {
|
||||
// Remove the OTP from the cache
|
||||
cacheService.del(`OTP:LOGIN:${phone}`);
|
||||
return res.json({ token: user.token });
|
||||
}
|
||||
}
|
||||
);
|
||||
} else {
|
||||
// Generate a new token if none exists
|
||||
const token = await jwt.sign({ _id: user._id }, secretKey, {
|
||||
expiresIn: "1h",
|
||||
});
|
||||
user.token = token;
|
||||
await user.save();
|
||||
// Remove the OTP from the cache
|
||||
cacheService.del(`OTP:LOGIN:${phone}`);
|
||||
return res.json({ token: user.token });
|
||||
}
|
||||
} catch (error) {
|
||||
return res500(res, error?.message);
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
/////////////////////////////////////////////////////////////////////// logout
|
||||
module.exports.logout = [
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
|
||||
// const databaseURL = 'mongodb://ostanmri_user:admin1234@localhost:27017/ostanmri_database'
|
||||
const databaseURL =
|
||||
"mongodb://root:f2d63313cc3ed6ff@srv-captain--ostandari-db:27017/ostan_db?authSource=admin";
|
||||
// "mongodb://root:f2d63313cc3ed6ff@srv-captain--ostandari-db:27017/ostan_db?authSource=admin";
|
||||
"mongodb://root:f2d63313cc3ed6ff@danak-db-public.danakcorp.com:50123/ostan_db?authSource=admin";
|
||||
//const databaseURL = 'mongodb://danakcorp:danakcorp%212024@ostan-mr.ir:27017/ostan_db?serverSelectionTimeoutMS=5000&connectTimeoutMS=10000&authSource=admin&authMechanism=SCRAM-SHA-1'
|
||||
|
||||
// const databaseURL = 'mongodb://ostanmri_user:admin1234@91.98.96.174:27017/ostanmri_database?serverSelectionTimeoutMS=5000&connectTimeoutMS=10000&authSource=ostanmri_database'
|
||||
|
||||
+4
-7
@@ -8,7 +8,7 @@ const {
|
||||
isLoggedIn,
|
||||
hasPermission,
|
||||
} = require("./authentication");
|
||||
const bodyParser = require("body-parser");
|
||||
// const bodyParser = require("body-parser");
|
||||
const cronJobs = require("./plugins/cronJobs");
|
||||
const swaggerJsdoc = require("swagger-jsdoc");
|
||||
const cors = require("cors");
|
||||
@@ -66,10 +66,11 @@ const options = {
|
||||
apis: ["./server/routes/*.js"],
|
||||
};
|
||||
|
||||
// const specs = swaggerJsdoc(options);
|
||||
const specs = swaggerJsdoc(options);
|
||||
|
||||
cronJobs();
|
||||
createAdmins();
|
||||
|
||||
const corsOptions = {
|
||||
origin: "*",
|
||||
credentials: true,
|
||||
@@ -81,11 +82,7 @@ app.use(express.json());
|
||||
app.use(express.urlencoded({ extended: true }));
|
||||
app.use(fileUpload());
|
||||
app.use(cors(corsOptions));
|
||||
// app.use(
|
||||
// "/v1",
|
||||
// swaggerUi.serve,
|
||||
// swaggerUi.setup(specs , {explorer:true})
|
||||
// );
|
||||
app.use("/v1", swaggerUi.serve, swaggerUi.setup(specs, { explorer: true }));
|
||||
// Require & Import API routes
|
||||
const Public = require("./routes/public");
|
||||
const admin = require("./routes/admin");
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
const mongoose = require('mongoose');
|
||||
const mongoosePaginate = require('mongoose-paginate-v2');
|
||||
const mongoose = require("mongoose");
|
||||
const mongoosePaginate = require("mongoose-paginate-v2");
|
||||
|
||||
const LoggerSchema = mongoose.Schema({
|
||||
LastLogin: String,
|
||||
user :{type: mongoose.Schema.Types.ObjectId, ref: 'User'},
|
||||
LastLogin: String,
|
||||
user: { type: mongoose.Schema.Types.ObjectId, ref: "User" },
|
||||
});
|
||||
|
||||
LoggerSchema.plugin(mongoosePaginate);
|
||||
|
||||
module.exports = mongoose.model('Logger', LoggerSchema);
|
||||
module.exports = mongoose.model("Logger", LoggerSchema);
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
const NodeCache = require("node-cache");
|
||||
|
||||
class CacheService extends NodeCache {}
|
||||
module.exports = new CacheService();
|
||||
@@ -0,0 +1,12 @@
|
||||
exports.paginationOptions = ({ page, limit, sort }) => {
|
||||
const parsedPage = parseInt(page, 10) || 1;
|
||||
const parsedLimit = parseInt(limit, 10) || 10;
|
||||
const parsedSort = sort === "asc" ? "asc" : "desc";
|
||||
|
||||
return {
|
||||
page: parsedPage,
|
||||
limit: parsedLimit,
|
||||
sort: parsedSort,
|
||||
skip: (parsedPage - 1) * parsedLimit,
|
||||
};
|
||||
};
|
||||
+546
-533
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,47 @@
|
||||
const axios = require("axios");
|
||||
module.exports.sms = async (phoneNumber, message) => {
|
||||
try {
|
||||
// get token
|
||||
const getToken = await axios.post("https://RestfulSms.com/api/Token", {
|
||||
UserApiKey: "569ee43ed0d9ac27708ce43d",
|
||||
SecretKey: "drtime@A!@#",
|
||||
});
|
||||
|
||||
if (!getToken.data.IsSuccessful) {
|
||||
throw new Error("sending sms failed");
|
||||
}
|
||||
|
||||
const token = getToken.data.TokenKey;
|
||||
//get lines
|
||||
const resData = await axios.get("https://RestfulSms.com/api/SMSLine", {
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"x-sms-ir-secure-token": token,
|
||||
},
|
||||
});
|
||||
|
||||
// message details
|
||||
const data = {
|
||||
Messages: [message],
|
||||
MobileNumbers: [phoneNumber],
|
||||
LineNumber: resData.data.SMSLines[0].LineNumber,
|
||||
SendDateTime: "",
|
||||
CanContinueInCaseOfError: "false",
|
||||
};
|
||||
|
||||
const response = await axios.post(
|
||||
`http://RestfulSms.com/api/MessageSend`,
|
||||
data,
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"x-sms-ir-secure-token": token,
|
||||
},
|
||||
}
|
||||
);
|
||||
return response.data;
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
+220
-151
File diff suppressed because it is too large
Load Diff
+89
-12
@@ -1,7 +1,7 @@
|
||||
const {Router} = require('express')
|
||||
const router = Router()
|
||||
const userController = require('../controllers/userController');
|
||||
const electionController = require('../controllers/electionController');
|
||||
const { Router } = require("express");
|
||||
const router = Router();
|
||||
const userController = require("../controllers/userController");
|
||||
const electionController = require("../controllers/electionController");
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
@@ -48,7 +48,84 @@ const electionController = require('../controllers/electionController');
|
||||
* description: Validation error. Indicates that the request body contains invalid data.
|
||||
*/
|
||||
// Login User
|
||||
router.post('/login', userController.login);
|
||||
router.post("/login", userController.login);
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /auth/otp:
|
||||
* post:
|
||||
* summary: Send OTP to user for login
|
||||
* description: Allows users to log in with their phone number by sending an OTP.
|
||||
* tags:
|
||||
* - Auth
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* phone:
|
||||
* type: string
|
||||
* example:
|
||||
* phone: "09124569875"
|
||||
* responses:
|
||||
* 200:
|
||||
* description: OTP sent successfully.
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* message:
|
||||
* type: string
|
||||
* example:
|
||||
* message: "OTP sent successfully."
|
||||
*/
|
||||
router.post("/otp", userController.otp);
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /auth/otp/verify:
|
||||
* post:
|
||||
* summary: Verify the OTP sent to user
|
||||
* description: Allows users to log in by verifying the OTP sent to their phone number.
|
||||
* tags:
|
||||
* - Auth
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* phone:
|
||||
* type: string
|
||||
* code:
|
||||
* type: string
|
||||
* example:
|
||||
* phone: "09124569875"
|
||||
* code: "12345"
|
||||
* responses:
|
||||
* 200:
|
||||
* description: User logged in successfully.
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* token:
|
||||
* type: string
|
||||
* example:
|
||||
* token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
|
||||
* 401:
|
||||
* description: Unauthorized. Indicates that the provided credentials are invalid.
|
||||
* 403:
|
||||
* description: Forbidden. Indicates that the account is inactive. Contact the admin for assistance.
|
||||
* 422:
|
||||
* description: Validation error. Indicates that the request body contains invalid data.
|
||||
*/
|
||||
router.post("/otp/verify", userController.verifyOtp);
|
||||
/**
|
||||
* @swagger
|
||||
* /auth/logout:
|
||||
@@ -73,7 +150,7 @@ router.post('/login', userController.login);
|
||||
* description: Unauthorized. Indicates that the user is not logged in.
|
||||
*/
|
||||
// Logout User
|
||||
router.delete('/logout', userController.logout);
|
||||
router.delete("/logout", userController.logout);
|
||||
/**
|
||||
* @swagger
|
||||
* /auth/user:
|
||||
@@ -96,7 +173,7 @@ router.delete('/logout', userController.logout);
|
||||
* description: Unauthorized. Indicates that the user is not authenticated or the token is invalid.
|
||||
*/
|
||||
// Data User
|
||||
router.get('/user', userController.getuser);
|
||||
router.get("/user", userController.getuser);
|
||||
/**
|
||||
* @swagger
|
||||
* /auth/forget-password:
|
||||
@@ -154,7 +231,7 @@ router.get('/user', userController.getuser);
|
||||
* description: Error message indicating the internal server error.
|
||||
*/
|
||||
// Change Password
|
||||
router.post('/changePassword' , userController.forgetPassGenerateToken);
|
||||
router.post("/changePassword", userController.forgetPassGenerateToken);
|
||||
/**
|
||||
* @swagger
|
||||
* /auth/changePassword/{token}:
|
||||
@@ -213,7 +290,7 @@ router.post('/changePassword' , userController.forgetPassGenerateToken);
|
||||
* description: Error message indicating the internal server error.
|
||||
*/
|
||||
// Change Password :token param
|
||||
router.put('/changePassword/:token' , userController.forgetPassGetToken);
|
||||
router.put("/changePassword/:token", userController.forgetPassGetToken);
|
||||
|
||||
///////// voter
|
||||
|
||||
@@ -272,7 +349,7 @@ router.put('/changePassword/:token' , userController.forgetPassGetToken);
|
||||
*/
|
||||
|
||||
//Voter Login
|
||||
router.post('/voter/login' , electionController.voterLogin);
|
||||
router.post("/voter/login", electionController.voterLogin);
|
||||
/**
|
||||
* @swagger
|
||||
* /auth/voter/user:
|
||||
@@ -316,6 +393,6 @@ router.post('/voter/login' , electionController.voterLogin);
|
||||
* description: Error message indicating the internal server error.
|
||||
*/
|
||||
// user Voter Data
|
||||
router.get('/voter/user' , electionController.getVoterUser);
|
||||
router.get("/voter/user", electionController.getVoterUser);
|
||||
|
||||
module.exports = router
|
||||
module.exports = router;
|
||||
|
||||
Reference in New Issue
Block a user