diff --git a/app.js b/app.js index da8f99b..4e183e4 100644 --- a/app.js +++ b/app.js @@ -12,7 +12,7 @@ const cors = require('cors') const app = express() -const allowedOrigins = ['http://localhost:3000'] +const allowedOrigins = ['http://localhost:3000', 'http://localhost:5173'] app.use( cors({ @@ -32,7 +32,7 @@ app.use(express.json()) app.set('view engine', 'ejs') app.use(express.static('views/public')) -app.use('/', routerEndpoints) +app.use('/api', routerEndpoints) databaseConnection(app) diff --git a/components/belonging/belongingModel.js b/components/belonging/belongingModel.js index 9214a71..f3faa91 100644 --- a/components/belonging/belongingModel.js +++ b/components/belonging/belongingModel.js @@ -26,11 +26,17 @@ const belongingSchema = new mongoose.Schema( required: true, }, }, - documents: [String], + documentNames: [String], + documentUrls: [String], + imageNames: [String], + imageUrls: [String], + mainImageUrl: String, + mainImageName: String, numId: { type: Number, unique: true, }, + tags: [String], isActive: { type: Boolean, default: true, diff --git a/components/category/categorySeeder.js b/components/category/categorySeeder.js new file mode 100644 index 0000000..2fdaa03 --- /dev/null +++ b/components/category/categorySeeder.js @@ -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 } diff --git a/components/role/roleSeeder.js b/components/role/roleSeeder.js index 8648875..dfc11ad 100644 --- a/components/role/roleSeeder.js +++ b/components/role/roleSeeder.js @@ -29,7 +29,7 @@ const runSeeder = async () => { await Role.deleteMany({}) 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)`)) } diff --git a/components/user/userController.js b/components/user/userController.js index 2918287..2afbc77 100644 --- a/components/user/userController.js +++ b/components/user/userController.js @@ -1,6 +1,7 @@ // userController.js const catchAsync = require('../../globalErrorHandler/catchAsync') const userService = require('./userService') +const AppError = require("../../globalErrorHandler/AppError"); exports.signup = catchAsync(async (req, res, next) => { 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) => { const user = await userService.getUser(req.params.userId) diff --git a/components/user/userRoutes.js b/components/user/userRoutes.js index da0800f..95b12b5 100644 --- a/components/user/userRoutes.js +++ b/components/user/userRoutes.js @@ -5,13 +5,15 @@ const loginCheck = require('../../middlewares/loginCheck') const router = new express.Router() -router.post('/signup', userController.signup) -router.post('/login', userController.loginUser) +router.post('/user/signup-email', userController.signup) +router.post('/user/login-email', userController.loginUser) router.post('/logout', userController.logoutUser) router.use(loginCheck.loginProtect) // router.use(loginCheck.adminProtect) +router.get('/user/get-self', userController.userGetSelf) + router.get('/', userController.getAllUsers) router.get('/:userId', userController.getUser) diff --git a/components/user/userSeeder.js b/components/user/userSeeder.js index 1059fe3..9f9c11d 100644 --- a/components/user/userSeeder.js +++ b/components/user/userSeeder.js @@ -5,7 +5,7 @@ const runSeeder = async () => { { _id: '66ddb52302f30f105de39e61', name: 'main admin', - email: 'superadmin@chayamarket.ir', + email: 'superadmin@belongingm.ir', password: '$2a$10$pabxmRjm6klipAC6vBvgI.J.GJpnG//L1MeNcdbtxuYQRYHLI/I3O', phoneNumber: '+989123456789', favorites: [], @@ -20,7 +20,7 @@ const runSeeder = async () => { await User.deleteMany({}) 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)`)) } diff --git a/config/.env b/config/.env index e76abc7..9edb537 100644 --- a/config/.env +++ b/config/.env @@ -3,7 +3,8 @@ NODE_ENV=development PORT=3000 JWT_SECRET=Y@RJ$WT!@K0NS@MPL! REDIS_URL= redis://:135792468@localhost:6379/0 -LOGIN_ATTEMPT_LIMIT=5 +LOGIN_ATTEMPT_LIMIT=900 SUPER_ADMIN_ROLE_ID=676afd6d076b286f9395b05f TYPE_SENSE_URL=localhost:8108 -TYPE_SENSE_API_KEY=vYQq7pTgl6ACoRy \ No newline at end of file +TYPE_SENSE_API_KEY=vYQq7pTgl6ACoRy +SUPER_ADMIN_ID=66a2da5b9b989a8909948848 \ No newline at end of file diff --git a/middlewares/loginCheck.js b/middlewares/loginCheck.js index 2ce6ab2..2b4a5d4 100644 --- a/middlewares/loginCheck.js +++ b/middlewares/loginCheck.js @@ -7,7 +7,8 @@ exports.loginProtect = async (req, res, next) => { // 1) Getting token and check if it's there let token - token = req.cookies.jwt || req.cookies['crm-jwt'] + + token = req.cookies['bm-token'] if (req.headers.authorization && req.headers.authorization.startsWith('Bearer')) { token = req.headers.authorization.split(' ')[1] @@ -30,6 +31,7 @@ exports.loginProtect = async (req, res, next) => { // 3) check if user still exist const loggedInUser = await User.findById(decodedToken.id).populate('role') + if (!loggedInUser) { return next(new AppError('TokenUserNotExist', 401, {})) } diff --git a/package-lock.json b/package-lock.json index 6b10861..e1d1a3c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "1.0.0", "license": "ISC", "dependencies": { + "axios": "^1.7.9", "bcryptjs": "^2.4.3", "body-parser": "^1.20.3", "chalk": "^4.1.2", @@ -21,12 +22,25 @@ "mongoose": "^8.9.0", "mongoose-sequence": "^6.0.1", "redis": "^4.7.0", + "typesense": "^1.8.2", "validator": "^13.12.0" }, "devDependencies": { "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": { "version": "1.1.9", "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", "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": { "version": "1.0.2", "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", "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": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", @@ -454,6 +494,14 @@ "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": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -638,6 +686,38 @@ "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": { "version": "0.2.0", "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", "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": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.0.0.tgz", @@ -1308,6 +1400,11 @@ "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": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", @@ -1374,6 +1471,9 @@ "version": "4.7.0", "resolved": "https://registry.npmjs.org/redis/-/redis-4.7.0.tgz", "integrity": "sha512-zvmkHEAdGMn+hMRXuMBtu4Vo5P6rHQjLoHftu+lBqq8ZTA3RCVC/WzD790bkKKiNFp7d5/9PcSD19fJyyRvOdQ==", + "workspaces": [ + "./packages/*" + ], "dependencies": { "@redis/bloom": "1.2.0", "@redis/client": "1.6.0", @@ -1383,6 +1483,12 @@ "@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": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -1638,6 +1744,21 @@ "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": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", diff --git a/seeder/seederRunner.js b/seeder/seederRunner.js index 5fbec05..6316fa9 100644 --- a/seeder/seederRunner.js +++ b/seeder/seederRunner.js @@ -1,5 +1,8 @@ const userSeeder = require('../components/user/userSeeder') - +const categorySeeder = require('../components/category/categorySeeder') +const roleSeeder = require('../components/role/roleSeeder') module.exports.run = async () => { await userSeeder.runSeeder() + await categorySeeder.runSeeder() + await roleSeeder.runSeeder() }