FIX: UserSeeder

ADD: Get-Self endpoint for users
ADD: Category and Role Seeder
FIX: Login Check Bug
ADD: Extra fields for documents and images in belonging model
ADD: localhost:5173 to cors
ADD: SuperAdmin ID to env
This commit is contained in:
2025-01-03 17:45:09 +03:30
parent bda5bca9de
commit 465b678357
11 changed files with 180 additions and 12 deletions
+2 -2
View File
@@ -12,7 +12,7 @@ const cors = require('cors')
const app = express() const app = express()
const allowedOrigins = ['http://localhost:3000'] const allowedOrigins = ['http://localhost:3000', 'http://localhost:5173']
app.use( app.use(
cors({ cors({
@@ -32,7 +32,7 @@ app.use(express.json())
app.set('view engine', 'ejs') app.set('view engine', 'ejs')
app.use(express.static('views/public')) app.use(express.static('views/public'))
app.use('/', routerEndpoints) app.use('/api', routerEndpoints)
databaseConnection(app) databaseConnection(app)
+7 -1
View File
@@ -26,11 +26,17 @@ const belongingSchema = new mongoose.Schema(
required: true, required: true,
}, },
}, },
documents: [String], documentNames: [String],
documentUrls: [String],
imageNames: [String],
imageUrls: [String],
mainImageUrl: String,
mainImageName: String,
numId: { numId: {
type: Number, type: Number,
unique: true, unique: true,
}, },
tags: [String],
isActive: { isActive: {
type: Boolean, type: Boolean,
default: true, default: true,
+22
View File
@@ -0,0 +1,22 @@
const Category = require('./categoryModel')
const chalk = require('chalk')
const runSeeder = async () => {
const categories = [
{ nativeName: 'ساختمان', englishName: 'Building' },
{ nativeName: 'زمین', englishName: 'Lot' },
{ nativeName: 'کالا', englishName: 'Product' },
]
await Category.deleteMany({})
console.log(chalk.red('Deleted all category records.'))
await Category.create(categories, null)
console.log(
chalk.green.bold(
`CATEGORY: Created ${categories.length} category(ies)`
)
)
}
module.exports = { runSeeder }
+1 -1
View File
@@ -29,7 +29,7 @@ const runSeeder = async () => {
await Role.deleteMany({}) await Role.deleteMany({})
console.log(chalk.red('Deleted all role records.')) console.log(chalk.red('Deleted all role records.'))
await Role.insertMany(roles, null) await Role.create(roles, null)
console.log(chalk.green.bold(`ROLE: Created ${roles.length} role(s)`)) console.log(chalk.green.bold(`ROLE: Created ${roles.length} role(s)`))
} }
+11
View File
@@ -1,6 +1,7 @@
// userController.js // userController.js
const catchAsync = require('../../globalErrorHandler/catchAsync') const catchAsync = require('../../globalErrorHandler/catchAsync')
const userService = require('./userService') const userService = require('./userService')
const AppError = require("../../globalErrorHandler/AppError");
exports.signup = catchAsync(async (req, res, next) => { exports.signup = catchAsync(async (req, res, next) => {
const { user, token, cookieOptions } = await userService.signup( const { user, token, cookieOptions } = await userService.signup(
@@ -55,6 +56,16 @@ exports.getAllUsers = catchAsync(async (req, res, next) => {
}) })
}) })
exports.userGetSelf = catchAsync(async (req, res, next) => {
const user = req.user
if (!user) {
throw new AppError('NotLoggedIn', 403, {})
}
return res.status(200).json({ status: 'success ', data: { user } })
})
exports.getUser = catchAsync(async (req, res, next) => { exports.getUser = catchAsync(async (req, res, next) => {
const user = await userService.getUser(req.params.userId) const user = await userService.getUser(req.params.userId)
+4 -2
View File
@@ -5,13 +5,15 @@ const loginCheck = require('../../middlewares/loginCheck')
const router = new express.Router() const router = new express.Router()
router.post('/signup', userController.signup) router.post('/user/signup-email', userController.signup)
router.post('/login', userController.loginUser) router.post('/user/login-email', userController.loginUser)
router.post('/logout', userController.logoutUser) router.post('/logout', userController.logoutUser)
router.use(loginCheck.loginProtect) router.use(loginCheck.loginProtect)
// router.use(loginCheck.adminProtect) // router.use(loginCheck.adminProtect)
router.get('/user/get-self', userController.userGetSelf)
router.get('/', userController.getAllUsers) router.get('/', userController.getAllUsers)
router.get('/:userId', userController.getUser) router.get('/:userId', userController.getUser)
+2 -2
View File
@@ -5,7 +5,7 @@ const runSeeder = async () => {
{ {
_id: '66ddb52302f30f105de39e61', _id: '66ddb52302f30f105de39e61',
name: 'main admin', name: 'main admin',
email: 'superadmin@chayamarket.ir', email: 'superadmin@belongingm.ir',
password: '$2a$10$pabxmRjm6klipAC6vBvgI.J.GJpnG//L1MeNcdbtxuYQRYHLI/I3O', password: '$2a$10$pabxmRjm6klipAC6vBvgI.J.GJpnG//L1MeNcdbtxuYQRYHLI/I3O',
phoneNumber: '+989123456789', phoneNumber: '+989123456789',
favorites: [], favorites: [],
@@ -20,7 +20,7 @@ const runSeeder = async () => {
await User.deleteMany({}) await User.deleteMany({})
console.log(chalk.red('Deleted all user records.')) console.log(chalk.red('Deleted all user records.'))
await User.insertMany(users, null) await User.create(users, null)
console.log(chalk.green.bold(`USER: Created ${users.length} user(s)`)) console.log(chalk.green.bold(`USER: Created ${users.length} user(s)`))
} }
+2 -1
View File
@@ -3,7 +3,8 @@ NODE_ENV=development
PORT=3000 PORT=3000
JWT_SECRET=Y@RJ$WT!@K0NS@MPL! JWT_SECRET=Y@RJ$WT!@K0NS@MPL!
REDIS_URL= redis://:135792468@localhost:6379/0 REDIS_URL= redis://:135792468@localhost:6379/0
LOGIN_ATTEMPT_LIMIT=5 LOGIN_ATTEMPT_LIMIT=900
SUPER_ADMIN_ROLE_ID=676afd6d076b286f9395b05f SUPER_ADMIN_ROLE_ID=676afd6d076b286f9395b05f
TYPE_SENSE_URL=localhost:8108 TYPE_SENSE_URL=localhost:8108
TYPE_SENSE_API_KEY=vYQq7pTgl6ACoRy TYPE_SENSE_API_KEY=vYQq7pTgl6ACoRy
SUPER_ADMIN_ID=66a2da5b9b989a8909948848
+3 -1
View File
@@ -7,7 +7,8 @@ exports.loginProtect = async (req, res, next) => {
// 1) Getting token and check if it's there // 1) Getting token and check if it's there
let token let token
token = req.cookies.jwt || req.cookies['crm-jwt']
token = req.cookies['bm-token']
if (req.headers.authorization && req.headers.authorization.startsWith('Bearer')) { if (req.headers.authorization && req.headers.authorization.startsWith('Bearer')) {
token = req.headers.authorization.split(' ')[1] token = req.headers.authorization.split(' ')[1]
@@ -30,6 +31,7 @@ exports.loginProtect = async (req, res, next) => {
// 3) check if user still exist // 3) check if user still exist
const loggedInUser = await User.findById(decodedToken.id).populate('role') const loggedInUser = await User.findById(decodedToken.id).populate('role')
if (!loggedInUser) { if (!loggedInUser) {
return next(new AppError('TokenUserNotExist', 401, {})) return next(new AppError('TokenUserNotExist', 401, {}))
} }
+121
View File
@@ -9,6 +9,7 @@
"version": "1.0.0", "version": "1.0.0",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"axios": "^1.7.9",
"bcryptjs": "^2.4.3", "bcryptjs": "^2.4.3",
"body-parser": "^1.20.3", "body-parser": "^1.20.3",
"chalk": "^4.1.2", "chalk": "^4.1.2",
@@ -21,12 +22,25 @@
"mongoose": "^8.9.0", "mongoose": "^8.9.0",
"mongoose-sequence": "^6.0.1", "mongoose-sequence": "^6.0.1",
"redis": "^4.7.0", "redis": "^4.7.0",
"typesense": "^1.8.2",
"validator": "^13.12.0" "validator": "^13.12.0"
}, },
"devDependencies": { "devDependencies": {
"nodemon": "^3.1.9" "nodemon": "^3.1.9"
} }
}, },
"node_modules/@babel/runtime": {
"version": "7.26.0",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz",
"integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==",
"peer": true,
"dependencies": {
"regenerator-runtime": "^0.14.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@mongodb-js/saslprep": { "node_modules/@mongodb-js/saslprep": {
"version": "1.1.9", "version": "1.1.9",
"resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.9.tgz", "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.9.tgz",
@@ -158,6 +172,21 @@
"resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz",
"integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==" "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA=="
}, },
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
},
"node_modules/axios": {
"version": "1.7.9",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz",
"integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==",
"dependencies": {
"follow-redirects": "^1.15.6",
"form-data": "^4.0.0",
"proxy-from-env": "^1.1.0"
}
},
"node_modules/balanced-match": { "node_modules/balanced-match": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -356,6 +385,17 @@
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
}, },
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"dependencies": {
"delayed-stream": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/compressible": { "node_modules/compressible": {
"version": "2.0.18", "version": "2.0.18",
"resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz",
@@ -454,6 +494,14 @@
"ms": "2.0.0" "ms": "2.0.0"
} }
}, },
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/depd": { "node_modules/depd": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
@@ -638,6 +686,38 @@
"node": ">= 0.8" "node": ">= 0.8"
} }
}, },
"node_modules/follow-redirects": {
"version": "1.15.9",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
"integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/RubenVerborgh"
}
],
"engines": {
"node": ">=4.0"
},
"peerDependenciesMeta": {
"debug": {
"optional": true
}
}
},
"node_modules/form-data": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz",
"integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/forwarded": { "node_modules/forwarded": {
"version": "0.2.0", "version": "0.2.0",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
@@ -941,6 +1021,18 @@
"resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
"integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg=="
}, },
"node_modules/loglevel": {
"version": "1.9.2",
"resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.9.2.tgz",
"integrity": "sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==",
"engines": {
"node": ">= 0.6.0"
},
"funding": {
"type": "tidelift",
"url": "https://tidelift.com/funding/github/npm/loglevel"
}
},
"node_modules/math-intrinsics": { "node_modules/math-intrinsics": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.0.0.tgz", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.0.0.tgz",
@@ -1308,6 +1400,11 @@
"node": ">= 0.10" "node": ">= 0.10"
} }
}, },
"node_modules/proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
},
"node_modules/pstree.remy": { "node_modules/pstree.remy": {
"version": "1.1.8", "version": "1.1.8",
"resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz",
@@ -1374,6 +1471,9 @@
"version": "4.7.0", "version": "4.7.0",
"resolved": "https://registry.npmjs.org/redis/-/redis-4.7.0.tgz", "resolved": "https://registry.npmjs.org/redis/-/redis-4.7.0.tgz",
"integrity": "sha512-zvmkHEAdGMn+hMRXuMBtu4Vo5P6rHQjLoHftu+lBqq8ZTA3RCVC/WzD790bkKKiNFp7d5/9PcSD19fJyyRvOdQ==", "integrity": "sha512-zvmkHEAdGMn+hMRXuMBtu4Vo5P6rHQjLoHftu+lBqq8ZTA3RCVC/WzD790bkKKiNFp7d5/9PcSD19fJyyRvOdQ==",
"workspaces": [
"./packages/*"
],
"dependencies": { "dependencies": {
"@redis/bloom": "1.2.0", "@redis/bloom": "1.2.0",
"@redis/client": "1.6.0", "@redis/client": "1.6.0",
@@ -1383,6 +1483,12 @@
"@redis/time-series": "1.1.0" "@redis/time-series": "1.1.0"
} }
}, },
"node_modules/regenerator-runtime": {
"version": "0.14.1",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
"integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==",
"peer": true
},
"node_modules/safe-buffer": { "node_modules/safe-buffer": {
"version": "5.2.1", "version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
@@ -1638,6 +1744,21 @@
"node": ">= 0.6" "node": ">= 0.6"
} }
}, },
"node_modules/typesense": {
"version": "1.8.2",
"resolved": "https://registry.npmjs.org/typesense/-/typesense-1.8.2.tgz",
"integrity": "sha512-aBpePjA99Qvo+OP2pJwMpvga4Jrm1Y2oV5NsrWXBxlqUDNEUCPZBIksPv2Hq0jxQxHhLLyJVbjXjByXsvpCDVA==",
"dependencies": {
"axios": "^1.6.0",
"loglevel": "^1.8.1"
},
"engines": {
"node": ">=18"
},
"peerDependencies": {
"@babel/runtime": "^7.23.2"
}
},
"node_modules/undefsafe": { "node_modules/undefsafe": {
"version": "2.0.5", "version": "2.0.5",
"resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz",
+4 -1
View File
@@ -1,5 +1,8 @@
const userSeeder = require('../components/user/userSeeder') const userSeeder = require('../components/user/userSeeder')
const categorySeeder = require('../components/category/categorySeeder')
const roleSeeder = require('../components/role/roleSeeder')
module.exports.run = async () => { module.exports.run = async () => {
await userSeeder.runSeeder() await userSeeder.runSeeder()
await categorySeeder.runSeeder()
await roleSeeder.runSeeder()
} }