From d887cf67c1833419355f0984dc5ab3bba6122d3f Mon Sep 17 00:00:00 2001 From: mahyargdz Date: Mon, 18 Nov 2024 09:16:17 +0330 Subject: [PATCH] chore: add otp based login --- .github/workflows/deploy.yaml | 2 +- Dockerfile.dev | 18 + docker-compose.yaml | 18 + package-lock.json | 44 +- package.json | 2 + server/controllers/adminLogController.js | 81 ++ server/controllers/userController.js | 176 ++++ server/databaseURL.js | 3 +- server/index.js | 11 +- server/models/Logger.js | 10 +- server/plugins/cache.js | 4 + server/plugins/pagination.js | 12 + server/plugins/serverResponses.js | 1079 +++++++++++----------- server/plugins/sms.js | 47 + server/routes/admin.js | 371 +++++--- server/routes/auth.js | 101 +- 16 files changed, 1266 insertions(+), 713 deletions(-) create mode 100644 Dockerfile.dev create mode 100644 docker-compose.yaml create mode 100644 server/controllers/adminLogController.js create mode 100644 server/plugins/cache.js create mode 100644 server/plugins/pagination.js create mode 100644 server/plugins/sms.js diff --git a/.github/workflows/deploy.yaml b/.github/workflows/deploy.yaml index 89d6f22..716c8cd 100644 --- a/.github/workflows/deploy.yaml +++ b/.github/workflows/deploy.yaml @@ -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 diff --git a/Dockerfile.dev b/Dockerfile.dev new file mode 100644 index 0000000..50f8727 --- /dev/null +++ b/Dockerfile.dev @@ -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"] diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..b953b28 --- /dev/null +++ b/docker-compose.yaml @@ -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: diff --git a/package-lock.json b/package-lock.json index d81a987..6226dcf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -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", diff --git a/package.json b/package.json index c48a291..2f388f9 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/server/controllers/adminLogController.js b/server/controllers/adminLogController.js new file mode 100644 index 0000000..731030a --- /dev/null +++ b/server/controllers/adminLogController.js @@ -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." }); + } + }, +]; diff --git a/server/controllers/userController.js b/server/controllers/userController.js index 0884af3..cc3f659 100644 --- a/server/controllers/userController.js +++ b/server/controllers/userController.js @@ -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 = [ diff --git a/server/databaseURL.js b/server/databaseURL.js index b9fb163..92b499c 100644 --- a/server/databaseURL.js +++ b/server/databaseURL.js @@ -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' diff --git a/server/index.js b/server/index.js index 7bc4f6f..f1658b7 100644 --- a/server/index.js +++ b/server/index.js @@ -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"); diff --git a/server/models/Logger.js b/server/models/Logger.js index 105d039..62d2fbc 100644 --- a/server/models/Logger.js +++ b/server/models/Logger.js @@ -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); diff --git a/server/plugins/cache.js b/server/plugins/cache.js new file mode 100644 index 0000000..5970f4d --- /dev/null +++ b/server/plugins/cache.js @@ -0,0 +1,4 @@ +const NodeCache = require("node-cache"); + +class CacheService extends NodeCache {} +module.exports = new CacheService(); diff --git a/server/plugins/pagination.js b/server/plugins/pagination.js new file mode 100644 index 0000000..123e1ab --- /dev/null +++ b/server/plugins/pagination.js @@ -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, + }; +}; diff --git a/server/plugins/serverResponses.js b/server/plugins/serverResponses.js index f2e6e83..d3fb5ac 100644 --- a/server/plugins/serverResponses.js +++ b/server/plugins/serverResponses.js @@ -1,605 +1,614 @@ module.exports._sr = { fa: { required: { - field: 'این فیلد نباید خالی باشد', + otp_code: "کد تایید نباید خالی باشد", + field: "این فیلد نباید خالی باشد", // developer validations - remember_me: 'پارامتر remember_me الزامی است', + remember_me: "پارامتر remember_me الزامی است", // registration validations - name: 'نام را وارد کنید', - first_name: 'نام را وارد کنید', - last_name: 'نام خانوادگی را وارد کنید', - email: 'ایمیل را وارد کنید', - national_code: 'کد ملی الزامی است', - email_personal: 'ایمیل شخصی الزامی است', - email_company: 'ایمیل کمپانی برای اشخاص حقوقی الزامی است', - company_name: 'درصورتی که شخص حقوقی هستید، نام کمپانی را وارد کنید', - username: 'نام کاربری را وارد کنید', - phone_number: 'شماره تماس را وارد کنید', - password: 'پسورد را وارد کنید', - birthdate: 'تاریخ تولد را وارد کنید', + name: "نام را وارد کنید", + first_name: "نام را وارد کنید", + last_name: "نام خانوادگی را وارد کنید", + email: "ایمیل را وارد کنید", + national_code: "کد ملی الزامی است", + email_personal: "ایمیل شخصی الزامی است", + email_company: "ایمیل کمپانی برای اشخاص حقوقی الزامی است", + company_name: "درصورتی که شخص حقوقی هستید، نام کمپانی را وارد کنید", + username: "نام کاربری را وارد کنید", + phone_number: "شماره تماس را وارد کنید", + password: "پسورد را وارد کنید", + birthdate: "تاریخ تولد را وارد کنید", // addressing validations - country: 'کشور را وارد کنید', - province: 'استان را وارد کنید', - city: 'شهر را وارد کنید', - address: 'آدرس را وارد کنید', - postal_code: 'کد پستی را وارد کنید', - plaque: 'پلاک را وارد کنید', - receiver_first_name: 'نام گیرنده را وارد کنید', - receiver_last_name: 'نام خانوادگی گیرنده را وارد کنید', - receiver_mobile: 'شماره موبایل گیرنده را وارد کنید', + country: "کشور را وارد کنید", + province: "استان را وارد کنید", + city: "شهر را وارد کنید", + address: "آدرس را وارد کنید", + postal_code: "کد پستی را وارد کنید", + plaque: "پلاک را وارد کنید", + receiver_first_name: "نام گیرنده را وارد کنید", + receiver_last_name: "نام خانوادگی گیرنده را وارد کنید", + receiver_mobile: "شماره موبایل گیرنده را وارد کنید", // global (post - gallery - ...) - title: 'عنوان را وارد کنید', - caption: 'متن را وارد کنید', - description: 'توضیحات را وارد کنید', - Twitter:'لینک Twitter را وارد کنید', - category: 'دسته بندی را انتخاب کنید', - image: 'عکس اجباری است', - cover: 'کاور اجباری است', - file: 'فایل اجباری است', - message: 'پیام را بنویسید', - quantity: 'تعداد را وارد کنید', - date: 'تاریخ را وارد کنید', - reason: 'دلیل را انتخاب کنید', - question: 'سوال را بنویسید', - answer: 'جواب را بنویسید', - price: 'قیمت را وارد کنید', - type: 'نوع را انتخاب کنید' + title: "عنوان را وارد کنید", + caption: "متن را وارد کنید", + description: "توضیحات را وارد کنید", + Twitter: "لینک Twitter را وارد کنید", + category: "دسته بندی را انتخاب کنید", + image: "عکس اجباری است", + cover: "کاور اجباری است", + file: "فایل اجباری است", + message: "پیام را بنویسید", + quantity: "تعداد را وارد کنید", + date: "تاریخ را وارد کنید", + reason: "دلیل را انتخاب کنید", + question: "سوال را بنویسید", + answer: "جواب را بنویسید", + price: "قیمت را وارد کنید", + type: "نوع را انتخاب کنید", }, format: { - phone_number: 'فرمت شماره تماس صحیح نیست', - email: 'فرمت ایمیل قابل قبول نیست', - number: 'مقدار باید از جنس عدد باشد', - boolean: 'مقدار باید از جنس Boolean باشد', - image: 'فرمت عکس قابل قبول نیست', - video: 'فرمت فیلم قابل قبول نیست', - national_code: 'کد ملی صحیح نیست' + otp_length: "فرمت کد تایید صحیح نیست", + phone_number: "فرمت شماره تماس صحیح نیست", + email: "فرمت ایمیل قابل قبول نیست", + number: "مقدار باید از جنس عدد باشد", + boolean: "مقدار باید از جنس Boolean باشد", + image: "فرمت عکس قابل قبول نیست", + video: "فرمت فیلم قابل قبول نیست", + national_code: "کد ملی صحیح نیست", }, min_char: { - min2: 'حداقل 2 کاراکتر', - min4: 'حداقل 4 کاراکتر', - min8: 'حداقل 8 کاراکتر', - min10: 'حداقل 10 کاراکتر', - min20: 'حداقل 20 کاراکتر', - min30: 'حداقل 30 کاراکتر', - min40: 'حداقل 40 کاراکتر', - min50: 'حداقل 50 کاراکتر', - min60: 'حداقل 60 کاراکتر', - min100: 'حداقل 100 کاراکتر', - min120: 'حداقل 120 کاراکتر', - min150: 'حداقل 150 کاراکتر', - min200: 'حداقل 200 کاراکتر', - data_size: 'حجم قابل قبول حداقل: ', - image_width_size: 'عرض حداقل: ', - image_height_size: 'ارتفاع حداقل: ', + min2: "حداقل 2 کاراکتر", + min4: "حداقل 4 کاراکتر", + min8: "حداقل 8 کاراکتر", + min10: "حداقل 10 کاراکتر", + min20: "حداقل 20 کاراکتر", + min30: "حداقل 30 کاراکتر", + min40: "حداقل 40 کاراکتر", + min50: "حداقل 50 کاراکتر", + min60: "حداقل 60 کاراکتر", + min100: "حداقل 100 کاراکتر", + min120: "حداقل 120 کاراکتر", + min150: "حداقل 150 کاراکتر", + min200: "حداقل 200 کاراکتر", + data_size: "حجم قابل قبول حداقل: ", + image_width_size: "عرض حداقل: ", + image_height_size: "ارتفاع حداقل: ", }, max_char: { - max4: 'حداکثر 4 کاراکتر', - max8: 'حداکثر 8 کاراکتر', - max10: 'حداکثر 10 کاراکتر', - max15: 'حداکثر 15 کاراکتر', - max20: 'حداکثر 20 کاراکتر', - max30: 'حداکثر 30 کاراکتر', - max40: 'حداکثر 40 کاراکتر', - max50: 'حداکثر 50 کاراکتر', - max60: 'حداکثر 60 کاراکتر', - max100: 'حداکثر 100 کاراکتر', - max120: 'حداکثر 120 کاراکتر', - max150: 'حداکثر 150 کاراکتر', - max200: 'حداکثر 200 کاراکتر', - data_size: 'حجم قابل قبول حداکثر: ', - image_width_size: 'عرض حداکثر: ', - image_height_size: 'ارتفاع حداکثر: ', + max4: "حداکثر 4 کاراکتر", + max8: "حداکثر 8 کاراکتر", + max10: "حداکثر 10 کاراکتر", + max15: "حداکثر 15 کاراکتر", + max20: "حداکثر 20 کاراکتر", + max30: "حداکثر 30 کاراکتر", + max40: "حداکثر 40 کاراکتر", + max50: "حداکثر 50 کاراکتر", + max60: "حداکثر 60 کاراکتر", + max100: "حداکثر 100 کاراکتر", + max120: "حداکثر 120 کاراکتر", + max150: "حداکثر 150 کاراکتر", + max200: "حداکثر 200 کاراکتر", + data_size: "حجم قابل قبول حداکثر: ", + image_width_size: "عرض حداکثر: ", + image_height_size: "ارتفاع حداکثر: ", }, not_found: { - user_id: 'کاربری با این مشخصات وجود ندارد', - admin_id: 'ادمینی با این مشخصات وجود ندارد', - order_id: 'سفارشی با این مشخصات وجود ندارد', - item_id: 'موردی با این مشخصات وجود ندارد', - password: 'رمز عبور یا آیدی درست نیست', - email : 'هیچ کاربری با ایمیل مورد نظر پیدا نشده است', - category : 'دسته بندی انتخاب شده وحود ندارد' /** @todo add this string to another language */ + user_id: "کاربری با این مشخصات وجود ندارد", + admin_id: "ادمینی با این مشخصات وجود ندارد", + order_id: "سفارشی با این مشخصات وجود ندارد", + item_id: "موردی با این مشخصات وجود ندارد", + password: "رمز عبور یا آیدی درست نیست", + email: "هیچ کاربری با ایمیل مورد نظر پیدا نشده است", + category: + "دسته بندی انتخاب شده وحود ندارد" /** @todo add this string to another language */, }, duplicated: { - username: 'این نام کاربری از قبل وجود دارد', - email: 'این ایمیل از قبل وجود دارد', - name: 'نام تکراری است', - title: 'عنوان تکراری است', - phoneNumber : 'شماره همراه وجود دارد' + username: "این نام کاربری از قبل وجود دارد", + email: "این ایمیل از قبل وجود دارد", + name: "نام تکراری است", + title: "عنوان تکراری است", + phoneNumber: "شماره همراه وجود دارد", }, response: { - logged_in: 'شما وارد سیستم شدید', - not_logged_in: 'شما وارد سیستم نشدید', - logged_out: 'شما از سیستم خارج شدید', - unauthenticated: 'غیرمجاز', - recovery_link: 'لینک بازیابی فرستاده شد', - success_save: 'با موفقیت ثبت شد', - success_remove: 'با موفقیت حذف شد', - cart_empty: 'سبد خرید خالی است', - already_has_address: 'آدرس قبلا اضافه شده', - activation_code: 'کد فعالسازی برای شما ارسال شد', - activation_email: 'ایمیل فعال سازی برای شما ارسال شد', - expired_reset_link: 'این لینک بازیابی منقضی شده است', - email_not_confirmed: 'ابتدا ایمیل خود را تایید کنید،لینک فعال سازی قبلا برای شما فرستاده شده است.', - expired_activation_link: 'این لینک فعال سازی منقضی شده است', - success_activation: 'اکانت شما با موفقیت فعال شد', - passwords_not_match: 'پسورد ها یکی نیست', - problem: 'مشکلی پیش آمده، لطفا دوباره تلاش کنید.', - latinChar: 'لطفا با حروف لاتین بنویسید', - persianChar: 'لطفا با حروف فارسی بنویسید', - whiteSpace: 'بین حروف و کلمات نباید فاصله باشد' + logged_in: "شما وارد سیستم شدید", + not_logged_in: "شما وارد سیستم نشدید", + logged_out: "شما از سیستم خارج شدید", + unauthenticated: "غیرمجاز", + recovery_link: "لینک بازیابی فرستاده شد", + success_save: "با موفقیت ثبت شد", + success_remove: "با موفقیت حذف شد", + cart_empty: "سبد خرید خالی است", + already_has_address: "آدرس قبلا اضافه شده", + activation_code: "کد فعالسازی برای شما ارسال شد", + activation_email: "ایمیل فعال سازی برای شما ارسال شد", + expired_reset_link: "این لینک بازیابی منقضی شده است", + email_not_confirmed: + "ابتدا ایمیل خود را تایید کنید،لینک فعال سازی قبلا برای شما فرستاده شده است.", + expired_activation_link: "این لینک فعال سازی منقضی شده است", + success_activation: "اکانت شما با موفقیت فعال شد", + passwords_not_match: "پسورد ها یکی نیست", + problem: "مشکلی پیش آمده، لطفا دوباره تلاش کنید.", + latinChar: "لطفا با حروف لاتین بنویسید", + persianChar: "لطفا با حروف فارسی بنویسید", + whiteSpace: "بین حروف و کلمات نباید فاصله باشد", }, optional: { - string : 'باید یک رشته باشد', - boolean : 'باید بولین باشد', - number : 'باید عدد باشد', - onlyValid : 'فقط این مقادیر قابل قبول می باشد' + string: "باید یک رشته باشد", + boolean: "باید بولین باشد", + number: "باید عدد باشد", + onlyValid: "فقط این مقادیر قابل قبول می باشد", }, file_types: { - jpg: 'فقط فرمت jpg قابل قبول است', - png: 'فقط فرمت png قابل قبول است', - gif: 'فقط فرمت gif قابل قبول است', - pdf: 'فقط فرمت pdf قابل قبول است', - txt: 'فقط فرمت txt قابل قبول است', - log: 'فقط فرمت log قابل قبول است', - mp3: 'فقط فرمت mp3 قابل قبول است', - ogg: 'فقط فرمت ogg قابل قبول است', - wmv: 'فقط فرمت wmv قابل قبول است', - mp4: 'فقط فرمت mp4 قابل قبول است', - mov: 'فقط فرمت mov قابل قبول است', - mkv: 'فقط فرمت mkv قابل قبول است', - flv: 'فقط فرمت flv قابل قبول است' - } + jpg: "فقط فرمت jpg قابل قبول است", + png: "فقط فرمت png قابل قبول است", + gif: "فقط فرمت gif قابل قبول است", + pdf: "فقط فرمت pdf قابل قبول است", + txt: "فقط فرمت txt قابل قبول است", + log: "فقط فرمت log قابل قبول است", + mp3: "فقط فرمت mp3 قابل قبول است", + ogg: "فقط فرمت ogg قابل قبول است", + wmv: "فقط فرمت wmv قابل قبول است", + mp4: "فقط فرمت mp4 قابل قبول است", + mov: "فقط فرمت mov قابل قبول است", + mkv: "فقط فرمت mkv قابل قبول است", + flv: "فقط فرمت flv قابل قبول است", + }, }, en: { required: { - field: 'This field is required', + field: "This field is required", // developer validations - remember_me: 'Remember_me parameter required', + remember_me: "Remember_me parameter required", // registration validations - name: 'Enter name', - first_name: 'Enter first name', - last_name: 'Enter last name', - national_code: 'National code is required', - email: 'Enter email', - email_personal: 'Personal email is required', - email_company: 'Company email is required for legal entities', - company_name: 'Enter company name if you are a legal entity', - username: 'Enter username', - phone_number: 'Enter phone number', - password: 'Enter password', - birthdate: 'Enter birthdate', + name: "Enter name", + first_name: "Enter first name", + last_name: "Enter last name", + national_code: "National code is required", + email: "Enter email", + email_personal: "Personal email is required", + email_company: "Company email is required for legal entities", + company_name: "Enter company name if you are a legal entity", + username: "Enter username", + phone_number: "Enter phone number", + password: "Enter password", + birthdate: "Enter birthdate", // addressing validations - country: 'Enter country', - province: 'Enter province', - city: 'Enter city', - address: 'Enter address', - postal_code: 'Enter postal code', - plaque: 'Enter plaque', - receiver_first_name: 'Enter recipient name', - receiver_last_name: 'Enter recipient surname', - receiver_mobile: 'Enter recipient\'s mobile number', + country: "Enter country", + province: "Enter province", + city: "Enter city", + address: "Enter address", + postal_code: "Enter postal code", + plaque: "Enter plaque", + receiver_first_name: "Enter recipient name", + receiver_last_name: "Enter recipient surname", + receiver_mobile: "Enter recipient's mobile number", // global (post - gallery - ...) - title: 'Enter title', - caption: 'Enter caption', - description: 'Enter description', - category: 'Select category', - image: 'Image is required', - cover: 'Cover is required', - file: 'File is required', - message: 'Write message', - quantity: 'Enter quantity', - date: 'Enter date', - reason: 'Select reason', - question: 'Write the question', - answer: 'Write the answer', - price: 'Enter Price', - type: 'Select type' + title: "Enter title", + caption: "Enter caption", + description: "Enter description", + category: "Select category", + image: "Image is required", + cover: "Cover is required", + file: "File is required", + message: "Write message", + quantity: "Enter quantity", + date: "Enter date", + reason: "Select reason", + question: "Write the question", + answer: "Write the answer", + price: "Enter Price", + type: "Select type", }, format: { - phone_number: 'Phone number format in incorrect', - email: 'Email format is not correct', - number: 'Value must be number', - boolean: 'Value must be Boolean', - image: 'Photo format is not acceptable', - video: 'Video format is not acceptable', - national_code: 'National code format is not correct' + phone_number: "Phone number format in incorrect", + email: "Email format is not correct", + number: "Value must be number", + boolean: "Value must be Boolean", + image: "Photo format is not acceptable", + video: "Video format is not acceptable", + national_code: "National code format is not correct", }, min_char: { - min2: 'At least 2 characters', - min4: 'At least 4 characters', - min8: 'At least 8 characters', - min10: 'At least 10 characters', - min20: 'At least 20 characters', - min30: 'At least 30 characters', - min40: 'At least 40 characters', - min50: 'At least 50 characters', - min60: 'At least 60 characters', - min100: 'At least 100 characters', - min120: 'At least 120 characters', - min150: 'At least 150 characters', - min200: 'At least 200 characters', - data_size: 'Acceptable minimum size: ', - image_width_size: 'Minimum width: ', - image_height_size: 'Minimum height: ', + min2: "At least 2 characters", + min4: "At least 4 characters", + min8: "At least 8 characters", + min10: "At least 10 characters", + min20: "At least 20 characters", + min30: "At least 30 characters", + min40: "At least 40 characters", + min50: "At least 50 characters", + min60: "At least 60 characters", + min100: "At least 100 characters", + min120: "At least 120 characters", + min150: "At least 150 characters", + min200: "At least 200 characters", + data_size: "Acceptable minimum size: ", + image_width_size: "Minimum width: ", + image_height_size: "Minimum height: ", }, max_char: { - max4: 'Maximum 4 characters', - max8: 'Maximum 8 characters', - max10: 'Maximum 10 characters', - max15: 'Maximum 15 characters', - max20: 'Maximum 20 characters', - max30: 'Maximum 30 characters', - max40: 'Maximum 40 characters', - max50: 'Maximum 50 characters', - max60: 'Maximum 60 characters', - max100: 'Maximum 100 characters', - max120: 'Maximum 120 characters', - max150: 'Maximum 150 characters', - max200: 'Maximum 200 characters', - data_size: 'Maximum acceptable size: ', - image_width_size: 'Maximum width: ', - image_height_size: 'Maximum height: ', + max4: "Maximum 4 characters", + max8: "Maximum 8 characters", + max10: "Maximum 10 characters", + max15: "Maximum 15 characters", + max20: "Maximum 20 characters", + max30: "Maximum 30 characters", + max40: "Maximum 40 characters", + max50: "Maximum 50 characters", + max60: "Maximum 60 characters", + max100: "Maximum 100 characters", + max120: "Maximum 120 characters", + max150: "Maximum 150 characters", + max200: "Maximum 200 characters", + data_size: "Maximum acceptable size: ", + image_width_size: "Maximum width: ", + image_height_size: "Maximum height: ", }, not_found: { - user_id: 'There is no user with this profile', - admin_id: 'There is no admin with this profile', - order_id: 'There is no order with this profile', - item_id: 'There is no item with this specification', - password: 'Password or ID is incorrect', - email : 'No users were found with the email in question' + user_id: "There is no user with this profile", + admin_id: "There is no admin with this profile", + order_id: "There is no order with this profile", + item_id: "There is no item with this specification", + password: "Password or ID is incorrect", + email: "No users were found with the email in question", }, duplicated: { - username: 'This username already exists', - email: 'This email already exists', - name: 'Name is duplicate', - title: 'Title is duplicate', - phoneNumber : 'phoneNumber already exists' + username: "This username already exists", + email: "This email already exists", + name: "Name is duplicate", + title: "Title is duplicate", + phoneNumber: "phoneNumber already exists", }, response: { - logged_in: 'You are logged in', - not_logged_in: 'You are not logged in', - logged_out: 'You are logged out', - unauthenticated: 'unauthenticated', - recovery_link: 'Recovery link sent', - success_save: 'Successfully saved', - success_remove: 'Successfully removed', - cart_empty: 'Cart is empty', - already_has_address: 'Already has address', - activation_code: 'Activation code sent to you', - activation_email: 'Activation email sent to you', - expired_reset_link: 'The current reset pass link has been expired', - email_not_confirmed: 'Confirm your email first, the activation link has already been sent to you.', - expired_activation_link: 'This activation link has expired', - success_activation: 'Your account has been successfully activated', - passwords_not_match: 'Passwords are not the same', - problem: 'There is a problem, please try again.', - latinChar: 'Please write in Latin letters', - persianChar: 'Please write in Persian letters', - whiteSpace: 'There should be no space between letters and words' + logged_in: "You are logged in", + not_logged_in: "You are not logged in", + logged_out: "You are logged out", + unauthenticated: "unauthenticated", + recovery_link: "Recovery link sent", + success_save: "Successfully saved", + success_remove: "Successfully removed", + cart_empty: "Cart is empty", + already_has_address: "Already has address", + activation_code: "Activation code sent to you", + activation_email: "Activation email sent to you", + expired_reset_link: "The current reset pass link has been expired", + email_not_confirmed: + "Confirm your email first, the activation link has already been sent to you.", + expired_activation_link: "This activation link has expired", + success_activation: "Your account has been successfully activated", + passwords_not_match: "Passwords are not the same", + problem: "There is a problem, please try again.", + latinChar: "Please write in Latin letters", + persianChar: "Please write in Persian letters", + whiteSpace: "There should be no space between letters and words", }, optional: { - string : 'must be a string', - boolean : 'must be boolean', - number : 'must be a number', - onlyValid : 'Only these values ​​are acceptable' + string: "must be a string", + boolean: "must be boolean", + number: "must be a number", + onlyValid: "Only these values ​​are acceptable", }, file_types: { - jpg: 'Only jpg format is acceptable', - png: 'Only png format is acceptable', - gif: 'Only gif format is acceptable', - pdf: 'Only pdf format is acceptable', - txt: 'Only txt format is acceptable', - log: 'Only log format is acceptable', - mp3: 'Only mp3 format is acceptable', - ogg: 'Only ogg format is acceptable', - wmv: 'Only wmv format is acceptable', - mp4: 'Only mp4 format is acceptable', - mov: 'Only mov format is acceptable', - mkv: 'Only mkv format is acceptable', - flv: 'Only flv format is acceptable' - } + jpg: "Only jpg format is acceptable", + png: "Only png format is acceptable", + gif: "Only gif format is acceptable", + pdf: "Only pdf format is acceptable", + txt: "Only txt format is acceptable", + log: "Only log format is acceptable", + mp3: "Only mp3 format is acceptable", + ogg: "Only ogg format is acceptable", + wmv: "Only wmv format is acceptable", + mp4: "Only mp4 format is acceptable", + mov: "Only mov format is acceptable", + mkv: "Only mkv format is acceptable", + flv: "Only flv format is acceptable", + }, }, de: { required: { - field: 'This field is required', + field: "This field is required", // developer validations - remember_me: 'Remember_me-Parameter erforderlich', + remember_me: "Remember_me-Parameter erforderlich", // registration validations - name: 'Name eingeben', - first_name: 'Name eingeben', - last_name: 'Nachnamen eingeben', + name: "Name eingeben", + first_name: "Name eingeben", + last_name: "Nachnamen eingeben", national_code: "Nationaler Code ist erforderlich", - email: 'Email eingeben', - email_personal: 'Persönliche E-Mail ist erforderlich', - email_company: 'Für juristische Personen ist eine Unternehmens-E-Mail erforderlich', - company_name: 'Geben Sie den Firmennamen ein, wenn Sie eine juristische Person sind', - username: 'Geben Sie den Benutzernamen ein', - phone_number: 'Telefonnummer eingeben', - password: 'Passwort eingeben', - birthdate: 'Enter birthdate', + email: "Email eingeben", + email_personal: "Persönliche E-Mail ist erforderlich", + email_company: + "Für juristische Personen ist eine Unternehmens-E-Mail erforderlich", + company_name: + "Geben Sie den Firmennamen ein, wenn Sie eine juristische Person sind", + username: "Geben Sie den Benutzernamen ein", + phone_number: "Telefonnummer eingeben", + password: "Passwort eingeben", + birthdate: "Enter birthdate", // addressing validations - country: 'Land eingeben', - province: 'Stadt betreten', - city: 'Stadt betreten', - address: 'Adresse eingeben', - postal_code: 'Postleitzahl eingeben', - plaque: 'Plakette eingeben', - receiver_first_name: 'Empfängername eingeben', - receiver_last_name: 'Nachname des Empfängers eingeben', - receiver_mobile: 'Handynummer des Empfängers eingebenr', + country: "Land eingeben", + province: "Stadt betreten", + city: "Stadt betreten", + address: "Adresse eingeben", + postal_code: "Postleitzahl eingeben", + plaque: "Plakette eingeben", + receiver_first_name: "Empfängername eingeben", + receiver_last_name: "Nachname des Empfängers eingeben", + receiver_mobile: "Handynummer des Empfängers eingebenr", // global (post - gallery - ...) - title: 'Titel eingeben', - caption: 'Beschriftung eingeben', - description: 'Beschreibung eingeben', - category: 'Kategorie wählen', - image: 'Bild ist erforderlich', - cover: 'Bild ist erforderlich Abdeckung ist erforderlich', - file: 'Datei ist erforderlich', - message: 'Nachricht schreiben', - quantity: 'Menge eingeben', - date: 'Enter date', - reason: 'Grund auswählen', - question: 'Schreibe die Frage', - answer: 'Schreibe die Antwort', - price: 'Enter Price', - type: 'Select type' + title: "Titel eingeben", + caption: "Beschriftung eingeben", + description: "Beschreibung eingeben", + category: "Kategorie wählen", + image: "Bild ist erforderlich", + cover: "Bild ist erforderlich Abdeckung ist erforderlich", + file: "Datei ist erforderlich", + message: "Nachricht schreiben", + quantity: "Menge eingeben", + date: "Enter date", + reason: "Grund auswählen", + question: "Schreibe die Frage", + answer: "Schreibe die Antwort", + price: "Enter Price", + type: "Select type", }, format: { - phone_number: 'Telefonnummernformat falsch', - email: 'E-Mail-Format nicht korrekt', - number: 'Wert muss Nummer sein', - boolean: 'Wert muss Boolescher Wert sein', - image: 'Photo format is not acceptable', - video: 'Video format is not acceptable', - national_code: "Nationales Codeformat ist nicht korrekt" + phone_number: "Telefonnummernformat falsch", + email: "E-Mail-Format nicht korrekt", + number: "Wert muss Nummer sein", + boolean: "Wert muss Boolescher Wert sein", + image: "Photo format is not acceptable", + video: "Video format is not acceptable", + national_code: "Nationales Codeformat ist nicht korrekt", }, min_char: { - min2: 'Mindestens 2 Zeichen', - min4: 'Mindestens 4 Zeichen', - min8: 'Mindestens 8 Zeichen', - min10: 'Mindestens 10 Zeichen', - min20: 'Mindestens 20 Zeichen', - min30: 'Mindestens 30 Zeichen', - min40: 'Mindestens 40 Zeichen', - min50: 'Mindestens 50 Zeichen', - min60: 'Mindestens 60 Zeichen', - min100: 'Mindestens 100 Zeichen', - min120: 'Mindestens 120 Zeichen', - min150: 'Mindestens 150 Zeichen', - min200: 'Mindestens 200 Zeichen', - data_size: 'Akzeptable Mindestgröße: ', - image_width_size: 'Mindestbreite: ', - image_height_size: 'Mindesthöhe: ', + min2: "Mindestens 2 Zeichen", + min4: "Mindestens 4 Zeichen", + min8: "Mindestens 8 Zeichen", + min10: "Mindestens 10 Zeichen", + min20: "Mindestens 20 Zeichen", + min30: "Mindestens 30 Zeichen", + min40: "Mindestens 40 Zeichen", + min50: "Mindestens 50 Zeichen", + min60: "Mindestens 60 Zeichen", + min100: "Mindestens 100 Zeichen", + min120: "Mindestens 120 Zeichen", + min150: "Mindestens 150 Zeichen", + min200: "Mindestens 200 Zeichen", + data_size: "Akzeptable Mindestgröße: ", + image_width_size: "Mindestbreite: ", + image_height_size: "Mindesthöhe: ", }, max_char: { - max4: 'Maximal 4 Zeichen', - max8: 'Maximal 8 Zeichen', - max10: 'Maximal 10 Zeichen', - max15: 'Maximal 15 Zeichen', - max20: 'Maximal 20 Zeichen', - max30: 'Maximal 30 Zeichen', - max40: 'Maximal 40 Zeichen', - max50: 'Maximal 50 Zeichen', - max60: 'Maximal 60 Zeichen', - max100: 'Maximal 100 Zeichen', - max120: 'Maximal 120 Zeichen', - max150: 'Maximal 150 Zeichen', - max200: 'Maximal 200 Zeichen', - data_size: 'Maximal zulässige Größe: ', - image_width_size: 'Maximale Breite: ', - image_height_size: 'Maximale Höhe: ', + max4: "Maximal 4 Zeichen", + max8: "Maximal 8 Zeichen", + max10: "Maximal 10 Zeichen", + max15: "Maximal 15 Zeichen", + max20: "Maximal 20 Zeichen", + max30: "Maximal 30 Zeichen", + max40: "Maximal 40 Zeichen", + max50: "Maximal 50 Zeichen", + max60: "Maximal 60 Zeichen", + max100: "Maximal 100 Zeichen", + max120: "Maximal 120 Zeichen", + max150: "Maximal 150 Zeichen", + max200: "Maximal 200 Zeichen", + data_size: "Maximal zulässige Größe: ", + image_width_size: "Maximale Breite: ", + image_height_size: "Maximale Höhe: ", }, not_found: { - user_id: 'Es gibt keinen Benutzer mit diesem Profil', - admin_id: 'Es gibt keinen Administrator mit diesem Profil', - order_id: 'Es gibt keine Bestellung mit diesem Profil', - item_id: 'Es gibt keinen Artikel mit dieser Spezifikation', - password: 'Passwort oder ID ist falsch', - email : 'Mit der betreffenden E-Mail wurden keine Benutzer gefunden' + user_id: "Es gibt keinen Benutzer mit diesem Profil", + admin_id: "Es gibt keinen Administrator mit diesem Profil", + order_id: "Es gibt keine Bestellung mit diesem Profil", + item_id: "Es gibt keinen Artikel mit dieser Spezifikation", + password: "Passwort oder ID ist falsch", + email: "Mit der betreffenden E-Mail wurden keine Benutzer gefunden", }, duplicated: { - username: 'Dieser Benutzername existiert bereits', - email: 'Diese E-Mail existiert bereits', - name: 'Name ist doppelt', - title: 'Titel ist doppelt', - phoneNumber : 'phoneNumber existiert bereits' + username: "Dieser Benutzername existiert bereits", + email: "Diese E-Mail existiert bereits", + name: "Name ist doppelt", + title: "Titel ist doppelt", + phoneNumber: "phoneNumber existiert bereits", }, response: { - logged_in: 'Sie sind angemeldet', - not_logged_in: 'Sie sind nicht angemeldet', - logged_out: 'Sie sind abgemeldet', - unauthenticated: 'nicht authentifiziert', - recovery_link: 'Wiederherstellungslink gesendet', - success_save: 'Erfolgreich gespeichert', - success_remove: 'Erfolgreich entfernt', - cart_empty: 'Warenkorb ist leer', - ready_has_address: 'Hat bereits Adresse', - activation_code: 'Activation code sent to you', - activation_email: 'Activation email sent to you', - expired_reset_link: 'Der aktuelle Reset-Pass-Link ist abgelaufen', - email_not_confirmed: "Bestätigen Sie zuerst Ihre E-Mail, der Aktivierungslink wurde bereits an Sie gesendet.", - expired_activation_link: 'Dieser Aktivierungslink ist abgelaufen', - success_activation: 'Ihr Konto wurde erfolgreich aktiviert', - passwords_not_match: 'Passwörter sind nicht dasselbe', + logged_in: "Sie sind angemeldet", + not_logged_in: "Sie sind nicht angemeldet", + logged_out: "Sie sind abgemeldet", + unauthenticated: "nicht authentifiziert", + recovery_link: "Wiederherstellungslink gesendet", + success_save: "Erfolgreich gespeichert", + success_remove: "Erfolgreich entfernt", + cart_empty: "Warenkorb ist leer", + ready_has_address: "Hat bereits Adresse", + activation_code: "Activation code sent to you", + activation_email: "Activation email sent to you", + expired_reset_link: "Der aktuelle Reset-Pass-Link ist abgelaufen", + email_not_confirmed: + "Bestätigen Sie zuerst Ihre E-Mail, der Aktivierungslink wurde bereits an Sie gesendet.", + expired_activation_link: "Dieser Aktivierungslink ist abgelaufen", + success_activation: "Ihr Konto wurde erfolgreich aktiviert", + passwords_not_match: "Passwörter sind nicht dasselbe", problem: "Es gibt ein Problem, bitte versuchen Sie es erneut.", - latinChar: 'Please write in Latin letters', - persianChar: 'Please write in Persian letters', - whiteSpace: 'There should be no space between letters and words' + latinChar: "Please write in Latin letters", + persianChar: "Please write in Persian letters", + whiteSpace: "There should be no space between letters and words", }, optional: { - string : 'muss eine Zeichenfolge sein', - boolean : 'muss boolesch sein', - number : 'muss eine Nummer sein', - onlyValid : 'Nur diese Werte sind akzeptabel' + string: "muss eine Zeichenfolge sein", + boolean: "muss boolesch sein", + number: "muss eine Nummer sein", + onlyValid: "Nur diese Werte sind akzeptabel", }, file_types: { - jpg: 'Nur das jpg-Format ist akzeptabel', - png: 'Nur das png-Format ist akzeptabel', - gif: 'Nur das gif-Format ist akzeptabel', - pdf: 'Nur das PDF-Format ist akzeptabel', - txt: 'Nur das txt-Format ist akzeptabel', - log: 'Nur das log-Format ist akzeptabel', - mp3: 'Nur das mp3-Format ist akzeptabel', - ogg: 'Nur das ogg-Format ist akzeptabel', - wmv: 'Nur das wmv-Format ist akzeptabel', - mp4: 'Nur das mp4-Format ist akzeptabel', - mov: 'Nur das mov-Format ist akzeptabel', - mkv: 'Nur das mkv-Format ist akzeptabel', - flv: 'Nur das flv-Format ist akzeptabel' - } + jpg: "Nur das jpg-Format ist akzeptabel", + png: "Nur das png-Format ist akzeptabel", + gif: "Nur das gif-Format ist akzeptabel", + pdf: "Nur das PDF-Format ist akzeptabel", + txt: "Nur das txt-Format ist akzeptabel", + log: "Nur das log-Format ist akzeptabel", + mp3: "Nur das mp3-Format ist akzeptabel", + ogg: "Nur das ogg-Format ist akzeptabel", + wmv: "Nur das wmv-Format ist akzeptabel", + mp4: "Nur das mp4-Format ist akzeptabel", + mov: "Nur das mov-Format ist akzeptabel", + mkv: "Nur das mkv-Format ist akzeptabel", + flv: "Nur das flv-Format ist akzeptabel", + }, }, tr: { required: { - field: 'This field is required', + field: "This field is required", // geliştirici doğrulamaları - Remember_me: 'Remember_me parametresi gerekli', + Remember_me: "Remember_me parametresi gerekli", // kayıt doğrulamaları - name: 'Adı girin', - first_name: 'Adı girin', - last_name: 'Soyadı girin', + name: "Adı girin", + first_name: "Adı girin", + last_name: "Soyadı girin", national_code: "Nationaler Kodu erforderlich", - email: 'E-posta girin', - email_personal: 'Kişisel e-posta gereklidir', - email_company: 'Tüzel kişiler için şirket e-postası gereklidir', - company_name: 'Tüzel kişiyseniz şirket adını girin', - username: 'Kullanıcı adını girin', - phone_number: 'Telefon numarasını girin', - password: 'Şifre girin', - birthdate: 'Enter birthdate', + email: "E-posta girin", + email_personal: "Kişisel e-posta gereklidir", + email_company: "Tüzel kişiler için şirket e-postası gereklidir", + company_name: "Tüzel kişiyseniz şirket adını girin", + username: "Kullanıcı adını girin", + phone_number: "Telefon numarasını girin", + password: "Şifre girin", + birthdate: "Enter birthdate", // doğrulamaları adresleme - country: 'Ülke girin', - province: 'İl girin', - city: 'Şehir girin', - address: 'Adres girin', - postal_code: 'Posta kodunu girin', - plaque: 'Plak girin', - receiver_first_name: 'Alıcı adını girin', - receiver_last_name: 'Alıcının soyadını girin', - receiver_mobile: 'Alıcının cep telefonu numarasını girin', + country: "Ülke girin", + province: "İl girin", + city: "Şehir girin", + address: "Adres girin", + postal_code: "Posta kodunu girin", + plaque: "Plak girin", + receiver_first_name: "Alıcı adını girin", + receiver_last_name: "Alıcının soyadını girin", + receiver_mobile: "Alıcının cep telefonu numarasını girin", // global (post - galeri - ...) - title: 'Başlığı girin', - caption: 'Başlık girin', - description: 'Açıklama girin', - category: 'Kategori seçin', - image: 'Resim gerekli', - cover: 'Kapak gereklidir', - file: 'Dosya gerekli', - message: 'Mesaj yaz', - quantity: 'Miktar girin', - date: 'Enter date', - reason: 'Nedeni seçin', - question: 'Soruyu yazın', - answer: 'Cevabı yaz', - price: 'Enter Price', - type: 'Select type' + title: "Başlığı girin", + caption: "Başlık girin", + description: "Açıklama girin", + category: "Kategori seçin", + image: "Resim gerekli", + cover: "Kapak gereklidir", + file: "Dosya gerekli", + message: "Mesaj yaz", + quantity: "Miktar girin", + date: "Enter date", + reason: "Nedeni seçin", + question: "Soruyu yazın", + answer: "Cevabı yaz", + price: "Enter Price", + type: "Select type", }, format: { - phone_number: 'Telefon numarası biçimi yanlış', - email: 'E-posta formatı doğru değil', - number: 'Değer sayı olmalıdır', - boolean: 'Değer Boole olmalıdır', - image: 'Photo format is not acceptable', - video: 'Video format is not acceptable', - national_code: 'Ulusal kod formatı doğru değil' + phone_number: "Telefon numarası biçimi yanlış", + email: "E-posta formatı doğru değil", + number: "Değer sayı olmalıdır", + boolean: "Değer Boole olmalıdır", + image: "Photo format is not acceptable", + video: "Video format is not acceptable", + national_code: "Ulusal kod formatı doğru değil", }, min_char: { - min2: 'En az 2 karakter', - min4: 'En az 4 karakter', - min8: 'En az 8 karakter', - min10: 'En az 10 karakter', - min20: 'En az 20 karakter', - min30: 'En az 30 karakter', - min40: 'En az 40 karakter', - min50: 'En az 50 karakter', - min60: 'En az 60 karakter', - min100: 'En az 100 karakter', - min120: 'En az 120 karakter', - min150: 'En az 150 karakter', - min200: 'En az 200 karakter', - data_size: 'Kabul edilebilir minimum boyut: ', - image_width_size: 'Minimum genişlik: ', - image_height_size: 'Minimum yükseklik: ', + min2: "En az 2 karakter", + min4: "En az 4 karakter", + min8: "En az 8 karakter", + min10: "En az 10 karakter", + min20: "En az 20 karakter", + min30: "En az 30 karakter", + min40: "En az 40 karakter", + min50: "En az 50 karakter", + min60: "En az 60 karakter", + min100: "En az 100 karakter", + min120: "En az 120 karakter", + min150: "En az 150 karakter", + min200: "En az 200 karakter", + data_size: "Kabul edilebilir minimum boyut: ", + image_width_size: "Minimum genişlik: ", + image_height_size: "Minimum yükseklik: ", }, max_char: { - max4: 'Maksimum 4 karakter', - max8: 'Maksimum 8 karakter', - max10: 'Maksimum 10 karakter', - max15: 'Maksimum 15 karakter', - max20: 'Maksimum 20 karakter', - max30: 'Maksimum 30 karakter', - max40: 'Maksimum 40 karakter', - max50: 'Maksimum 50 karakter', - max60: 'Maksimum 60 karakter', - max100: 'Maksimum 100 karakter', - max120: 'Maksimum 120 karakter', - max150: 'Maksimum 150 karakter', - max200: 'Maksimum 200 karakter', - data_size: 'Kabul edilebilir maksimum boyut: ', - image_width_size: 'Maksimum genişlik: ', - image_height_size: 'Maksimum yükseklik: ', + max4: "Maksimum 4 karakter", + max8: "Maksimum 8 karakter", + max10: "Maksimum 10 karakter", + max15: "Maksimum 15 karakter", + max20: "Maksimum 20 karakter", + max30: "Maksimum 30 karakter", + max40: "Maksimum 40 karakter", + max50: "Maksimum 50 karakter", + max60: "Maksimum 60 karakter", + max100: "Maksimum 100 karakter", + max120: "Maksimum 120 karakter", + max150: "Maksimum 150 karakter", + max200: "Maksimum 200 karakter", + data_size: "Kabul edilebilir maksimum boyut: ", + image_width_size: "Maksimum genişlik: ", + image_height_size: "Maksimum yükseklik: ", }, not_found: { - user_id: 'Bu profile sahip kullanıcı yok', - admin_id: 'Bu profile sahip yönetici yok', - order_id: 'Bu profilde sipariş yok', - item_id: 'Bu spesifikasyona sahip hiçbir öğe yok', - password: 'Şifre veya kimlik yanlış', - email : 'Söz konusu e-postaya sahip kullanıcı bulunamadı' + user_id: "Bu profile sahip kullanıcı yok", + admin_id: "Bu profile sahip yönetici yok", + order_id: "Bu profilde sipariş yok", + item_id: "Bu spesifikasyona sahip hiçbir öğe yok", + password: "Şifre veya kimlik yanlış", + email: "Söz konusu e-postaya sahip kullanıcı bulunamadı", }, duplicated: { - username: 'Bu kullanıcı adı zaten mevcut', - email: 'Bu email zaten var', - name: 'Ad çift', - title: 'Başlık yineleniyor', - phoneNumber : 'phoneNumber zaten mevcut' + username: "Bu kullanıcı adı zaten mevcut", + email: "Bu email zaten var", + name: "Ad çift", + title: "Başlık yineleniyor", + phoneNumber: "phoneNumber zaten mevcut", }, response: { - logged_in: 'Giriş yaptınız', - not_logged_in: 'Giriş yapmadınız', - logged_out: 'Çıkış yaptınız', - unauthenticated: 'unauthenticated', - recovery_link: 'Kurtarma bağlantısı gönderildi', - success_save: 'Başarıyla kaydedildi', - success_remove: 'Başarıyla kaldırıldı', - cart_empty: 'Sepet boş', - already_has_address: 'Zaten adresi var', - activation_code: 'Activation code sent to you', - activation_email: 'Activation email sent to you', - expired_reset_link: 'Mevcut sıfırlama geçiş bağlantısının süresi doldu', - email_not_confirmed: 'Önce e-postanızı onaylayın, aktivasyon bağlantısı size zaten gönderildi.', + logged_in: "Giriş yaptınız", + not_logged_in: "Giriş yapmadınız", + logged_out: "Çıkış yaptınız", + unauthenticated: "unauthenticated", + recovery_link: "Kurtarma bağlantısı gönderildi", + success_save: "Başarıyla kaydedildi", + success_remove: "Başarıyla kaldırıldı", + cart_empty: "Sepet boş", + already_has_address: "Zaten adresi var", + activation_code: "Activation code sent to you", + activation_email: "Activation email sent to you", + expired_reset_link: "Mevcut sıfırlama geçiş bağlantısının süresi doldu", + email_not_confirmed: + "Önce e-postanızı onaylayın, aktivasyon bağlantısı size zaten gönderildi.", expired_activation_link: "Bu aktivasyon bağlantısının süresi doldu", - success_activation: 'Hesabınız başarıyla etkinleştirildi', - passwords_not_match: 'Şifreler aynı değil', - problem: 'Bir sorun var, lütfen tekrar deneyin.', - latinChar: 'Please write in Latin letters', - persianChar: 'Please write in Persian letters', - whiteSpace: 'There should be no space between letters and words' + success_activation: "Hesabınız başarıyla etkinleştirildi", + passwords_not_match: "Şifreler aynı değil", + problem: "Bir sorun var, lütfen tekrar deneyin.", + latinChar: "Please write in Latin letters", + persianChar: "Please write in Persian letters", + whiteSpace: "There should be no space between letters and words", }, optional: { - string : 'bir dizi olmalı', - boolean : 'boole olmalı', - number : 'bir sayı olmalı', - onlyValid : 'Yalnızca bu değerler kabul edilebilir' + string: "bir dizi olmalı", + boolean: "boole olmalı", + number: "bir sayı olmalı", + onlyValid: "Yalnızca bu değerler kabul edilebilir", }, file_types: { - jpg: 'Yalnızca jpg formatı kabul edilebilir', - png: 'Sadece png formatı kabul edilebilir', - gif: 'Yalnızca gif formatı kabul edilebilir', - pdf: 'Yalnızca pdf formatı kabul edilebilir', - txt: 'Yalnızca txt formatı kabul edilebilir', - log: 'Yalnızca log formatı kabul edilebilir', - mp3: 'Yalnızca mp3 formatı kabul edilebilir', - ogg: 'Yalnızca ogg formatı kabul edilebilir', - wmv: 'Yalnızca wmv formatı kabul edilebilir', - mp4: 'Yalnızca mp4 formatı kabul edilebilir', - mov: 'Yalnızca mov formatı kabul edilebilir', - mkv: 'Yalnızca mkv formatı kabul edilebilir', - flv: 'Yalnızca flv biçimi kabul edilebilir' - } + jpg: "Yalnızca jpg formatı kabul edilebilir", + png: "Sadece png formatı kabul edilebilir", + gif: "Yalnızca gif formatı kabul edilebilir", + pdf: "Yalnızca pdf formatı kabul edilebilir", + txt: "Yalnızca txt formatı kabul edilebilir", + log: "Yalnızca log formatı kabul edilebilir", + mp3: "Yalnızca mp3 formatı kabul edilebilir", + ogg: "Yalnızca ogg formatı kabul edilebilir", + wmv: "Yalnızca wmv formatı kabul edilebilir", + mp4: "Yalnızca mp4 formatı kabul edilebilir", + mov: "Yalnızca mov formatı kabul edilebilir", + mkv: "Yalnızca mkv formatı kabul edilebilir", + flv: "Yalnızca flv biçimi kabul edilebilir", + }, }, it: { required: { - field: 'This field is required', + field: "This field is required", // convalide dello sviluppatore Remember_me: "Remember_me parameter required", // convalide della registrazione @@ -609,12 +618,14 @@ module.exports._sr = { national_code: "Il codice Nationaler è comune", email: "Enter email", email_personal: "L'email personale è obbligatoria", - email_company: "L'email aziendale è obbligatoria per le persone giuridiche", - company_name: "Inserisci il nome dell'azienda se sei una persona giuridica", + email_company: + "L'email aziendale è obbligatoria per le persone giuridiche", + company_name: + "Inserisci il nome dell'azienda se sei una persona giuridica", username: "Inserisci nome utente", phone_number: "Inserisci numero di telefono", password: "Inserisci password", - birthdate: 'Enter birthdate', + birthdate: "Enter birthdate", // indirizzamento delle convalide country: "Inserisci paese", province: "Inserisci provincia", @@ -635,21 +646,21 @@ module.exports._sr = { file: "Il file è obbligatorio", message: "Scrivi messaggio", quantity: "Inserisci quantità", - date: 'Enter date', - reason: 'Seleziona motivo', - question: 'Scrivi la domanda', - answer: 'Scrivi la risposta', - price: 'Enter Price', - type: 'Select type' + date: "Enter date", + reason: "Seleziona motivo", + question: "Scrivi la domanda", + answer: "Scrivi la risposta", + price: "Enter Price", + type: "Select type", }, format: { phone_number: "Formato del numero di telefono non corretto", email: "Formato email non corretto", number: "Il valore deve essere un numero", boolean: "Il valore deve essere booleano", - image: 'Photo format is not acceptable', - video: 'Video format is not acceptable', - national_code: "Il formato del codice nazionale non è corretto" + image: "Photo format is not acceptable", + video: "Video format is not acceptable", + national_code: "Il formato del codice nazionale non è corretto", }, min_char: { min2: "Almeno 2 caratteri", @@ -693,14 +704,14 @@ module.exports._sr = { order_id: "Nessun ordine con questo profilo", item_id: "Nessun articolo con questa specifica", password: "La password o l'ID non sono corretti", - email : "Nessun utente trovato con l'email in questione" + email: "Nessun utente trovato con l'email in questione", }, duplicated: { username: "Questo nome utente esiste già", email: "Questa email esiste già", name: "Il nome è duplicato", title: "Il titolo è duplicato", - phoneNumber : "phoneNumber esiste già" + phoneNumber: "phoneNumber esiste già", }, response: { logged_in: "Hai effettuato l'accesso", @@ -712,23 +723,25 @@ module.exports._sr = { success_remove: "Rimosso con successo", cart_empty: "Il carrello è vuoto", already_has_address: "Ha già indirizzo", - activation_code: 'Activation code sent to you', - activation_email: 'Activation email sent to you', - expired_reset_link: "L'attuale link del passaggio di reimpostazione è scaduto", - email_not_confirmed: "Conferma prima la tua email, il link di attivazione ti è già stato inviato.", + activation_code: "Activation code sent to you", + activation_email: "Activation email sent to you", + expired_reset_link: + "L'attuale link del passaggio di reimpostazione è scaduto", + email_not_confirmed: + "Conferma prima la tua email, il link di attivazione ti è già stato inviato.", expired_activation_link: "Questo link di attivazione è scaduto", success_activation: "Il tuo account è stato attivato con successo", passwords_not_match: "Le password non sono le stesse", problem: "Si è verificato un problema, riprova.", - latinChar: 'Please write in Latin letters', - persianChar: 'Please write in Persian letters', - whiteSpace: 'There should be no space between letters and words' + latinChar: "Please write in Latin letters", + persianChar: "Please write in Persian letters", + whiteSpace: "There should be no space between letters and words", }, optional: { - string : 'deve essere una stringa', - boolean : 'deve essere booleano', - number : 'deve essere un numero', - onlyValid : 'Solo questi valori sono accettabili' + string: "deve essere una stringa", + boolean: "deve essere booleano", + number: "deve essere un numero", + onlyValid: "Solo questi valori sono accettabili", }, file_types: { jpg: "È accettabile solo il formato jpg", @@ -743,9 +756,9 @@ module.exports._sr = { mp4: "È accettabile solo il formato mp4", mov: "È accettabile solo il formato mov", mkv: "È accettabile solo il formato mkv", - flv: "È accettabile solo il formato flv" - } + flv: "È accettabile solo il formato flv", + }, }, - supportedImageFormats: ['jpg', 'jpeg', 'png', 'webp'], - supportedVideoFormats: ['mp4', 'avi', 'wmv'] -} + supportedImageFormats: ["jpg", "jpeg", "png", "webp"], + supportedVideoFormats: ["mp4", "avi", "wmv"], +}; diff --git a/server/plugins/sms.js b/server/plugins/sms.js new file mode 100644 index 0000000..43e3e75 --- /dev/null +++ b/server/plugins/sms.js @@ -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; + } +}; diff --git a/server/routes/admin.js b/server/routes/admin.js index e579d85..5a18d57 100644 --- a/server/routes/admin.js +++ b/server/routes/admin.js @@ -1,30 +1,35 @@ -const {Router} = require('express') +const { Router } = require("express"); const router = Router(); -const {hasPermission, hasSubPermission} = require('../authentication'); +const { hasPermission, hasSubPermission } = require("../authentication"); /////////////////////////////////////////////////////////// controllers -const categoryController = require('../controllers/categoryController'); -const userController = require('../controllers/userController'); -const newsController = require('../controllers/newsController'); -const newsFileController = require('../controllers/newsFileController'); -const dynamicController = require('../controllers/dynamicController'); -const pdfController = require('../controllers/pdfController'); +const categoryController = require("../controllers/categoryController"); +const userController = require("../controllers/userController"); +const newsController = require("../controllers/newsController"); +const newsFileController = require("../controllers/newsFileController"); +const dynamicController = require("../controllers/dynamicController"); +const pdfController = require("../controllers/pdfController"); +const adminLogController = require("../controllers/adminLogController"); -const contentController = require('../controllers/contentController'); -const pollController = require('../controllers/pollController'); -const yearBannerController = require('../controllers/yearBannerController'); -const counterDayController = require('../controllers/counterDayController'); -const galleryController = require('../controllers/galleryController'); -const permissionsController = require('../controllers/permissionsController'); -const portalController = require('../controllers/portalController'); -const commentController = require('../controllers/commentController'); -const linksController = require('../controllers/linksController'); -const sliderController = require('../controllers/sliderController'); -const homeController = require('../controllers/homeController'); -const occasionController = require('../controllers/occasionController'); -const electionController = require('../controllers/electionController'); -const dataBackupController = require('../controllers/dataBackupController'); -const meetingController = require('../controllers/meetingController'); -// Permission +const contentController = require("../controllers/contentController"); +const pollController = require("../controllers/pollController"); +const yearBannerController = require("../controllers/yearBannerController"); +const counterDayController = require("../controllers/counterDayController"); +const galleryController = require("../controllers/galleryController"); +const permissionsController = require("../controllers/permissionsController"); +const portalController = require("../controllers/portalController"); +const commentController = require("../controllers/commentController"); +const linksController = require("../controllers/linksController"); +const sliderController = require("../controllers/sliderController"); +const homeController = require("../controllers/homeController"); +const occasionController = require("../controllers/occasionController"); +const electionController = require("../controllers/electionController"); +const dataBackupController = require("../controllers/dataBackupController"); +const meetingController = require("../controllers/meetingController"); + +////////////////////////////////////////////////////admin login log +router.get("/logs", adminLogController.getAdminLoginLogs); + +//////////////////////////////////////////////////// Permission /** * @swagger * /admin/permissions: @@ -54,7 +59,7 @@ const meetingController = require('../controllers/meetingController'); * type: string * description: Error message indicating the internal server error. */ -router.get('/permissions', permissionsController.getAll); +router.get("/permissions", permissionsController.getAll); // Portals /** * @swagger @@ -93,9 +98,9 @@ router.get('/permissions', permissionsController.getAll); * type: string * description: Error message indicating the internal server error. */ -router.get('/portals', portalController.getAll); +router.get("/portals", portalController.getAll); -router.post('/setScope/:id' , permissionsController.SetPermission) +router.post("/setScope/:id", permissionsController.SetPermission); /////////////// home controller /** * @swagger @@ -174,7 +179,7 @@ router.post('/setScope/:id' , permissionsController.SetPermission) * type: string * description: Error message indicating the internal server error. */ -router.get('/homePageSettings', homeController.getHomePage) +router.get("/homePageSettings", homeController.getHomePage); // Home Page Setting /** * @swagger @@ -263,7 +268,7 @@ router.get('/homePageSettings', homeController.getHomePage) * type: string * description: Error message indicating the internal server error. */ -router.post('/homePageSettings', homeController.updateHomePage); +router.post("/homePageSettings", homeController.updateHomePage); // Change Show InHome /** * @swagger @@ -337,7 +342,7 @@ router.post('/homePageSettings', homeController.updateHomePage); * type: string * description: Error message indicating the internal server error. */ -router.put('/changeShowInHome', homeController.changeShowInHome); +router.put("/changeShowInHome", homeController.changeShowInHome); // Get all Show In Home /** * @swagger @@ -387,7 +392,7 @@ router.put('/changeShowInHome', homeController.changeShowInHome); * type: string * description: Error message indicating the internal server error. */ -router.get('/getAllShowInHome', homeController.getAllShowInHomeFalse) +router.get("/getAllShowInHome", homeController.getAllShowInHomeFalse); //////////////// category policy // router.use('/category', ); @@ -446,7 +451,11 @@ router.get('/getAllShowInHome', homeController.getAllShowInHomeFalse) * type: string * description: Error message indicating the internal server error. */ -router.post('/category', hasPermission('categories'), categoryController.addCategory); +router.post( + "/category", + hasPermission("categories"), + categoryController.addCategory +); /** * @swagger @@ -517,7 +526,11 @@ router.post('/category', hasPermission('categories'), categoryController.addCate * type: string * description: Error message indicating the internal server error. */ -router.put('/category/:id', hasPermission('categories'), categoryController.updateCategory); +router.put( + "/category/:id", + hasPermission("categories"), + categoryController.updateCategory +); /** * @swagger @@ -582,7 +595,11 @@ router.put('/category/:id', hasPermission('categories'), categoryController.upda * type: string * description: Error message indicating the internal server error. */ -router.delete('/category/:id', hasPermission('categories'), categoryController.deletOneCategory); +router.delete( + "/category/:id", + hasPermission("categories"), + categoryController.deletOneCategory +); /** * @swagger * /admin/category/permissions: @@ -617,7 +634,7 @@ router.delete('/category/:id', hasPermission('categories'), categoryController.d * type: string * description: Error message indicating the internal server error. */ -router.get('/category/permissions', categoryController.permissions); +router.get("/category/permissions", categoryController.permissions); /** * @swagger * /admin/category/getParent: @@ -652,7 +669,7 @@ router.get('/category/permissions', categoryController.permissions); * type: string * description: Error message indicating the internal server error. */ -router.get('/category/getParent', categoryController.getParent); +router.get("/category/getParent", categoryController.getParent); /** * @swagger * /admin/category: @@ -682,7 +699,7 @@ router.get('/category/getParent', categoryController.getParent); * description: Error message indicating the internal server error. */ -router.get('/category', hasPermission('categories'), categoryController.getAll); +router.get("/category", hasPermission("categories"), categoryController.getAll); // router.get('/category/getIndex' , hasPermission('categories') , categoryController.getNavIndex); /** * @swagger @@ -737,7 +754,11 @@ router.get('/category', hasPermission('categories'), categoryController.getAll); * type: string * description: Error message indicating the internal server error. */ -router.get('/category/:id', hasPermission('categories'), categoryController.getOneCategory); +router.get( + "/category/:id", + hasPermission("categories"), + categoryController.getOneCategory +); /** * @swagger * /admin/category/search: @@ -776,7 +797,11 @@ router.get('/category/:id', hasPermission('categories'), categoryController.getO * type: string * description: Error message indicating the internal server error. */ -router.post('/category/search', hasPermission('categories'), categoryController.search); +router.post( + "/category/search", + hasPermission("categories"), + categoryController.search +); /** * @swagger * /admin/category/termsFile/{categoryId}: @@ -854,7 +879,11 @@ router.post('/category/search', hasPermission('categories'), categoryController. * type: string * description: Error message indicating the internal server error. */ -router.post('/category/termsFile/:categoryId', hasPermission('categories'), categoryController.addTermsFileToCategory); +router.post( + "/category/termsFile/:categoryId", + hasPermission("categories"), + categoryController.addTermsFileToCategory +); /** * @swagger * /admin/category/termsFile/{fileId}: @@ -902,7 +931,11 @@ router.post('/category/termsFile/:categoryId', hasPermission('categories'), cate * type: string * description: Error message indicating the internal server error. */ -router.delete('/category/termsFile/:fileId', hasPermission('categories'), categoryController.removeTermsFileFromCategory); +router.delete( + "/category/termsFile/:fileId", + hasPermission("categories"), + categoryController.removeTermsFileFromCategory +); // router.delete('/category' , categoryController.deleteAllCategory); //////////////// users policy @@ -1003,7 +1036,11 @@ router.delete('/category/termsFile/:fileId', hasPermission('categories'), catego * type: string * description: Error message indicating the internal server error. */ -router.post('/user/registerAdmin', hasPermission('users'), userController.registerAdmin); +router.post( + "/user/registerAdmin", + hasPermission("users"), + userController.registerAdmin +); /** * @swagger * /admin/user/changeStatus/{id}: @@ -1041,7 +1078,11 @@ router.post('/user/registerAdmin', hasPermission('users'), userController.regist * schema: * type: string */ -router.put('/user/changeStatus/:id', hasPermission('users'), userController.changeUserStatus); +router.put( + "/user/changeStatus/:id", + hasPermission("users"), + userController.changeUserStatus +); /** * @swagger * /admin/user/changePass/{id}: @@ -1112,7 +1153,11 @@ router.put('/user/changeStatus/:id', hasPermission('users'), userController.chan * type: string * example: { "message": "مشکلی در اجرای درخواست شما بوجود امده است" } */ -router.put('/user/changePass/:id', hasPermission('users'), userController.changePassword); +router.put( + "/user/changePass/:id", + hasPermission("users"), + userController.changePassword +); /** * @swagger * /admin/user: @@ -1168,7 +1213,7 @@ router.put('/user/changePass/:id', hasPermission('users'), userController.change * type: string * example: { "message": "مشکلی در گرفتن اطلاعات پیش آمده لطفا دوباره تلاش کنید" } */ -router.get('/user', hasPermission('users'), userController.getAllUsers); +router.get("/user", hasPermission("users"), userController.getAllUsers); /** * @swagger * /admin/user/{id}: @@ -1206,7 +1251,7 @@ router.get('/user', hasPermission('users'), userController.getAllUsers); * type: string * example: { "message": "An error occurred while processing your request." } */ -router.get('/user/:id', hasPermission('users'), userController.getUserByAdmin); +router.get("/user/:id", hasPermission("users"), userController.getUserByAdmin); /** * @swagger * /admin/user/{id}: @@ -1260,7 +1305,11 @@ router.get('/user/:id', hasPermission('users'), userController.getUserByAdmin); * type: string * example: "An error occurred while processing your request." */ -router.delete('/user/:id', hasPermission('users'), userController.deleteOneUser); +router.delete( + "/user/:id", + hasPermission("users"), + userController.deleteOneUser +); /** * @swagger * /admin/user/{id}: @@ -1380,7 +1429,7 @@ router.delete('/user/:id', hasPermission('users'), userController.deleteOneUser) * type: string * example: "An error occurred while processing your request." */ -router.put('/user/:id', hasPermission('users'), userController.updateUser); +router.put("/user/:id", hasPermission("users"), userController.updateUser); /** * @swagger * /admin/user/search: @@ -1444,7 +1493,7 @@ router.put('/user/:id', hasPermission('users'), userController.updateUser); * type: string * example: "An error occurred while processing your request." */ -router.post('/user/search', hasPermission('users'), userController.search); +router.post("/user/search", hasPermission("users"), userController.search); /** * @swagger * /admin/profile: @@ -1483,7 +1532,7 @@ router.post('/user/search', hasPermission('users'), userController.search); * type: string * example: "مشکلی در اجرای درخواست شما بوجود امده است" */ -router.get('/profile', userController.getProfile); +router.get("/profile", userController.getProfile); /** * @swagger * /admin/profile: @@ -1551,7 +1600,7 @@ router.get('/profile', userController.getProfile); * type: string * example: "مشکلی در اجرای درخواست شما بوجود امده است" */ -router.put('/profile', userController.updateProfile); +router.put("/profile", userController.updateProfile); /** * @swagger * /admin/profile/changePass: @@ -1617,18 +1666,16 @@ router.put('/profile', userController.updateProfile); * type: string * example: "مشکلی در اجرای درخواست شما بوجود امده است" */ -router.put('/profile/changePass', userController.changePasswordProfile); +router.put("/profile/changePass", userController.changePasswordProfile); +router.post("/book/add", pdfController.AddPDF); -router.post('/book/add', pdfController.AddPDF) - -router.get('/book/:id', pdfController.GetOne) - -router.delete('/book/:id', pdfController.DeleteOne) +router.get("/book/:id", pdfController.GetOne); +router.delete("/book/:id", pdfController.DeleteOne); //////////////// news policy -router.use('/news', hasPermission('news')); +router.use("/news", hasPermission("news")); /** * @swagger @@ -1714,7 +1761,7 @@ router.use('/news', hasPermission('news')); * type: string * example: "مشکلی در اجرای درخواست شما بوجود امده است" */ -router.post('/news', newsController.addNews); +router.post("/news", newsController.addNews); /** * @swagger * /admin/news/{id}: @@ -1775,7 +1822,7 @@ router.post('/news', newsController.addNews); * type: string * example: "مشکلی در اجرای درخواست شما بوجود امده است" */ -router.put('/news/:id', newsController.updateNews); +router.put("/news/:id", newsController.updateNews); /** * @swagger * /admin/news/{id}: @@ -1832,9 +1879,9 @@ router.put('/news/:id', newsController.updateNews); * example: "مشکلی در اجرای درخواست شما بوجود امده است" */ -router.get('/news/mostviewed' , newsController.MostViewdNews) +router.get("/news/mostviewed", newsController.MostViewdNews); -router.delete('/news/:id', newsController.deletOneNews); +router.delete("/news/:id", newsController.deletOneNews); /** * @swagger * /admin/news: @@ -1874,7 +1921,7 @@ router.delete('/news/:id', newsController.deletOneNews); * type: string * example: "مشکلی در گرفتن اطلاعات پیش آمده است" */ -router.get('/news', newsController.getAll); +router.get("/news", newsController.getAll); /** * @swagger * /admin/news/search: @@ -1945,7 +1992,7 @@ router.get('/news', newsController.getAll); * type: string * example: "خطای سرور: مشکلی در جستجوی خبرها رخ داده است" */ -router.post('/news/search', newsController.search); +router.post("/news/search", newsController.search); /** * @swagger * /admin/news/{id}: @@ -2001,7 +2048,7 @@ router.post('/news/search', newsController.search); * type: string * example: "خطای سرور: مشکلی در بازیابی خبر رخ داده است" */ -router.get('/news/:id', newsController.getOneNews); +router.get("/news/:id", newsController.getOneNews); /** * @swagger * /admin/news/attachments/{newsId}: @@ -2076,7 +2123,7 @@ router.get('/news/:id', newsController.getOneNews); * type: string * example: "خطای سرور: مشکلی در ذخیره اطلاعات رخ داده است" */ -router.post('/news/attachments/:newsId', newsController.addAttachmentToNews); +router.post("/news/attachments/:newsId", newsController.addAttachmentToNews); /** * @swagger * /admin/news/attachments/{fileId}: @@ -2126,9 +2173,10 @@ router.post('/news/attachments/:newsId', newsController.addAttachmentToNews); * type: string * example: "خطای سرور: مشکلی در ذخیره اطلاعات رخ داده است" */ -router.delete('/news/attachments/:fileId', newsController.removeAttachmentFromNews); - - +router.delete( + "/news/attachments/:fileId", + newsController.removeAttachmentFromNews +); /** * @swagger @@ -2200,7 +2248,11 @@ router.delete('/news/attachments/:fileId', newsController.removeAttachmentFromNe * type: string * example: "خطای سرور: مشکلی در اضافه کردن پرونده پرونده خبریی پیش آمده است" */ -router.post('/newsFile', hasPermission('newsFile'), newsFileController.addNewsFile); +router.post( + "/newsFile", + hasPermission("newsFile"), + newsFileController.addNewsFile +); /** * @swagger * /admin/newsFile/{id}: @@ -2298,7 +2350,11 @@ router.post('/newsFile', hasPermission('newsFile'), newsFileController.addNewsFi * type: string * example: "خطای سرور: مشکلی در آپدیت کردن پرونده خبریی پیش آمده است" */ -router.put('/newsFile/:id', hasPermission('newsFile'), newsFileController.updateNewsFile); +router.put( + "/newsFile/:id", + hasPermission("newsFile"), + newsFileController.updateNewsFile +); /** * @swagger * /admin/newsFile/{id}: @@ -2354,7 +2410,11 @@ router.put('/newsFile/:id', hasPermission('newsFile'), newsFileController.update * type: string * example: "Internal Server Error: Something went wrong" */ -router.delete('/newsFile/:id', hasPermission('newsFile'), newsFileController.deletOneNewsFile); +router.delete( + "/newsFile/:id", + hasPermission("newsFile"), + newsFileController.deletOneNewsFile +); /** * @swagger * /admin/newsFile: @@ -2385,7 +2445,7 @@ router.delete('/newsFile/:id', hasPermission('newsFile'), newsFileController.del * type: string * example: "Internal Server Error: Something went wrong" */ -router.get('/newsFile', newsFileController.getAll); +router.get("/newsFile", newsFileController.getAll); /** * @swagger * /admin/newsFile/{id}: @@ -2441,7 +2501,11 @@ router.get('/newsFile', newsFileController.getAll); * type: string * example: "Internal Server Error: Something went wrong" */ -router.get('/newsFile/:id', hasPermission('newsFile'), newsFileController.getOneNewsFile); +router.get( + "/newsFile/:id", + hasPermission("newsFile"), + newsFileController.getOneNewsFile +); /** * @swagger * /admin/newsFile/search: @@ -2491,10 +2555,14 @@ router.get('/newsFile/:id', hasPermission('newsFile'), newsFileController.getOne * type: string * example: "Internal Server Error: Something went wrong" */ -router.post('/newsFile/search', hasPermission('newsFile'), newsFileController.search); +router.post( + "/newsFile/search", + hasPermission("newsFile"), + newsFileController.search +); //////////////// contents policy -router.use('/content', hasPermission('contents')); +router.use("/content", hasPermission("contents")); /** * @swagger @@ -2560,7 +2628,7 @@ router.use('/content', hasPermission('contents')); * type: string * example: "Internal Server Error: Something went wrong" */ -router.post('/content', contentController.addContent); +router.post("/content", contentController.addContent); /** * @swagger * /admin/content/{param}: @@ -2635,7 +2703,7 @@ router.post('/content', contentController.addContent); * type: string * example: "Internal Server Error: Something went wrong" */ -router.put('/content/:param', contentController.updateContent); +router.put("/content/:param", contentController.updateContent); /** * @swagger * /admin/content/{param}: @@ -2677,12 +2745,12 @@ router.put('/content/:param', contentController.updateContent); * type: string * example: "Internal Server Error: Something went wrong" */ -router.get('/content/:param', contentController.getOneContent); +router.get("/content/:param", contentController.getOneContent); //////////////// comments policy // router.use('/comment/:model', hasPermission('newsComment')); -router.param('model', hasSubPermission()) +router.param("model", hasSubPermission()); /** * @swagger * /admin/comment/{model}/changeStatus/{id}: @@ -2730,7 +2798,7 @@ router.param('model', hasSubPermission()) * type: string * example: "Internal Server Error: Something went wrong" */ -router.put('/comment/:model/changeStatus/:id', commentController.changeStatus); +router.put("/comment/:model/changeStatus/:id", commentController.changeStatus); /** * @swagger * /admin/comment/{model}/{id}: @@ -2810,7 +2878,7 @@ router.put('/comment/:model/changeStatus/:id', commentController.changeStatus); * type: string * example: "Internal Server Error: Something went wrong" */ -router.put('/comment/:model/:id', commentController.updateComment); +router.put("/comment/:model/:id", commentController.updateComment); /** * @swagger * /admin/comment/{model}/{id}: @@ -2858,7 +2926,7 @@ router.put('/comment/:model/:id', commentController.updateComment); * type: string * example: "Internal Server Error: Something went wrong" */ -router.delete('/comment/:model/:id', commentController.deletOneComment); +router.delete("/comment/:model/:id", commentController.deletOneComment); /** * @swagger * /admin/comment/countAll/{model}: @@ -2903,7 +2971,7 @@ router.delete('/comment/:model/:id', commentController.deletOneComment); * type: string * example: "Internal Server Error: Something went wrong" */ -router.get('/comment/countAll/:model', commentController.getAllforCount); +router.get("/comment/countAll/:model", commentController.getAllforCount); /** * @swagger * /admin/comment/{model}: @@ -2966,7 +3034,7 @@ router.get('/comment/countAll/:model', commentController.getAllforCount); * type: string * example: "Internal Server Error: Something went wrong" */ -router.get('/comment/:model', commentController.getAll); +router.get("/comment/:model", commentController.getAll); /** * @swagger * /admin/comment/{model}/search: @@ -3053,7 +3121,7 @@ router.get('/comment/:model', commentController.getAll); * type: string * example: "Internal Server Error: Something went wrong" */ -router.post('/comment/:model/search', commentController.search); +router.post("/comment/:model/search", commentController.search); /** * @swagger * /admin/comment/{model}/{id}: @@ -3097,13 +3165,12 @@ router.post('/comment/:model/search', commentController.search); * schema: * $ref: '#/components/schemas/Error' */ -router.get('/comment/:model/:id', commentController.getOneComment); +router.get("/comment/:model/:id", commentController.getOneComment); /////////////// contactUs // router.put('/contactUs' , contactUsController.updateContacUs); // router.get('/contactUs' , contactUsController.getOneContacUs); - /** * @swagger * /admin/comment/{model}/{id}: @@ -3147,7 +3214,7 @@ router.get('/comment/:model/:id', commentController.getOneComment); * schema: * $ref: '#/components/schemas/Error' */ -router.post('/yearBanner', yearBannerController.updateYearBanner); +router.post("/yearBanner", yearBannerController.updateYearBanner); /** * @swagger * /admin/counterDay: @@ -3204,7 +3271,7 @@ router.post('/yearBanner', yearBannerController.updateYearBanner); * $ref: '#/components/schemas/Error' */ ////////////// counter day -router.post('/counterDay', counterDayController.updateCounterDay); +router.post("/counterDay", counterDayController.updateCounterDay); /** * @swagger * /admin/counterDay: @@ -3229,10 +3296,9 @@ router.post('/counterDay', counterDayController.updateCounterDay); * schema: * $ref: '#/components/schemas/Error' */ -router.get('/counterDay', counterDayController.getCounterDayByAdmin); +router.get("/counterDay", counterDayController.getCounterDayByAdmin); - -router.use('/gallery', hasPermission('gallery')); +router.use("/gallery", hasPermission("gallery")); /** * @swagger @@ -3284,7 +3350,7 @@ router.use('/gallery', hasPermission('gallery')); * schema: * $ref: '#/components/schemas/Error' */ -router.post('/gallery/uploadFile', galleryController.uploadFile); +router.post("/gallery/uploadFile", galleryController.uploadFile); /** * @swagger * /admin/gallery/deleteFile: @@ -3336,7 +3402,7 @@ router.post('/gallery/uploadFile', galleryController.uploadFile); * schema: * $ref: '#/components/schemas/Error' */ -router.post('/gallery/deleteFile', galleryController.deleteFile); +router.post("/gallery/deleteFile", galleryController.deleteFile); /** * @swagger * /admin/gallery/uploadCover: @@ -3388,7 +3454,7 @@ router.post('/gallery/deleteFile', galleryController.deleteFile); * schema: * $ref: '#/components/schemas/Error' */ -router.post('/gallery/uploadCover', galleryController.uploadCover); +router.post("/gallery/uploadCover", galleryController.uploadCover); /** * @swagger * /admin/gallery: @@ -3485,7 +3551,7 @@ router.post('/gallery/uploadCover', galleryController.uploadCover); * schema: * $ref: '#/components/schemas/Error' */ -router.post('/gallery', galleryController.addGallery); +router.post("/gallery", galleryController.addGallery); /** * @swagger * /admin/gallery/{id}: @@ -3595,7 +3661,7 @@ router.post('/gallery', galleryController.addGallery); * schema: * $ref: '#/components/schemas/Error' */ -router.put('/gallery/:id', galleryController.updateGallery); +router.put("/gallery/:id", galleryController.updateGallery); /** * @swagger * /admin/gallery/{id}: @@ -3639,7 +3705,7 @@ router.put('/gallery/:id', galleryController.updateGallery); * schema: * $ref: '#/components/schemas/Error' */ -router.delete('/gallery/:id', galleryController.deletOneGallery); +router.delete("/gallery/:id", galleryController.deletOneGallery); /** * @swagger * /admin/gallery: @@ -3700,7 +3766,7 @@ router.delete('/gallery/:id', galleryController.deletOneGallery); * schema: * $ref: '#/components/schemas/Error' */ -router.get('/gallery', galleryController.getAll); +router.get("/gallery", galleryController.getAll); /** * @swagger * /admin/gallery/search: @@ -3794,7 +3860,7 @@ router.get('/gallery', galleryController.getAll); * message: * type: string */ -router.post('/gallery/search', galleryController.search); +router.post("/gallery/search", galleryController.search); /** * @swagger * /admin/gallery/{id}: @@ -3839,10 +3905,10 @@ router.post('/gallery/search', galleryController.search); * message: * type: string */ -router.get('/gallery/:id', galleryController.getOneGallery); +router.get("/gallery/:id", galleryController.getOneGallery); //////////// policy -router.use('/links', hasPermission('superAdmin')); +router.use("/links", hasPermission("superAdmin")); /** * @swagger @@ -3910,7 +3976,7 @@ router.use('/links', hasPermission('superAdmin')); * message: * type: string */ -router.post('/links', linksController.addLinks); +router.post("/links", linksController.addLinks); /** * @swagger * /admin/links/{id}: @@ -3993,7 +4059,7 @@ router.post('/links', linksController.addLinks); * message: * type: string */ -router.put('/links/:id', linksController.updateLinks); +router.put("/links/:id", linksController.updateLinks); /** * @swagger * /admin/links/{id}: @@ -4037,7 +4103,7 @@ router.put('/links/:id', linksController.updateLinks); * message: * type: string */ -router.delete('/links/:id', linksController.deletOneLinks); +router.delete("/links/:id", linksController.deletOneLinks); /** * @swagger * /admin/links: @@ -4067,7 +4133,7 @@ router.delete('/links/:id', linksController.deletOneLinks); * message: * type: string */ -router.get('/links', linksController.getAll); +router.get("/links", linksController.getAll); /** * @swagger * /admin/links/{id}: @@ -4123,10 +4189,10 @@ router.get('/links', linksController.getAll); * type: string * description: Error message indicating server error. */ -router.get('/links/:id', linksController.getOneLinks); +router.get("/links/:id", linksController.getOneLinks); //////////// policy -router.use('/slider', hasPermission('superAdmin')); +router.use("/slider", hasPermission("superAdmin")); /** * @swagger @@ -4187,7 +4253,7 @@ router.use('/slider', hasPermission('superAdmin')); * type: string * description: Error message indicating server error. */ -router.post('/slider', sliderController.addSlider); +router.post("/slider", sliderController.addSlider); /** * @swagger * /admin/slider/{id}: @@ -4256,7 +4322,7 @@ router.post('/slider', sliderController.addSlider); * type: string * description: Error message indicating server error. */ -router.put('/slider/:id', sliderController.updateSlider); +router.put("/slider/:id", sliderController.updateSlider); /** * @swagger * /admin/slider/{id}: @@ -4294,7 +4360,7 @@ router.put('/slider/:id', sliderController.updateSlider); * type: string * description: Error message indicating server error. */ -router.delete('/slider/:id', sliderController.deletOneSlider); +router.delete("/slider/:id", sliderController.deletOneSlider); /** * @swagger * /admin/slider: @@ -4325,7 +4391,7 @@ router.delete('/slider/:id', sliderController.deletOneSlider); * type: string * description: Error message indicating server error. */ -router.get('/slider', sliderController.getAllSliderByAdmin); +router.get("/slider", sliderController.getAllSliderByAdmin); /** * @swagger * /admin/slider/search: @@ -4385,7 +4451,7 @@ router.get('/slider', sliderController.getAllSliderByAdmin); * type: string * description: Error message indicating server error. */ -router.post('/slider/search', sliderController.search); +router.post("/slider/search", sliderController.search); /** * @swagger * /admin/slider/{id}: @@ -4442,7 +4508,7 @@ router.post('/slider/search', sliderController.search); * type: string * description: Error message indicating server error. */ -router.get('/slider/:id', sliderController.getOneSlider); +router.get("/slider/:id", sliderController.getOneSlider); /** * @swagger @@ -4507,7 +4573,7 @@ router.get('/slider/:id', sliderController.getOneSlider); * description: Error message indicating a server error. */ //////////// occasion -router.post('/occasion', occasionController.addOccasion); +router.post("/occasion", occasionController.addOccasion); /** * @swagger * /occasion/{id}: @@ -4587,7 +4653,7 @@ router.post('/occasion', occasionController.addOccasion); * type: string * description: Error message indicating a server error. */ -router.put('/occasion/:id', occasionController.updateOccasion); +router.put("/occasion/:id", occasionController.updateOccasion); /** * @swagger * /occasion/{id}: @@ -4637,7 +4703,7 @@ router.put('/occasion/:id', occasionController.updateOccasion); * type: string * description: Error message indicating a server error. */ -router.delete('/occasion/:id', occasionController.deleteOccasion); +router.delete("/occasion/:id", occasionController.deleteOccasion); /** * @swagger * /occasion: @@ -4704,7 +4770,7 @@ router.delete('/occasion/:id', occasionController.deleteOccasion); * type: string * description: Error message indicating a server error. */ -router.get('/occasion', occasionController.getAllOccasionByAdmin); +router.get("/occasion", occasionController.getAllOccasionByAdmin); /** * @swagger * /occasion/allOccasion: @@ -4733,7 +4799,7 @@ router.get('/occasion', occasionController.getAllOccasionByAdmin); * type: string * description: Error message indicating a server error. */ -router.get('/occasion/allOccasion', occasionController.getAllOccasionForIndex); +router.get("/occasion/allOccasion", occasionController.getAllOccasionForIndex); /** * @swagger * /occasion/search: @@ -4800,7 +4866,7 @@ router.get('/occasion/allOccasion', occasionController.getAllOccasionForIndex); * type: string * description: Error message indicating a server error. */ -router.post('/occasion/search', occasionController.search); +router.post("/occasion/search", occasionController.search); /** * @swagger * /occasion/{id}: @@ -4844,7 +4910,7 @@ router.post('/occasion/search', occasionController.search); * type: string * description: Error message indicating a server error. */ -router.get('/occasion/:id', occasionController.getOccasionByAdmin); +router.get("/occasion/:id", occasionController.getOccasionByAdmin); /** * @swagger * /admin/clearBackups: @@ -4876,14 +4942,14 @@ router.get('/occasion/:id', occasionController.getOccasionByAdmin); * description: Error message indicating a server error. */ //////////// backup -router.post('/clearBackups', dataBackupController.removeOldBackups) +router.post("/clearBackups", dataBackupController.removeOldBackups); -router.post('/create-model' , dynamicController.CreateModel) +router.post("/create-model", dynamicController.CreateModel); -router.post('/save-form' , dynamicController.SaveDataModel) +router.post("/save-form", dynamicController.SaveDataModel); //////////////// polls policy -router.use('/poll', hasPermission('polls')); +router.use("/poll", hasPermission("polls")); /** * @swagger * /admin/poll: @@ -4989,7 +5055,7 @@ router.use('/poll', hasPermission('polls')); * example: "مشکلی در اجرای درخواست شما بوجود آمده است" */ /////////////// polls -router.post('/poll', pollController.addSurvey); +router.post("/poll", pollController.addSurvey); /** * @swagger * /admin/poll/{id}: @@ -5112,7 +5178,7 @@ router.post('/poll', pollController.addSurvey); * description: Error message. * example: "مشکلی در اجرای درخواست شما بوجود آمده است" */ -router.put('/poll/:id', pollController.updateSurvey); +router.put("/poll/:id", pollController.updateSurvey); /** * @swagger * /admin/poll/{id}: @@ -5174,7 +5240,7 @@ router.put('/poll/:id', pollController.updateSurvey); * description: Error message. * example: "مشکلی در اجرای درخواست شما بوجود آمده است" */ -router.delete('/poll/:id', pollController.deletOneSurvey); +router.delete("/poll/:id", pollController.deletOneSurvey); /** * @swagger * /admin/poll: @@ -5272,7 +5338,7 @@ router.delete('/poll/:id', pollController.deletOneSurvey); * description: Error message. * example: "مشکلی در اجرای درخواست شما بوجود آمده است" */ -router.get('/poll', pollController.getAllSurvey); +router.get("/poll", pollController.getAllSurvey); /** * @swagger * /admin/poll/search: @@ -5389,7 +5455,7 @@ router.get('/poll', pollController.getAllSurvey); * description: Error message. * example: "مشکلی در اجرای درخواست شما بوجود آمده است" */ -router.post('/poll/search', pollController.search); +router.post("/poll/search", pollController.search); /** * @swagger * /admin/poll/{id}: @@ -5493,10 +5559,10 @@ router.post('/poll/search', pollController.search); * description: Error message. * example: "مشکلی در اجرای درخواست شما بوجود آمده است" */ -router.get('/poll/:id', pollController.getOneSurvey); +router.get("/poll/:id", pollController.getOneSurvey); //////////////// election policy -router.use('/election', hasPermission('elections')); +router.use("/election", hasPermission("elections")); /** * @swagger * /admin/election: @@ -5604,7 +5670,7 @@ router.use('/election', hasPermission('elections')); * example: "مشکلی در اجرای درخواست شما بوجود آمده است" */ /////////////// election -router.post('/election', electionController.addElection); +router.post("/election", electionController.addElection); /** * @swagger * /admin/election/{id}: @@ -5692,7 +5758,7 @@ router.post('/election', electionController.addElection); * description: Error message. * example: "مشکلی در اجرای درخواست شما بوجود آمده است" */ -router.put('/election/:id', electionController.updateElection); +router.put("/election/:id", electionController.updateElection); /** * @swagger * /admin/election/{id}: @@ -5753,7 +5819,7 @@ router.put('/election/:id', electionController.updateElection); * description: Error message. * example: "مشکلی در اجرای درخواست شما بوجود آمده است" */ -router.delete('/election/:id', electionController.deletOneElection); +router.delete("/election/:id", electionController.deletOneElection); /** * @swagger * /admin/election: @@ -5841,7 +5907,7 @@ router.delete('/election/:id', electionController.deletOneElection); * description: Error message. * example: "مشکلی در اجرای درخواست شما بوجود آمده است" */ -router.get('/election', electionController.getAllElection); +router.get("/election", electionController.getAllElection); /** * @swagger * /admin/election/search: @@ -5909,7 +5975,7 @@ router.get('/election', electionController.getAllElection); * description: Error message. * example: "مشکلی در اجرای درخواست شما بوجود آمده است" */ -router.post('/election/search', electionController.search); +router.post("/election/search", electionController.search); /** * @swagger * /admin/election/{id}: @@ -5967,7 +6033,7 @@ router.post('/election/search', electionController.search); * description: Error message. * example: "مشکلی در اجرای درخواست شما بوجود آمده است" */ -router.get('/election/:id', electionController.getOneElection); +router.get("/election/:id", electionController.getOneElection); /** * @swagger * /admin/election/candidate/{id}: @@ -6085,7 +6151,7 @@ router.get('/election/:id', electionController.getOneElection); * example: "مشکلی در اجرای درخواست شما بوجود آمده است" */ /////////////// candidate -router.post('/election/candidate/:id', electionController.addCandidate); +router.post("/election/candidate/:id", electionController.addCandidate); /** * @swagger * /admin/election/candidate/{id}: @@ -6208,7 +6274,7 @@ router.post('/election/candidate/:id', electionController.addCandidate); * description: Error message. * example: "مشکلی در اجرای درخواست شما بوجود آمده است" */ -router.put('/election/candidate/:id', electionController.updateCandidate); +router.put("/election/candidate/:id", electionController.updateCandidate); /** * @swagger * /admin/election/candidate/{id}/{canId}: @@ -6268,7 +6334,10 @@ router.put('/election/candidate/:id', electionController.updateCandidate); * description: Error message. * example: "مشکلی در اجرای درخواست شما بوجود آمده است" */ -router.delete('/election/candidate/:id/:canId', electionController.deleteCandidate); +router.delete( + "/election/candidate/:id/:canId", + electionController.deleteCandidate +); /** * @swagger * /admin/election/voter/{id}: @@ -6346,7 +6415,7 @@ router.delete('/election/candidate/:id/:canId', electionController.deleteCandida * example: "مشکلی در اجرای درخواست شما بوجود آمده است" */ /////////////// voter -router.post('/election/voter/:id', electionController.addVoter); +router.post("/election/voter/:id", electionController.addVoter); /** * @swagger * /admin/election/voter/{id}: @@ -6423,7 +6492,7 @@ router.post('/election/voter/:id', electionController.addVoter); * description: Error message. * example: "مشکلی در اجرای درخواست شما بوجود آمده است" */ -router.put('/election/voter/:id', electionController.updateVoter); +router.put("/election/voter/:id", electionController.updateVoter); /** * @swagger * /admin/election/voter/{id}/{voterId}: @@ -6481,7 +6550,7 @@ router.put('/election/voter/:id', electionController.updateVoter); * description: Error message. * example: "مشکلی در اجرای درخواست شما بوجود آمده است" */ -router.delete('/election/voter/:id/:voterId', electionController.deleteVoter); +router.delete("/election/voter/:id/:voterId", electionController.deleteVoter); /** * @swagger * /admin/meeting/{id}: @@ -6579,7 +6648,7 @@ router.delete('/election/voter/:id/:voterId', electionController.deleteVoter); * example: "مشکلی در اجرای درخواست شما بوجود آمده است" */ //////////// meeting -router.put('/meeting/:id', meetingController.updateMeeting); +router.put("/meeting/:id", meetingController.updateMeeting); /** * @swagger * /admin/meeting/{id}: @@ -6631,7 +6700,7 @@ router.put('/meeting/:id', meetingController.updateMeeting); * example: "مشکلی در اجرای درخواست شما بوجود آمده است" */ -router.delete('/meeting/:id', meetingController.deletOneMeeting); +router.delete("/meeting/:id", meetingController.deletOneMeeting); /** * @swagger * /admin/meeting: @@ -6696,7 +6765,7 @@ router.delete('/meeting/:id', meetingController.deletOneMeeting); * description: Error message. * example: "مشکلی در اجرای درخواست شما بوجود آمده است" */ -router.get('/meeting', meetingController.getAll); +router.get("/meeting", meetingController.getAll); /** * @swagger * /admin/meeting/getCount: @@ -6725,7 +6794,7 @@ router.get('/meeting', meetingController.getAll); * description: Error message. * example: "مشکلی در اجرای درخواست شما بوجود آمده است" */ -router.get('/meeting/getCount', meetingController.getAllForCount); +router.get("/meeting/getCount", meetingController.getAllForCount); /** * @swagger * /admin/meeting/search: @@ -6785,7 +6854,7 @@ router.get('/meeting/getCount', meetingController.getAllForCount); * description: Error message. * example: "مشکلی در اجرای درخواست شما بوجود آمده است" */ -router.post('/meeting/search', meetingController.search); +router.post("/meeting/search", meetingController.search); /** * @swagger * /admin/meeting/{id}: @@ -6831,6 +6900,6 @@ router.post('/meeting/search', meetingController.search); * description: Error message. * example: "مشکلی در اجرای درخواست شما بوجود آمده است" */ -router.get('/meeting/:id', meetingController.getOneMeeting); +router.get("/meeting/:id", meetingController.getOneMeeting); module.exports = router; diff --git a/server/routes/auth.js b/server/routes/auth.js index 2c0aa0c..07fb70e 100644 --- a/server/routes/auth.js +++ b/server/routes/auth.js @@ -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;