feat: add ci cd files dont edit those files

This commit is contained in:
mahyargdz
2024-10-21 10:22:26 +03:30
commit fb5b440d42
321 changed files with 188273 additions and 0 deletions
+166
View File
@@ -0,0 +1,166 @@
const jwt = require('jsonwebtoken')
const User = require('./models/User');
const {res500} = require('./plugins/controllersHelperFunctions');
const Category = require('./models/Category');
const Election = require('./models/Election');
const authentication = {
// secret for generating jwt token
secretKey: 'kyQa8pFI5BJnj7LCVPlSfoATTSZuS5DMSjgBPxQo2zkcdKnxKCPzWs1DEBgMfnXFsjgT0YWgqn8HgLLcmdIgSR6fSQpy6vchmY3kUSD564J',
// check if just logged in (admin-or-user) (middleware)
isLoggedIn: async function (req, res, next) {
try {
const token = req.headers.authorization?.replace(/^Bearer\s/, '');
if (token) {
// check if token is not destroyed
var user = await User.findOne({token: token});
if (!user) {
return res.status(401).json({message: 'unauthorized'});
}
if (!user.registration_done) {
return res500(res, 'user is disable please contact to support');
}
//verifies secret and checks if the token is expired
try {
var checkToken = await jwt.verify(user.token.replace(/^Bearer\s/, ''), authentication.secretKey);
if (!checkToken) {
return res.status(401).json({message: 'unauthorized'});
}
} catch (error) {
return res.status(401).json({message: 'unauthorized'});
}
req.user = {
_id: user._id,
scope: user.scope,
portals: user.portals,
permissions: user.permissions,
specialPermissions: user.specialPermissions,
private: user.private
};
return next();
} else {
return res.status(401).json({message: 'unauthorized'});
}
} catch (error) {
return res500(res, error.message);
}
},
// check if admin logged in (middleware)
isAdmin: async function (req, res, next) {
/** if req.user exist find user and check scope */
/** req.user send from isLoggedIn */
try {
if (req.user) {
const scope = req.user.scope;
if (!scope.includes('admin')) {
return res.status(401).json({message: 'unauthorized'});
}
return next()
} else {
return res.status(401).json({message: 'unauthorized'});
}
} catch (error) {
return res.status(401).json({message: 'unauthorized'});
}
},
// check if user has permission (middleware)
hasPermission: (permission) => {
return (req, res, next) => {
if (req.user && req.user.permissions) {
const permissions = req.user.permissions;
if (permissions.includes('superAdmin')) {
return next();
}
if (!permissions.includes(permission)) {
return res.status(401).json({message: 'unauthorized'});
} else {
return next();
}
} else {
return res.status(401).json({message: 'unauthorized'});
}
}
},
// hasSpecPermission: () => {
// return async (req, res, next) => {
// if (req.user && req.user.specialPermissions.length) {
// const specialPermissions = req.user.specialPermissions;
// if (req.user.permissions.includes('superAdmin')) {
// return next();
// }
// let tempSpec = [];
// for (const spec of specialPermissions) {
// const check = await Category.findById(spec);
//
// if (check){
// tempSpec.push(check._id);
// }
// }
//
// if (tempSpec.length){
// req.user.allSpecialPermissions = tempSpec;
// next();
// }else {
// return res.status(401).json({message: 'unauthorized'});
// }
// } else {
// return next();
// }
// }
// },
hasSubPermission: () => {
return (req, res, next, value) => {
if (req.user && req.user.permissions) {
var permissions = req.user.permissions;
if (permissions.includes('superAdmin')) {
return next();
}
if (!permissions.some(item => new RegExp(value, 'i').test(item))) {
return res.status(401).json({message: 'unauthorized'});
} else {
return next();
}
} else {
return res.status(401).json({message: 'unauthorized'});
}
}
},
isVoter: async function (req, res, next) {
try {
const token = req.headers.authorization?.replace(/^Bearer\s/, '');
if (token) {
// check if token is not destroyed
const user = await Election.findOne({'voters': {$elemMatch: {_id: token}}});
if (!user) {
return res.status(401).json({message: 'unauthorized'});
}
const voter = user.voters.id(token);
req.voter = {
_id: voter._id,
username: voter.username,
password: voter.password,
voted: voter.voted
};
return next();
} else {
return res.status(401).json({message: 'unauthorized'});
}
} catch (error) {
return res500(res, error.message);
}
},
}
module.exports = authentication
+28
View File
@@ -0,0 +1,28 @@
const Captcha = require('../models/Captcha');
const svgCaptcha = require('svg-captcha');
const {_sr} = require('../plugins/serverResponses');
const {res404, res500, generateRandomDigits} = require('../plugins/controllersHelperFunctions');
const svgWidth = 50;
const svgHeight = 20;
module.exports.getCaptcha = [
async (req, res) => {
try {
const generateCaptcha = svgCaptcha.create({
size : 6,
noise : 2
});
const saveCaptcha = await Captcha.create({code : generateCaptcha.text});
if (saveCaptcha){
return res.json(generateCaptcha.data);
}else {
return res500(res , `مشکلی در اجرای درخواست شما پیش آمده است`);
}
}catch (e) {
return res500(res , `مشکلی در اجرای درخواست شما پیش آمده است`);
}
}
]
File diff suppressed because it is too large Load Diff
+459
View File
@@ -0,0 +1,459 @@
const {body, validationResult} = require('express-validator');
const {_sr} = require('../plugins/serverResponses');
const {res404, res500} = require('../plugins/controllersHelperFunctions');
const Comment = require('../models/Comment');
const News = require('../models/News');
const ContactUs = require('../models/ContactUs');
const Category = require('../models/Category');
const Captcha = require('../models/Captcha');
const limit = 20;
/////////////////////////////////////////////////////////////////////// admin
module.exports.updateComment = [
[
body('name')
.notEmpty().withMessage(_sr['fa'].required.name),
body('description')
.notEmpty().withMessage(_sr['fa'].required.description),
body('email')
.isEmail().withMessage(_sr['fa'].format.email),
body('allowShow')
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
],
async (req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({
validation: errors.mapped()
});
try {
/**
* get data from input
*/
var {
name,
description,
email,
allowShow
} = req.body;
/**
* get id
*/
var commentId = req.params.id;
/**
* check comment exist or not
*/
var targetComment = await Comment.findOne({_id : commentId});
if(!targetComment) return res404(res,`پیام مورد نظر پیدا نشد`);
/**
* make update object
*/
targetComment.name = name.trim();
targetComment.description = description.trim();
targetComment.email = email;
targetComment.allowShow = allowShow;
await targetComment.save();
/**
* show result
*/
return res.json(targetComment);
} catch (error) {
return res500(res , error?.message);
}
}
]
module.exports.changeStatus = [
async (req, res) => {
try {
/**
* get id
*/
var commentId = req.params.id;
/**
* check comment exist or not
*/
var targetComment = await Comment.findOne({_id : commentId});
if(!targetComment) return res404(res,`پیام مورد نظر پیدا نشد`);
/**
* make update object
*/
targetComment.allowShow = !targetComment.allowShow;
await targetComment.save();
/**
* show result
*/
return res.json(targetComment);
} catch (error) {
return res500(res , error.message);
}
}
]
module.exports.deletOneComment = [
async (req, res) => {
try {
var commentId = req.params.id;
/**
* check comment
*/
var targetComment = await Comment.findOne({_id : commentId});
if(!targetComment){
return res404(res , `پیام مورد نظر پیدا نشد`);
}
/**
* delete comment
*/
targetComment.deleteOne();
/**
* show result
*/
return res.json(targetComment);
} catch (error) {
/**
* if we got unknown error show to client
*/
res500(res , error);
}
}
]
module.exports.getOneComment = [
async (req, res) => {
try {
const commentId = req.params.id;
/**
* get comment
*/
const targetComment = await Comment.findOne({_id : commentId}).populate('modelRef');
/**
* if not exist
*/
if(!targetComment){
return res404(res , `پیام مورد نظر پیدا نشد`);
}
if(!targetComment.read){
targetComment.read = true;
await targetComment.save();
}
/**
* show result
*/
return res.json(targetComment);
} catch (error) {
/**
* if we got unknown error show to client
*/
res500(res , error);
}
}
]
module.exports.getAll = [
async (req, res) => {
try {
let findQuery = {};
findQuery.modelName = req.params.model;
if (req.params.model !== 'ContactUs'){
if (req.user.specialPermissions.length) {
findQuery.catsId = {$in : req.user.specialPermissions};
}
}
/**
* get all comment
*/
const getAll = await Comment.paginate(findQuery ,
{page: req.query.page || 1 , limit , populate : 'modelRef' , sort:{created_at : -1}});
/**
* show result
*/
return res.json(getAll);
} catch (error) {
return res500(res , error.message);
}
}
]
module.exports.getAllforCount = [
async (req, res) => {
try {
let findQuery = {};
findQuery.modelName = req.params.model;
if (req.params.model !== 'ContactUs'){
if (req.user.specialPermissions.length) {
findQuery.catsId = {$in : req.user.specialPermissions};
}
}
/**
* get all comment
*/
const getAll = await Comment.find(findQuery).populate('modelRef');
/**
* show result
*/
return res.json(getAll);
} catch (error) {
return res500(res , error.message);
}
}
]
module.exports.search = [
async (req, res) => {
try {
var findQuery = {};
findQuery['$and'] = [];
findQuery['$or'] = [];
var {
name,
email,
read,
allowShow,
date
} = req.body;
findQuery.modelName = req.params.model;
if (req.params.model !== 'ContactUs'){
if (req.user.specialPermissions.length) {
findQuery.catsId = {$in : req.user.specialPermissions};
}
}
/** search by term */
if (name && !_.isEmpty(name)) {
findQuery['$or'].push(
{
name: {
$regex: '.*' + name + '.*'
},
}
);
}
/** search by email */
if (email && !_.isEmpty(email)) {
findQuery['$and'].push({
email
});
}
/** search by read */
if (!_.isUndefined(read) && _.isBoolean(read)) {
findQuery['$and'].push({
read
});
}
/** search by allowShow */
if (!_.isUndefined(allowShow) && _.isBoolean(allowShow)) {
findQuery['$and'].push({
allowShow
})
}
/** search by date */
if (date && !_.isEmpty(date)) {
if(date.length === 1){
findQuery['$and'].push({
created_at: {
$gte: moment(date[0]).startOf('days'),
$lt: moment(date[0]).endOf('days')
}
});
}else{
findQuery['$and'].push({
created_at: {
$gte: new Date(date[0]),
$lt: new Date(date[1])
}
});
}
}
_.isEmpty(findQuery['$and']) && delete findQuery['$and'];
_.isEmpty(findQuery['$or']) && delete findQuery['$or'];
/** get comments */
var comments = await Comment.paginate(findQuery , {page : req.query.page , limit, populate : 'modelRef' , sort:{created_at : -1}});
/** show result */
return res.json(comments);
} catch (error) {
return res500(res ,error?.message)
}
}
]
/////////////////////////////////////////////////////////////////////// public
module.exports.addComment = [
[
body('name')
.notEmpty().withMessage(_sr['fa'].required.title),
body('description')
.notEmpty().withMessage(_sr['fa'].required.description),
body('email')
.isEmail().withMessage(_sr['fa'].format.email),
body('modelId')
.if((value , {req}) => {
return req.body.modelName !== 'contactus';
})
.notEmpty().withMessage(`این فیلد ${_sr['fa'].optional.string}`),
body('modelName')
.isString().withMessage(`این فیلد ${_sr['fa'].optional.string}`)
.bail()
.isIn(['news' , 'contactus' , 'category']).withMessage(`${_sr['fa'].optional.onlyValid} 'news' , 'contactus' , 'category'`),
body('captcha')
.notEmpty().withMessage(_sr['fa'].required.field)
.custom((value , {req}) => {
return Captcha.findOne({code : value}).then(data => {
if (!data) return Promise.reject(`عبارت وارد شده صحیح نمیباشد`)
else return true
})
}),
],
async (req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({
validation: errors.mapped()
});
try {
let {
name,
description,
email,
modelId,
modelName
} = req.body;
let Model;
switch (modelName) {
case 'news':
Model = News;
modelName = 'News';
break;
case 'contactus':
Model = ContactUs
modelName = 'ContactUs';
break;
case 'category':
Model = Category
modelName = 'Category';
break;
}
let checkParent = null;
if(modelName !== 'ContactUs'){
checkParent = await Model.findOne({_id : modelId});
if(!checkParent){
return res404(res , `ای دی فرستاده شده وجود ندارد`);
}
if(!checkParent?.allowComment){
return res.status(403).json({message : `شما اجازه پیام گذاشتن برای این خبر یا صفحه را ندارید`});
}
}
const commentData = {
name : name.trim(),
description : description.trim(),
email : email.trim(),
modelRef : modelId || null,
modelName,
modelType : checkParent?.modelType || null,
_updatedBy : req.user?._id || null
};
if (modelName !== 'ContactUs'){
commentData.catsId = modelName === 'Category' ? checkParent?.treeCat || [] : checkParent?.allCat || []
}
/**
* add new comment
*/
const create = await Comment.create(commentData);
/**
* check added or not
*/
if (!create) {
return res500(res, `مشکلی در اضافه کردن پیام پیش آمده است`);
}
/**
* show result
*/
return res.json(create);
} catch (error) {
/**
* if we got unknown error show to client
*/
return res500(res , error?.message);
}
}
]
module.exports.getCommentById = [
async (req , res) => {
try {
const modelId = req.params.id;
const getComments = await Comment.find({modelRef: modelId, allowShow: true});
return res.json(getComments);
} catch (error) {
return res500(res , error?.message);
}
}
]
+140
View File
@@ -0,0 +1,140 @@
const ContactUs = require('../models/ContactUs');
const {body, validationResult , checkSchema} = require('express-validator');
const {_sr} = require('../plugins/serverResponses');
const {res404, res500, hasWhiteSpaces, isLatinCharactersWithSymbol, generateRandomDigits} = require('../plugins/controllersHelperFunctions');
/////////////////////////////////////////////////////////////////////// admin
module.exports.updateContacUs = [
checkSchema({
description : {
notEmpty : true,
errorMessage : _sr['fa'].required.description
},
email : {
isEmail : true,
errorMessage : _sr['fa'].format.email,
},
phone : {
isNumeric : true,
errorMessage : `شماره تلفن ${_sr['fa'].optional.number}`
},
address : {
isString : true,
errorMessage : `آدرس ${_sr['fa'].optional.string}`
},
'location.type' : {
isString : true,
},
'location.coordinates' : {
isArray : true
}
}),
async (req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({
validation: errors.mapped()
});
try {
/**
* get data from input
*/
var {
description,
email,
phone,
address,
location,
} = req.body;
/**
* get id
*/
// var contactUsId = req.params.id;
var contactUs = await ContactUs.findOne();
if(!contactUs){
return res404(res , `صفحه ارتباط با ما وجود ندارد`);
}
/**
* make update object
*/
contactUs.title = contactUs.title.trim();
contactUs.description = description.trim();
contactUs.email = email.trim();
contactUs.phone = phone.trim();
contactUs.address = address.trim();
contactUs.location = {
type : location.type,
coordinates : location.coordinates
};
contactUs.main = contactUs.main;
contactUs.showInMenu = contactUs.showInMenu;
contactUs._creator = req.user?._id || null;
contactUs._updatedBy = req.user?._id || null;
contactUs.siteMap = contactUs.siteMap;
contactUs.showInFooter = contactUs.showInFooter;
await contactUs.save();
/**
* show result
*/
return res.json(contactUs);
} catch (error) {
return res500(res , error.message);
}
}
]
module.exports.getOneContacUs = [
async (req, res) => {
try {
// var add = new ContactUs({
// description: "توضیحات صفحه تماس با ما",
// showInMenu: true,
// main: true,
// email: 'test@gmail.com',
// phone: '08632222222',
// address: 'میدان فاطمیه',
// _creator: null,
// _updatedBy: null,
// location: {
// type: 'Point',
// coordinates: [-118.2870407961309, 33.93508571994455]
// },
// siteMap: true,
// showInFooter: true
// });
// await add.save();
/**
* get ContacUs
*/
const getContacUs = await ContactUs.find({});
/**
* if not exist
*/
if(!getContacUs.length){
return res404(res , `صفحه ارتباط با ما وجود ندارد`);
}
/**
* show result
*/
return res.json(getContacUs[0]);
} catch (error) {
/**
* if we got unkown error show to client
*/
res500(res , error);
}
}
]
+300
View File
@@ -0,0 +1,300 @@
const {body, validationResult} = require('express-validator');
const sharp = require('sharp');
const {_sr} = require('../plugins/serverResponses');
const {res404, res500, hasWhiteSpaces, isLatinCharactersWithSymbol, generateRandomDigits} = require('../plugins/controllersHelperFunctions');
const Content = require('../models/Content');
const fs = require('fs');
////// variables
const profileWidth = 1000;
const profileHeight = 600;
const profileQuality = 100;
const profileThumbWidth = 400;
const profileThumbHeight = 400;
const profileThumbQuality = 100;
/////////////////////////////////////////////////////////////////////// admin
module.exports.addContent = [
[
body('title')
.notEmpty().withMessage(_sr['fa'].required.title),
body('param')
.notEmpty().withMessage(_sr['fa'].required.field),
body('pageContent')
.notEmpty().withMessage(_sr['fa'].required.field),
body('showInMenu')
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
],
async (req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({
validation: errors.mapped()
});
try {
let {
title,
param,
pageContent,
email,
showInMenu
} = req.body;
const catData = {
title: title.trim(),
param: param,
pageContent: pageContent,
showInMenu,
_creator: req.user._id,
_updatedBy: req.user._id
}
if (email) catData.email = email
/**
* add new content
*/
let create = await Content.create(catData);
/**
* check added or not
*/
if (!create) {
return res500(res, `مشکلی در اضافه کردن محتوا پیش آمده است`);
}
/**
* if we have pic upload to server
*/
if (req.files && req.files.cover) {
const image = req.files.cover;
if (!_sr.supportedImageFormats.includes(image.mimetype.split('/')[1])) {
return res.status(422).json({
validation: {
cover: {
msg: _sr['fa'].format.image
}
}
});
}
const imageName = `manager_${Date.now()}_${create._id}.${image.mimetype.split('/')[1]}`;
const thumbName = 'thumb_' + imageName
try {
const target = sharp(image.data)
await target
.resize(profileWidth, profileHeight, {
fit: 'cover'
})
.jpeg({
quality: profileQuality
})
.toFile(`./static/uploads/images/content/${imageName}`)
await target
.resize(profileThumbWidth, profileThumbHeight, {
fit: 'cover'
})
.jpeg({
quality: profileThumbQuality
})
.toFile(`./static/uploads/images/content/${thumbName}`)
create.cover = imageName;
create.thumb = imageName;
await create.save();
} catch (e) {
return res500(res, e?.message);
}
}
/**
* show result
*/
return res.json(create);
} catch (error) {
res500(res, error.message);
}
}
]
module.exports.updateContent = [
[
body('title')
.notEmpty().withMessage(_sr['fa'].required.title),
body('pageContent')
.notEmpty().withMessage(_sr['fa'].required.field),
body('showInMenu')
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
],
async (req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({
validation: errors.mapped()
});
try {
/**
* get data from input
*/
let {
title,
pageContent,
email,
showInMenu
} = req.body;
/**
* get id
*/
var contentParam = req.params.param;
/**
* check content exist or not
*/
var targetContent = await Content.findOne({param: contentParam});
if (!targetContent) return res404(res, `صفحه ی مورد نظر پیدا نشد`);
/**
* if we have pic upload to server
*/
if (req.files && req.files.cover) {
const image = req.files.cover;
if (!_sr.supportedImageFormats.includes(image.mimetype.split('/')[1])) {
return res.status(422).json({
validation: {
cover: {
msg: _sr['fa'].format.image
}
}
});
}
const imageName = `manager_${Date.now()}_${targetContent._id}.${image.mimetype.split('/')[1]}`;
const thumbName = 'thumb_' + imageName
try {
const target = sharp(image.data)
await target
.resize(profileWidth, profileHeight, {
fit: 'cover'
})
.jpeg({
quality: profileQuality
})
.toFile(`./static/uploads/images/content/${imageName}`)
await target
.resize(profileThumbWidth, profileThumbHeight, {
fit: 'cover'
})
.jpeg({
quality: profileThumbQuality
})
.toFile(`./static/uploads/images/content/${thumbName}`)
/**
* if exist old pic delete it from file
*/
if (targetContent.cover) {
const oldPic = `./static${targetContent.cover}`
const oldThumb = `./static${targetContent.thumb}`
if (fs.existsSync(oldPic)) {
fs.unlink(oldPic, (err) => {
if (err) return res500(res, err?.message);
});
}
if (fs.existsSync(oldThumb)) {
fs.unlink(oldThumb, (err) => {
if (err) return res500(res, err?.message);
});
}
}
targetContent.cover = imageName;
targetContent.thumb = thumbName;
} catch (e) {
return res500(res, e?.message);
}
}
/**
* make update object
*/
targetContent.title = title.trim();
targetContent._updatedBy = req.user._id;
targetContent.pageContent = pageContent;
targetContent.showInMenu = showInMenu || false;
if (email) targetContent.email = email
await targetContent.save();
/**
* show result
*/
return res.json(targetContent);
} catch (error) {
return res500(res, error?.message);
}
}
]
module.exports.getOneContent = [
async (req, res) => {
try {
var contentParam = req.params.param;
/**
* get content
*/
const targetContent = await Content.findOne({param: contentParam});
/**
* show result
*/
return res.json(targetContent);
} catch (error) {
return res500(res, error?.message);
}
}
]
/////////////////////////////////////////////////////////////////////// public
module.exports.footer = [
async (req, res) => {
try {
var findQuery = {showInFooter: {$ne: 0}};
var getContents = await Content.find(findQuery).sort({priority: -1});
return res.json(getContents);
} catch (error) {
return res500(res, error?.message);
}
}
]
module.exports.viewContent = [
async (req, res) => {
try {
var param = req.params.param;
var getContent = await Content.findOne({param});
if (!getContent) {
return res404(res, `صفحه ی مورد نظر پیدا نشد`);
}
return res.json(getContent);
} catch (error) {
return res500(res, error?.message);
}
}
]
@@ -0,0 +1,91 @@
const CounterDay = require('../models/CounterDay');
const {body, validationResult} = require('express-validator');
const {_sr} = require('../plugins/serverResponses');
const {res404, res500} = require('../plugins/controllersHelperFunctions');
const fs = require('fs');
const sharp = require('sharp');
const moment = require('moment-jalaali');
/////////////////////////////////////////////////////////////////////// admin
module.exports.updateCounterDay = [
[
body('title')
.notEmpty().withMessage(_sr['fa'].required.title),
body('publish')
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
body('expireDate')
.notEmpty().withMessage(`لطفا یک تاریخ تعیین کنید`),
],
async (req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({
validation: errors.mapped()
});
try {
const {title, publish , expireDate} = req.body;
const targetCounterDay = await CounterDay.findOne();
if (targetCounterDay) {
targetCounterDay.title = title;
targetCounterDay.publish = publish;
targetCounterDay.expireDate = moment(expireDate).startOf('days');
targetCounterDay._updatedBy = req.user._id;
await targetCounterDay.save();
return res.json({message: _sr['fa'].response.success_save});
}else {
const data = {
title,
publish,
expireDate : moment(expireDate).startOf('days'),
_creator : req.user._id,
_updatedBy: req.user._id
}
await CounterDay.create(data);
return res.json({message: _sr['fa'].response.success_save});
}
} catch (error) {
return res500(res, `مشکلی در اجرای درخواست پیش آمده است`);
}
}
]
module.exports.getCounterDayByAdmin = [
async (req, res) => {
try {
const targetCounterDay = await CounterDay.findOne();
if (!targetCounterDay) return res.json({title: '', publish: true , expireDate : ''});
return res.json(targetCounterDay);
} catch (error) {
return res500(res, `مشکلی در اجرای درخواست شما پیش آمده است`);
}
}
]
////////////////////////////////////////////////////////////////// public
module.exports.getCounterDayByUser = [
async (req, res) => {
try {
const targetCounterDay = await CounterDay.findOne({publish : true , expireDate : {$gte : new Date()}});
if (!targetCounterDay) return res.json(null);
return res.json(targetCounterDay);
} catch (error) {
return res500(res, `مشکلی در اجرای درخواست شما پیش آمده است`);
}
}
]
+187
View File
@@ -0,0 +1,187 @@
const fs = require('fs')
const archiver = require('archiver')
const moment = require('moment')
const jwt = require('jsonwebtoken')
const {secretKey} = require('../authentication')
const {_sr} = require('../plugins/serverResponses')
// models
const Category = require('../models/Category')
const Comment = require('../models/Comment')
const ContactUs = require('../models/ContactUs')
const Content = require('../models/Content')
const Gallery = require('../models/Gallery')
const HomePage = require('../models/HomePage')
const Links = require('../models/Links')
const Meeting = require('../models/Meeting')
const News = require('../models/News')
const NewsFile = require('../models/NewsFile')
const Occasion = require('../models/Occasion')
const Services = require('../models/Services')
const Slider = require('../models/Slider')
const User = require('../models/User')
const YearBanner = require('../models/YearBanner')
module.exports.createBackUp = [
// check user token and permission to backup
async (req, res, next) => {
const token = req.params.token
if (!token) return res.status(401).json({message: 'unauthorized'})
try {
// check if token is not destroyed
const user = await User.findOne({token: token})
if (!user) return res.status(401).json({message: 'unauthorized'})
// verify token
const checkToken = await jwt.verify(user.token.replace(/^Bearer\s/, ''), secretKey)
if (!checkToken) return res.status(401).json({message: 'unauthorized'})
// check user permissions
const permissions = user.permissions
if (!permissions.includes('superAdmin')) res.status(401).json({message: 'unauthorized'})
return next()
} catch (e) {
res.status(401).json({message: 'unauthorized'})
}
},
// do backup :)
async (req, res) => {
try {
console.log('backup started')
const dataBaseQueries = [
// categories
Category.find(),
// comments
Comment.find(),
// contact us
ContactUs.find(),
// content
Content.find(),
// gallery
Gallery.find(),
// home page
HomePage.find(),
// links
Links.find(),
// meetings
Meeting.find(),
// news
News.find(),
// newsFile
NewsFile.find(),
// services
Services.find(),
// sliders
Slider.find(),
// users
User.find(),
// year banner
YearBanner.find(),
// occasion
Occasion.find()
]
const [categories, comments, contactus, contents, galleries, homepage, links, meetings, news, newsFiles, services, sliders, users, yearBanner, occasion] = await Promise.all(dataBaseQueries)
if (await !fs.existsSync('./backup/database')) await fs.mkdirSync('./backup/database')
await Promise.all([
fs.writeFileSync(`./backup/database/categories_${moment(Date.now()).format('YYYY-MM-DD')}.json`, JSON.stringify(categories)),
fs.writeFileSync(`./backup/database/comments_${moment(Date.now()).format('YYYY-MM-DD')}.json`, JSON.stringify(comments)),
fs.writeFileSync(`./backup/database/contactus_${moment(Date.now()).format('YYYY-MM-DD')}.json`, JSON.stringify(contactus)),
fs.writeFileSync(`./backup/database/contents_${moment(Date.now()).format('YYYY-MM-DD')}.json`, JSON.stringify(contents)),
fs.writeFileSync(`./backup/database/galleries_${moment(Date.now()).format('YYYY-MM-DD')}.json`, JSON.stringify(galleries)),
fs.writeFileSync(`./backup/database/homepage_${moment(Date.now()).format('YYYY-MM-DD')}.json`, JSON.stringify(homepage)),
fs.writeFileSync(`./backup/database/links_${moment(Date.now()).format('YYYY-MM-DD')}.json`, JSON.stringify(links)),
fs.writeFileSync(`./backup/database/meetings_${moment(Date.now()).format('YYYY-MM-DD')}.json`, JSON.stringify(meetings)),
fs.writeFileSync(`./backup/database/news_${moment(Date.now()).format('YYYY-MM-DD')}.json`, JSON.stringify(news)),
fs.writeFileSync(`./backup/database/newsFiles_${moment(Date.now()).format('YYYY-MM-DD')}.json`, JSON.stringify(newsFiles)),
fs.writeFileSync(`./backup/database/services_${moment(Date.now()).format('YYYY-MM-DD')}.json`, JSON.stringify(services)),
fs.writeFileSync(`./backup/database/sliders_${moment(Date.now()).format('YYYY-MM-DD')}.json`, JSON.stringify(sliders)),
fs.writeFileSync(`./backup/database/users_${moment(Date.now()).format('YYYY-MM-DD')}.json`, JSON.stringify(users)),
fs.writeFileSync(`./backup/database/yearBanner_${moment(Date.now()).format('YYYY-MM-DD')}.json`, JSON.stringify(yearBanner)),
fs.writeFileSync(`./backup/database/occasion_${moment(Date.now()).format('YYYY-MM-DD')}.json`, JSON.stringify(occasion))
])
/////////////////// create backup zip file
const backupName = 'backup_' + moment(Date.now()).format('YYYY-MM-DD') + '.zip'
// create a file to stream archive data to.
const output = fs.createWriteStream(`./backup/${backupName}`)
const archive = archiver('zip', {
zlib: {level: 9} // Sets the compression level.
})
// listen for all archive data to be written
// 'close' event is fired only when a file descriptor is involved
output.on('close', function () {
console.log(archive.pointer() + ' total bytes')
console.log('archiver has been finalized and the output file descriptor has closed.')
return res.download(`./backup/${backupName}`)
})
// This event is fired when the data source is drained no matter what was the data source.
// It is not part of this library but rather from the NodeJS Stream API.
// @see: https://nodejs.org/api/stream.html#stream_event_end
output.on('end', function () {
console.log('Data has been drained')
return res.status(500).send('<h1 style="margin-top: 150px;text-align: center;direction: rtl;color: red;">فضای هاست پر میباشد.لطفا نسبت به پاک کردن بکاپ های قبلی یا افزایش فضای هاست اقدام فرمایید.</h1>')
})
// good practice to catch warnings (ie stat failures and other non-blocking errors)
archive.on('warning', function (err) {
if (err.code === 'ENOENT') {
// log warning
console.log('On archiver warning -- ENOENT error code', err)
} else {
// throw error
console.log('On archiver warning -- other error codes ', err)
}
return res.status(500).send('<h1 style="margin-top: 150px;text-align: center;direction: rtl;color: red;">فضای هاست پر میباشد.لطفا نسبت به پاک کردن بکاپ های قبلی یا افزایش فضای هاست اقدام فرمایید.</h1>')
})
// good practice to catch this error explicitly
archive.on('error', function (err) {
// throw err
console.log(err)
return res.status(500).json({message: 'مشکلی پیش آمده'})
})
// pipe archive data to the file
await archive.pipe(output)
// append files from a sub-directory and naming it `new-subdir` within the archive
await archive.directory(`./static/uploads/`, 'uploads')
await archive.directory(`./backup/database/`, 'database')
// finalize the archive (ie we are done appending files but streams have to finish yet)
// 'close', 'end' or 'finish' may be fired right after calling this method so register to them beforehand
await archive.finalize()
await fs.rmdirSync('./backup/database', {recursive: true})
} catch (e) {
return res.status(500).send('<h1 style="margin-top: 150px;text-align: center;direction: rtl;color: red;">فضای هاست پر میباشد.لطفا نسبت به پاک کردن بکاپ های قبلی یا افزایش فضای هاست اقدام فرمایید.</h1>')
}
}
]
module.exports.removeOldBackups = [
async (req, res) => {
try {
const files = await fs.readdirSync('./backup')
for await (const file of files) {
const isDirectory = await fs.statSync(`./backup/${file}`).isDirectory()
if (isDirectory) await fs.rmdirSync(`./backup/${file}`, {recursive: true})
else await fs.unlinkSync(`./backup/${file}`)
}
return res.json({message: _sr['fa'].response.success_remove})
} catch (e) {
return res.status(500).json({message: e})
}
}
]
+51
View File
@@ -0,0 +1,51 @@
const mongoose = require('mongoose')
const dynamicModelSchema = new mongoose.Schema({}, { strict: false });
module.exports.CreateModel = [
async (req, res, next) => {
try {
const { modelName, fields } = req.body;
if (!modelName || !fields || !Array.isArray(fields)) {
return res.status(400).send('ورودی نامعتبر');
}
if (mongoose.modelNames().includes(modelName)) {
return res.status(400).json({ message: "مدل قبلا ایجاد شده" });
}
const schemaDefinition = {};
fields.forEach(field => {
schemaDefinition[field] = { type: String };
});
const schema = new mongoose.Schema(schemaDefinition);
mongoose.model(modelName, schema);
return res.status(200).json(`مدل ${modelName} ایجاد شد با فیلد های: ${fields.join(', ')}`);
} catch (e) {
next(e);
}
}
];
module.exports.SaveDataModel = [
async (req,res,next)=>{
const { modelName, data } = req.body;
if (!modelName || !data || typeof data !== 'object') {
return res.status(400).send('ورودی نامعتبر');
}
try {
const DynamicModel = mongoose.model(modelName);
const instance = new DynamicModel(data);
await instance.save();
res.send('داده فرم ذخیره شد');
} catch (error) {
next(error)
}
}
]
+884
View File
@@ -0,0 +1,884 @@
const Category = require('../models/Category');
const Election = require('../models/Election');
const {body, validationResult} = require('express-validator');
const {_sr} = require('../plugins/serverResponses');
const {
res404,
res500,
checkValidations,
generateRandomDigits,
hasWhiteSpaces,
isLatinCharactersWithSymbol
} = require('../plugins/controllersHelperFunctions');
const fs = require('fs');
const sharp = require('sharp');
////// variables
const profileWidth = 300;
const profileHeight = 400;
const profileQuality = 100;
const limit = 20;
//// functions
const _checkSpecPermission = async (req, category) => {
return !req.user.specialPermissions.includes(category._id) && //check parent id exist in special permissions or not
!req.user.specialPermissions.some(item => category?.treeCat?.join().includes(item));
}
const _generatePass = async () => {
let pass = generateRandomDigits(8);
let checkPass = await Election.findOne({'voters.password': pass});
if (checkPass) return await _generatePass();
return pass;
}
/////////////////////////////////////////////////////////////////////// admin election
module.exports.addElection = [
[
body('title')
.notEmpty().withMessage(_sr['fa'].required.field),
body('catId')
.isMongoId().withMessage(_sr['fa'].required.field)
.if((value, {req}) => {
return req.body.catId
})
.custom((value) => {
return Category.findOne({
_id: value
})
.then(category => {
if (!category) return Promise.reject(_sr['fa'].not_found.category);
else return true
})
}),
body('startDate')
.notEmpty().withMessage(`لطفا یک تاریخ شروع تعیین کنید`),
body('endDate')
.notEmpty().withMessage(`لطفا یک تاریخ پایان تعیین کنید`),
body('publish')
.isBoolean().withMessage(_sr['fa'].format.boolean),
],
checkValidations(validationResult),
async (req, res) => {
try {
const {
title,
catId,
description,
startDate,
endDate,
publish
} = req.body;
const data = {
title: title.trim(),
catId,
description,
startDate,
endDate,
publish,
_creator: req.user._id,
_updatedBy: req.user._id
}
const category = await Category.findOne({
_id: catId
}).populate({
path: 'parent',
populate: {
path: 'parent',
model: 'Category'
}
});
if (!category) return res404(res, 'دسته بندی مورد نظر پیدا نشد');
/** check special permission */
if (req.user.specialPermissions.length && await _checkSpecPermission(req, category)) {
return res.status(403).json({
message: `شما نمیتوانید این دسته بندی را انتخاب کنید`
});
}
data.allCat = category.treeCat;
data.rootParent = category.rootParent || category._id;
const createElection = await Election.create(data);
if (!createElection) return res500(res, `مشکلی در اجرای درخواست شما پیش آمده است`);
return res.json(createElection);
} catch (error) {
return res500(res, `مشکلی در اجرای درخواست شما بوجود آمده است`);
}
}
]
module.exports.updateElection = [
[
body('title')
.notEmpty().withMessage(_sr['fa'].required.field),
body('catId')
.isMongoId().withMessage(_sr['fa'].required.field)
.if((value, {req}) => {
return req.body.catId
})
.custom((value) => {
return Category.findOne({
_id: value
})
.then(category => {
if (!category) return Promise.reject(_sr['fa'].not_found.category);
else return true
})
}),
body('startDate')
.notEmpty().withMessage(`لطفا یک تاریخ شروع تعیین کنید`),
body('endDate')
.notEmpty().withMessage(`لطفا یک تاریخ پایان تعیین کنید`),
body('publish')
.isBoolean().withMessage(_sr['fa'].format.boolean),
],
checkValidations(validationResult),
async (req, res) => {
try {
const electionId = req.params.id;
const {
title,
catId,
description,
startDate,
endDate,
publish
} = req.body;
//// check election
const targetElection = await Election.findById(electionId);
if (!targetElection) return res404(res, `انتخابات مورد نظر پیدا نشد`);
if (catId && targetElection.catId !== catId) {
const category = await Category.findOne({
_id: catId
}).populate({
path: 'parent',
populate: {
path: 'parent',
model: 'Category'
}
});
if (!category) return res404(res, 'دسته بندی مورد نظر پیدا نشد');
/** check special permission */
if (req.user.specialPermissions.length && await _checkSpecPermission(req, category)) {
return res.status(403).json({
message: `شما نمیتوانید این دسته بندی را انتخاب کنید`
});
}
targetElection.catId = catId;
targetElection.allCat = category.treeCat;
targetElection.rootParent = category.rootParent || category._id;
}
targetElection.title = title;
targetElection.description = description;
targetElection.startDate = startDate;
targetElection.endDate = endDate;
targetElection.publish = publish;
targetElection._updatedBy = req.user._id;
await targetElection.save();
return res.json({message: _sr['fa'].response.success_save});
} catch (error) {
return res500(res, `مشکلی در اجرای درخواست شما بوجود آمده است`);
}
}
]
module.exports.getAllElection = [
async (req, res) => {
try {
let findQuery = {};
if (req.user.specialPermissions.length) {
findQuery.catId = {$in: req.user.specialPermissions}
}
const allElection = await Election.paginate(findQuery, {
page: req.query.page || 1,
populate: [
{path: 'catId'},
{
path: '_creator',
select: {
firstName: 1,
lastName: 1,
profilePic: 1
}
}
],
limit,
sort: {created_at: -1}
});
if (!allElection) return res500(res, `مشکلی در گرفتن اطلاعات پیش آمده است`);
return res.json(allElection);
} catch (error) {
return res500(res, `مشکلی در اجرای درخواست شما بوجود آمده است`);
}
}
]
module.exports.getOneElection = [
async (req, res) => {
try {
const electionId = req.params.id;
const findQuery = {
_id: electionId
};
const election = await Election.findOne(findQuery).populate('catId');
if (!election) return res404(res, `اطلاعات مورد نظر پیدا نشد`);
if (req.user.specialPermissions.length && await _checkSpecPermission(req, election.catId)) {
return res.status(403).json({
message: `شما مجاز به دیدن اطلاعات این انتخابات نمی باشید`
});
}
return res.json(election);
} catch (error) {
return res500(res, `مشکلی در اجرای درخواست شما بوجود آمده است`);
}
}
]
module.exports.deletOneElection = [
async (req, res) => {
try {
const electionId = req.params.id;
const deleteElection = await Election.findById(electionId).populate('catId');
if (!deleteElection) return res404(res, `انتخابات مورد نظر پیدا نشد`);
if (req.user.specialPermissions.length && await _checkSpecPermission(req, deleteElection.catId)) {
return res.status(403).json({
message: `شما اجازه حذف این انتخابات را ندارید`
});
}
if (deleteElection.candidates.length) {
const targetDir = `./static/uploads/images/election/`;
const getFiles = fs.readdirSync(targetDir);
for (const file of getFiles) {
if (file.includes(deleteElection._id)) {
fs.unlink(`./static/uploads/images/election/${file}`, (err) => {
if (err) console.log(err)
});
}
}
}
await deleteElection.deleteOne();
return res.json({message: _sr['fa'].response.success_remove});
} catch (error) {
return res500(res, `مشکلی در اجرای درخواست شما بوجود آمده است`);
}
}
]
module.exports.search = [
async (req, res) => {
try {
let query = {};
let populate = [
{
path: '_creator',
select: {firstName: 1, lastName: 1, profilePic: 1}
},
{
path: 'catId'
}
];
query['$and'] = [];
const {
term,
catId,
publish,
date
} = req.body;
/** search by term */
if (term && !_.isEmpty(term)) {
query['$and'].push({
$or: [{
title: {
$regex: '.*' + term + '.*'
}
}]
});
}
if (req.user.specialPermissions.length) {
query.catId = {$in: req.user.specialPermissions}
} else if (catId && !_.isEmpty(catId)) {
query['$and'].push({
catId
});
}
/** search by publish */
if (!_.isUndefined(publish) && _.isBoolean(publish)) {
query['$and'].push({
publish
});
}
/** search by date */
if (date && !_.isEmpty(date)) {
if (date.length === 1) {
query['$and'].push({
startDate: {$lte: new Date(date[0])},
endDate: {$gte: new Date(date[0])}
});
} else {
query['$and'].push({
startDate: {$lte: new Date(date[0])},
endDate: {$gte: new Date(date[1])}
});
}
}
_.isEmpty(query['$and']) && delete query['$and'];
// _.isEmpty(input['$or']) && delete input['$or'];
/** get elections */
const elections = await Election.paginate(query, {
page: req.query.page || 1,
limit,
populate,
sort: {_id: -1}
});
/** show result */
return res.json(elections);
} catch (error) {
return res500(res, `مشکلی در اجرای درخواست شما بوجود آمده است`);
}
}
]
///////////////////////////////////////////////////////////////////// admin candidate
module.exports.addCandidate = [
[
body('firstName')
.notEmpty().withMessage(_sr['fa'].required.first_name),
body('lastName')
.notEmpty().withMessage(_sr['fa'].required.last_name),
body('nationalCode')
.optional().isNumeric().withMessage(_sr['fa'].required.national_code)
.bail()
.isLength({min: 10, max: 10}).withMessage('کد ملی 10 رقمی می باشد'),
],
checkValidations(validationResult),
async (req, res) => {
try {
const electionId = req.params.id;
const {
firstName,
lastName,
bornDate,
education,
nationalCode,
resume
} = req.body;
const data = {
firstName,
lastName,
bornDate,
education,
nationalCode,
resume,
_creator: req.user._id,
_updatedBy: req.user._id
}
if (!req?.files?.profilePic) {
return res.status(422).json({
validation: {profilePic: {msg: `لطفا یک فایل ارسال کنید`}}
});
}
const targetElection = await Election.findById(electionId);
if (!targetElection) return res404(res, 'انتخابات مورد نظر پیدا نشد');
/////// add pic
const image = req.files.profilePic;
if (!_sr.supportedImageFormats.includes(image.mimetype.split('/')[1])) {
return res.status(422).json({validation: {profilePic: {msg: _sr['fa'].format.image}}});
}
const imageName = 'candidate_' + Date.now() + '_' + targetElection._id + '.jpg';
data.profilePic = imageName;
const target = sharp(image.data)
await target
.resize(profileWidth, profileHeight, {
fit: 'cover'
})
.toFormat('jpg')
.jpeg({
quality: profileQuality
})
.toFile(`./static/uploads/images/election/${imageName}`)
targetElection.candidates.push(data);
await targetElection.save();
return res.json({message: _sr['fa'].response.success_save});
} catch (error) {
console.log(error.message)
return res500(res, `مشکلی در اجرای درخواست شما بوجود آمده است`);
}
}
]
module.exports.updateCandidate = [
[
body('candidateId')
.notEmpty().withMessage(_sr['fa'].required.field),
body('firstName')
.notEmpty().withMessage(_sr['fa'].required.first_name),
body('lastName')
.notEmpty().withMessage(_sr['fa'].required.last_name),
body('nationalCode')
.optional().isNumeric().withMessage(_sr['fa'].required.national_code)
.bail()
.isLength({min: 10, max: 10}).withMessage('کد ملی 10 رقمی می باشد'),
],
checkValidations(validationResult),
async (req, res) => {
try {
const electionId = req.params.id;
const {
candidateId,
firstName,
lastName,
bornDate,
education,
nationalCode,
resume
} = req.body;
const targetElection = await Election.findById(electionId);
if (!targetElection) return res404(res, 'انتخابات مورد نظر پیدا نشد');
let candidate = targetElection.candidates.id(candidateId);
if (!candidate) return res404(res, `کاندید مورد نظر پیدا نشد`);
if (req?.files?.profilePic) {
const image = req.files.profilePic;
if (!_sr.supportedImageFormats.includes(image.mimetype.split('/')[1])) {
return res.status(422).json({validation: {profilePic: {msg: _sr['fa'].format.image}}});
}
const imageName = 'candidate_' + Date.now() + '_' + targetElection._id + '.jpg';
const target = sharp(image.data)
await target
.resize(profileWidth, profileHeight, {
fit: 'cover'
})
.toFormat('jpg')
.jpeg({
quality: profileQuality
})
.toFile(`./static/uploads/images/election/${imageName}`)
/**
* if exist old pic delete it from file
*/
if (candidate.profilePic) {
const oldPic = `./static${candidate.profilePic}`;
if (fs.existsSync(oldPic)) {
fs.unlink(oldPic, (err) => {
if (err) return res500(res, err?.message);
});
}
}
candidate.profilePic = imageName;
}
candidate.firstName = firstName;
candidate.lastName = lastName;
candidate.bornDate = bornDate;
candidate.education = education;
candidate.nationalCode = nationalCode;
candidate.resume = resume;
candidate._updatedBy = req.user._id;
await targetElection.save();
return res.json({message: _sr['fa'].response.success_save});
} catch (error) {
return res500(res, `مشکلی در اجرای درخواست شما بوجود آمده است`);
}
}
]
module.exports.deleteCandidate = [
async (req, res) => {
try {
const electionId = req.params.id;
const candidateId = req.params.canId;
const targetElection = await Election.findById(electionId);
if (!targetElection) return res404(res, 'انتخابات مورد نظر پیدا نشد');
let candidate = targetElection.candidates.id(candidateId);
if (!candidate) return res404(res, `کاندید مورد نظر پیدا نشد`);
if (candidate.profilePic) {
const oldPic = `./static${candidate.profilePic}`;
if (fs.existsSync(oldPic)) {
fs.unlink(oldPic, (err) => {
if (err) return res500(res, err?.message);
});
}
}
await targetElection.candidates.id(candidateId).remove();
await targetElection.save();
return res.json({message: _sr['fa'].response.success_remove});
} catch (error) {
return res500(res, `مشکلی در اجرای درخواست شما بوجود آمده است`);
}
}
]
///////////////////////////////////////////////////////////////////// admin voter
module.exports.addVoter = [
[
body('firstName')
.notEmpty().withMessage(_sr['fa'].required.first_name),
body('lastName')
.notEmpty().withMessage(_sr['fa'].required.last_name),
body('nationalCode')
.notEmpty().withMessage(_sr['fa'].required.national_code)
.bail()
.isLength({min: 10, max: 10}).withMessage('کد ملی 10 رقمی می باشد'),
body('username')
.isLength({min: 4}).withMessage(_sr['fa'].min_char.min4)
.bail()
.custom((value, {req}) => {
if (hasWhiteSpaces(value)) return Promise.reject(_sr['fa'].response.whiteSpace)
else return true
})
.bail()
.custom((value, {req}) => {
if (!isLatinCharactersWithSymbol(value)) return Promise.reject(_sr['fa'].response.latinChar)
else return true
})
.bail()
.custom((value, {req}) => {
return Election.findOne({'voters.username': value})
.then(user => {
if (user) return Promise.reject(_sr['fa'].duplicated.username)
else return true
})
}),
],
checkValidations(validationResult),
async (req, res) => {
try {
const electionId = req.params.id;
const {
firstName,
lastName,
username,
nationalCode,
mobileNumber,
job
} = req.body;
//// generate password
// async function generatePass(){
// let pass = generateRandomDigits(8);
// let checkPass = Election.findOne({'voters.password' : pass});
//
// console.log(checkPass)
//
// if (checkPass) return await generatePass();
//
// return pass;
// }
const data = {
firstName,
lastName,
username,
password: await _generatePass(),
mobileNumber,
nationalCode,
job,
_creator: req.user._id,
_updatedBy: req.user._id
}
const targetElection = await Election.findById(electionId);
if (!targetElection) return res404(res, 'انتخابات مورد نظر پیدا نشد');
targetElection.voters.push(data);
await targetElection.save();
return res.json({message: _sr['fa'].response.success_save});
} catch (error) {
console.log(error.message)
return res500(res, `مشکلی در اجرای درخواست شما بوجود آمده است`);
}
}
]
module.exports.updateVoter = [
[
body('voterId')
.notEmpty().withMessage(_sr['fa'].required.field),
body('firstName')
.notEmpty().withMessage(_sr['fa'].required.first_name),
body('lastName')
.notEmpty().withMessage(_sr['fa'].required.last_name),
body('nationalCode')
.notEmpty().withMessage(_sr['fa'].required.national_code),
],
checkValidations(validationResult),
async (req, res) => {
try {
const electionId = req.params.id;
const {
voterId,
firstName,
lastName,
nationalCode,
mobileNumber,
job
} = req.body;
const targetElection = await Election.findById(electionId);
if (!targetElection) return res404(res, 'انتخابات مورد نظر پیدا نشد');
let voter = targetElection.voters.id(voterId);
if (!voter) return res404(res, `رای دهنده مورد نظر پیدا نشد`);
voter.firstName = firstName;
voter.lastName = lastName;
voter.mobileNumber = mobileNumber;
voter.job = job;
voter.nationalCode = nationalCode;
voter._updatedBy = req.user._id;
await targetElection.save();
return res.json({message: _sr['fa'].response.success_save});
} catch (error) {
return res500(res, `مشکلی در اجرای درخواست شما بوجود آمده است`);
}
}
]
module.exports.deleteVoter = [
async (req, res) => {
try {
const electionId = req.params.id;
const voterId = req.params.voterId;
const targetElection = await Election.findById(electionId);
if (!targetElection) return res404(res, 'انتخابات مورد نظر پیدا نشد');
let voter = targetElection.voters.id(voterId);
if (!voter) return res404(res, `کاربر مورد نظر پیدا نشد`);
await targetElection.voters.id(voterId).remove();
await targetElection.save();
return res.json({message: _sr['fa'].response.success_remove});
} catch (error) {
return res500(res, `مشکلی در اجرای درخواست شما بوجود آمده است`);
}
}
]
//////////////////////////////////////////////////////////////////// auth voter
module.exports.voterLogin = [
[
body('username')
.notEmpty().withMessage(_sr['fa'].required.username),
body('password')
.notEmpty().withMessage(_sr['fa'].required.password)
],
checkValidations(validationResult),
async (req, res) => {
try {
const {username, password} = req.body;
const user = await Election.findOne({voters: {$elemMatch: {username, password, voted: false}}})
if (!user) return res.status(422).json({validation: {username: {msg: _sr['fa'].not_found.password}}});
return res.json({token: user.voters.find(item => item.password === password)._id});
} catch (error) {
return res500(res, `مشکلی در اجرای درخواست شما بوجود آمده است`);
}
}
]
module.exports.getVoterUser = [
async (req, res) => {
try {
const token = req.headers.authorization?.replace(/^Bearer\s/, '');
const election = await Election.findOne({'voters._id': token});
if (!election) return res.status(422).json({validation: {username: {msg: _sr['fa'].not_found.password}}});
const user = await election.voters.id(token);
return res.json({user});
} catch (error) {
return res500(res, `مشکلی در اجرای درخواست شما بوجود آمده است`);
}
}
]
/////////////////////////////////////////////////////////////////////// public
module.exports.getElectionByUser = [
async (req, res) => {
try {
if (!req.voter) return res.status(403).json({message: 'شما اجازه دیدن این صفحه را ندارید'});
const targetElection = await Election.findOne({voters: {$elemMatch: {_id: req.voter._id, voted: false}}})
return res.json(targetElection);
} catch (error) {
return res500(res, `مشکلی در اجرای درخواست شما بوجود آمده است`);
}
}
]
module.exports.addVote = [
[
body('electionId')
.notEmpty().withMessage(_sr['fa'].required.field),
body('candidateId')
.notEmpty().withMessage(_sr['fa'].required.field)
],
checkValidations(validationResult),
async (req, res) => {
try {
if (!req.voter) return res.status(403).json({message: 'شما اجازه رای دادن ندارید'});
const {electionId, candidateId} = req.body;
const targetElection = await Election.findById(electionId);
if (!targetElection) return res404(res, 'انتخابات مورد نظر پیدا نشد');
const voter = await targetElection.voters.id(req.voter._id);
if (!voter) return res.status(403).json({message: 'شما اجازه رای دادن ندارید'});
voter.voted = true;
const candidate = await targetElection.candidates.id(candidateId);
if (!candidate) return res404(res, 'کاندیدای انتخاب شده وجود ندارد');
const voteObj = {
voter: voter._id,
candidate: candidate._id
}
targetElection.votes.push(voteObj);
await targetElection.save();
return res.json({message: 'رای شما با موفقیت ثبت شد'});
} catch (error) {
return res500(res, `مشکلی در اجرای درخواست شما بوجود آمده است`);
}
}
]
+461
View File
@@ -0,0 +1,461 @@
const {body, validationResult} = require('express-validator');
const {_sr} = require('../plugins/serverResponses');
const {res404, res500} = require('../plugins/controllersHelperFunctions');
const FeedBack = require('../models/FeedBack');
const Captcha = require('../models/Captcha');
const nodemailer = require("nodemailer");
const limit = 20;
/////////////////////////////////////////////////////////////////////// admin
module.exports.updateFeedBack = [
[
body('name')
.notEmpty().withMessage(_sr['fa'].required.title),
body('description')
.notEmpty().withMessage(_sr['fa'].required.description),
body('twitter').notEmpty()
.withMessage(_sr['fa'].required.Twitter),
body('email')
.optional().isEmail().withMessage(_sr['fa'].format.email),
body('phoneNumber')
.if((value, {req}) => {
return req.body.phoneNumber
})
.custom((value, {req}) => {
if (!_.isEmpty(value) && !lodash.isNumeric(value)) {
return Promise.reject(_sr['fa'].format.number);
} else return true;
}),
// body('cptcha')
// .notEmpty().withMessage(_sr['fa'].required.field)
// .custom((value , {req}) => {
// console.log(req.session);
// if(value != req.session.captcha){
// return Promise.reject(`کپچا وارد شده صحیح نمی باشد`);
// }else{
// return true
// }
// }),
],
async (req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({
validation: errors.mapped()
});
try {
/**
* get data from input
*/
const {
name,
subject,
description,
phoneNumber,
twitter,
email,
nationalCode
} = req.body;
/**
* get id
*/
const meetingId = req.params.id;
/**
* check meeting exist or not
*/
var targetFeedBack = await FeedBack.findById(meetingId);
if (!targetFeedBack) return res404(res, `درخواست مورد نظر پیدا نشد`);
/**
* make update object
*/
targetFeedBack.name = name.trim();
targetFeedBack.subject = subject.trim();
targetFeedBack.description = description.trim();
targetFeedBack.email = email;
targetFeedBack.twitter = twitter.trim()
targetFeedBack.phoneNumber = phoneNumber;
targetFeedBack.nationalCode = nationalCode;
await targetFeedBack.save();
/**
* show result
*/
return res.json(targetFeedBack);
} catch (error) {
return res500(res, error?.message);
}
}
]
module.exports.deletOneFeedBack = [
async (req, res) => {
try {
const meetingId = req.params.id;
/**
* check meeting
*/
let targetFeedBack = await FeedBack.findByIdAndDelete(meetingId);
if (!targetFeedBack) {
return res404(res, `درخواست مورد نظر پیدا نشد`);
}
/**
* show result
*/
return res.json(targetFeedBack);
} catch (error) {
/**
* if we got unknown error show to client
*/
res500(res, error);
}
}
]
module.exports.getOneFeedBack = [
async (req, res) => {
try {
const meetingId = req.params.id;
/**
* get meeting
*/
const targetFeedBack = await FeedBack.findOne({_id: meetingId});
/**
* if not exist
*/
if (!targetFeedBack) {
return res404(res, `درخواست مورد نظر پیدا نشد`);
}
if (!targetFeedBack.read) {
targetFeedBack.read = true;
await targetFeedBack.save();
}
/**
* show result
*/
return res.json(targetFeedBack);
} catch (error) {
/**
* if we got unknown error show to client
*/
res500(res, error);
}
}
]
module.exports.getAll = [
async (req, res) => {
try {
let findQuery = {};
/**
* get all meeting
*/
const getAll = await FeedBack.paginate(findQuery,
{page: req.query.page || 1, limit, sort: {created_at: -1}});
/**
* show result
*/
return res.json(getAll);
} catch (error) {
return res500(res, error.message);
}
}
]
module.exports.getAllForCount = [
async (req, res) => {
try {
/**
* get all meeting
*/
const getAll = await FeedBack.find({});
/**
* show result
*/
return res.json(getAll);
} catch (error) {
return res500(res, error.message);
}
}
]
module.exports.search = [
async (req, res) => {
try {
let findQuery = {};
findQuery['$and'] = [];
findQuery['$or'] = [];
const {
name,
email,
terms,
phoneNumber,
nationalCode,
read,
date
} = req.body;
findQuery.modelName = req.params.model;
/** search by term */
if (terms && !_.isEmpty(terms)) {
findQuery['$or'].push(
{
subject: {
$regex: '.*' + name + '.*'
},
description: {
$regex: '.*' + name + '.*'
},
}
);
}
/** search by name */
if (name && !_.isEmpty(name)) {
findQuery['$or'].push(
{
name: {
$regex: '.*' + name + '.*'
}
}
);
}
/** search by email */
if (email && !_.isEmpty(email)) {
findQuery['$and'].push({
email
});
}
/** search by phoneNumber */
if (phoneNumber && !_.isEmpty(phoneNumber)) {
findQuery['$and'].push({
phoneNumber
});
}
/** search by nationalCode */
if (nationalCode && !_.isEmpty(nationalCode)) {
findQuery['$and'].push({
nationalCode
});
}
/** search by read */
if (!_.isUndefined(read) && _.isBoolean(read)) {
findQuery['$and'].push({
read
});
}
/** search by date */
if (date && !_.isEmpty(date)) {
if (date.length === 1) {
findQuery['$and'].push({
created_at: {
$gte: moment(date[0]).startOf('days'),
$lt: moment(date[0]).endOf('days')
}
});
} else {
findQuery['$and'].push({
created_at: {
$gte: new Date(date[0]),
$lt: new Date(date[1])
}
});
}
}
_.isEmpty(findQuery['$and']) && delete findQuery['$and'];
_.isEmpty(findQuery['$or']) && delete findQuery['$or'];
/** get meetings */
var meetings = await FeedBack.paginate(findQuery, {
page: req.query.page,
limit,
sort: {created_at: -1}
});
/** show result */
return res.json(meetings);
} catch (error) {
return res500(res, error?.message)
}
}
]
/////////////////////////////////////////////////////////////////////// public
module.exports.addFeedBack = [
[
body('name')
.notEmpty().withMessage(_sr['fa'].required.title),
body('description')
.notEmpty().withMessage(_sr['fa'].required.description),
body('twitter')
.notEmpty().withMessage(_sr['fa'].required.Twitter),
body('email')
.optional().isEmail().withMessage(_sr['fa'].format.email),
body('phoneNumber')
.custom((value, {req}) => {
if (_.isEmpty(value)) return Promise.reject(_sr['fa'].required.phone_number);
if (!_.isEmpty(value) && !lodash.isNumeric(value)) {
return Promise.reject(_sr['fa'].format.number);
} else return true;
}),
// body('captcha')
// .notEmpty().withMessage(_sr['fa'].required.field)
// .custom((value, {req}) => {
// return Captcha.findOne({code: value}).then(data => {
// if (!data) return Promise.reject(`عبارت وارد شده صحیح نمیباشد`)
// else return true
// })
// }),
],
async (req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({
validation: errors.mapped()
});
try {
const {
name,
description,
twitter,
phoneNumber,
email
} = req.body;
const data = {
name,
description,
twitter,
phoneNumber,
email
};
const createFeedBack = await FeedBack.create(data);
if (!createFeedBack) return res500(res, `مشکلی در ثبت درخواست پیش آمده است`)
let transporter = nodemailer.createTransport({
host: "mail.ostan-mr.ir",
port: 465,
secure: true, // true for 465, false for other ports
auth: {
user: 'feedback@ostan-mr.ir', // generated ethereal user
pass: 'danak@ostan1400', // generated ethereal password
},
});
let info = await transporter.sendMail({
from: 'feedback@ostan-mr.ir', // sender address
to: "feedback@ostan-mr.ir", // list of receivers
subject: "نظر و پیشنهاد", // Subject line
text: data.description, // plain text body
html: `<html lang="en" dir="ltr">
<head>
<title>نظر و پیشنهاد</title>
<style>
.view-form{
justify-content: center;
/*display: flex;*/
flex-direction: column;
align-items: center;
width: 100%;
max-width: 600px;
background-color: #fff;
border-radius: 10px;
padding: 30px 40px;
box-shadow: 0 5px 20px #999;
direction: rtl;
}
.formRow{
margin-bottom: 10px;
text-align: right;
}
.input{
width: 100%;
margin: 10px 0;
padding: 15px;
box-sizing: border-box;
border: 1px solid #ffffff;
background-color: #f4f4f4;
}
</style>
</head>
<body>
<div class="view-form">
<div class="formRow">
<label for="name">نام و نام خانوادگی:</label>
<input class="input" value="${data.name}" type="text" id="name" disabled/>
</div>
<div class="formRow">
<label for="email">ایمیل:</label>
<input class="input" value="${data.email}" type="email" id="email" disabled/>
</div>
<div class="formRow">
<label for="phone">شماره تماس:</label>
<input class="input" value="${data.phoneNumber}" type="text" id="phone" disabled/>
</div>
<div class="formRow">
<label for="description">توضیحات:</label>
<textarea class="input" id="description" type="text" disabled>
${data.description}
</textarea>
</div>
</div>
</body>
</html>`, // html body
});
/**
* show result
*/
return res.json({message:_sr['fa'].response.success_save});
} catch (error) {
/**
* if we got unknown error show to client
*/
return res500(res, error?.message);
}
}
]
File diff suppressed because it is too large Load Diff
+413
View File
@@ -0,0 +1,413 @@
const {body, validationResult} = require('express-validator');
const mongoose = require('mongoose');
const sharp = require('sharp');
const {_sr} = require('../plugins/serverResponses');
const allPortals = require('../plugins/portals');
const {res404, res500} = require('../plugins/controllersHelperFunctions');
const fs = require('fs');
const moment = require('moment-jalaali');
const axios = require('axios');
const HomePage = require('../models/HomePage');
const News = require('./../models/News');
const Gallery = require('./../models/Gallery');
const Category = require('./../models/Category');
const NewsFile = require('./../models/NewsFile');
const Slider = require('./../models/Slider');
const Links = require('./../models/Links');
const Content = require('./../models/Content');
const Occasion = require('./../models/Occasion');
/////////////////////////////////////////////////////// admin
module.exports.updateHomePage = [
async (req, res) => {
try {
const {
s2,
s3,
s4,
s5,
s6,
s2Side,
s3Side,
s4Side,
s5Side,
s6Side
} = req.body;
const portal = req.query.portal ? 'ostandari' : req.query.portal;
if (!req.user.portals.includes(portal)) {
return res.status(403).json({message: `شما اجازه دسترسی به اطلاعات این صفحه را ندارید`});
}
if (!allPortals.some(item => item.value === portal)) {
return res.status(403).json(`پرتال ارسال شده وجود ندارد`);
}
const addHome = await HomePage.findOne({modelType: portal});
if (addHome) {
const oldData = addHome
oldData.s2 = s2 || null
oldData.s3 = s3 || null
oldData.s4 = s4 || null
oldData.s5 = s5 || null
oldData.s6 = s6 || null
// side bar
oldData.s2Side = s2Side || null
oldData.s3Side = s3Side || null
oldData.s4Side = s4Side || null
oldData.s5Side = s5Side || null
oldData.s6Side = s6Side || null
await oldData.save();
return res.json({message: _sr['fa'].response.success_save})
} else {
const data = {
s2: s2 || null,
s3: s3 || null,
s4: s4 || null,
s5: s5 || null,
s6: s6 || null,
s2Side: s2Side || null,
s3Side: s3Side || null,
s4Side: s4Side || null,
s5Side: s5Side || null,
s6Side: s6Side || null,
modelType: portal
}
const addHome = await HomePage.create(data);
if (!addHome) return res500(res, `مشکلی در اجرای درخواست شما به وجود آمده است`);
return res.json({message: _sr['fa'].response.success_save})
}
} catch (e) {
console.log(e)
return res500(res, 'مشکلی در گرفتن اطلاعات پیش آمده است');
}
}
]
module.exports.getHomePage = [
async (req, res) => {
try {
const portal = req?.query?.portal ? req.query.portal : 'ostandari';
if (!req.user.portals.includes(portal)) {
return res.status(403).json(`شما اجازه دسترسی به اطلاعات این صفحه را ندارید`);
}
const getHome = await HomePage.find({modelType: portal});
if (getHome.length) return res.json(getHome[0])
else return res.json({
s2: '',
s3: '',
s4: '',
s5: [],
s6: '',
s2Side: '',
s3Side: '',
s4Side: '',
s5Side: '',
s6Side: ''
})
} catch (e) {
return res500(res, 'مشکلی در گرفتن اطلاعات پیش آمده است');
}
}
]
module.exports.changeShowInHome = [
[
body('id')
.notEmpty().withMessage(_sr['fa'].required.title),
body('modelName')
.custom((value, {req}) => {
const models = ['news', 'newsFile', 'gallery']
if (!models.includes(value)) {
return Promise.reject(_sr['fa'].required.field);
} else {
return true
}
})
],
async (req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({
validation: errors.mapped()
});
try {
const {id, modelName} = req.body;
let Model;
switch (modelName) {
case 'news':
Model = News;
break;
case 'newsFile' :
Model = NewsFile;
break;
case 'gallery':
Model = Gallery;
break;
}
const targetModel = await Model.findById(id)
if (!targetModel) return res404(res, `اطلاعات مورد یافت نشد`);
targetModel.showInHome = !targetModel.showInHome;
await targetModel.save();
return res.json(targetModel);
} catch (e) {
return res500(res, 'مشکلی در گرفتن اطلاعات پیش آمده است');
}
}
]
module.exports.getAllShowInHomeFalse = [
async (req, res) => {
try {
const portal = req?.query?.portal ? req.query.portal : 'ostandari';
const requests = [
News.find({modelType: portal, showInHome: false}),
NewsFile.find({modelType: portal, showInHome: false}),
Gallery.find({modelType: portal, showInHome: false}),
]
let fetch = await Promise.all(requests);
const [news, newsFile, media] = fetch;
return res.json({
news,
newsFile,
media
})
} catch (e) {
return res500(res, 'مشکلی در گرفتن اطلاعات پیش آمده است');
}
}
]
/////////////////////////////////////////////////////// public
module.exports.getHomeByUser = [
async (req, res) => {
try {
const homeSetting = await HomePage.find();
const data = {
occasion: [],
s1: [],
s2: [],
s3: [],
s4: [],
s5: [],
s6: [],
s2Side: [],
s3Side: [],
s4Side: [],
s5Side: [],
s6Side: [],
};
const portal = req?.query?.portal ? req.query.portal : 'ostandari'
const settings = homeSetting[0]
const query = {publish: true, showInHome: true, modelType: portal}
const request = [
// Occasion
Occasion.find({
publish: true,
status: true,
startDate: {$lte: new Date()},
endDate: {$gte: new Date()}
}),
// s1
Slider.find({modelType: portal}),
// s2
News.find(settings?.s2 ? {
...query,
catId: settings?.s2,
newsStatus: true
} : {...query, newsStatus: true}).populate('catId', 'title').limit(8).sort({customDate: -1}),
// s3
NewsFile.find(settings?.s3 ? {
...query,
catId: settings?.s3
} : query).populate('catId', 'title').limit(4).sort({_id: -1}),
// s6
News.find(settings?.s6 ? {
...query,
catId: settings?.s6,
newsStatus: true
} : {...query, newsStatus: true}).limit(8).sort({userViews: -1}),
// s1Side
Content.find({param: 'manager'}),
// s2Side
Gallery.find(settings?.s2Side ? {
...query,
catId: settings?.s2Side,
galleryType: 'image',
galleryStatus: true
} : {...query, galleryType: 'image', galleryStatus: true}).populate('catId', 'title').limit(4).sort({customDate: -1}),
// s3Side
Gallery.find(settings?.s3Side ? {
...query,
catId: settings?.s3Side,
galleryType: 'video',
galleryStatus: true
} : {...query, galleryType: 'video', galleryStatus: true}).populate('catId', 'title').limit(4).sort({customDate: -1}),
// s4Side
Gallery.find(settings?.s4Side ? {
...query,
catId: settings?.s4Side,
galleryType: 'graphic',
galleryStatus: true
} : {...query, galleryType: 'graphic', galleryStatus: true}).populate('catId', 'title').limit(4).sort({customDate: -1}),
// s5Side
News.find(settings?.s5Side ? {
...query,
catId: settings?.s5Side,
special: true,
newsStatus: true
} : {...query, newsStatus: true, special: true}).limit(4).sort({customDate: -1}),
// s6Side
News.find(settings?.s6Side ? {
...query,
catId: settings?.s6Side,
newsStatus: true
} : {...query, newsStatus: true}).limit(6).sort({customDate: -1}),
// s7Side
Links.find({modelType: portal, showInHome: true}),
// notifications-side
News.find(settings?.s6Side ? {
...query,
catId: settings?.s5Side,
newsStatus: true,
notifications: true
} : {...query, newsStatus: true, notifications: true}).limit(6).sort({customDate: -1}),
]
const fetch = await Promise.all(request)
const [occasion, s1, s2, s3, s6, s1Side, s2Side, s3Side, s4Side, s5Side, s6Side, s7Side, notificationsSide] = fetch;
data.occasion = occasion
data.s1 = s1
data.s2 = s2
data.s3 = s3
data.s6 = s6
data.s1Side = s1Side
data.s2Side = s2Side
data.s3Side = s3Side
data.s4Side = s4Side
data.s5Side = s5Side
data.s6Side = s6Side
data.s7Side = s7Side
data.notificationsSide = notificationsSide
////////////////// computed main news
const nameTag = await Category.findById(settings?.s4);
const s4Categories = await Category.find(settings?.s4 ? {parent: settings?.s4} : {})
const s4Obj = {};
s4Obj.nameTag = nameTag ? nameTag.title : '';
let s4News = [];
if (settings?.s4) {
for await (const cat of s4Categories) {
const getNew = await News.find({...query, catId: cat._id , newsStatus : true}).sort({customDate: -1})
if (getNew.length) s4News.push(getNew[0])
}
if (s4Categories.length !== 4) {
const getNews = await News.find({...query, catId: settings?.s4 , newsStatus : true}).populate('catId', 'title').limit(4 - s4News.length).sort({customDate: -1})
for (const item of getNews) {
s4News.push(item);
}
}
} else {
s4News = await News.find({...query,newsStatus : true}).populate('catId', 'title').limit(4).sort({customDate: -1});
}
s4Obj.news = s4News
data.s4 = s4Obj;
//// s5
if (settings?.s5?.length) {
const s5News = []
for await (const id of settings?.s5) {
const item = {}
const nameTag = await Category.findById(id)
item.nameTag = nameTag ? nameTag.title : '';
item.news = await News.find({...query, rootParent: id , newsStatus : true}).limit(10).sort({_id: -1})
s5News.push(item)
}
data.s5 = s5News
}
return res.json(data);
} catch (e) {
return res500(res, 'مشکلی در گرفتن اطلاعات پیش آمده است');
}
}
]
module.exports.search = [
async (req, res) => {
const {portal, terms} = req.query;
try {
const requests = [
News.find({
newsStatus: true, publish: true, $or: [
{title: {$regex: terms, $options: 'i'}},
{summaryTitle: {$regex: terms, $options: 'i'}},
{keywords: {$in: terms}}
]
}),
Gallery.find({
galleryStatus: true, publish: true, $or: [
{title: {$regex: terms, $options: 'i'}},
{summaryTitle: {$regex: terms, $options: 'i'}},
{keywords: {$in: terms}}
]
}),
Category.find({
$or: [
{title: {$regex: terms, $options: 'i'}},
{pageContent: {$regex: terms, $options: 'i'}}
]
})
]
const getData = await Promise.all(requests);
let [news, gallery, category] = getData;
return res.json({
news,
media: gallery,
pages: category
});
} catch (e) {
return res500(res, 'مشکلی در گرفتن اطلاعات پیش آمده است');
}
}
]
+430
View File
@@ -0,0 +1,430 @@
const Links = require('../models/Links');
const {
body,
validationResult
} = require('express-validator');
const sharp = require('sharp');
const {
_sr
} = require('../plugins/serverResponses');
const {
res404,
res500,
hasWhiteSpaces,
isLatinCharactersWithSymbol,
generateRandomDigits
} = require('../plugins/controllersHelperFunctions');
const fs = require('fs');
////// variables
const profileWidth = 50;
const profileHeight = 50;
const profileQuality = 100;
/////////////////////////////////////////////////////////////////////// admin
module.exports.addLinks = [
[
body('title')
.notEmpty().withMessage(_sr['fa'].required.title),
body('url')
.notEmpty().withMessage(_sr['fa'].required.field),
body('index')
.optional().isNumeric().withMessage(_sr['fa'].format.number),
body('showInHome')
.isBoolean().withMessage(_sr['fa'].format.boolean),
body('siteMap')
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
body('modelType')
.custom((value, {
req
}) => {
if (req.user.portals.join() === portal.join()) {
if (!portal.includes(value)) {
return Promise.reject(_sr['fa'].required.field);
} else {
return true
}
} else {
return true
}
})
],
async (req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({
validation: errors.mapped()
});
try {
let {
title,
url,
index,
showInHome,
siteMap,
modelType,
} = req.body;
/** set portals */
modelType = (req.user.portals.join() === portal.join()) ? modelType : req.user.portals[0];
const linksData = {
title : title.trim(),
url : url.trim(),
index,
showInHome,
siteMap,
_creator: req.user._id,
_updatedBy: req.user._id,
modelType,
};
var createLinks = await Links.create(linksData);
if (!createLinks) {
res500(res, `error in add links to data base`);
}
/**
* if we have pic upload to server
*/
if (req.files && req.files.icon) {
const image = req.files.icon;
if (!_sr.supportedImageFormats.includes(image.mimetype.split('/')[1])) {
return res.status(422).json({
validation: {
cover: {
msg: _sr['fa'].format.image
}
}
});
}
const imageName = `links_${Date.now()}_${createLinks._id}.${image.mimetype.split('/')[1]}`;
try {
const target = sharp(image.data)
await target
.resize(profileWidth, profileHeight, {
fit: 'cover'
})
.jpeg({
quality: profileQuality
})
.toFile(`./static/uploads/images/links/${imageName}`);
createLinks.icon = imageName;
await createLinks.save();
} catch (e) {
return res500(res, e?.message);
}
}
/**
* show result
*/
return res.json(createLinks);
} catch (error) {
/**
* if we got unkown error show to client
*/
res500(res, error.message);
}
}
]
module.exports.updateLinks = [
[
body('title')
.notEmpty().withMessage(_sr['fa'].required.title),
body('url')
.notEmpty().withMessage(_sr['fa'].required.field),
body('index')
.optional().isNumeric().withMessage(_sr['fa'].format.number),
body('showInHome')
.isBoolean().withMessage(_sr['fa'].format.boolean),
body('siteMap')
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
body('modelType')
.custom((value, {
req
}) => {
if (req.user.portals.join() === portal.join()) {
if (!portal.includes(value)) {
return Promise.reject(_sr['fa'].required.field);
} else {
return true
}
} else {
return true
}
})
],
async (req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({
validation: errors.mapped()
});
try {
/**
* get data from input
*/
let {
title,
url,
index,
showInHome,
siteMap,
modelType,
} = req.body;
/**
* get id
*/
var linksId = req.params.id;
var targetLinks = await Links.findOne({
_id: linksId
});
/** check links exist or not */
if (!targetLinks) {
return res404(res, `پیوند مورد نظر پیدا نشد`);
}
/** check access portal */
if (!req.user.portals.includes(targetLinks.modelType)) {
return res500(res, `شما اجازه آپدیت این پیوند را ندارید`);
}
if (targetLinks.title !== title) {
var checkDuppTitle = await Links.findOne({
title: title
});
if (checkDuppTitle) {
return res.status(422).json({
validation: {
title: {
msg: _sr['fa'].duplicated.title
}
}
});
}
}
/**
* if we have pic upload to server
*/
if (req.files && req.files.icon) {
const image = req.files.icon;
if (!_sr.supportedImageFormats.includes(image.mimetype.split('/')[1])) {
return res.status(422).json({
validation: {
cover: {
msg: _sr['fa'].format.image
}
}
});
}
const imageName = `links_${Date.now()}_${targetLinks._id}.${image.mimetype.split('/')[1]}`;
try {
const target = sharp(image.data)
await target
.resize(profileWidth, profileHeight, {
fit: 'cover'
})
.jpeg({
quality: profileQuality
})
.toFile(`./static/uploads/images/links/${imageName}`);
/**
* if exist old pic delete it from file
*/
if (targetLinks.icon) {
var oldPic = `./static${targetLinks.icon}`;
if (fs.existsSync(oldPic)) {
fs.unlink(oldPic, (err) => {
if (err) return res500(res, err?.message);
});
}
}
targetLinks.icon = imageName;
targetLinks.linksStatus = true;
} catch (e) {
return res500(res, e?.message);
}
}
targetLinks.title = title.trim();
targetLinks.url = url.trim();
targetLinks.index = index;
targetLinks.showInHome = showInHome;
targetLinks.siteMap = siteMap;
targetLinks.modelType = modelType;
await targetLinks.save();
/**
* show result
*/
return res.json(targetLinks);
} catch (error) {
return res500(res, error.message);
}
}
]
module.exports.deletOneLinks = [
async (req, res) => {
try {
var linksId = req.params.id;
var targetLinks = await Links.findOne({
_id: linksId
});
/** check links exist or not */
if (!targetLinks) {
return res404(res, `پیوند مورد نظر پیدا نشد`);
}
/** check access portal */
if (!req.user.portals.includes(targetLinks.modelType)) {
return res500(res, `شما اجازه حذف این پیوند را ندارید`);
}
if (targetLinks.icon) {
var oldPic = `./static${targetLinks.icon}`;
if (fs.existsSync(oldPic)) {
fs.unlink(oldPic, (error) => {
if (error) return res500(res, error?.message);
});
}
}
/** delete links */
await targetLinks.deleteOne();
/**
* show result
*/
return res.json(targetLinks);
} catch (error) {
/**
* if we got unkown error show to client
*/
res500(res, error);
}
}
]
module.exports.getOneLinks = [
async (req, res) => {
try {
var linksId = req.params.id;
var findQuery = {
_id: linksId
};
var links = await Links.findOne(findQuery);
if (!links) {
return res404(res, `پیوند مورد نظر پیدا نشد`);
}
/** check access portal */
if (!req.user.portals.includes(links.modelType)) {
return res.status(403).json({
message: `شما اجازه دسترسی به اطلاعات این پیوند را ندارید`
});
}
/**
* show result
*/
return res.json(links);
} catch (error) {
/**
* if we got unkown error show to client
*/
res500(res, error);
}
}
]
module.exports.getAll = [
async (req, res) => {
try {
var findQuery = {};
if (req.user.portals.length) {
findQuery.modelType = {
$in: req.user.portals
};
}
/** get all links */
const allLinks = await Links.find(findQuery).sort({
index: 1
});
/** if null we have error */
if (!allLinks) {
return res500(res, `مشکلی در گرفتن اطلاعات پیش آمده است`);
}
/** show result to client */
return res.json(allLinks);
} catch (error) {
/** if we have unkown error show it */
return res500(res, error?.message);
}
}
]
/////////////////////////////////////////////////////////////////////// public
module.exports.getAllLinks = [
async (req, res) => {
try {
const {
portal,
} = req.query;
let findQuery = {};
const setSort = {index: 1};
findQuery.modelType = !portal ? 'ostandari' : portal;
findQuery.showInHome = true;
const getLinks = await Links.find(findQuery).sort(setSort);
return res.json(getLinks);
} catch (error) {
return res500(res, error?.message);
}
}
]
+396
View File
@@ -0,0 +1,396 @@
const {body, validationResult} = require('express-validator');
const {_sr} = require('../plugins/serverResponses');
const {res404, res500} = require('../plugins/controllersHelperFunctions');
const Meeting = require('../models/Meeting');
const Captcha = require('../models/Captcha');
const limit = 20;
/////////////////////////////////////////////////////////////////////// admin
module.exports.updateMeeting = [
[
body('name')
.notEmpty().withMessage(_sr['fa'].required.title),
body('subject')
.notEmpty().withMessage(_sr['fa'].required.description),
body('description')
.notEmpty().withMessage(_sr['fa'].required.description),
body('email')
.optional().isEmail().withMessage(_sr['fa'].format.email),
body('phoneNumber')
.if((value, {req}) => {
return req.body.phoneNumber
})
.custom((value, {req}) => {
if (!_.isEmpty(value) && !lodash.isNumeric(value)) {
return Promise.reject(_sr['fa'].format.number);
} else return true;
}),
body('nationalCode')
.notEmpty().withMessage(_sr['fa'].format.national_code)
// body('cptcha')
// .notEmpty().withMessage(_sr['fa'].required.field)
// .custom((value , {req}) => {
// console.log(req.session);
// if(value != req.session.captcha){
// return Promise.reject(`کپچا وارد شده صحیح نمی باشد`);
// }else{
// return true
// }
// }),
],
async (req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({
validation: errors.mapped()
});
try {
/**
* get data from input
*/
const {
name,
subject,
description,
phoneNumber,
email,
nationalCode
} = req.body;
/**
* get id
*/
const meetingId = req.params.id;
/**
* check meeting exist or not
*/
var targetMeeting = await Meeting.findById(meetingId);
if (!targetMeeting) return res404(res, `درخواست مورد نظر پیدا نشد`);
/**
* make update object
*/
targetMeeting.name = name.trim();
targetMeeting.subject = subject.trim();
targetMeeting.description = description.trim();
targetMeeting.email = email;
targetMeeting.phoneNumber = phoneNumber;
targetMeeting.nationalCode = nationalCode;
await targetMeeting.save();
/**
* show result
*/
return res.json(targetMeeting);
} catch (error) {
return res500(res, error?.message);
}
}
]
module.exports.deletOneMeeting = [
async (req, res) => {
try {
const meetingId = req.params.id;
/**
* check meeting
*/
let targetMeeting = await Meeting.findByIdAndDelete(meetingId);
if (!targetMeeting) {
return res404(res, `درخواست مورد نظر پیدا نشد`);
}
/**
* show result
*/
return res.json(targetMeeting);
} catch (error) {
/**
* if we got unknown error show to client
*/
res500(res, error);
}
}
]
module.exports.getOneMeeting = [
async (req, res) => {
try {
const meetingId = req.params.id;
/**
* get meeting
*/
const targetMeeting = await Meeting.findOne({_id: meetingId});
/**
* if not exist
*/
if (!targetMeeting) {
return res404(res, `درخواست مورد نظر پیدا نشد`);
}
if (!targetMeeting.read) {
targetMeeting.read = true;
await targetMeeting.save();
}
/**
* show result
*/
return res.json(targetMeeting);
} catch (error) {
/**
* if we got unknown error show to client
*/
res500(res, error);
}
}
]
module.exports.getAll = [
async (req, res) => {
try {
let findQuery = {};
/**
* get all meeting
*/
const getAll = await Meeting.paginate(findQuery,
{page: req.query.page || 1, limit, sort: {created_at: -1}});
/**
* show result
*/
return res.json(getAll);
} catch (error) {
return res500(res, error.message);
}
}
]
module.exports.getAllForCount = [
async (req, res) => {
try {
/**
* get all meeting
*/
const getAll = await Meeting.find({});
/**
* show result
*/
return res.json(getAll);
} catch (error) {
return res500(res, error.message);
}
}
]
module.exports.search = [
async (req, res) => {
try {
let findQuery = {};
findQuery['$and'] = [];
findQuery['$or'] = [];
const {
name,
email,
terms,
phoneNumber,
nationalCode,
read,
date
} = req.body;
findQuery.modelName = req.params.model;
/** search by term */
if (terms && !_.isEmpty(terms)) {
findQuery['$or'].push(
{
subject: {
$regex: '.*' + name + '.*'
},
description: {
$regex: '.*' + name + '.*'
},
}
);
}
/** search by name */
if (name && !_.isEmpty(name)) {
findQuery['$or'].push(
{
name: {
$regex: '.*' + name + '.*'
}
}
);
}
/** search by email */
if (email && !_.isEmpty(email)) {
findQuery['$and'].push({
email
});
}
/** search by phoneNumber */
if (phoneNumber && !_.isEmpty(phoneNumber)) {
findQuery['$and'].push({
phoneNumber
});
}
/** search by nationalCode */
if (nationalCode && !_.isEmpty(nationalCode)) {
findQuery['$and'].push({
nationalCode
});
}
/** search by read */
if (!_.isUndefined(read) && _.isBoolean(read)) {
findQuery['$and'].push({
read
});
}
/** search by date */
if (date && !_.isEmpty(date)) {
if (date.length === 1) {
findQuery['$and'].push({
created_at: {
$gte: moment(date[0]).startOf('days'),
$lt: moment(date[0]).endOf('days')
}
});
} else {
findQuery['$and'].push({
created_at: {
$gte: new Date(date[0]),
$lt: new Date(date[1])
}
});
}
}
_.isEmpty(findQuery['$and']) && delete findQuery['$and'];
_.isEmpty(findQuery['$or']) && delete findQuery['$or'];
/** get meetings */
var meetings = await Meeting.paginate(findQuery, {
page: req.query.page,
limit,
sort: {created_at: -1}
});
/** show result */
return res.json(meetings);
} catch (error) {
return res500(res, error?.message)
}
}
]
/////////////////////////////////////////////////////////////////////// public
module.exports.addMeeting = [
[
body('name')
.notEmpty().withMessage(_sr['fa'].required.title),
body('subject')
.notEmpty().withMessage(_sr['fa'].required.description),
body('description')
.notEmpty().withMessage(_sr['fa'].required.description),
body('email')
.optional().isEmail().withMessage(_sr['fa'].format.email),
body('phoneNumber')
.custom((value, {req}) => {
if (_.isEmpty(value)) return Promise.reject(_sr['fa'].required.phone_number);
if (!_.isEmpty(value) && !lodash.isNumeric(value)) {
return Promise.reject(_sr['fa'].format.number);
} else return true;
}),
body('nationalCode')
.notEmpty().withMessage(_sr['fa'].format.national_code),
body('captcha')
.notEmpty().withMessage(_sr['fa'].required.field)
.custom((value, {req}) => {
return Captcha.findOne({code: value}).then(data => {
if (!data) return Promise.reject(`عبارت وارد شده صحیح نمیباشد`)
else return true
})
}),
],
async (req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({
validation: errors.mapped()
});
try {
let {
name,
subject,
description,
phoneNumber,
email,
nationalCode
} = req.body;
const data = {
name,
subject,
description,
phoneNumber,
email,
nationalCode
};
const createMeeting = await Meeting.create(data);
if (!createMeeting) {
return res500(res, `مشکلی در ثبت درخواست پیش آمده است`);
}
/**
* show result
*/
return res.json(createMeeting);
} catch (error) {
/**
* if we got unknown error show to client
*/
return res500(res, error?.message);
}
}
]
File diff suppressed because it is too large Load Diff
+684
View File
@@ -0,0 +1,684 @@
const NewsFile = require('../models/NewsFile')
const {body, validationResult} = require('express-validator')
const {_sr} = require('../plugins/serverResponses')
const {res404, res500} = require('../plugins/controllersHelperFunctions')
const News = require('../models/News')
const Category = require('../models/Category')
const sharp = require('sharp')
const fs = require('fs')
////// variables
const noCover = '/img/no-cover.jpg'
const limit = 5;
const limitDetails = 11;
const titleFilterRegex = new RegExp('/', 'g')
////// variables
const coverNewsWidth = 1000;
const coverNewsHeight = 600;
const coverQuality = 100;
const thumbCoverNewsWidth = 600;
const thumbCoverNewsHeight = 300;
const thumbCoverQuality = 200;
////// functions
const changePriority = async (catId, modelType) => {
try {
const getAllNews = await News.find({
catId,
modelType,
priority: true
});
for (const item of getAllNews) {
item.priority = false;
await item.save();
}
return true
} catch (error) {
console.log(error)
}
}
const _checkSpecPermission = async (req, category) => {
return !req.user.specialPermissions.includes(category._id) && //check parent id exist in special permissions or not
!req.user.specialPermissions.some(item => category?.treeCat?.join().includes(item));
}
/////////////////////////////////////////////////////////////////////// admin
module.exports.addNewsFile = [
[
body('title')
.notEmpty().withMessage(_sr['fa'].required.title)
.custom((value, {req}) => {
return NewsFile.findOne({title: value})
.then(newsFile => {
if (newsFile) return Promise.reject(_sr['fa'].duplicated.title);
else return true
})
}),
body('description')
.optional().isString().withMessage(`نوع مقدار ارسال شده صحیح نمی باشد`),
body('catId')
.isMongoId().withMessage(_sr['fa'].required.field)
.if((value, {
req
}) => {
return req.body.catId
})
.custom((value) => {
return Category.findOne({
_id: value
})
.then(category => {
if (!category) return Promise.reject(_sr['fa'].not_found.category);
else return true
})
}),
body('index')
.isNumeric().withMessage(`لطفا ترتیب نمایش را مشخص کنید`),
body('showInHome')
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
body('siteMap')
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
body('modelType')
.custom((value, {req}) => {
if (req.user.portals.join() === portal.join()) {
if (!portal.includes(value)) {
return Promise.reject(_sr['fa'].required.field);
} else {
return true
}
} else {
return true
}
})
],
async (req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({
validation: errors.mapped()
});
try {
let {
title,
description,
catId,
index,
showInHome,
siteMap,
modelType
} = req.body;
/** set portals */
modelType = (req.user.portals.join() === portal.join()) ? modelType : req.user.portals[0];
let newsFileData = {
title: title.trim().replace(titleFilterRegex, '-'),
description: description.trim(),
catId,
index,
showInHome,
siteMap,
_creator: req.user._id,
_updatedBy: req.user._id,
modelType
};
if (catId) {
/** get category with populate parent */
const category = await Category.findOne({
_id: catId
})
.populate({
path: 'parent',
populate: {
path: 'parent',
model: 'Category'
}
});
/** if undefined we have error from database */
if (!category) return res404(res, `دسته بندی انتخاب شده برای این پرونده خبری پیدا نشد`);
/** check special permission */
if (req.user.specialPermissions.length && await _checkSpecPermission(req, category)) {
return res.status(403).json({
message: `شما نمیتوانید این دسته بندی را انتخاب کنید`
});
}
if (category.modelType !== modelType) {
return res.status(403).json({
message: `شما اجازه استفاده از این دسته بندی را ندارید`
});
}
newsFileData.allCat = category.treeCat;
newsFileData.rootParent = category.rootParent || category._id;
}
const createNewsFile = await NewsFile.create(newsFileData);
if (!createNewsFile) res500(res, `مشکلی در اضافه کردن پرونده پرونده خبریی پیش آمده است`)
/**
* if we have pic upload to server
*/
if (req.files?.cover) {
const image = req.files.cover;
if (!_sr.supportedImageFormats.includes(image.mimetype.split('/')[1])) return res.status(422).json({
validation: {
cover: {
msg: _sr['fa'].format.image
}
}
})
const imageName = `news_${Date.now()}_${createNewsFile._id}.${image.mimetype.split('/')[1]}`;
try {
const target = sharp(image.data)
await target
.resize(coverNewsWidth, coverNewsHeight, {fit: 'cover'})
.jpeg({quality: coverQuality})
.toFile(`./static/uploads/images/news/${imageName}`);
createNewsFile.cover = imageName;
await target
.resize(thumbCoverNewsWidth, thumbCoverNewsHeight, {fit: 'cover'})
.jpeg({quality: thumbCoverQuality})
.toFile(`./static/uploads/images/news/thumb_${imageName}`);
createNewsFile.thumbCover = `thumb_${imageName}`;
await createNewsFile.save();
} catch (e) {
return res500(res, e?.message);
}
}
/**
* show result
*/
return res.json(createNewsFile);
} catch (error) {
res500(res, error.message);
}
}
]
module.exports.updateNewsFile = [
[
body('title')
.notEmpty().withMessage(_sr['fa'].required.title),
body('catId')
.isMongoId().withMessage(_sr['fa'].required.field)
.if((value, {
req
}) => {
return req.body.catId
})
.custom((value) => {
return Category.findOne({
_id: value
})
.then(category => {
if (!category) return Promise.reject(_sr['fa'].not_found.category);
else return true
})
}),
body('description')
.optional().isString().withMessage(`نوع مقدار ارسال شده صحیح نمی باشد`),
body('index')
.isNumeric().withMessage(`لطفا ترتیب نمایش را مشخص کنید`),
body('showInHome')
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
body('siteMap')
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
body('modelType')
.custom((value, {req}) => {
if (req.user.portals.join() === portal.join()) {
if (!portal.includes(value)) {
return Promise.reject(_sr['fa'].required.field);
} else {
return true
}
} else {
return true
}
})
],
async (req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({
validation: errors.mapped()
});
try {
/**
* get data from input
*/
const {
title,
description,
catId,
index,
showInHome,
siteMap,
modelType
} = req.body;
/**
* get id
*/
var newsFileId = req.params.id;
var targetNewsFile = await NewsFile.findById(newsFileId);
/** check newsFile exist or not */
if (!targetNewsFile) return res404(res, `پرونده خبری مورد نظر پیدا نشد`);
/** check access portal */
if (!req.user.portals.includes(targetNewsFile.modelType)) return res.status(403).json({message: `شما اجازه آپدیت این پرونده خبری را ندارید`});
if (targetNewsFile.title !== title) {
var checkDuppTitle = await NewsFile.findOne({
title: title
});
if (checkDuppTitle) {
return res.status(422).json({validation: {title: {msg: _sr['fa'].duplicated.title}}});
}
}
if (modelType !== targetNewsFile.modelType) {
/** check have news or not */
var checkNews = await News.find({newsFileId: targetNewsFile._id});
if (checkNews.length) {
return res.status(403).json({message: `این پرونده خبری دارای خبر می باشد و شما نمی توانید نوع آن را تغییر دهید`});
}
}
/** get category with populate parent */
var category = await Category.findOne({
_id: catId
})
.populate({
path: 'parent',
populate: {
path: 'parent',
model: 'Category'
}
});
/** if undefined we have error from database */
if (!category) return res404(res, `دسته بندی انتخاب شده برای این خبر پیدا نشد`);
/** check special permission */
if (req.user.specialPermissions.length && await _checkSpecPermission(req, category)) {
return res.status(403).json({
message: `شما مجاز به انتخاب این دسته بندی نمی باشید`
});
}
if (category.modelType !== modelType) return res.status(403).json({
message: `محدوده انتخاب شده شما با محدوده دسته بندی همخوانی ندارد`
});
if (catId && targetNewsFile.catId !== catId) {
targetNewsFile.allCat = category.treeCat;
targetNewsFile.rootParent = category.rootParent || category._id;
}
targetNewsFile.title = title.trim().replace(titleFilterRegex, '-')
targetNewsFile.description = description.trim();
targetNewsFile.catId = catId;
targetNewsFile.index = index;
targetNewsFile.showInHome = showInHome;
targetNewsFile.siteMap = siteMap;
targetNewsFile.modelType = modelType;
/**
* if we have pic upload to server
*/
if (req.files?.cover) {
const image = req.files.cover;
if (!_sr.supportedImageFormats.includes(image.mimetype.split('/')[1])) {
return res.status(422).json({
validation: {
cover: {
msg: _sr['fa'].format.image
}
}
});
}
const imageName = `news_${Date.now()}_${targetNewsFile._id}.${image.mimetype.split('/')[1]}`;
try {
const target = sharp(image.data)
await target
.resize(coverNewsWidth, coverNewsHeight, {fit: 'cover'})
.jpeg({quality: coverQuality})
.toFile(`./static/uploads/images/news/${imageName}`);
await target
.resize(thumbCoverNewsWidth, thumbCoverNewsHeight, {fit: 'cover'})
.jpeg({quality: thumbCoverQuality})
.toFile(`./static/uploads/images/news/thumb_${imageName}`);
/**
* if exist old pic delete it from file
*/
if (targetNewsFile.cover !== noCover) {
let oldPic = `./static${targetNewsFile.cover}`;
if (await fs.existsSync(oldPic)) {
fs.unlink(oldPic, (err) => {
if (err) return res500(res, err?.message);
});
}
}
if (targetNewsFile.thumbCover !== noCover) {
let oldPic = `./static${targetNewsFile.thumbCover}`;
if (await fs.existsSync(oldPic)) {
fs.unlink(oldPic, (err) => {
if (err) return res500(res, err?.message);
});
}
}
targetNewsFile.cover = imageName;
targetNewsFile.thumbCover = `thumb_${imageName}`;
} catch (e) {
return res500(res, e?.message);
}
}
await targetNewsFile.save();
/**
* show result
*/
return res.json(targetNewsFile);
} catch (error) {
return res500(res, error.message);
}
}
]
module.exports.deletOneNewsFile = [
async (req, res) => {
try {
var newsFileId = req.params.id;
var targetNewsFile = await NewsFile.findOne({_id: newsFileId});
/** check newsFile exist or not */
if (!targetNewsFile) {
return res404(res, `پرونده خبری مورد نظر پیدا نشد`);
}
/** check access portal */
if (!req.user.portals.includes(targetNewsFile.modelType)) {
return res.status(403).json({message: `شما اجازه حذف این پرونده خبری را ندارید`});
}
/** check have news or not */
var checkNews = await News.find({newsFileId: targetNewsFile._id});
if (checkNews.length) {
return res.status(403).json({message: `این پرونده خبری دارای خبر می باشد و شما نمی توانید آن را حذف دهید`});
}
/** delete newsFile */
await targetNewsFile.deleteOne();
/**
* show result
*/
return res.json(targetNewsFile);
} catch (error) {
res500(res, error);
}
}
]
module.exports.deleteAllNewsFile = [
async (req, res) => {
try {
} catch (error) {
/**
* if we got unkown error show to client
*/
res500(res, error);
}
}
]
module.exports.getOneNewsFile = [
async (req, res) => {
try {
var newsFileId = req.params.id;
var findQuery = {_id: newsFileId};
var newsFile = await NewsFile.findOne(findQuery).populate('catId');
if (!newsFile) {
return res404(res, `پرونده خبری مورد نظر پیدا نشد`);
}
/** check access portal */
if (!req.user.portals.includes(newsFile.modelType)) {
return res.status(403).json({message: `شما اجازه دسترسی به اطلاعات این پرونده خبری را ندارید`});
}
/**
* show result
*/
return res.json(newsFile);
} catch (error) {
res500(res, error);
}
}
]
module.exports.getAll = [
async (req, res) => {
try {
var findQuery = {};
// @todo can change it
if (req.user.specialPermissions.length) {
findQuery.catId = {$in: req.user.specialPermissions}
}
if (req.user.portals.length) {
findQuery.modelType = {$in: req.user.portals};
}
/** get all newsFile */
const allNewsFile = await NewsFile.find(findQuery).populate('_creator', {
firstName: 1,
lastName: 1,
profilePic: 1
})
.sort({created_at: -1});
/** if null we have error */
if (!allNewsFile) {
return res500(res, `مشکلی در گرفتن اطلاعات پیش آمده است`);
}
/** show result to client */
return res.json(allNewsFile);
} catch (error) {
return res500(res, error?.message);
}
}
]
module.exports.search = [
async (req, res) => {
try {
var query = {};
let populate = [{
path: '_creator',
select: {firstName: 1, lastName: 1, profilePic: 1}
},
{
path: 'catId'
}];
query['$and'] = [];
var {
term,
showInHome,
catId,
portals
} = req.body;
///////////// permissions
/** search by catId */
if (req.user.specialPermissions.length) {
query.catId = {$in: req.user.specialPermissions}
} else if (catId && !_.isEmpty(catId)) {
query['$and'].push({
catId
});
}
/** search by portals */
if (portals && !_.isEmpty(portals)) {
query['$and'].push({
modelType: {
$in: portals
}
})
} else {
if (req.user.portals.length) {
query.modelType = {$in: req.user.portals};
}
}
/** search by term */
if (term && !_.isEmpty(term)) {
query['$and'].push({
$or: [{
title: {
$regex: '.*' + term + '.*'
}
}]
});
}
/** search by showInHome */
if (!_.isUndefined(showInHome) && _.isBoolean(showInHome)) {
query['$and'].push({
showInHome
});
}
_.isEmpty(query['$and']) && delete query['$and'];
// _.isEmpty(input['$or']) && delete input['$or'];
/** get news */
const news = await NewsFile.paginate(query, {page: req.query.page, limit, populate, sort: {_id: -1}});
/** show result */
return res.json(news);
} catch (error) {
return res500(res, error?.message)
}
}
]
/////////////////////////////////////////////////////////////////////// public
module.exports.viewNewsFile = [
async (req, res) => {
try {
const newsFileTitle = req.params.title;
let targetNewsFile = await NewsFile.findOne({
title: newsFileTitle
})
.populate('_creator', {firstName: 1, lastName: 1, profilePic: 1});
if (!targetNewsFile) {
return res404(res, `پرونده خبری مورد نطر پیدا نشد`);
}
++targetNewsFile.userViews;
await targetNewsFile.save();
/** get news */
let getNews = await News.paginate({newsFileId: targetNewsFile._id}, {page: req.query.page || 1, limit: limitDetails , sort : {customDate : -1}});
let result = {
newsFile: targetNewsFile,
news: getNews
};
return res.json(result);
} catch (error) {
return res500(res, `مشکلی در اجرای درخواست شما پیش آمده است`);
}
}
]
module.exports.getAllNewsFile = [
async (req, res) => {
try {
const {
portal,
limit,
skip
} = req.query;
const findQuery = {};
const setLimit = parseInt(limit) || 4;
const setSort = {index: 1};
const setSkip = parseInt(skip) || 0;
findQuery.modelType = portal;
findQuery.publish = true;
const getNewsFile = await NewsFile.find(findQuery).limit(setLimit).skip(setSkip).sort(setSort);
return res.json(getNewsFile);
} catch (error) {
return res500(res, error?.message);
}
}
]
+341
View File
@@ -0,0 +1,341 @@
const Occasion = require('../models/Occasion');
const {body, validationResult} = require('express-validator');
const {_sr} = require('../plugins/serverResponses');
const {res404, res500} = require('../plugins/controllersHelperFunctions');
const fs = require('fs');
const sharp = require('sharp');
const moment = require('moment-jalaali');
////// variables
const occasionWidth = 1920
const occasionHeight = 180
const occasionQuality = 100
const limit = 5;
/////////////////////////////////////////////////////////////////////// admin
module.exports.addOccasion = [
[
body('title')
.notEmpty().withMessage(_sr['fa'].required.title),
body('publish')
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
body('index')
.isNumeric().withMessage(_sr['fa'].format.number),
body('startDate')
.notEmpty().withMessage(`لطفا یک تاریخ شروع تعیین کنید`),
body('endDate')
.notEmpty().withMessage(`لطفا یک تاریخ پایان تعیین کنید`),
],
async (req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({
validation: errors.mapped()
});
try {
const {title, publish, index, startDate, endDate} = req.body;
const occasionData = {
title,
publish,
index,
startDate,
endDate,
_creator: req.user._id,
_updatedBy: req.user._id,
}
const addOccasion = await Occasion.create(occasionData);
if (!addOccasion) return res500(res, `مشلی در اجرای درخواست شما پیش امده است`);
if (req?.files && req.files?.cover) {
const image = req.files.cover;
if (!_sr.supportedImageFormats.includes(image.mimetype.split('/')[1])) {
return res.status(422).json({validation: {cover: {msg: _sr['fa'].format.image}}});
}
const imageName = `occasion_${addOccasion._id}_${Date.now()}.jpg`;
const target = sharp(image.data)
await target
.resize(occasionWidth, occasionHeight, {
fit: 'cover'
})
.toFormat('jpg')
.jpeg({
quality: occasionQuality
})
.toFile(`./static/uploads/images/occasion/${imageName}`);
addOccasion.status = true;
addOccasion.mainCover = imageName;
await addOccasion.save();
}
/**
* show result
*/
return res.json(addOccasion);
} catch (error) {
return res500(res, `مشکلی در اجرای درخواست پیش آمده است`);
}
}
]
module.exports.updateOccasion = [
[
body('title')
.notEmpty().withMessage(_sr['fa'].required.title),
body('publish')
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
body('index')
.isNumeric().withMessage(_sr['fa'].format.number),
body('startDate')
.notEmpty().withMessage(`لطفا یک تاریخ شروع تعیین کنید`),
body('endDate')
.notEmpty().withMessage(`لطفا یک تاریخ پایان تعیین کنید`),
],
async (req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({
validation: errors.mapped()
});
try {
const {title, publish, index, startDate, endDate} = req.body;
const occasionId = req.params.id;
const targetOccasion = await Occasion.findById(occasionId);
if (!targetOccasion) {
return res404(res, `مناسبت مورد نظر پیدا نشد`);
}
if (req?.files && req.files?.cover) {
const image = req.files.cover;
if (!_sr.supportedImageFormats.includes(image.mimetype.split('/')[1])) {
return res.status(422).json({validation: {cover: {msg: _sr['fa'].format.image}}});
}
const imageName = `occasion_${targetOccasion._id}_${Date.now()}.jpg`;
const target = sharp(image.data)
await target
.resize(occasionWidth, occasionHeight, {
fit: 'cover'
})
.toFormat('jpg')
.jpeg({
quality: occasionQuality
})
.toFile(`./static/uploads/images/occasion/${imageName}`);
if (targetOccasion.mainCover) {
var oldPic = `./static${targetOccasion.mainCover}`;
if (fs.existsSync(oldPic)) {
fs.unlink(oldPic, (err) => {
if (err) return res500(res, err?.message);
});
}
}
targetOccasion.status = true;
targetOccasion.mainCover = imageName;
}
targetOccasion.title = title;
targetOccasion.publish = publish;
targetOccasion.index = index;
targetOccasion.startDate = startDate;
targetOccasion.endDate = endDate;
targetOccasion._updatedBy = req.user._id;
await targetOccasion.save();
return res.json(targetOccasion);
} catch (error) {
return res500(res, `مشکلی در اجرای درخواست پیش آمده است`);
}
}
]
module.exports.deleteOccasion = [
async (req, res) => {
try {
const occasionId = req.params.id;
const targetOccasion = await Occasion.findById(occasionId);
if (!targetOccasion) {
return res404(res, `مناسبت مورد نظر پیدا نشد`);
}
if (targetOccasion.mainCover) {
var oldPic = `./static${targetOccasion.mainCover}`;
if (fs.existsSync(oldPic)) {
fs.unlink(oldPic, (err) => {
if (err) return res500(res, err?.message);
});
}
}
await targetOccasion.deleteOne();
return res.json({message: `مناسبت مورد نظر حذف گرید`});
} catch (error) {
return res500(res, `مشکلی در اجرای درخواست پیش آمده است`);
}
}
]
module.exports.getOccasionByAdmin = [
async (req, res) => {
try {
const occasionId = req.params.id;
const getOccasion = await Occasion.findById(occasionId);
/**
* if not exist
*/
if (!getOccasion) return res404(res, `اطلاعات مورد نظر پیدا نشد`);
/**
* show result
*/
return res.json(getOccasion);
} catch (error) {
/**
* if we got unkown error show to client
*/
return res500(res, `مشکلی در اجرای درخواست شما پیش آمده است`);
}
}
]
module.exports.getAllOccasionByAdmin = [
async (req, res) => {
try {
const getAllOccasion = await Occasion.paginate({}, {
page: req.query.page || 1,
populate: {path: '_creator', select: 'firstName lastName'},
limit,
sort: {_id: -1}
});
return res.json(getAllOccasion);
} catch (error) {
/**
* if we got unkown error show to client
*/
return res500(res, `مشکلی در اجرای درخواست شما پیش آمده است`);
}
}
]
module.exports.getAllOccasionForIndex = [
async (req, res) => {
try {
const getAllOccasion = await Occasion.find();
return res.json(getAllOccasion);
} catch (error) {
/**
* if we got unkown error show to client
*/
return res500(res, `مشکلی در اجرای درخواست شما پیش آمده است`);
}
}
]
module.exports.search = [
async (req, res) => {
try {
let query = {};
let populate = [{
path: '_creator',
select: {firstName: 1, lastName: 1, profilePic: 1}
}];
query['$and'] = [];
const {
term,
publish,
status,
date
} = req.body;
/** search by term */
if (term && !_.isEmpty(term)) {
query['$and'].push({
$or: [{
title: {
$regex: '.*' + term + '.*'
}
}]
});
}
/** search by publish */
if (!_.isUndefined(publish) && _.isBoolean(publish)) {
query['$and'].push({
publish
});
}
/** search by status */
if (!_.isUndefined(status) && _.isBoolean(status)) {
query['$and'].push({
status
});
}
/** search by date */
if (date && !_.isEmpty(date)) {
if (date.length === 1) {
query['$and'].push({
startDate:{$lte : new Date(date[0])},
endDate: {$gte : new Date(date[0])}
});
} else {
query['$and'].push({
startDate: {$lte : new Date(date[0])},
endDate:{$gte : new Date(date[1])}
});
}
}
_.isEmpty(query['$and']) && delete query['$and'];
// _.isEmpty(input['$or']) && delete input['$or'];
/** get news */
const occasion = await Occasion.paginate(query, {
page: req.query.page || 1,
limit,
populate,
sort: {_id: -1}
});
/** show result */
return res.json(occasion);
} catch (error) {
return res500(res, error?.message)
}
}
]
+109
View File
@@ -0,0 +1,109 @@
const { body, validationResult } = require("express-validator");
const { _sr } = require("../plugins/serverResponses");
const { checkValidations } = require("../plugins/controllersHelperFunctions");
const Book = require("../models/Book");
var convertapi = require('convertapi')('6zZB0nquI5V3P3Vg');
module.exports.AddPDF = [
[
body('title')
.notEmpty().withMessage(_sr['fa'].required.title)
],
checkValidations(validationResult),
async (req, res) => {
try {
const firstbook = [];
if (!req.files?.file) {
return res.status(422).json({ validation: { file: { msg: _sr['fa'].required.file } } });
}
if (req.files?.file.mimetype.split('/')[1] !== 'pdf') {
return res.status(422).json({ validation: { file: { msg: 'فقط فرمت PDF قابل قبول است' } } });
}
const book = await Book.findById(req.body.bookId);
const bookId = book ? book._id : null;
const data = { title: req.body.title };
const file = req.files.file;
const fileName = req.body.title.replace(Date.now(), '-') + '_' + Date.now() + '.pdf';
const imageName = req.body.title.replace(Date.now(), '-') + '_' + Date.now();
const filePath = `./static/uploads/pdf/${fileName}`;
await file.mv(filePath);
data.file = fileName;
const convertPromise = convertapi.convert('jpg', {
File: filePath
}, 'pdf');
const result = await convertPromise;
const savedFiles = await result.saveFiles(`./static/uploads/books/${imageName}.jpeg`);
const imagePath = `https://ostan-mr.ir/uploads/books/${imageName}.jpeg`;
firstbook.push(imagePath);
if (bookId) {
const update = await Book.findByIdAndUpdate(
{_id:bookId},
{ $push: { slides: imagePath } },
{ upsert: true }
);
return res.status(201).json({ msg: "اسلاید کتاب اضافه شد", Data: update });
} else {
const newBook = new Book({
title: req.body.title,
uri: `https://ostan-mr.ir/uploads/pdf/${fileName}`,
slides: firstbook
});
await newBook.save();
return res.status(201).json({ msg: "کتاب ایجاد شد", Data: newBook });
}
} catch (error) {
console.error(error);
return res.status(500).json({ msg: "خطایی در پردازش فایل رخ داد", error: error.message });
}
}
];
module.exports.GetAll = [
async (req, res,next) => {
try {
const Books = await Book.find({});
return res.status(200).json({ Books });
} catch (error) {
next(error)
}
}
];
module.exports.GetOne = [
async (req, res,next) => {
try {
const id = req.params.id
const book = await Book.findById(id);
return res.status(200).json({ msg: book });
} catch (error) {
next(error)
}
}
];
module.exports.DeleteOne = [
async(req,res,next)=>{
try {
const book = await Book.deleteOne({_id:req.params.id})
if(!book){
return res.status(200).json({ msg: 'کتاب وجود ندارد ' });
}
return res.status(200).json({ msg: 'کتاب حذف شد' });
} catch (error) {
next(error)
}
}
]
@@ -0,0 +1,36 @@
const permissions = require('../plugins/permissions');
const {body, validationResult} = require('express-validator');
const sharp = require('sharp');
const User = require('../models/User')
const {_sr} = require('../plugins/serverResponses');
const {res404, res500, hasWhiteSpaces, isLatinCharactersWithSymbol, generateRandomDigits} = require('../plugins/controllersHelperFunctions');
/** @todo add show in footer */
/////////////////////////////////////////////////////////////////////// admin
module.exports.getAll = [
async (req, res) => {
try {
return res.json(permissions);
} catch (error) {
return res500(res , error.message);
}
}
]
module.exports.SetPermission = [
async (req,res)=>{
try {
const {id} = req.params;
const lastuser = await User.findById(id)
if(lastuser.scope.includes('PublisherNews')){
return res.status(200).json({message:"کاربر به عنوان دبیر ثبت شده"})
}
const user = await User.findByIdAndUpdate({_id:id} , {$push:{scope:"PublisherNews"}} , {new:true});
return res.status(200).json(user)
}catch (e) {
return res.status(500).json(e.message)
}
}
]
+436
View File
@@ -0,0 +1,436 @@
const Category = require('../models/Category');
const {body, validationResult} = require('express-validator');
const {_sr} = require('../plugins/serverResponses');
const {res404, res500, checkValidations} = require('../plugins/controllersHelperFunctions');
const Polls = require('../models/Polls');
const fs = require('fs')
// variables
const titleFilterRegex = new RegExp('/', 'g')
const limit = 20;
//// functions
const _checkSpecPermission = async (req, category) => {
return !req.user.specialPermissions.includes(category._id) && //check parent id exist in special permissions or not
!req.user.specialPermissions.some(item => category?.treeCat?.join().includes(item));
}
/////////////////////////////////////////////////////////////////////// admin
module.exports.addSurvey = [
[
body('title')
.notEmpty().withMessage(_sr['fa'].required.field),
body('catId')
.isMongoId().withMessage(_sr['fa'].required.field)
.if((value, {req}) => {
return req.body.catId
})
.custom((value) => {
return Category.findOne({
_id: value
})
.then(category => {
if (!category) return Promise.reject(_sr['fa'].not_found.category);
else return true
})
}),
// body('index')
// .isNumeric().withMessage(`لطفا ترتیب نمایش را مشخص کنید`),
body('surveyType')
.notEmpty().withMessage(_sr['fa'].required.field)
.bail()
.isIn(['check', 'radio']).withMessage(`${_sr['fa'].optional.onlyValid} => 'check' , 'radio'`),
body('startDate')
.notEmpty().withMessage(`لطفا یک تاریخ شروع تعیین کنید`),
body('endDate')
.notEmpty().withMessage(`لطفا یک تاریخ پایان تعیین کنید`),
body('publish')
.isBoolean().withMessage(_sr['fa'].format.boolean),
body('options')
.notEmpty().withMessage(_sr['fa'].required.field)
.bail()
.isArray().withMessage(`اطلاعات را باید به صورت آرایه بفرستید`),
],
checkValidations(validationResult),
async (req, res) => {
try {
const {
title,
catId,
description,
// index,
surveyType,
startDate,
endDate,
options,
publish
} = req.body;
const data = {
title: title.trim(),
catId,
description,
// index,
surveyType,
startDate,
endDate,
options,
publish,
_creator: req.user._id,
_updatedBy: req.user._id
}
const category = await Category.findOne({
_id: catId
}).populate({
path: 'parent',
populate: {
path: 'parent',
model: 'Category'
}
});
if (!category) return res404(res, 'دسته بندی مورد نظر پیدا نشد');
/** check special permission */
if (req.user.specialPermissions.length && await _checkSpecPermission(req, category)) {
return res.status(403).json({
message: `شما نمیتوانید این دسته بندی را انتخاب کنید`
});
}
data.allCat = category.treeCat;
data.rootParent = category.rootParent || category._id;
const createPoll = await Polls.create(data);
if (!createPoll) return res500(res, `مشکلی در اجرای درخواست شما پیش آمده است`);
return res.json({message: _sr['fa'].response.success_save});
} catch (error) {
return res500(res, `مشکلی در اجرای درخواست شما بوجود آمده است`);
}
}
]
module.exports.updateSurvey = [
[
body('title')
.notEmpty().withMessage(_sr['fa'].required.field),
body('catId')
.isMongoId().withMessage(_sr['fa'].required.field)
.if((value, {req}) => {
return req.body.catId
})
.custom((value) => {
return Category.findOne({
_id: value
})
.then(category => {
if (!category) return Promise.reject(_sr['fa'].not_found.category);
else return true
})
}),
// body('index')
// .isNumeric().withMessage(`لطفا ترتیب نمایش را مشخص کنید`),
body('surveyType')
.notEmpty().withMessage(_sr['fa'].required.field)
.bail()
.isIn(['check', 'radio']).withMessage(`${_sr['fa'].optional.onlyValid} => 'check' , 'radio'`),
body('startDate')
.notEmpty().withMessage(`لطفا یک تاریخ شروع تعیین کنید`),
body('endDate')
.notEmpty().withMessage(`لطفا یک تاریخ پایان تعیین کنید`),
body('options')
.notEmpty().withMessage(_sr['fa'].required.field)
.bail()
.isArray().withMessage(`اطلاعات را باید به صورت آرایه بفرستید`),
body('publish')
.isBoolean().withMessage(_sr['fa'].format.boolean),
],
checkValidations(validationResult),
async (req, res) => {
try {
const pollId = req.params.id;
const {
title,
surveyType,
description,
catId,
// index,
startDate,
endDate,
options,
publish
} = req.body;
//// check poll
const targetPoll = await Polls.findById(pollId);
if (!targetPoll) return res404(res, `نظر سنجی مورد نظر پیدا نشد`);
if (catId && targetPoll.catId !== catId) {
const category = await Category.findOne({
_id: catId
}).populate({
path: 'parent',
populate: {
path: 'parent',
model: 'Category'
}
});
if (!category) return res404(res, 'دسته بندی مورد نظر پیدا نشد');
/** check special permission */
if (req.user.specialPermissions.length && await _checkSpecPermission(req, category)) {
return res.status(403).json({
message: `شما نمیتوانید این دسته بندی را انتخاب کنید`
});
}
targetPoll.catId = catId;
targetPoll.allCat = category.treeCat;
targetPoll.rootParent = category.rootParent || category._id;
}
targetPoll.title = title;
targetPoll.surveyType = surveyType;
targetPoll.description = description;
// targetPoll.index = index;
targetPoll.startDate = startDate;
targetPoll.endDate = endDate;
targetPoll.options = options;
targetPoll.publish = publish;
targetPoll._updatedBy = req.user._id;
await targetPoll.save();
return res.json({message: _sr['fa'].response.success_save});
} catch (error) {
return res500(res, `مشکلی در اجرای درخواست شما بوجود آمده است`);
}
}
]
module.exports.getAllSurvey = [
async (req, res) => {
try {
let findQuery = {};
if (req.user.specialPermissions.length) {
findQuery.catId = {$in: req.user.specialPermissions}
}
const allPolls = await Polls.paginate(findQuery, {
page: req.query.page || 1,
populate: {path: 'catId'},
limit,
sort: {created_at: -1}
});
if (!allPolls) return res500(res, `مشکلی در گرفتن اطلاعات پیش آمده است`);
return res.json(allPolls);
} catch (error) {
return res500(res, `مشکلی در اجرای درخواست شما بوجود آمده است`);
}
}
]
module.exports.getOneSurvey = [
async (req, res) => {
try {
const pollId = req.params.id;
const findQuery = {
_id: pollId
};
const poll = await Polls.findOne(findQuery).populate('catId');
if (!poll) return res404(res, `اطلاعات مورد نظر پیدا نشد`);
if (req.user.specialPermissions.length && await _checkSpecPermission(req, poll.catId)) {
return res.status(403).json({
message: `شما مجاز به دیدن اطلاعات این نظرسنجی نمی باشید`
});
}
return res.json(poll);
} catch (error) {
return res500(res, `مشکلی در اجرای درخواست شما بوجود آمده است`);
}
}
]
module.exports.deletOneSurvey = [
async (req, res) => {
try {
const pollId = req.params.id;
const deletePoll = await Polls.findById(pollId).populate('catId');
if (!deletePoll) return res404(res, `نظرسنجی مورد نظر پیدا نشد`);
if (req.user.specialPermissions.length && await _checkSpecPermission(req, deletePoll.catId)) {
return res.status(403).json({
message: `شما اجازه حذف این نظرسنجی را ندارید`
});
}
await deletePoll.deleteOne();
return res.json({message: _sr['fa'].response.success_remove});
} catch (error) {
return res500(res, `مشکلی در اجرای درخواست شما بوجود آمده است`);
}
}
]
module.exports.search = [
async (req, res) => {
try {
let query = {};
let populate = [{
path: '_creator',
select: {firstName: 1, lastName: 1, profilePic: 1}
}];
query['$and'] = [];
const {
term,
catId,
publish,
date
} = req.body;
/** search by term */
if (term && !_.isEmpty(term)) {
query['$and'].push({
$or: [{
title: {
$regex: '.*' + term + '.*'
}
}]
});
}
if (req.user.specialPermissions.length) {
query.catId = {$in: req.user.specialPermissions}
} else if (catId && !_.isEmpty(catId)) {
query['$and'].push({
catId
});
}
/** search by publish */
if (!_.isUndefined(publish) && _.isBoolean(publish)) {
query['$and'].push({
publish
});
}
/** search by date */
if (date && !_.isEmpty(date)) {
if (date.length === 1) {
query['$and'].push({
startDate: {$lte: new Date(date[0])},
endDate: {$gte: new Date(date[0])}
});
} else {
query['$and'].push({
startDate: {$lte: new Date(date[0])},
endDate: {$gte: new Date(date[1])}
});
}
}
_.isEmpty(query['$and']) && delete query['$and'];
// _.isEmpty(input['$or']) && delete input['$or'];
/** get polls */
const polls = await Polls.paginate(query, {
page: req.query.page || 1,
limit,
populate,
sort: {_id: -1}
});
/** show result */
return res.json(polls);
} catch (error) {
return res500(res, `مشکلی در اجرای درخواست شما بوجود آمده است`);
}
}
]
/////////////////////////////////////////////////////////////////////// public
module.exports.answer = [
[
body('surveyId')
.notEmpty().withMessage(_sr['fa'].required.field),
body('option')
.notEmpty().withMessage(_sr['fa'].required.field),
body('pollToken')
.notEmpty().withMessage(_sr['fa'].required.field)
],
checkValidations(validationResult),
async (req, res) => {
try {
const {
surveyId,
option,
pollToken
} = req.body;
//// check category
const targetPoll = await Polls.findById(surveyId);
if (!targetPoll) return res404(res, `نظر سنجی مورد نظر پیدا نشد`);
for (const item of option) {
targetPoll.answers.push(item);
}
targetPoll.userIds.push(pollToken);
await targetPoll.save();
return res.json({message: _sr['fa'].response.success_save});
} catch (error) {
return res500(res, `مشکلی در اجرای درخواست شما بوجود آمده است`);
}
}
]
+17
View File
@@ -0,0 +1,17 @@
const portals = require('../plugins/portals');
const {_sr} = require('../plugins/serverResponses');
const {res404, res500, hasWhiteSpaces, isLatinCharactersWithSymbol, generateRandomDigits} = require('../plugins/controllersHelperFunctions');
/** @todo add show in footer */
/////////////////////////////////////////////////////////////////////// admin
module.exports.getAll = [
async (req, res) => {
try {
var result = portals.filter((item) => req.user.portals.includes(item.value));
return res.json(result);
} catch (error) {
return res500(res , error.message);
}
}
]
+542
View File
@@ -0,0 +1,542 @@
const Slider = require('../models/Slider');
const {
body,
validationResult
} = require('express-validator');
const sharp = require('sharp');
const {
_sr
} = require('../plugins/serverResponses');
const {
res404,
res500,
hasWhiteSpaces,
isLatinCharactersWithSymbol,
generateRandomDigits
} = require('../plugins/controllersHelperFunctions');
const fs = require('fs');
////// variables
const profileWidth = 600;
const profileHeight = 400;
const profileQuality = 100;
/////////////////////////////////////////////////////////////////////// admin
module.exports.addSlider = [
[
body('title')
.notEmpty().withMessage(_sr['fa'].required.title),
body('summaryTitle')
.notEmpty().withMessage(_sr['fa'].required.field),
body('url')
.notEmpty().withMessage(_sr['fa'].required.field),
body('index')
.optional().isNumeric().withMessage(_sr['fa'].format.number),
body('isLocal')
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
body('siteMap')
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
body('modelType')
.custom((value, {
req
}) => {
if (req.user.portals.join() === portal.join()) {
if (!portal.includes(value)) {
return Promise.reject(_sr['fa'].required.field);
} else {
return true
}
} else {
return true
}
})
],
async (req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({
validation: errors.mapped()
});
try {
var {
title,
summaryTitle,
isLocal,
url,
index,
siteMap,
modelType,
} = req.body;
/** set portals */
modelType = (req.user.portals.join() === portal.join()) ? modelType : req.user.portals[0];
const sliderData = {
title : title.trim(),
summaryTitle : summaryTitle.trim(),
url : url.trim(),
isLocal,
index,
siteMap,
_creator: req.user._id,
_updatedBy: req.user._id,
modelType,
};
var createSlider = await Slider.create(sliderData);
if (!createSlider) {
res500(res, `error in add slider to data base`);
}
/**
* if we have pic upload to server
*/
if (req.files && req.files.cover) {
const image = req.files.cover;
if (!_sr.supportedImageFormats.includes(image.mimetype.split('/')[1])) {
return res.status(422).json({
validation: {
cover: {
msg: _sr['fa'].format.image
}
}
});
}
const imageName = `slider_${Date.now()}_${createSlider._id}.${image.mimetype.split('/')[1]}`;
try {
const target = sharp(image.data)
await target
.resize(profileWidth, profileHeight, {
fit: 'cover'
})
.jpeg({
quality: profileQuality
})
.toFile(`./static/uploads/images/slider/${imageName}`);
createSlider.cover = imageName;
await createSlider.save();
} catch (e) {
return res500(res, e?.message);
}
}
/**
* show result
*/
return res.json(createSlider);
} catch (error) {
console.log(error);
/**
* if we got unkown error show to client
*/
res500(res, error.message);
}
}
]
module.exports.updateSlider = [
[
body('title')
.notEmpty().withMessage(_sr['fa'].required.title),
body('summaryTitle')
.notEmpty().withMessage(_sr['fa'].required.field),
body('url')
.notEmpty().withMessage(_sr['fa'].required.field),
body('isLocal')
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
body('index')
.optional().isNumeric().withMessage(_sr['fa'].format.number),
body('siteMap')
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
body('modelType')
.custom((value, {
req
}) => {
if (req.user.portals.join() === portal.join()) {
if (!portal.includes(value)) {
return Promise.reject(_sr['fa'].required.field);
} else {
return true
}
} else {
return true
}
})
],
async (req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({
validation: errors.mapped()
});
try {
/**
* get data from input
*/
var {
title,
summaryTitle,
url,
isLocal,
index,
siteMap,
modelType,
} = req.body;
/**
* get id
*/
var sliderId = req.params.id;
var targetSlider = await Slider.findOne({
_id: sliderId
});
/** check slider exist or not */
if (!targetSlider) {
return res404(res, `اسلایدر مورد نظر پیدا نشد`);
}
/** check access portal */
if (!req.user.portals.includes(targetSlider.modelType)) {
return res500(res, `شما اجازه آپدیت این اسلایدر را ندارید`);
}
if (targetSlider.title !== title) {
var checkDuppTitle = await Slider.findOne({
title: title
});
if (checkDuppTitle) {
return res.status(422).json({
validation: {
title: {
msg: _sr['fa'].duplicated.title
}
}
});
}
}
/**
* if we have pic upload to server
*/
if (req.files && req.files.cover) {
const image = req.files.cover;
if (!_sr.supportedImageFormats.includes(image.mimetype.split('/')[1])) {
return res.status(422).json({
validation: {
cover: {
msg: _sr['fa'].format.image
}
}
});
}
const imageName = `slider_${Date.now()}_${targetSlider._id}.${image.mimetype.split('/')[1]}`;
try {
const target = sharp(image.data)
await target
.resize(profileWidth, profileHeight, {
fit: 'cover'
})
.jpeg({
quality: profileQuality
})
.toFile(`./static/uploads/images/slider/${imageName}`);
/**
* if exist old pic delete it from file
*/
if (targetSlider.cover) {
var oldPic = `./static${targetSlider.cover}`;
if (fs.existsSync(oldPic)) {
fs.unlink(oldPic, (err) => {
if (err) return res500(res, err?.message);
});
}
}
targetSlider.cover = imageName;
} catch (e) {
return res500(res, e?.message);
}
}
targetSlider.title = title.trim();
targetSlider.summaryTitle = summaryTitle.trim();
targetSlider.url = url.trim();
targetSlider.isLocal = isLocal
targetSlider.index = index;
targetSlider.siteMap = siteMap;
targetSlider.modelType = modelType;
await targetSlider.save();
/**
* show result
*/
return res.json(targetSlider);
} catch (error) {
return res500(res, error.message);
}
}
]
module.exports.deletOneSlider = [
async (req, res) => {
try {
var sliderId = req.params.id;
var targetSlider = await Slider.findOne({
_id: sliderId
});
/** check slider exist or not */
if (!targetSlider) {
return res404(res, `اسلایدر مورد نظر پیدا نشد`);
}
/** check access portal */
if (!req.user.portals.includes(targetSlider.modelType)) {
return res500(res, `شما اجازه حذف این اسلایدر را ندارید`);
}
if (targetSlider.cover) {
var oldPic = `./static${targetSlider.cover}`;
if (fs.existsSync(oldPic)) {
fs.unlink(oldPic, (error) => {
if (error) return res500(res, error?.message);
});
}
}
/** delete slider */
await targetSlider.deleteOne();
/**
* show result
*/
return res.json(targetSlider);
} catch (error) {
/**
* if we got unkown error show to client
*/
res500(res, error);
}
}
]
module.exports.getOneSlider = [
async (req, res) => {
try {
var sliderId = req.params.id;
var findQuery = {
_id: sliderId
};
var slider = await Slider.findOne(findQuery);
if (!slider) {
return res404(res, `اسلایدر مورد نظر پیدا نشد`);
}
/** check access portal */
if (!req.user.portals.includes(slider.modelType)) {
return res.status(403).json({
message: `شما اجازه دسترسی به اطلاعات این اسلایدر را ندارید`
});
}
/**
* show result
*/
return res.json(slider);
} catch (error) {
/**
* if we got unkown error show to client
*/
res500(res, error);
}
}
]
module.exports.getAllSliderByAdmin = [
async (req, res) => {
try {
var findQuery = {};
if (req.user.portals.length) {
findQuery.modelType = {
$in: req.user.portals
};
}
/** get all slider */
var allSlider = await Slider.find(findQuery).sort({
_id: -1
});
/** if null we have error */
if (!allSlider) {
return res500(res, `مشکلی در گرفتن اطلاعات پیش آمده است`);
}
/** show result to client */
return res.json(allSlider);
} catch (error) {
/** if we have unkown error show it */
return res500(res, error?.message);
}
}
]
module.exports.search = [
async (req, res) => {
try {
var findQuery = {};
findQuery['$and'] = [];
findQuery['$or'] = [];
if (req.user.portals.length) {
findQuery.modelType = {
$in: req.user.portals
};
}
var {
term,
portals,
galleryStatus,
publish,
galleryType,
date
} = req.body;
/** search by term */
if (term && !_.isEmpty(term)) {
findQuery['$or'].push(
{
title: {
$regex: '.*' + term + '.*'
},
}
);
}
/** search by galleryType */
if (galleryType && !_.isEmpty(galleryType)) {
findQuery['$and'].push({
galleryType
});
}
/** search by publish */
if (!_.isUndefined(publish) && _.isBoolean(publish)) {
findQuery['$and'].push({
publish
});
}
/** search by portals */
if (portals && !_.isEmpty(portals)) {
findQuery['$and'].push({
modelType: {
$in: portals
}
})
}
/** search by galleryStatus */
if (!_.isUndefined(galleryStatus) && _.isBoolean(galleryStatus)) {
findQuery['$and'].push({
galleryStatus
})
}
/** search by date */
if (date && !_.isEmpty(date)) {
if(date.length === 1){
findQuery['$and'].push({
created_at: {
$gte: moment(date[0]).startOf('days'),
$lt: moment(date[0]).endOf('days')
}
});
}else{
findQuery['$and'].push({
created_at: {
$gte: new Date(date[0]),
$lt: new Date(date[1])
}
});
}
}
_.isEmpty(findQuery['$and']) && delete findQuery['$and'];
_.isEmpty(findQuery['$or']) && delete findQuery['$or'];
/** get gallery */
var gallery = await Gallery.paginate(findQuery , {page : req.query.page , limit, populate : [{
path : '_creator',
select : {
firstName: 1,
lastName: 1,
profilePic: 1
}
}],
sort :{
created_at: -1
}
});
/** show result */
return res.json(gallery);
} catch (error) {
return res500(res ,error?.message)
}
}
]
/////////////////////////////////////////////////////////////////////// public
module.exports.getAllSliderByUser = [
async (req, res) => {
try {
var {
portal,
} = req.query;
var findQuery = {};
var setSort = {index : 1};
findQuery.modelType = !portal ? 'ostandari' : portal;
var getSlider = await Slider.find(findQuery).sort(setSort);
return res.json(getSlider);
} catch (error) {
return res500(res, error?.message);
}
}
]
+543
View File
@@ -0,0 +1,543 @@
const Slider = require('../models/Slider');
const {
body,
validationResult
} = require('express-validator');
const sharp = require('sharp');
const {
_sr
} = require('../plugins/serverResponses');
const {
res404,
res500,
hasWhiteSpaces,
isLatinCharactersWithSymbol,
generateRandomDigits
} = require('../plugins/controllersHelperFunctions');
const fs = require('fs');
////// variables
const profileWidth = 880;
const profileHeight = 450;
const profileQuality = 100;
/////////////////////////////////////////////////////////////////////// admin
module.exports.addSlider = [
[
body('title')
.notEmpty().withMessage(_sr['fa'].required.title),
// body('summaryTitle')
// .notEmpty().withMessage(_sr['fa'].required.field),
body('url')
.notEmpty().withMessage(_sr['fa'].required.field),
body('index')
.optional().isNumeric().withMessage(_sr['fa'].format.number),
body('isLocal')
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
body('siteMap')
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
body('modelType')
.custom((value, {
req
}) => {
if (req.user.portals.join() === portal.join()) {
if (!portal.includes(value)) {
return Promise.reject(_sr['fa'].required.field);
} else {
return true
}
} else {
return true
}
})
],
async (req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({
validation: errors.mapped()
});
try {
var {
title,
summaryTitle,
isLocal,
url,
index,
siteMap,
modelType,
} = req.body;
/** set portals */
modelType = (req.user.portals.join() === portal.join()) ? modelType : req.user.portals[0];
const sliderData = {
title: title.trim(),
summaryTitle: summaryTitle.trim(),
url: url.trim(),
isLocal,
index,
siteMap,
_creator: req.user._id,
_updatedBy: req.user._id,
modelType,
};
var createSlider = await Slider.create(sliderData);
if (!createSlider) {
res500(res, `error in add slider to data base`);
}
/**
* if we have pic upload to server
*/
if (req.files && req.files.cover) {
const image = req.files.cover;
if (!_sr.supportedImageFormats.includes(image.mimetype.split('/')[1])) {
return res.status(422).json({
validation: {
cover: {
msg: _sr['fa'].format.image
}
}
});
}
const imageName = `slider_${Date.now()}_${createSlider._id}.${image.mimetype.split('/')[1]}`;
try {
const target = sharp(image.data)
await target
.resize(profileWidth, profileHeight, {
fit: 'cover'
})
.jpeg({
quality: profileQuality
})
.toFile(`./static/uploads/images/slider/${imageName}`);
createSlider.cover = imageName;
await createSlider.save();
} catch (e) {
return res500(res, e?.message);
}
}
/**
* show result
*/
return res.json(createSlider);
} catch (error) {
console.log(error);
/**
* if we got unkown error show to client
*/
res500(res, error.message);
}
}
]
module.exports.updateSlider = [
[
body('title')
.notEmpty().withMessage(_sr['fa'].required.title),
// body('summaryTitle')
// .notEmpty().withMessage(_sr['fa'].required.field),
body('url')
.notEmpty().withMessage(_sr['fa'].required.field),
body('isLocal')
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
body('index')
.optional().isNumeric().withMessage(_sr['fa'].format.number),
body('siteMap')
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
body('modelType')
.custom((value, {
req
}) => {
if (req.user.portals.join() === portal.join()) {
if (!portal.includes(value)) {
return Promise.reject(_sr['fa'].required.field);
} else {
return true
}
} else {
return true
}
})
],
async (req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({
validation: errors.mapped()
});
try {
/**
* get data from input
*/
var {
title,
summaryTitle,
url,
isLocal,
index,
siteMap,
modelType,
} = req.body;
/**
* get id
*/
var sliderId = req.params.id;
var targetSlider = await Slider.findOne({
_id: sliderId
});
/** check slider exist or not */
if (!targetSlider) {
return res404(res, `اسلایدر مورد نظر پیدا نشد`);
}
/** check access portal */
if (!req.user.portals.includes(targetSlider.modelType)) {
return res500(res, `شما اجازه آپدیت این اسلایدر را ندارید`);
}
if (targetSlider.title !== title) {
var checkDuppTitle = await Slider.findOne({
title: title
});
if (checkDuppTitle) {
return res.status(422).json({
validation: {
title: {
msg: _sr['fa'].duplicated.title
}
}
});
}
}
/**
* if we have pic upload to server
*/
if (req.files && req.files.cover) {
const image = req.files.cover;
if (!_sr.supportedImageFormats.includes(image.mimetype.split('/')[1])) {
return res.status(422).json({
validation: {
cover: {
msg: _sr['fa'].format.image
}
}
});
}
const imageName = `slider_${Date.now()}_${targetSlider._id}.${image.mimetype.split('/')[1]}`;
try {
const target = sharp(image.data)
await target
.resize(profileWidth, profileHeight, {
fit: 'cover'
})
.jpeg({
quality: profileQuality
})
.toFile(`./static/uploads/images/slider/${imageName}`);
/**
* if exist old pic delete it from file
*/
if (targetSlider.cover) {
var oldPic = `./static${targetSlider.cover}`;
if (fs.existsSync(oldPic)) {
fs.unlink(oldPic, (err) => {
if (err) return res500(res, err?.message);
});
}
}
targetSlider.cover = imageName;
} catch (e) {
return res500(res, e?.message);
}
}
targetSlider.title = title.trim();
targetSlider.summaryTitle = summaryTitle.trim();
targetSlider.url = url.trim();
targetSlider.isLocal = isLocal
targetSlider.index = index;
targetSlider.siteMap = siteMap;
targetSlider.modelType = modelType;
await targetSlider.save();
/**
* show result
*/
return res.json(targetSlider);
} catch (error) {
return res500(res, error.message);
}
}
]
module.exports.deletOneSlider = [
async (req, res) => {
try {
var sliderId = req.params.id;
var targetSlider = await Slider.findOne({
_id: sliderId
});
/** check slider exist or not */
if (!targetSlider) {
return res404(res, `اسلایدر مورد نظر پیدا نشد`);
}
/** check access portal */
if (!req.user.portals.includes(targetSlider.modelType)) {
return res500(res, `شما اجازه حذف این اسلایدر را ندارید`);
}
if (targetSlider.cover) {
var oldPic = `./static${targetSlider.cover}`;
if (fs.existsSync(oldPic)) {
fs.unlink(oldPic, (error) => {
if (error) return res500(res, error?.message);
});
}
}
/** delete slider */
await targetSlider.deleteOne();
/**
* show result
*/
return res.json(targetSlider);
} catch (error) {
/**
* if we got unkown error show to client
*/
res500(res, error);
}
}
]
module.exports.getOneSlider = [
async (req, res) => {
try {
var sliderId = req.params.id;
var findQuery = {
_id: sliderId
};
var slider = await Slider.findOne(findQuery);
if (!slider) {
return res404(res, `اسلایدر مورد نظر پیدا نشد`);
}
/** check access portal */
if (!req.user.portals.includes(slider.modelType)) {
return res.status(403).json({
message: `شما اجازه دسترسی به اطلاعات این اسلایدر را ندارید`
});
}
/**
* show result
*/
return res.json(slider);
} catch (error) {
/**
* if we got unkown error show to client
*/
res500(res, error);
}
}
]
module.exports.getAllSliderByAdmin = [
async (req, res) => {
try {
var findQuery = {};
if (req.user.portals.length) {
findQuery.modelType = {
$in: req.user.portals
};
}
/** get all slider */
var allSlider = await Slider.find(findQuery).sort({
index: 1
});
/** if null we have error */
if (!allSlider) {
return res500(res, `مشکلی در گرفتن اطلاعات پیش آمده است`);
}
/** show result to client */
return res.json(allSlider);
} catch (error) {
/** if we have unkown error show it */
return res500(res, error?.message);
}
}
]
module.exports.search = [
async (req, res) => {
try {
var findQuery = {};
findQuery['$and'] = [];
findQuery['$or'] = [];
if (req.user.portals.length) {
findQuery.modelType = {
$in: req.user.portals
};
}
var {
term,
portals,
galleryStatus,
publish,
galleryType,
date
} = req.body;
/** search by term */
if (term && !_.isEmpty(term)) {
findQuery['$or'].push(
{
title: {
$regex: '.*' + term + '.*'
},
}
);
}
/** search by galleryType */
if (galleryType && !_.isEmpty(galleryType)) {
findQuery['$and'].push({
galleryType
});
}
/** search by publish */
if (!_.isUndefined(publish) && _.isBoolean(publish)) {
findQuery['$and'].push({
publish
});
}
/** search by portals */
if (portals && !_.isEmpty(portals)) {
findQuery['$and'].push({
modelType: {
$in: portals
}
})
}
/** search by galleryStatus */
if (!_.isUndefined(galleryStatus) && _.isBoolean(galleryStatus)) {
findQuery['$and'].push({
galleryStatus
})
}
/** search by date */
if (date && !_.isEmpty(date)) {
if (date.length === 1) {
findQuery['$and'].push({
created_at: {
$gte: moment(date[0]).startOf('days'),
$lt: moment(date[0]).endOf('days')
}
});
} else {
findQuery['$and'].push({
created_at: {
$gte: new Date(date[0]),
$lt: new Date(date[1])
}
});
}
}
_.isEmpty(findQuery['$and']) && delete findQuery['$and'];
_.isEmpty(findQuery['$or']) && delete findQuery['$or'];
/** get gallery */
var gallery = await Gallery.paginate(findQuery, {
page: req.query.page, limit, populate: [{
path: '_creator',
select: {
firstName: 1,
lastName: 1,
profilePic: 1
}
}],
sort: {
index: -1
}
});
/** show result */
return res.json(gallery);
} catch (error) {
return res500(res, error?.message)
}
}
]
/////////////////////////////////////////////////////////////////////// public
module.exports.getAllSliderByUser = [
async (req, res) => {
try {
let {
portal,
} = req.query;
let findQuery = {};
let setSort = {index: -1};
findQuery.modelType = !portal ? 'ostandari' : portal;
let getSlider = await Slider.find(findQuery).sort(setSort);
return res.json(getSlider);
} catch (error) {
return res500(res, error?.message);
}
}
]
File diff suppressed because it is too large Load Diff
+142
View File
@@ -0,0 +1,142 @@
const YearBanner = require('../models/YearBanner');
const {body, validationResult, checkSchema} = require('express-validator');
const {_sr} = require('../plugins/serverResponses');
const {res404, res500} = require('../plugins/controllersHelperFunctions');
const fs = require('fs');
const sharp = require('sharp');
////// variables
const yearBannerWidth = 1920
const yearBannerHeight = 160
const yearBannerQuality = 100
module.exports.updateYearBanner = [
checkSchema({
iranFlag: {
optional: true,
isBoolean: true,
errorMessage: _sr['fa'].format.boolean
}
}),
async (req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()});
try {
/**
* get data from input
*/
const {
iranFlag,
electionBtn,
hasEmail,
hasGPlus,
hasTweeter,
hasInstagram,
email,
gPlus,
tweeter,
instagram
} = req.body
const yearBanner = await YearBanner.findOne();
let imageName
if (req.files?.mainCover) {
const image = req.files.mainCover;
if (!_sr.supportedImageFormats.includes(image.mimetype.split('/')[1])) {
return res.status(422).json({validation: {cover: {msg: _sr['fa'].format.image}}});
}
imageName = `mainPage_cover.jpg`;
const target = sharp(image.data)
await target
.resize(yearBannerWidth, yearBannerHeight, {fit: 'cover'})
.toFormat('jpg')
.jpeg({quality: yearBannerQuality})
.toFile(`./static/uploads/images/mainCover/${imageName}`);
}
if (yearBanner) {
yearBanner.iranFlag = iranFlag;
yearBanner.electionBtn = electionBtn;
// footerOptions
yearBanner.hasEmail = hasEmail;
yearBanner.hasGPlus = hasGPlus;
yearBanner.hasTweeter = hasTweeter;
yearBanner.hasInstagram = hasInstagram;
yearBanner.email = email;
yearBanner.gPlus = gPlus;
yearBanner.tweeter = tweeter;
yearBanner.instagram = instagram;
if (req.files?.mainCover) yearBanner.mainCover = imageName;
yearBanner._updatedBy = req.user._id;
await yearBanner.save();
return res.json({message: _sr['fa'].response.success_save});
} else {
const data = {
iranFlag,
electionBtn,
hasEmail,
hasGPlus,
hasTweeter,
hasInstagram,
email,
gPlus,
tweeter,
instagram,
_updatedBy: req.user._id
}
if (req.files?.mainCover) data.mainCover = imageName;
await YearBanner.create(data);
return res.json({message: _sr['fa'].response.success_save});
}
} catch (error) {
return res500(res, `مشکلی در اجرای درخواست پیش آمده است`);
}
}
]
module.exports.getYearBanner = [
async (req, res) => {
try {
/**
* get getYearBanner
*/
const getYearBanner = await YearBanner.findOne();
/**
* if not exist
*/
if (!getYearBanner) return res.json({
mainCover: '',
iranFlag: true,
electionBtn: true,
hasEmail: true,
hasGPlus: true,
hasTweeter: true,
hasInstagram: true,
email: '',
gPlus: '',
tweeter: '',
instagram: ''
});
/**
* show result
*/
return res.json(getYearBanner);
} catch (error) {
/**
* if we got unkown error show to client
*/
return res500(res, `مشکلی در اجرای درخواست شما پیش آمده است`);
}
}
]
+32
View File
@@ -0,0 +1,32 @@
const mongoose = require('mongoose')
const databaseURL = require('./databaseURL')
mongoose.plugin(schema => {
schema.set('toObject', {
getters: true
})
schema.set('toJSON', {
getters: true
})
schema.set('timestamps', {
createdAt: 'created_at',
updatedAt: 'updated_at'
})
})
// mongodb database connection string. change it as per your needs. here "mydb" is the name of the database. You don't need to create DB from mongodb terminal. mongoose create the database automatically.
mongoose.connect(databaseURL, {
useNewUrlParser: true,
useUnifiedTopology: true,
useFindAndModify: false,
useCreateIndex: true
})
const database = mongoose.connection
database.on('error', console.error.bind(console, 'connection error:'))
database.once('open', function callback() {
console.log("MongoDB Connected...")
})
module.exports = database
+14
View File
@@ -0,0 +1,14 @@
// const databaseURL = 'mongodb://ostandari:ali09186206935@cluster0-shard-00-00.4bq1y.azure.mongodb.net:27017,cluster0-shard-00-01.4bq1y.azure.mongodb.net:27017,cluster0-shard-00-02.4bq1y.azure.mongodb.net:27017/ostandari?ssl=true&replicaSet=atlas-qfv5i1-shard-0&authSource=admin&retryWrites=true&w=majority'
// const databaseURL = 'mongodb://ostanmri_ostan:admin1234@localhost:27017/ostanmri_portal'
// const databaseURL = 'mongodb://localhost:27017/ostanDariPortal'
// const databaseURL = 'mongodb://ostanmri_user:admin1234@localhost:27017/ostanmri_database'
const databaseURL =
"mongodb://root:LelJFpa2SVS5Qk6ytuWLIJpW@bromo.liara.cloud:32357/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'
module.exports = databaseURL;
+104
View File
@@ -0,0 +1,104 @@
const express = require('express');
const database = require('./database');
const fileUpload = require('express-fileupload');
const { isUser, isAdmin, isLoggedIn, hasPermission } = require('./authentication');
const bodyParser = require('body-parser');
const cronJobs = require('./plugins/cronJobs');
const swaggerJsdoc = require("swagger-jsdoc");
const cors = require('cors')
const swaggerUi = require("swagger-ui-express");
const { createAdmins } = require('./plugins/privateAdmin');
const portals = require('./plugins/portals');
global._ = require('lodash');
global.lodash = require('lodash-contrib');
global.portal = [];
for (const item of portals) {
portal.push(item.value);
}
// Create express instance
const app = express();
const options = {
definition: {
openapi: "3.0.0",
info: {
title: "Ostandari Swagger RestFul API",
version: "1.0.0",
description: "API documentation",
license: {
name: "MIT",
},
},
components: {
securitySchemes: {
bearerAuth: {
type: 'http',
in: 'header',
name: 'Authorization',
description: 'Bearer Token',
scheme: 'bearer',
bearerFormat: 'JWT',
},
},
},
security: {
bearerAuth: [],
},
servers: [
{
url: "http://localhost:3756",
},
],
},
apis: ['./server/routes/*.js']
};
const specs = swaggerJsdoc(options);
cronJobs();
createAdmins();
const corsOptions ={
origin:'*',
credentials:true,
optionSuccessStatus:200,
}
// Init body-parser options (inbuilt with express)
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})
);
// Require & Import API routes
const Public = require('./routes/public');
const admin = require('./routes/admin');
const auth = require('./routes/auth');
const user = require('./routes/user');
// Use API Routes
app.use('/public', Public);
app.use('/auth', auth);
app.use('/admin', [isLoggedIn, isAdmin], admin);
// app.use('/user', isUser, user);
// Error handling middleware to catch buffer issues
app.use((err, req, res, next) => {
if (err.code === 'ENOBUFS') {
console.error('Buffer space error:', err);
res.status(500).send('Server is experiencing buffer space issues.');
} else {
next(err);
}
});
// Export the server middleware
module.exports = {
path: '/api',
handler: app
};
+19
View File
@@ -0,0 +1,19 @@
const mongoose = require('mongoose');
const mongoosePaginate = require('mongoose-paginate-v2');
function PDF(pdf) {
if (pdf) return '/uploads/files/ReadOnly-PDF' + pdf
}
const BookSchema = mongoose.Schema({
title: String,
uri: String,
slides:{
default:[],
type:Array
}
});
BookSchema.plugin(mongoosePaginate);
module.exports = mongoose.model('Book', BookSchema);
+8
View File
@@ -0,0 +1,8 @@
const mongoose = require('mongoose');
const CaptchaSchema = mongoose.Schema({
code : String,
createdAt : {type : Date , expires : 60 , default : Date.now()}
});
module.exports = mongoose.model('Captcha', CaptchaSchema);
+77
View File
@@ -0,0 +1,77 @@
const mongoose = require('mongoose');
function autoPopulateSubs(next) {
this.populate({
path: 'childs',
select: 'title childs navIndex url modelType treeCat parent defaultPageType',
options:{
sort : 'navIndex'
}
// sort: {navIndex: -1},
});
next();
}
function file(file) {
return '/uploads/files/terms/' + file
}
function image(img) {
if (img) return '/uploads/images/category/' + img
else return '/img/no-cover.jpg'
}
const CategoryTermsFile = mongoose.Schema({
file: {type: String, get: file},
title: String
})
const CategorySchema = mongoose.Schema({
title: String,
parent: {type: mongoose.Schema.Types.ObjectId, ref: 'Category', default: null},
childs: [{type: mongoose.Schema.Types.ObjectId, ref: 'Category'}],
treeCat: [{type: mongoose.Schema.Types.ObjectId, ref: 'Category'}],
rootParent: {type: mongoose.Schema.Types.ObjectId, ref: 'Category'},
priority: {type: Number, default: 0},
showInMenu: Boolean,
navIndex: {type: Number, default: null},
news: {type: Boolean, default: true},
child: {type: Boolean, default: true},
special: {type: Boolean, default: false},
allowComment: {type: Boolean, default: false},
level: {type: Number, default: 1},
siteMap: {type: Boolean, default: true},
modelType: String,
_creator: {type: mongoose.Schema.Types.ObjectId, ref: 'User'},
_updatedBy: {type: mongoose.Schema.Types.ObjectId, ref: 'User'},
haveNews: {type: Boolean, default: false},
///// for client
hasNewsTab: {type: Boolean, default: true},
hasContentTab: {type: Boolean, default: true},
hasMediaTab: {type: Boolean, default: true},
hasSubMenusTab: {type: Boolean, default: true},
hasTermsTab: {type: Boolean, default: true},
hasNotificationsTab: {type: Boolean, default: true},
hasSpecNewsTab: {type: Boolean, default: true},
hasNazarTab: {type: Boolean, default: true},
hasNewsFileTab: {type: Boolean, default: true},
defaultPageType: {type: String, default: 'news'},
/** page */
showInFooter: {type: Number, enum: [0, 1, 2, 3], default: 0},
url: {type: String, default: null},
pageContent: String,
terms: [CategoryTermsFile],
hasManagerInfo: {type: Boolean, default: true},
managerCover: {type: String, get: image},
managerName: String,
managerDescription: String
});
CategorySchema.index({parent: 1, childs: 1});
CategorySchema
.pre('findOne', autoPopulateSubs)
.pre('find', autoPopulateSubs);
module.exports = mongoose.model('Category', CategorySchema);
+32
View File
@@ -0,0 +1,32 @@
const mongoose = require('mongoose');
const mongoosePaginate = require('mongoose-paginate-v2');
const CommentSchema = mongoose.Schema({
name : String,
description: String,
email : String,
read : {type : Boolean , default : false},
allowShow : {type : Boolean , default : false},
catsId : {type : Array , default : []},
_updatedBy: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
},
modelRef : {
type : mongoose.Schema.Types.ObjectId,
refPath: 'modelName'
},
modelName : {
type: String,
required: true,
enum: ['News', 'Category' , 'ContactUs']
},
modelType : String
});
CommentSchema.index({modelRef: 1});
CommentSchema.plugin(mongoosePaginate);
module.exports = mongoose.model('Comment', CommentSchema);
+22
View File
@@ -0,0 +1,22 @@
const mongoose = require('mongoose');
const ContactUsSchema = mongoose.Schema({
title : {type : String , default : 'تماس با ما'},
description: String,
showInMenu: Boolean,
email : String,
phone : String,
address : String,
main : {type : Boolean , default : false},
// catId : { type: mongoose.Schema.Types.ObjectId, ref: 'Category'},
_creator: {type: mongoose.Schema.Types.ObjectId , ref: 'User'},
_updatedBy : {type: mongoose.Schema.Types.ObjectId , ref: 'User'},
location : { type: {type:String}, coordinates: [Number]},
siteMap : {type : Boolean , default : true},
showInFooter : {type : Number , enum : [0,1,2,3] , default : 0},
});
ContactUsSchema.index({ location : '2dsphere'});
module.exports = mongoose.model('ContactUs', ContactUsSchema);
+26
View File
@@ -0,0 +1,26 @@
const mongoose = require('mongoose');
function image(img) {
if (img) return '/uploads/images/content/' + img
}
const ContentSchema = mongoose.Schema({
title: String,
param: String,
email: String,
cover: {type: String, get: image, default: null},
thumb: {type: String, get: image, default: null},
showInMenu: {type: Boolean, default: false},
pageContent: String,
showInFooter: {type: Number, enum: [0, 1, 2, 3], default: 0},
showInSubFooter: {type: Boolean, default: false},
index: {type: Number, default: null},
private: {type: Boolean, default: true},
_creator: {type: mongoose.Schema.Types.ObjectId, ref: 'User'},
_updatedBy: {type: mongoose.Schema.Types.ObjectId, ref: 'User'},
siteMap: {type: Boolean, default: true},
modelType: {type: String, default: 'ostandari'}
});
module.exports = mongoose.model('Content', ContentSchema);
+15
View File
@@ -0,0 +1,15 @@
const mongoose = require('mongoose');
const mongoosePaginate = require('mongoose-paginate-v2');
const CounterDaySchema = mongoose.Schema({
title : String,
expireDate : Date,
publish : {type : Boolean , default: true},
_creator :{type: mongoose.Schema.Types.ObjectId, ref: 'User'},
_updatedBy: {type: mongoose.Schema.Types.ObjectId, ref: 'User'},
});
CounterDaySchema.plugin(mongoosePaginate);
module.exports = mongoose.model('CounterDay', CounterDaySchema);
+52
View File
@@ -0,0 +1,52 @@
const mongoose = require('mongoose');
const mongoosePaginate = require('mongoose-paginate-v2');
function image(img) {
if (img) return '/uploads/images/election/' + img
}
const CandidatesSchema = mongoose.Schema({
firstName: String,
lastName: String,
bornDate : {type: Date , default: null},
education: {type: String, default: null},
nationalCode : {type: String, default: null},
resume : {type: String, default: null},
profilePic : {type: String, get: image, default: null},
_creator :{type: mongoose.Schema.Types.ObjectId, ref: 'User'},
_updatedBy: {type: mongoose.Schema.Types.ObjectId, ref: 'User'},
});
const VotersSchema = mongoose.Schema({
firstName: String,
lastName: String,
nationalCode : String,
password: String,
scope:{type: Array, default: ['voter']},
username: {type: String, unique: true},
mobileNumber: {type: String, default: null},
job: {type: String, default: null},
voted: {type: Boolean, default: false},
_creator :{type: mongoose.Schema.Types.ObjectId, ref: 'User'},
_updatedBy: {type: mongoose.Schema.Types.ObjectId, ref: 'User'},
});
const ElectionSchema = mongoose.Schema({
title: String,
description : {type : String , default : null},
catId: {type: mongoose.Schema.Types.ObjectId, ref: 'Category'},
allCat: [{type: mongoose.Schema.Types.ObjectId, ref: 'Category'}],
rootParent: {type: mongoose.Schema.Types.ObjectId, ref: 'Category'},
candidates : [CandidatesSchema],
voters : [VotersSchema],
votes : {type : Array , default : []},
startDate : Date,
endDate : Date,
publish: {type: Boolean, default: false},
_creator :{type: mongoose.Schema.Types.ObjectId, ref: 'User'},
_updatedBy: {type: mongoose.Schema.Types.ObjectId, ref: 'User'},
});
ElectionSchema.plugin(mongoosePaginate);
module.exports = mongoose.model('Election', ElectionSchema);
+20
View File
@@ -0,0 +1,20 @@
const mongoose = require('mongoose');
const mongoosePaginate = require('mongoose-paginate-v2');
const FeedBackSchema = mongoose.Schema({
name : String,
description: String,
email : String,
twitter:String,
phoneNumber : String,
read : {type : Boolean , default : false},
_updatedBy: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
}
});
FeedBackSchema.plugin(mongoosePaginate);
module.exports = mongoose.model('FeedBack', FeedBackSchema);
+57
View File
@@ -0,0 +1,57 @@
const mongoose = require('mongoose');
const mongoosePaginate = require('mongoose-paginate-v2');
function image(img) {
if (img) return '/uploads/images/gallery/' + img
}
function graphic(img) {
if (img) return '/uploads/graphics/gallery/' + img
}
function video(vdo) {
if (vdo) return '/uploads/videos/gallery/' + vdo
}
const GallerySchema = mongoose.Schema({
title: String,
shortTitlePanel: String,
shortTitleFront: String,
summaryTitle: String,
shortSummaryTitle: String,
leadTitle: String,
catId: {type: mongoose.Schema.Types.ObjectId, ref: 'Category'},
rootParent: {type: mongoose.Schema.Types.ObjectId, ref: 'Category'},
allCat: [{type: mongoose.Schema.Types.ObjectId, ref: 'Category'}],
newsFileId: {type: mongoose.Schema.Types.ObjectId, ref: 'NewsFile'},
// priority: {type : Number , default : 0},
publish: {type: Boolean, default: false},
showInHome: {type: Boolean, default: true},
graphic: {type: String, get: graphic, default: null},
thumbGraphic: {type: String, get: graphic, default: null},
cover: {type: String, get: image, default: null},
thumbCover: {type: String, get: image, default: null},
uidImage:[{type:String , get:image , default:null}],
images: [{type: String, get: image, default: null}],
thumbImages: [{type: String, get: image, default: null}],
video: {type: String, get: video, default: null},
isEmbedded: {type: Boolean, default: false},
embeddedCode: String,
userViews: {type: Number, default: 0},
special: {type: Boolean, default: false},
_creator: {type: mongoose.Schema.Types.ObjectId, ref: 'User'},
_updatedBy: {type: mongoose.Schema.Types.ObjectId, ref: 'User'},
siteMap: {type: Boolean, default: true},
modelType: String,
keywords: {type: Array, default: []},
metaTagDesc: {type: String, default: null},
galleryType: {type: String, enum: ['image', 'video', 'graphic']},
galleryStatus: {type: Boolean, default: false},
customDate: {type: Date, default: Date.now},
customDateHistory: Array,
favorite: {type: Boolean, default: false}
}, {toJson: {getters: false}});
GallerySchema.plugin(mongoosePaginate);
module.exports = mongoose.model('Gallery', GallerySchema);
+18
View File
@@ -0,0 +1,18 @@
const mongoose = require('mongoose');
const HomePageSchema = mongoose.Schema({
s2: {type: mongoose.Schema.Types.ObjectId, ref: 'Category', default: null},
s3: {type: mongoose.Schema.Types.ObjectId, ref: 'Category', default: null},
s4: {type: mongoose.Schema.Types.ObjectId, ref: 'Category', default: null},
s5: [{type: mongoose.Schema.Types.ObjectId, ref: 'Category', default: null}],
s6: {type: mongoose.Schema.Types.ObjectId, ref: 'Category', default: null},
// side bar
s2Side: {type: mongoose.Schema.Types.ObjectId, ref: 'Category', default: null},
s3Side: {type: mongoose.Schema.Types.ObjectId, ref: 'Category', default: null},
s4Side: {type: mongoose.Schema.Types.ObjectId, ref: 'Category', default: null},
s5Side: {type: mongoose.Schema.Types.ObjectId, ref: 'Category', default: null},
s6Side: {type: mongoose.Schema.Types.ObjectId, ref: 'Category', default: null},
modelType : String
});
module.exports = mongoose.model('HomePage', HomePageSchema);
+20
View File
@@ -0,0 +1,20 @@
const mongoose = require('mongoose');
function image(img) {
if (img) return '/uploads/images/links/' + img
}
const LinksSchema = mongoose.Schema({
title: String,
url : String,
icon : {type: String, get: image , default : null},
index: {type : Number , default : null},
showInHome : {type : Boolean , default : false},
_creator: {type: mongoose.Schema.Types.ObjectId , ref: 'User'},
_updatedBy: {type: mongoose.Schema.Types.ObjectId , ref: 'User'},
siteMap : {type : Boolean , default : false},
modelType : String
});
module.exports = mongoose.model('Links', LinksSchema);
+11
View File
@@ -0,0 +1,11 @@
const mongoose = require('mongoose');
const mongoosePaginate = require('mongoose-paginate-v2');
const LoggerSchema = mongoose.Schema({
LastLogin: String,
user :{type: mongoose.Schema.Types.ObjectId, ref: 'User'},
});
LoggerSchema.plugin(mongoosePaginate);
module.exports = mongoose.model('Logger', LoggerSchema);
+21
View File
@@ -0,0 +1,21 @@
const mongoose = require('mongoose');
const mongoosePaginate = require('mongoose-paginate-v2');
const MeetingSchema = mongoose.Schema({
name : String,
subject : String,
description: String,
email : String,
phoneNumber : String,
nationalCode : String,
read : {type : Boolean , default : false},
_updatedBy: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
}
});
MeetingSchema.plugin(mongoosePaginate);
module.exports = mongoose.model('Meeting', MeetingSchema);
+61
View File
@@ -0,0 +1,61 @@
const mongoose = require('mongoose');
const mongoosePaginate = require('mongoose-paginate-v2');
function image(img) {
if (img) return '/uploads/images/news/' + img
else return '/img/no-cover.jpg'
}
function file(file) {
return '/uploads/files/newsAttachments/' + file
}
const NewsAttachmentSchema = mongoose.Schema({
file: {type: String, get: file},
title: String
})
const NewsSchema = mongoose.Schema({
title: String,
shortTitlePanel: String,
shortTitleFront: String,
summaryTitle: String,
leadTitle: String,
shortSummaryTitle: String,
customDate: {type: Date, default: Date.now},
catId: {type: mongoose.Schema.Types.ObjectId, ref: 'Category'},
allCat: [{type: mongoose.Schema.Types.ObjectId, ref: 'Category'}],
newsFileId: {type: mongoose.Schema.Types.ObjectId, ref: 'NewsFile'},
rootParent: {type: mongoose.Schema.Types.ObjectId, ref: 'Category'},
priority: {type: Boolean, default: false},
allowComment: {type: Boolean, default: false},
showInHome: {type: Boolean, default: true},
slider: {type: Boolean, default: false},
PublisherId:{type:String},
PublisherAccept:{type:Boolean , default:false},
publish: {type: Boolean, default: false},
pageContent: String,
cover: {type: String, get: image, default: null},
thumbCover: {type: String, get: image, default: null},
content:{type:String , default:''},
userViews: {type: Number, default: 0},
special: {type: Boolean, default: false},
notifications: {type: Boolean, default: false},
_creator: {type: mongoose.Schema.Types.ObjectId, ref: 'User'},
_updatedBy: {type: mongoose.Schema.Types.ObjectId, ref: 'User'},
siteMap: {type: Boolean, default: true},
keywords: {type: Array, default: []},
metaTagDesc: {type: String, default: null},
newsStatus: {type: Boolean, default: false},
modelType: String,
customDateHistory: Array,
attachments: [NewsAttachmentSchema],
imported: Boolean,
superNews: Boolean
});
NewsSchema.index({catId: 1, allCat: 1});
NewsSchema.plugin(mongoosePaginate);
module.exports = mongoose.model('News', NewsSchema);
+31
View File
@@ -0,0 +1,31 @@
const mongoose = require('mongoose');
const mongoosePaginate = require('mongoose-paginate-v2');
function image(img) {
if (img) return '/uploads/images/news/' + img
else return '/img/no-cover.jpg'
}
const NewsFileSchema = mongoose.Schema({
title: String,
description: String,
index: {type: Number, default: null},
catId: {type: mongoose.Schema.Types.ObjectId, ref: 'Category'},
allCat: [{type: mongoose.Schema.Types.ObjectId, ref: 'Category'}],
rootParent: {type: mongoose.Schema.Types.ObjectId, ref: 'Category'},
showInHome: {type: Boolean, default: true},
showInMenu: {type: Boolean, default: false},
_creator: {type: mongoose.Schema.Types.ObjectId, ref: 'User'},
_updatedBy: {type: mongoose.Schema.Types.ObjectId, ref: 'User'},
siteMap: {type: Boolean, default: true},
userViews: {type: Number, default: 0},
modelType: String,
publish: {type: Boolean, default: true},
cover: {type: String, get: image, default: null},
thumbCover: {type: String, get: image, default: null},
});
NewsFileSchema.plugin(mongoosePaginate);
module.exports = mongoose.model('NewsFile', NewsFileSchema);
+22
View File
@@ -0,0 +1,22 @@
const mongoose = require('mongoose');
const mongoosePaginate = require('mongoose-paginate-v2');
function image(img) {
if (img) return '/uploads/images/occasion/' + img
}
const OccasionSchema = mongoose.Schema({
title : String,
mainCover: {type: String, get: image, default: null},
startDate : Date,
endDate : Date,
index: {type: Number, default: null},
publish : {type : Boolean , default: true},
status : {type : Boolean , default: false},
_creator :{type: mongoose.Schema.Types.ObjectId, ref: 'User'},
_updatedBy: {type: mongoose.Schema.Types.ObjectId, ref: 'User'},
});
OccasionSchema.plugin(mongoosePaginate);
module.exports = mongoose.model('Occasion', OccasionSchema);
+24
View File
@@ -0,0 +1,24 @@
const mongoose = require('mongoose');
const mongoosePaginate = require('mongoose-paginate-v2');
const PollSchema = mongoose.Schema({
title: String,
description : {type : String , default : null},
surveyType : {type : String , default : 'check'},
catId: {type: mongoose.Schema.Types.ObjectId, ref: 'Category'},
allCat: [{type: mongoose.Schema.Types.ObjectId, ref: 'Category'}],
rootParent: {type: mongoose.Schema.Types.ObjectId, ref: 'Category'},
// index: {type: Number, default: null},
options : {type : Array , default : []},
answers : {type : Array , default : []},
userIds : {type : Array , default : []},
startDate : Date,
endDate : Date,
publish: {type: Boolean, default: false},
_creator :{type: mongoose.Schema.Types.ObjectId, ref: 'User'},
_updatedBy: {type: mongoose.Schema.Types.ObjectId, ref: 'User'},
});
PollSchema.plugin(mongoosePaginate);
module.exports = mongoose.model('Poll', PollSchema);
+20
View File
@@ -0,0 +1,20 @@
const mongoose = require('mongoose');
const mongoosePaginate = require('mongoose-paginate-v2');
function image(img) {
if (img) return '/uploads/images/services/' + img
}
const ServicesSchema = mongoose.Schema({
title: String,
url : String,
cover : {type: String, get: image , default : null},
index: {type : Number , default : null},
_creator: {type: mongoose.Schema.Types.ObjectId , ref: 'User'},
_updatedBy: {type: mongoose.Schema.Types.ObjectId , ref: 'User'},
modelType : String
});
ServicesSchema.plugin(mongoosePaginate);
module.exports = mongoose.model('Services', ServicesSchema);
+24
View File
@@ -0,0 +1,24 @@
const mongoose = require('mongoose');
const mongoosePaginate = require('mongoose-paginate-v2');
function image(img) {
if (img) return '/uploads/images/slider/' + img
}
const SliderSchema = mongoose.Schema({
title: String,
summaryTitle : String,
url : String,
newsTitle : String,
isLocal : {type : Boolean , default : false},
cover : {type: String, get: image , default : null},
index: {type : Number , default : null},
_creator: {type: mongoose.Schema.Types.ObjectId , ref: 'User'},
_updatedBy: {type: mongoose.Schema.Types.ObjectId , ref: 'User'},
siteMap : {type : Boolean , default : false},
modelType : String
});
SliderSchema.plugin(mongoosePaginate);
module.exports = mongoose.model('Slider', SliderSchema);
+29
View File
@@ -0,0 +1,29 @@
const mongoose = require('mongoose');
const mongoosePaginate = require('mongoose-paginate-v2');
function image(img) {
if (img) return '/uploads/images/users/' + img
}
const AdminSchema = mongoose.Schema({
firstName: String,
lastName: String,
password: String,
scope: {type: Array, default: ['admin']},
token: {type: String, default: null},
profilePic: {type: String, get: image, default: null},
mobileNumber: {type: String, default: null},
email: String,
registration_done: {type: Boolean, default: false},
_creator: {type: mongoose.Schema.Types.ObjectId, ref: 'User'},
_updatedBy: {type: mongoose.Schema.Types.ObjectId, ref: 'User'},
username: {type: String, unique: true},
portals: {type: Array, default: []},
permissions: Array,
specialPermissions: [{type: mongoose.Schema.Types.ObjectId, ref: 'Category'}],
private: {type: Boolean, default: false}
})
AdminSchema.plugin(mongoosePaginate);
module.exports = mongoose.model('User', AdminSchema)
+26
View File
@@ -0,0 +1,26 @@
const mongoose = require('mongoose');
function image(img) {
if (img) return '/uploads/images/mainCover/' + img
}
const YearBannerSchema = mongoose.Schema({
mainCover: {type: String, get: image, default: null},
iranFlag: {type: Boolean, default: true},
// electionBtn
electionBtn: {type: Boolean, default: true},
// social links
hasEmail: {type: Boolean, default: true},
hasGPlus: {type: Boolean, default: true},
hasTweeter: {type: Boolean, default: true},
hasInstagram: {type: Boolean, default: true},
email: {type: String, default: ''},
gPlus: {type: String, default: ''},
tweeter: {type: String, default: ''},
instagram: {type: String, default: ''},
// textCover : {type : String , default : null},
_updatedBy: {type: mongoose.Schema.Types.ObjectId, ref: 'User'},
});
module.exports = mongoose.model('YearBanner', YearBannerSchema);
+14
View File
@@ -0,0 +1,14 @@
module.exports = function checkNationalCode(code) {
var L = code.length
if (L < 8 || parseInt(code, 10) == 0) return false
code = ('0000' + code).substr(L + 4 - 10)
if (parseInt(code.substr(3, 6), 10) == 0) return false
var c = parseInt(code.substr(9, 1), 10)
var s = 0
for (var i = 0; i < 9; i++) {
s += parseInt(code.substr(i, 1), 10) * (10 - i)
}
s = s % 11;
return (s < 2 && c == s) || (s >= 2 && c == (11 - s))
}
@@ -0,0 +1,79 @@
module.exports.res404 = (res, err) => {
return res.status(404).json({message: err})
}
module.exports.res500 = (res, err) => {
return res.status(500).json({message: err})
}
module.exports.checkValidations = validationResult => {
return (req, res, next) => {
const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()})
else next()
}
}
module.exports.removeWhiteSpaces = str => {
return str.replace(/ /g, '')
}
module.exports.nameOptimizer = name => {
function regex(str) {
return new RegExp(str)
}
return name
.replace(regex('آقای'), '')
.replace(regex('آقا'), '')
.replace(regex('جنابه'), '')
.replace(regex('جناب'), '')
.replace(regex('سرکار خانوم'), '')
.replace(regex('سرکار خانم'), '')
.replace(regex('سرکارخانوم'), '')
.replace(regex('سرکارخانومه'), '')
.replace(regex('سرکارخانمه'), '')
.replace(regex('سرکارخانم'), '')
.replace(regex('سرکار'), '')
.replace(regex('خانوم'), '')
.replace(regex('خانم'), '')
}
module.exports.checkNationalCode = code => {
var L = code.length
if (L < 8 || parseInt(code, 10) == 0) return false
code = ('0000' + code).substr(L + 4 - 10)
if (parseInt(code.substr(3, 6), 10) == 0) return false
var c = parseInt(code.substr(9, 1), 10)
var s = 0
for (var i = 0; i < 9; i++) {
s += parseInt(code.substr(i, 1), 10) * (10 - i)
}
s = s % 11;
return (s < 2 && c == s) || (s >= 2 && c == (11 - s))
}
module.exports.isLatinCharactersWithoutSymbol = str => {
return str.match(/^[A-Za-z]+$/g)
}
module.exports.isLatinCharactersWithSymbol = str => {
return str.match(/^[a-zA-Z0-9()*_\-!#$%^&*,."\'\][]*$/g)
}
module.exports.hasWhiteSpaces = str => {
return str.includes(' ')
}
module.exports.generateRandomDigits = digitsLength => {
var add = 1, max = 12 - add // 12 is the min safe number Math.random() can generate without it starting to pad the end with zeros.
if (digitsLength > max) {
return generateRandomDigits(max) + generateRandomDigits(digitsLength - max)
}
max = Math.pow(10, digitsLength + add)
var min = max / 10 // Math.pow(10, n) basically
var number = Math.floor(Math.random() * (max - min + 1)) + min
return ('' + number).substring(add)
}
+152
View File
@@ -0,0 +1,152 @@
const User = require('../models/User')
const News = require('../models/News')
const Category = require('../models/Category')
const fs = require('fs')
const minute = 1000 * 60
const hour = minute * 60
const day = hour * 24
module.exports = async () => {
// check users for activation
// setInterval(() => {
// User.find({confirmed: false})
// .then(users => {
// if (users.length) {
// ///////////////////////
// users.forEach((item, index) => {
// // item time and timeout
// const itemTime = Date.parse(item.created_at)
// const timeout = itemTime + day
// ////////////////////////////
// if (Date.now() >= timeout) {
// item.remove()
// }
// if (index === users.length - 1) {
// // console.log('Unconfirmed users deleted.')
// }
// })
// }
// })
// .catch(err => {
// console.log(err)
// })
// }, hour)
// console.log('migration started ...')
// try {
// const rawFile = await fs.readFileSync(`./server/ostan_wp_posts.json`)
// const parsedData = await JSON.parse(rawFile)
//
// // console.log(parsedData[0])
//
// const posts = []
//
// // dynamic
// const rootParent = '60e95a43111ba696ea3d5171' // فرمانداری ها
// const category = '60e95c7d111ba696ea3d5301' // فرماندای شهرستان خنداب
//
// // static
// const creator = '60eaaf8db36930ef88d3d377'
//
// const newArray = []
//
// for await (const item of parsedData) {
//
// // console.log(item.post_type)
// if (item.post_type === 'post' && posts.includes(item.ID) && item.post_status === 'publish') {
// await newArray.push(item)
// }
// }
//
// console.log('-- posts length: ', newArray.length)
//
// let index = 0
// for await (const item of newArray) {
// const newPost = new News({
// title: item.post_title,
// shortTitlePanel: item.post_title,
// shortTitleFront: item.post_title,
// summaryTitle: item.post_title,
// leadTitle: '',
// shortSummaryTitle: item.post_title,
// customDate: item.post_date,
// /// ****************************************
// catId: category,
// /// ****************************************
// allCat: [],
// newsFileId: null,
// /// ****************************************
// rootParent: rootParent,
// /// ****************************************
// priority: false,
// allowComment: false,
// showInHome: false,
// slider: false,
// publish: true,
// pageContent: item.post_content,
// cover: null,
// thumbCover: null,
// userViews: 200,
// special: false,
// notifications: false,
// _creator: creator,
// _updatedBy: creator,
// siteMap: true,
// keywords: [],
// metaTagDesc: item.post_title,
// newsStatus: true,
// modelType: 'ostandari',
// attachments: [],
// imported: true
// })
// await newPost.save()
// if (index === newArray.length - 1) console.log('---- data entry finished')
// index++
// }
//
//
// } catch (e) {
// console.log('this is catch error --- ', e)
// }
// update all news
// try {
// const news = await News.find()
// const regex = new RegExp('/', 'g')
// let index = 0
// for await (const item of news) {
// console.log(index)
// item.title = item.title.replace(regex, ',')
// await item.save()
// if (index === news.length - 1) console.log('update finished')
// index++
//
// }
// } catch (e) {
// console.log('-- this is catch error:', e)
// }
// update all categories
// try {
// const categories = await Category.find()
// // const regex = new RegExp('/', 'g')
// let index = 0
// for await (const item of categories) {
// console.log(index)
// // item.title = item.title.replace(regex, ',')
// await item.save()
// if (index === categories.length - 1) console.log('update finished')
// index++
//
// }
// } catch (e) {
// console.log('-- this is catch error:', e)
// }
}
+161
View File
@@ -0,0 +1,161 @@
// province cities
const eastazarbaijan1 = ['آذرشهر', 'اسکو', 'اهر', 'بستان‌آباد', 'بناب', 'تبریز', 'جلفا', 'چاراویماق', 'سراب', 'شبستر', 'مراغه']
const westazarbaijan2 = ['ارومیه', 'اشنویه', 'بوکان', 'پیرانشهر', 'تکاب', 'چالدران', 'خوی', 'سردشت', 'سلماس', 'شاهین‌دژ', 'ماکو', 'مهاباد', 'میاندوآب', 'نقده']
const ardabil3 = ['اردبیل', 'بیله‌سوار', 'پارس‌آباد', 'خلخال', 'کوثر', 'گِرمی', 'مِشگین‌شهر', 'نَمین', 'نیر']
const esfahan4 = ['آران و بیدگل', 'اردستان', 'اصفهان', 'برخوار و میمه', 'تیران و کرون', 'چادگان', 'خمینی‌شهر', 'خوانسار', 'سمیرم', 'شهرضا', 'سمیرم سفلی', 'فریدن', 'فریدون‌شهر', 'فلاورجان', 'کاشان', 'گلپایگان', 'لنجان', 'مبارکه', 'نائین', 'نجف‌آباد', 'نطنز']
const ilam5 = ['آبدانان', 'ایلام', 'ایوان', 'دره‌شهر', 'دهلران', 'شیروان و چرداول', 'مهران']
const booshehr6 = ['بوشهر', 'تنگستان', 'جم', 'دشتستان', 'دشتی', 'دیر', 'دیلم', 'کنگان', 'گناوه']
const tehran7 = ['اسلام‌شهر', 'پاکدشت', 'تهران', 'دماوند', 'رباط‌کریم', 'ری', 'ساوجبلاغ', 'شمیرانات', 'شهریار', 'فیروزکوه', 'ورامین']
const chaharmahalobakhtiari8 = ['اردل', 'بروجن', 'شهرکرد', 'فارسان', 'کوهرنگ', 'لردگان']
const khorasanjonoobi9 = ['بیرجند', 'درمیان', 'سرایان', 'سربیشه', 'فردوس', 'قائنات', 'نهبندان']
const khorasanrazavi10 = ['بردسکن', 'تایباد', 'تربت جام', 'تربت حیدریه', 'چناران', 'خلیل‌آباد', 'خواف', 'درگز', 'رشتخوار', 'سبزوار', 'سرخس', 'فریمان', 'قوچان', 'کاشمر', 'کلات', 'گناباد', 'مشهد', 'مه ولات', 'نیشابور']
const khorasanshomali11 = ['اسفراین', 'بجنورد', 'جاجرم', 'شیروان', 'فاروج', 'مانه و سملقان']
const khoozestan12 = ['آبادان', 'امیدیه', 'اندیمشک', 'اهواز', 'ایذه', 'باغ‌ملک', 'بندر ماهشهر', 'بهبهان', 'خرمشهر', 'دزفول', 'دشت آزادگان', 'رامشیر', 'رامهرمز', 'شادگان', 'شوش', 'شوشتر']
const zanjan13 = ['ابهر', 'ایجرود', 'خدابنده', 'خرمدره', 'زنجان', 'طارم', 'ماه‌نشان']
const semnan14 = ['دامغان', 'سمنان', 'شاهرود', 'گرمسار', 'مهدی‌شهر']
const sistanobaloochestan15 = ['ایرانشهر', 'چابهار', 'خاش', 'دلگان', 'زابل', 'زاهدان', 'زهک', 'سراوان', 'سرباز', 'کنارک', 'نیک‌شهر']
const fars16 = ['آباده', 'ارسنجان', 'استهبان', 'اقلید', 'بوانات', 'پاسارگاد', 'جهرم', 'خرم‌بید', 'خنج', 'داراب', 'زرین‌دشت', 'سپیدان', 'شیراز', 'فراشبند', 'فسا', 'فیروزآباد', 'قیر و کارزین', 'کازرون', 'لارستان', 'لامِرد', 'مرودشت', 'ممسنی', 'مهر', 'نی‌ریز']
const qazvin17 = ['آبیک', 'البرز', 'بوئین‌زهرا', 'تاکستان', 'قزوین']
const qom18 = ['قم']
const kordestan19 = ['بانه', 'بیجار', 'دیواندره', 'سروآباد', 'سقز', 'سنندج', 'قروه', 'کامیاران', 'مریوان']
const kerman20 = ['بافت', 'بردسیر', 'بم', 'جیرفت', 'راور', 'رفسنجان', 'رودبار جنوب', 'زرند', 'سیرجان', 'شهر بابک', 'عنبرآباد', 'قلعه گنج', 'کرمان', 'کوهبنان', 'کهنوج', 'منوجان']
const kermanshah21 = ['اسلام‌آباد غرب', 'پاوه', 'ثلاث باباجانی', 'جوانرود', 'دالاهو', 'روانسر', 'سرپل ذهاب', 'سنقر', 'صحنه', 'قصر شیرین', 'کرمانشاه', 'کنگاور', 'گیلان غرب', 'هرسین']
const kohkilooyevaboyrahmad22 = ['بویراحمد', 'بهمئی', 'دنا', 'کهگیلویه', 'گچساران']
const golestan23 = ['آزادشهر', 'آق‌قلا', 'بندر گز', 'ترکمن', 'رامیان', 'علی‌آباد', 'کردکوی', 'کلاله', 'گرگان', 'گنبد کاووس', 'مراوه‌تپه', 'مینودشت']
const gilan24 = ['آستارا', 'آستانه اشرفیه', 'اَملَش', 'بندر انزلی', 'رشت', 'رضوانشهر', 'رودبار', 'رودسر', 'سیاهکل', 'شَفت', 'صومعه‌سرا', 'طوالش', 'فومَن', 'لاهیجان', 'لنگرود', 'ماسال']
const lorestan25 = ['ازنا', 'الیگودرز', 'بروجرد', 'پل‌دختر', 'خرم‌آباد', 'دورود', 'دلفان', 'سلسله ,کوهدشت']
const mazandaran26 = ['آمل', 'بابل', 'بابلسر', 'بهشهر', 'تنکابن', 'جویبار', 'چالوس', 'رامسر', 'ساری', 'سوادکوه', 'قائم‌شهر', 'گلوگاه', 'محمودآباد', 'نکا', 'نور', 'نوشهر']
const markazi27 = ['آشتیان', 'اراک', 'تفرش', 'خمین', 'دلیجان', 'زرندیه', 'ساوه', 'شازند', 'کمیجان', 'محلات']
const hormozgan28 = ['ابوموسی', 'بستک', 'بندر عباس', 'بندر لنگه', 'جاسک', 'حاجی‌آباد', 'شهرستان خمیر', 'رودان', 'قشم', 'گاوبندی', 'میناب']
const hamedan29 = ['اسدآباد', 'بهار', 'تویسرکان', 'رزن', 'کبودرآهنگ', 'ملایر', 'نهاوند', 'همدان']
const yazd30 = ['ابرکوه', 'اردکان', 'بافق', 'تفت', 'خاتم', 'صدوق', 'طبس', 'مهریز', 'مِیبُد', 'یزد']
const alborz31 = ['کرج', 'نظرآباد', 'فردیس', 'اشتهارد', 'هشتگرد', 'طالقان']
// provinces list
module.exports.iranCities = [
{
name: 'آذربایجان شرقی',
cities: eastazarbaijan1
},
{
name: 'آذربایجان غربی',
cities: westazarbaijan2
},
{
name: 'اردبیل',
cities: ardabil3
},
{
name: 'اصفهان',
cities: esfahan4
},
{
name: 'ایلام',
cities: ilam5
},
{
name: 'بوشهر',
cities: booshehr6
},
{
name: 'تهران',
cities: tehran7
},
{
name: 'چهارمحال بختیاری',
cities: chaharmahalobakhtiari8
},
{
name: 'خراسان جنوبی',
cities: khorasanjonoobi9
},
{
name: 'خراسان رضوی',
cities: khorasanrazavi10
},
{
name: 'خراسان شمالی',
cities: khorasanshomali11
},
{
name: 'خوزستان',
cities: khoozestan12
},
{
name: 'زنجان',
cities: zanjan13
},
{
name: 'سمنان',
cities: semnan14
},
{
name: 'سیستان بلوچستان',
cities: sistanobaloochestan15
},
{
name: 'فارس',
cities: fars16
},
{
name: 'قزوین',
cities: qazvin17
},
{
name: 'قم',
cities: qom18
},
{
name: 'کردستان',
cities: kordestan19
},
{
name: 'کرمان',
cities: kerman20
},
{
name: 'کرمانشاه',
cities: kermanshah21
},
{
name: 'کهکیلویه و بویراحمد',
cities: kohkilooyevaboyrahmad22
},
{
name: 'گلستان',
cities: golestan23
},
{
name: 'گیلان',
cities: gilan24
},
{
name: 'لرستان',
cities: lorestan25
},
{
name: 'مازندران',
cities: mazandaran26
},
{
name: 'مرکزی',
cities: markazi27
},
{
name: 'هرمزگان',
cities: hormozgan28
},
{
name: 'همدان',
cities: hamedan29
},
{
name: 'یزد',
cities: yazd30
},
{
name: 'البرز',
cities: alborz31
}
]
+36
View File
@@ -0,0 +1,36 @@
const ContactUs = require('../models/ContactUs');
const database = require('../database');
module.exports.createAdmins = () => {
database.once('open', async cb => {
try {
const contactUs = await ContactUs.find();
if (!contactUs.length) {
const data = {
description : "توضیحات صفحه تماس با ما",
showInMenu : true,
main : true,
email : 'test@gmail.com',
phone : '08632222222',
address : 'میدان فاطمیه',
catId : null,
_creator : null,
_updatedBy : null,
location : {
type : 'Point',
coordinates : [-118.2870407961309,33.93508571994455]
},
siteMap : true,
showInFooter : true
};
const newContactUs = new ContactUs(data);
newContactUs.save(err => {
if (err) console.log(err)
})
}
} catch
(e) {
console.log('defualt contact us creation has error -- ', e)
}
})
}
+42
View File
@@ -0,0 +1,42 @@
module.exports = [
{
name: 'دسترسی کامل',
value: 'superAdmin'
},
{
name: 'مدیریت اخبار',
value: 'news'
},
{
name: 'مدیریت دسته بندی ها و صفحات',
value: 'categories'
},
{
name: 'مدیریت رسانه ها',
value: 'gallery'
},
{
name: 'مدیریت نظرسنجی ها',
value: 'polls'
},
{
name: 'مدیریت انتخابات',
value: 'elections'
},
{
name: 'مدیریت صفحات خاص',
value: 'contents'
},
{
name: 'مدیریت پرونده خبری',
value: 'newsFile'
},
{
name: 'مدیریت پیام های اخبار',
value: 'comment-News'
},
{
name: 'مدیریت پیام های ارتباط با ما',
value: 'comment-ContactUs'
}
]
+10
View File
@@ -0,0 +1,10 @@
module.exports = [
{
name: 'استانداری',
value: 'ostandari'
},
{
name: 'ستاد انتخابات',
value: 'election'
}
]
+39
View File
@@ -0,0 +1,39 @@
const User = require('../models/User')
const _privateAdminInfo = require('./privateAdminData')
const bcrypt = require('bcryptjs')
const database = require('../database')
module.exports.createAdmins = () => {
database.once('open', async cb => {
for (const item of _privateAdminInfo) {
try {
const user = await User.findOne({username: item.username})
if (!user) {
const data = {
firstName: item.firstName,
lastName: item.lastName,
username: item.username,
email : item.email,
mobileNumber : item.mobileNumber,
scope: ['admin'],
private: true,
registration_done: true,
permissions: ['superAdmin'],
portals: item.portals
}
// hash password
const salt = await bcrypt.genSalt(10)
const hash = await bcrypt.hash(item.password, salt)
data.password = hash
const newUser = new User(data)
newUser.save(err => {
if (err) console.log(err)
})
}
} catch
(e) {
console.log('Private admin creation has error -- ', e)
}
}
})
}
+55
View File
@@ -0,0 +1,55 @@
////////////////////////////////// example
//////////////////////////////////
// module.exports = [
// {
// first_name: '',
// last_name: '',
// username: '',
// password: ''
// },
// {
// first_name: '',
// last_name: '',
// username: '',
// password: ''
// }
// ]
////////////////////////////////////
//////////////////////////////////// example
//////////////////////////////////////////////////
//////////////////////////////////////////////////
//////////////////////////////////////////////////
// *remove data from this file after first run* //
//////////////////////////////////////////////////
//////////////////////////////////////////////////
//////////////////////////////////////////////////
module.exports = [
{
firstName: 'Arman',
lastName: 'Mousavi',
username: 'manager',
password: '#$2021managementAdmin%',
email: 'admin1@gmail.com',
mobileNumber: '09365385627',
registration_done: true,
portals: ['ostandari', 'election'],
permissions: ['superAdmin'],
private: true
},
{
firstName: 'admin',
lastName: 'admin',
username: 'negareh_support',
password: '*^@admin1234$#?@',
email: 'admin2@gmail.com',
mobileNumber: '000000',
registration_done: true,
portals: ['ostandari', 'election'],
permissions: ['superAdmin'],
private: true
}
]
+751
View File
@@ -0,0 +1,751 @@
module.exports._sr = {
fa: {
required: {
field: 'این فیلد نباید خالی باشد',
// developer validations
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: 'تاریخ تولد را وارد کنید',
// addressing validations
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: 'نوع را انتخاب کنید'
},
format: {
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: 'ارتفاع حداقل: ',
},
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: 'ارتفاع حداکثر: ',
},
not_found: {
user_id: 'کاربری با این مشخصات وجود ندارد',
admin_id: 'ادمینی با این مشخصات وجود ندارد',
order_id: 'سفارشی با این مشخصات وجود ندارد',
item_id: 'موردی با این مشخصات وجود ندارد',
password: 'رمز عبور یا آیدی درست نیست',
email : 'هیچ کاربری با ایمیل مورد نظر پیدا نشده است',
category : 'دسته بندی انتخاب شده وحود ندارد' /** @todo add this string to another language */
},
duplicated: {
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: 'بین حروف و کلمات نباید فاصله باشد'
},
optional: {
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 قابل قبول است'
}
},
en: {
required: {
field: 'This field is required',
// developer validations
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',
// 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',
// 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'
},
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'
},
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: ',
},
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: ',
},
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'
},
duplicated: {
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'
},
optional: {
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'
}
},
de: {
required: {
field: 'This field is required',
// developer validations
remember_me: 'Remember_me-Parameter erforderlich',
// registration validations
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',
// 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',
// 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'
},
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"
},
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: ',
},
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: ',
},
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'
},
duplicated: {
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',
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'
},
optional: {
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'
}
},
tr: {
required: {
field: 'This field is required',
// geliştirici doğrulamaları
Remember_me: 'Remember_me parametresi gerekli',
// kayıt doğrulamaları
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',
// 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',
// 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'
},
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'
},
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: ',
},
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: ',
},
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ı'
},
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'
},
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.',
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'
},
optional: {
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'
}
},
it: {
required: {
field: 'This field is required',
// convalide dello sviluppatore
Remember_me: "Remember_me parameter required",
// convalide della registrazione
name: "Inserisci nome",
first_name: "Inserisci nome",
last_name: "Inserisci il cognome",
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",
username: "Inserisci nome utente",
phone_number: "Inserisci numero di telefono",
password: "Inserisci password",
birthdate: 'Enter birthdate',
// indirizzamento delle convalide
country: "Inserisci paese",
province: "Inserisci provincia",
city: "Inserisci città",
address: "Inserisci indirizzo",
postal_code: "Inserisci codice postale",
plaque: "Inserisci targa",
receiver_first_name: "Inserisci il nome del destinatario",
receiver_last_name: "Inserisci il cognome del destinatario",
receiver_mobile: "Inserisci il numero di cellulare del destinatario",
// globale (post - gallery - ...)
title: "Inserisci titolo",
caption: "Inserisci didascalia",
description: "Inserisci descrizione",
category: "Seleziona categoria",
image: "L'immagine è obbligatoria",
cover: "Cover is required",
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'
},
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"
},
min_char: {
min2: "Almeno 2 caratteri",
min4: "Almeno 4 caratteri",
min8: "Almeno 8 caratteri",
min10: "Almeno 10 caratteri",
min20: "Almeno 20 caratteri",
min30: "Almeno 30 caratteri",
min40: "Almeno 40 caratteri",
min50: "Almeno 50 caratteri",
min60: "Almeno 60 caratteri",
min100: "Almeno 100 caratteri",
min120: "Almeno 120 caratteri",
min150: "Almeno 150 caratteri",
min200: "Almeno 200 caratteri",
data_size: "Dimensione minima accettabile: ",
image_width_size: "Larghezza minima: ",
image_height_size: "Altezza minima: ",
},
max_char: {
max4: "Massimo 4 caratteri",
max8: "Massimo 8 caratteri",
max10: "Massimo 10 caratteri",
max15: "Massimo 15 caratteri",
max20: "Massimo 20 caratteri",
max30: "Massimo 30 caratteri",
max40: "Massimo 40 caratteri",
max50: "Massimo 50 caratteri",
max60: "Massimo 60 caratteri",
max100: "Massimo 100 caratteri",
max120: "Massimo 120 caratteri",
max150: "Massimo 150 caratteri",
max200: "Massimo 200 caratteri",
data_size: "Dimensione massima accettabile: ",
image_width_size: "Larghezza massima: ",
image_height_size: "Altezza massima: ",
},
not_found: {
user_id: "Nessun utente con questo profilo",
admin_id: "Nessun amministratore con questo profilo",
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"
},
duplicated: {
username: "Questo nome utente esiste già",
email: "Questa email esiste già",
name: "Il nome è duplicato",
title: "Il titolo è duplicato",
phoneNumber : "phoneNumber esiste già"
},
response: {
logged_in: "Hai effettuato l'accesso",
not_logged_in: "Non sei loggato",
logged_out: "Sei disconnesso",
unauthenticated: "unauthenticated",
recovery_link: "Link di ripristino inviato",
success_save: "Salvataggio riuscito",
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.",
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'
},
optional: {
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",
png: "È accettabile solo il formato png",
gif: "È accettabile solo il formato GIF",
pdf: "È accettabile solo il formato pdf",
txt: "È accettabile solo il formato txt",
log: "È accettabile solo il formato log",
mp3: "È accettabile solo il formato mp3",
ogg: "È accettabile solo il formato ogg",
wmv: "È accettabile solo il formato wmv",
mp4: "È accettabile solo il formato mp4",
mov: "È accettabile solo il formato mov",
mkv: "È accettabile solo il formato mkv",
flv: "È accettabile solo il formato flv"
}
},
supportedImageFormats: ['jpg', 'jpeg', 'png', 'webp'],
supportedVideoFormats: ['mp4', 'avi', 'wmv']
}
File diff suppressed because it is too large Load Diff
+321
View File
@@ -0,0 +1,321 @@
const {Router} = require('express')
const router = Router()
const userController = require('../controllers/userController');
const electionController = require('../controllers/electionController');
/**
* @swagger
* /auth/login:
* post:
* summary: User login
* description: Allows users to log in with their username or email and password.
* tags:
* - Auth
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* username:
* type: string
* password:
* type: string
* remember_me:
* type: boolean
* example:
* username: johndoe
* password: password123
* remember_me: true
* 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.
*/
// Login User
router.post('/login', userController.login);
/**
* @swagger
* /auth/logout:
* delete:
* summary: User logout
* description: Logs out the user by invalidating the token associated with the request.
* tags:
* - Auth
* responses:
* '200':
* description: User logged out successfully.
* content:
* application/json:
* schema:
* type: object
* properties:
* message:
* type: string
* example:
* message: "You are logged out."
* '401':
* description: Unauthorized. Indicates that the user is not logged in.
*/
// Logout User
router.delete('/logout', userController.logout);
/**
* @swagger
* /auth/user:
* get:
* summary: Get user information
* description: Retrieves information about the authenticated user.
* tags:
* - Auth
* responses:
* '200':
* description: User information retrieved successfully.
* content:
* application/json:
* schema:
* type: object
* properties:
* user:
* $ref: '#/components/schemas/User'
* '401':
* description: Unauthorized. Indicates that the user is not authenticated or the token is invalid.
*/
// Data User
router.get('/user', userController.getuser);
/**
* @swagger
* /auth/forget-password:
* post:
* summary: Generate token for password reset
* description: Sends a token to the user's email for password reset.
* tags:
* - Auth
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* email:
* type: string
* responses:
* '200':
* description: Token generated successfully and sent to the user's email.
* content:
* application/json:
* schema:
* type: string
* description: Token generated for password reset.
* '422':
* description: Validation error. Indicates that the provided email is not valid.
* content:
* application/json:
* schema:
* type: object
* properties:
* validation:
* type: object
* description: Error messages for validation failures.
* '404':
* description: User not found. Indicates that the provided email does not belong to any user.
* content:
* application/json:
* schema:
* type: object
* properties:
* message:
* type: string
* description: Error message indicating that the user was not found.
* '500':
* description: Internal server error. Indicates that an unexpected error occurred.
* content:
* application/json:
* schema:
* type: object
* properties:
* message:
* type: string
* description: Error message indicating the internal server error.
*/
// Change Password
router.post('/changePassword' , userController.forgetPassGenerateToken);
/**
* @swagger
* /auth/changePassword/{token}:
* put:
* summary: Reset password using token
* description: Resets the user's password using the provided token.
* tags:
* - Auth
* parameters:
* - in: path
* name: token
* required: true
* description: The token sent to the user's email for password reset.
* schema:
* type: string
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* password:
* type: string
* description: The new password.
* responses:
* '200':
* description: Password reset successful.
* content:
* application/json:
* schema:
* type: object
* properties:
* message:
* type: string
* description: Success message indicating that the password was reset successfully.
* '422':
* description: Validation error. Indicates that the provided password does not meet the requirements or the passwords do not match.
* content:
* application/json:
* schema:
* type: object
* properties:
* validation:
* type: object
* description: Error messages for validation failures.
* '500':
* description: Internal server error. Indicates that an unexpected error occurred.
* content:
* application/json:
* schema:
* type: object
* properties:
* message:
* type: string
* description: Error message indicating the internal server error.
*/
// Change Password :token param
router.put('/changePassword/:token' , userController.forgetPassGetToken);
///////// voter
/**
* @swagger
* /auth/voter/login:
* post:
* summary: Voter login
* description: Logs in a voter to participate in an election.
* tags:
* - Auth
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* username:
* type: string
* description: The username of the voter.
* password:
* type: string
* description: The password of the voter.
* responses:
* '200':
* description: Voter login successful.
* content:
* application/json:
* schema:
* type: object
* properties:
* token:
* type: string
* description: The token associated with the voter.
* '422':
* description: Validation error. Indicates that the provided username or password is incorrect.
* content:
* application/json:
* schema:
* type: object
* properties:
* validation:
* type: object
* description: Error message for validation failure.
* '500':
* description: Internal server error. Indicates that an unexpected error occurred.
* content:
* application/json:
* schema:
* type: object
* properties:
* message:
* type: string
* description: Error message indicating the internal server error.
*/
//Voter Login
router.post('/voter/login' , electionController.voterLogin);
/**
* @swagger
* /auth/voter/user:
* get:
* summary: Get voter user
* description: Retrieves the details of the logged-in voter.
* tags:
* - Auth
* security:
* - BearerAuth: []
* responses:
* '200':
* description: Voter user details retrieved successfully.
* content:
* application/json:
* schema:
* type: object
* properties:
* user:
* type: object
* description: Details of the logged-in voter.
* '422':
* description: Validation error. Indicates that the token is invalid or the voter does not exist.
* content:
* application/json:
* schema:
* type: object
* properties:
* validation:
* type: object
* description: Error message for validation failure.
* '500':
* description: Internal server error. Indicates that an unexpected error occurred.
* content:
* application/json:
* schema:
* type: object
* properties:
* message:
* type: string
* description: Error message indicating the internal server error.
*/
// user Voter Data
router.get('/voter/user' , electionController.getVoterUser);
module.exports = router
File diff suppressed because it is too large Load Diff
+5
View File
@@ -0,0 +1,5 @@
const {Router} = require('express')
const router = Router()
module.exports = router