Initial Version
This commit is contained in:
55
server/models/Address.js
Normal file
55
server/models/Address.js
Normal file
@@ -0,0 +1,55 @@
|
||||
const mongoose = require("mongoose");
|
||||
const Schema = mongoose.Schema
|
||||
const pointSchema = new mongoose.Schema({
|
||||
type: {
|
||||
type: String,
|
||||
enum: ['Point']
|
||||
},
|
||||
coordinates: {
|
||||
type: [Number]
|
||||
}
|
||||
});
|
||||
|
||||
const addressSchema = new mongoose.Schema({
|
||||
user: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: "user",
|
||||
required: true
|
||||
},
|
||||
label: {
|
||||
type: String,
|
||||
trim: true,
|
||||
enum:['home','office','other']
|
||||
},
|
||||
region: {//pradesh
|
||||
type: String,
|
||||
trim: true,
|
||||
},
|
||||
city: {
|
||||
type: String,
|
||||
trim: true,
|
||||
},
|
||||
area: {//tole,area name
|
||||
type: String,
|
||||
trim: true,
|
||||
},
|
||||
address: {//street level address
|
||||
type: String,
|
||||
trim: true,
|
||||
},
|
||||
geolocation: {
|
||||
type: pointSchema,
|
||||
},
|
||||
phoneno: {
|
||||
type: String,
|
||||
trim: true,
|
||||
max: 9999999999,
|
||||
},
|
||||
isActive:{
|
||||
type: Date,
|
||||
default: null
|
||||
}
|
||||
}, { timestamps: true });
|
||||
addressSchema.index({ geolocation: "2dsphere" });
|
||||
|
||||
module.exports = mongoose.model("address", addressSchema);
|
||||
149
server/models/Admin.js
Normal file
149
server/models/Admin.js
Normal file
@@ -0,0 +1,149 @@
|
||||
const mongoose = require("mongoose");
|
||||
const crypto = require("crypto");
|
||||
const Schema = mongoose.Schema
|
||||
const pointSchema = new mongoose.Schema({
|
||||
type: {
|
||||
type: String,
|
||||
enum: ['Point']
|
||||
},
|
||||
coordinates: {
|
||||
type: [Number]
|
||||
}
|
||||
});
|
||||
const adminSchema = new mongoose.Schema({
|
||||
name: {
|
||||
type: String,
|
||||
trim: true,
|
||||
required: true,
|
||||
maxlength: 32
|
||||
},
|
||||
shopName: {
|
||||
type: String,
|
||||
trim: true,
|
||||
maxlength: 32
|
||||
},
|
||||
address: {
|
||||
type: String,
|
||||
trim: true,
|
||||
maxlength: 32
|
||||
},
|
||||
geolocation: {
|
||||
type: pointSchema,//of superadmin used to calculate geodistance between user nd the order dispatch system
|
||||
},
|
||||
shippingRate: {
|
||||
type: Number// added only by superadmin
|
||||
},
|
||||
shippingCost: {
|
||||
type: Number// added only by superadmin
|
||||
},
|
||||
district: {
|
||||
type: String,
|
||||
trim: true,
|
||||
maxlength: 32
|
||||
},
|
||||
muncipality: {
|
||||
type: String,
|
||||
trim: true,
|
||||
maxlength: 32
|
||||
},
|
||||
wardno: {
|
||||
type: Number
|
||||
},
|
||||
businessInfo: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: "businessinfo"
|
||||
},
|
||||
adminBank: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: "adminbank"
|
||||
},
|
||||
adminWareHouse: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: "adminwarehouse"
|
||||
},
|
||||
phone: {
|
||||
type: Number,
|
||||
max: 9999999999
|
||||
},
|
||||
email: {
|
||||
type: String,
|
||||
trim: true,
|
||||
unique: true
|
||||
},
|
||||
password: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
photo: {
|
||||
type: String
|
||||
},
|
||||
holidayMode: {
|
||||
start: {
|
||||
type: Number
|
||||
},
|
||||
end: {
|
||||
type: Number
|
||||
}
|
||||
},
|
||||
salt: String,
|
||||
role: {
|
||||
type: String,
|
||||
enum: ["admin", "superadmin"],
|
||||
default: "admin"
|
||||
},
|
||||
resetPasswordLink: {
|
||||
type: String,
|
||||
default: ""
|
||||
},
|
||||
emailVerifyLink: {
|
||||
type: String,
|
||||
default: ""
|
||||
},
|
||||
isVerified: {
|
||||
type: Date,
|
||||
default: null
|
||||
},
|
||||
isBlocked: {
|
||||
type: Date,
|
||||
default: null
|
||||
}
|
||||
}, { timestamps: true });
|
||||
adminSchema.index({ geolocation: "2dsphere" });
|
||||
|
||||
const sha512 = function (password, salt) {
|
||||
let hash = crypto.createHmac('sha512', salt);
|
||||
hash.update(password);
|
||||
let value = hash.digest('hex');
|
||||
return {
|
||||
passwordHash: value
|
||||
};
|
||||
};
|
||||
adminSchema.pre('save', function (next) {
|
||||
let admin = this;
|
||||
if (admin.isModified('password')) {
|
||||
// salt
|
||||
const ranStr = function (n) {
|
||||
return crypto.randomBytes(Math.ceil(8))
|
||||
.toString('hex')
|
||||
.slice(0, n);
|
||||
};
|
||||
// applying sha512 alogrithm
|
||||
let salt = ranStr(16);
|
||||
let passwordData = sha512(admin.password, salt);
|
||||
admin.password = passwordData.passwordHash;
|
||||
admin.salt = salt;
|
||||
next();
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
})
|
||||
adminSchema.statics.findByCredentials = async function (email, password) {
|
||||
let Admin = this;
|
||||
const admin = await Admin.findOne({ email })
|
||||
if (!admin) return ''
|
||||
let passwordData = sha512(password, admin.salt)
|
||||
if (passwordData.passwordHash == admin.password) {
|
||||
return admin
|
||||
}
|
||||
}
|
||||
module.exports = mongoose.model("admin", adminSchema);
|
||||
49
server/models/AdminBank.js
Normal file
49
server/models/AdminBank.js
Normal file
@@ -0,0 +1,49 @@
|
||||
const mongoose = require("mongoose");
|
||||
const Schema = mongoose.Schema
|
||||
const bankSchema = new mongoose.Schema({
|
||||
admin: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: "admin",
|
||||
required: true
|
||||
},
|
||||
accountHolder: {
|
||||
type: String,
|
||||
trim: true,
|
||||
required: true,
|
||||
maxlength: 32
|
||||
},
|
||||
bankName: {
|
||||
type: String,
|
||||
trim: true,
|
||||
required: true,
|
||||
maxlength: 32
|
||||
},
|
||||
branchName: {
|
||||
type: String,
|
||||
trim: true,
|
||||
required: true,
|
||||
maxlength: 32
|
||||
},
|
||||
accountNumber: {
|
||||
type: String,
|
||||
trim: true,
|
||||
required: true,
|
||||
maxlength: 32
|
||||
},
|
||||
routingNumber: {
|
||||
type: String,
|
||||
trim: true,
|
||||
required: true,
|
||||
maxlength: 32
|
||||
},
|
||||
chequeCopy: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: "adminfile",
|
||||
},
|
||||
isVerified: {
|
||||
type: Date,//as we may need verified date
|
||||
default: null
|
||||
}
|
||||
}, { timestamps: true });
|
||||
|
||||
module.exports = mongoose.model("adminbank", bankSchema);
|
||||
10
server/models/AdminFiles.js
Normal file
10
server/models/AdminFiles.js
Normal file
@@ -0,0 +1,10 @@
|
||||
const mongoose = require('mongoose');
|
||||
const Schema = mongoose.Schema
|
||||
const adminFileSchema = new mongoose.Schema({
|
||||
admin: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: "admin",
|
||||
},
|
||||
fileUri: String
|
||||
}, { timestamps: true });
|
||||
module.exports = mongoose.model('adminfile', adminFileSchema);
|
||||
39
server/models/AdminWarehouse.js
Normal file
39
server/models/AdminWarehouse.js
Normal file
@@ -0,0 +1,39 @@
|
||||
const mongoose = require("mongoose");
|
||||
const Schema = mongoose.Schema
|
||||
const warehouseSchema = new mongoose.Schema({
|
||||
admin: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: "admin",
|
||||
required: true
|
||||
},
|
||||
name: {
|
||||
type: String,
|
||||
trim: true,
|
||||
required: true,
|
||||
maxlength: 32
|
||||
},
|
||||
address: {
|
||||
type: String,
|
||||
trim: true,
|
||||
required: true,
|
||||
maxlength: 32
|
||||
},
|
||||
phoneno: {
|
||||
type: String,
|
||||
trim: true,
|
||||
required: true,
|
||||
maxlength: 32
|
||||
},
|
||||
city: {
|
||||
type: String,
|
||||
trim: true,
|
||||
required: true,
|
||||
maxlength: 32
|
||||
},
|
||||
isVerified: {
|
||||
type: Date,//as we may need verified date
|
||||
default: null
|
||||
}
|
||||
}, { timestamps: true });
|
||||
|
||||
module.exports = mongoose.model("adminwarehouse", warehouseSchema);
|
||||
19
server/models/Banner.js
Normal file
19
server/models/Banner.js
Normal file
@@ -0,0 +1,19 @@
|
||||
const mongoose = require('mongoose');
|
||||
const Schema = mongoose.Schema;
|
||||
const bannerSchema = mongoose.Schema({
|
||||
bannerPhoto :{
|
||||
type:String
|
||||
},
|
||||
link: {
|
||||
type: String
|
||||
},
|
||||
product: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: 'product'
|
||||
},
|
||||
isDeleted: {
|
||||
type: Date,
|
||||
default: null
|
||||
},
|
||||
}, { timestamps: true });
|
||||
module.exports = mongoose.model('banner', bannerSchema);
|
||||
57
server/models/BusinessInfo.js
Normal file
57
server/models/BusinessInfo.js
Normal file
@@ -0,0 +1,57 @@
|
||||
const mongoose = require("mongoose");
|
||||
const Schema = mongoose.Schema
|
||||
const businessSchema = new mongoose.Schema({
|
||||
admin: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: "admin",
|
||||
required: true
|
||||
},
|
||||
ownerName: {
|
||||
type: String,
|
||||
trim: true,
|
||||
required: true,
|
||||
maxlength: 32
|
||||
},
|
||||
address: {
|
||||
type: String,
|
||||
trim: true,
|
||||
required: true,
|
||||
maxlength: 32
|
||||
},
|
||||
city: {
|
||||
type: String,
|
||||
trim: true,
|
||||
required: true,
|
||||
maxlength: 32
|
||||
},
|
||||
citizenshipNumber: {
|
||||
type: String,
|
||||
trim: true,
|
||||
required: true,
|
||||
maxlength: 32
|
||||
},
|
||||
businessRegisterNumber:{
|
||||
type: String,
|
||||
trim: true,
|
||||
required: true,
|
||||
maxlength: 32
|
||||
},
|
||||
citizenshipFront: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: "adminfile",
|
||||
},
|
||||
citizenshipBack: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: "adminfile",
|
||||
},
|
||||
businessLicence:{
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: "adminfile",
|
||||
},
|
||||
isVerified:{
|
||||
type: Date,//as we may need verified date
|
||||
default: null
|
||||
}
|
||||
}, { timestamps: true });
|
||||
|
||||
module.exports = mongoose.model("businessinfo", businessSchema);
|
||||
23
server/models/Cart.js
Normal file
23
server/models/Cart.js
Normal file
@@ -0,0 +1,23 @@
|
||||
const mongoose = require('mongoose');
|
||||
const Schema = mongoose.Schema;
|
||||
const cartSchema = mongoose.Schema({
|
||||
user: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: 'user'
|
||||
},
|
||||
product: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: 'product'
|
||||
},
|
||||
quantity: {
|
||||
type: Number,
|
||||
},
|
||||
productAttributes: {
|
||||
type: String
|
||||
},
|
||||
isDeleted: {
|
||||
type: Date,
|
||||
default: null
|
||||
}
|
||||
}, { timestamps: true });
|
||||
module.exports = mongoose.model('cart', cartSchema);
|
||||
34
server/models/Category.js
Normal file
34
server/models/Category.js
Normal file
@@ -0,0 +1,34 @@
|
||||
const mongoose = require("mongoose");
|
||||
const URLSlugs = require('mongoose-url-slugs');
|
||||
const Schema = mongoose.Schema
|
||||
const categorySchema = new mongoose.Schema({
|
||||
systemName: {
|
||||
type: String,
|
||||
trim: true,
|
||||
required: true,
|
||||
maxlength: 32
|
||||
},
|
||||
displayName: {
|
||||
type: String,
|
||||
trim: true,
|
||||
required: true,
|
||||
maxlength: 32
|
||||
},
|
||||
parent: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: 'productbrand'
|
||||
},
|
||||
brands: [{
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: 'category'
|
||||
}],
|
||||
slug:{
|
||||
type: String
|
||||
},
|
||||
isDisabled: {
|
||||
type: Date,
|
||||
default:null
|
||||
}
|
||||
});
|
||||
categorySchema.plugin(URLSlugs('displayName', { field: 'slug', update: true }));
|
||||
module.exports = mongoose.model("category", categorySchema);
|
||||
76
server/models/Dispatcher.js
Normal file
76
server/models/Dispatcher.js
Normal file
@@ -0,0 +1,76 @@
|
||||
const mongoose = require("mongoose");
|
||||
const crypto = require("crypto");
|
||||
const Schema = mongoose.Schema
|
||||
const dispatcherSchema = new mongoose.Schema({
|
||||
name: {
|
||||
type: String,
|
||||
trim: true,
|
||||
required: true,
|
||||
maxlength: 32
|
||||
},
|
||||
address: {
|
||||
type: String,
|
||||
trim: true,
|
||||
maxlength: 32
|
||||
},
|
||||
phone: {
|
||||
type: Number,
|
||||
max: 9999999999
|
||||
},
|
||||
email: {
|
||||
type: String,
|
||||
trim: true,
|
||||
unique: true
|
||||
},
|
||||
password: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
salt: String,
|
||||
resetPasswordLink: {
|
||||
type: String,
|
||||
default: ""
|
||||
},
|
||||
isBlocked: {
|
||||
type: Date,
|
||||
default: null
|
||||
}
|
||||
}, { timestamps: true });
|
||||
|
||||
const sha512 = function (password, salt) {
|
||||
let hash = crypto.createHmac('sha512', salt);
|
||||
hash.update(password);
|
||||
let value = hash.digest('hex');
|
||||
return {
|
||||
passwordHash: value
|
||||
};
|
||||
};
|
||||
dispatcherSchema.pre('save', function (next) {
|
||||
let dispatcher = this;
|
||||
if (dispatcher.isModified('password')) {
|
||||
// salt
|
||||
const ranStr = function (n) {
|
||||
return crypto.randomBytes(Math.ceil(8))
|
||||
.toString('hex')
|
||||
.slice(0, n);
|
||||
};
|
||||
// applying sha512 alogrithm
|
||||
let salt = ranStr(16);
|
||||
let passwordData = sha512(dispatcher.password, salt);
|
||||
dispatcher.password = passwordData.passwordHash;
|
||||
dispatcher.salt = salt;
|
||||
next();
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
})
|
||||
dispatcherSchema.statics.findByCredentials = async function (email, password) {
|
||||
let Dispatcher = this;
|
||||
const dispatcher = await Dispatcher.findOne({ email })
|
||||
if (!dispatcher) return ''
|
||||
let passwordData = sha512(password, dispatcher.salt)
|
||||
if (passwordData.passwordHash == dispatcher.password) {
|
||||
return dispatcher
|
||||
}
|
||||
}
|
||||
module.exports = mongoose.model("dispatcher", dispatcherSchema);
|
||||
10
server/models/Districts.js
Normal file
10
server/models/Districts.js
Normal file
@@ -0,0 +1,10 @@
|
||||
const mongoose = require('mongoose');
|
||||
const { districts } = require('../middleware/common');
|
||||
const districtSchema = mongoose.Schema({
|
||||
name: {
|
||||
type: String,
|
||||
unique: true,
|
||||
enum : districts
|
||||
}
|
||||
}, { timestamps: true });
|
||||
module.exports = mongoose.model('district', districtSchema);
|
||||
12
server/models/Lead.js
Normal file
12
server/models/Lead.js
Normal file
@@ -0,0 +1,12 @@
|
||||
const mongoose = require('mongoose');
|
||||
const leadSchema = mongoose.Schema({
|
||||
email: {
|
||||
type: String,
|
||||
unique: true
|
||||
},
|
||||
isDeleted: {
|
||||
type: Date,
|
||||
default: null
|
||||
}
|
||||
}, { timestamps: true });
|
||||
module.exports = mongoose.model('lead', leadSchema);
|
||||
18
server/models/ManualOrder.js
Normal file
18
server/models/ManualOrder.js
Normal file
@@ -0,0 +1,18 @@
|
||||
const mongoose = require('mongoose');
|
||||
const Schema = mongoose.Schema;
|
||||
const manualOrderSchema = mongoose.Schema({
|
||||
productName:{
|
||||
type: String
|
||||
},
|
||||
link:{
|
||||
type: String
|
||||
},
|
||||
description: {
|
||||
type: String
|
||||
},
|
||||
isDeleted: {
|
||||
type: Date,
|
||||
default: null
|
||||
}
|
||||
}, { timestamps: true });
|
||||
module.exports = mongoose.model('manualorder', manualOrderSchema);
|
||||
29
server/models/Notification.js
Normal file
29
server/models/Notification.js
Normal file
@@ -0,0 +1,29 @@
|
||||
const mongoose = require('mongoose');
|
||||
const Schema = mongoose.Schema
|
||||
const notificationSchema = new mongoose.Schema({
|
||||
admin: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: "admin",
|
||||
},
|
||||
notifications: [{
|
||||
notificationType: String, //order, question_on_product, answer_on_product, review
|
||||
notificationDetail: Object, //details in key/value
|
||||
hasRead: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
date: {
|
||||
type: Date
|
||||
},
|
||||
// hasSeen: {
|
||||
// type: Boolean,
|
||||
// default: false
|
||||
// }
|
||||
}],
|
||||
noOfUnseen: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
|
||||
});
|
||||
module.exports = mongoose.model('notification', notificationSchema);
|
||||
149
server/models/Order.js
Normal file
149
server/models/Order.js
Normal file
@@ -0,0 +1,149 @@
|
||||
const mongoose = require("mongoose");
|
||||
const { allOrderStatus } = require("../middleware/common");
|
||||
|
||||
const Schema = mongoose.Schema
|
||||
const pointSchema = new mongoose.Schema({
|
||||
type: {
|
||||
type: String,
|
||||
enum: ['Point']
|
||||
},
|
||||
coordinates: {
|
||||
type: [Number]
|
||||
}
|
||||
});
|
||||
const orderSchema = new mongoose.Schema({
|
||||
user: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: "user",
|
||||
required: true
|
||||
},
|
||||
orderID:{
|
||||
type: String,
|
||||
require: true
|
||||
},
|
||||
product: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: "product",
|
||||
required: true
|
||||
},
|
||||
payment: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: "payment",
|
||||
},
|
||||
quantity: {
|
||||
type: Number
|
||||
},
|
||||
soldBy:{
|
||||
type: Schema.Types.ObjectId,
|
||||
ref:"admin"
|
||||
},
|
||||
status: {
|
||||
currentStatus: {
|
||||
type: String,
|
||||
enum: allOrderStatus
|
||||
},
|
||||
activeDate: {
|
||||
type: Date,
|
||||
default: null
|
||||
},
|
||||
approvedDate: {
|
||||
type: Date,
|
||||
default: null
|
||||
},
|
||||
dispatchedDetail: {
|
||||
dispatchedDate: {
|
||||
type: Date,
|
||||
default: null
|
||||
},
|
||||
dispatchedBy: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: 'dispatcher'
|
||||
},
|
||||
},
|
||||
cancelledDetail: {
|
||||
cancelledDate:{
|
||||
type: Date,
|
||||
default: null
|
||||
},
|
||||
cancelledBy:{
|
||||
type: Schema.Types.ObjectId,
|
||||
refPath: "cancelledByModel"
|
||||
},
|
||||
remark: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: 'remark'
|
||||
},
|
||||
},
|
||||
completedDate: {
|
||||
type: Date,
|
||||
default: null
|
||||
},
|
||||
tobereturnedDate: {
|
||||
type: Date,
|
||||
default: null
|
||||
},
|
||||
// tobeReturnedDetail: {
|
||||
// tobereturnedDate: {
|
||||
// type: Date
|
||||
// },
|
||||
// remark: {
|
||||
// type: Schema.Types.ObjectId,
|
||||
// ref: 'remark'
|
||||
// },
|
||||
// },
|
||||
returnedDetail: {
|
||||
returnedDate: {
|
||||
type: Date,
|
||||
default: null
|
||||
},
|
||||
returneddBy: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: 'dispatcher'
|
||||
},
|
||||
remark: [{
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: 'remark'
|
||||
}],
|
||||
},
|
||||
},
|
||||
shipto:{
|
||||
region: {//pradesh
|
||||
type: String,
|
||||
trim: true,
|
||||
},
|
||||
city: {
|
||||
type: String,
|
||||
trim: true,
|
||||
},
|
||||
area: {//tole,area name
|
||||
type: String,
|
||||
trim: true,
|
||||
},
|
||||
address: {//street level address
|
||||
type: String,
|
||||
trim: true,
|
||||
},
|
||||
geolocation: {
|
||||
type: pointSchema,
|
||||
},
|
||||
phoneno: {
|
||||
type: String,
|
||||
trim: true,
|
||||
max: 9999999999,
|
||||
}
|
||||
},
|
||||
isPaid:{
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
cancelledByModel: {
|
||||
type: String,
|
||||
enum: ['user', 'admin']
|
||||
},
|
||||
productAttributes:{
|
||||
type: String
|
||||
}
|
||||
}, { timestamps: true });
|
||||
orderSchema.index({ geolocation: "2dsphere" });
|
||||
|
||||
module.exports = mongoose.model("order", orderSchema);
|
||||
43
server/models/Payment.js
Normal file
43
server/models/Payment.js
Normal file
@@ -0,0 +1,43 @@
|
||||
const mongoose = require("mongoose");
|
||||
const Schema = mongoose.Schema
|
||||
const paymentSchema = new mongoose.Schema({
|
||||
user: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: "user",
|
||||
required: true
|
||||
},
|
||||
order: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: "order",
|
||||
required: true
|
||||
},
|
||||
method: {
|
||||
type: String,
|
||||
enum: ['Cash on Delivery','manual']//manual ==> bank or manual esewa..
|
||||
},
|
||||
shippingCharge: {
|
||||
type: Number,
|
||||
},
|
||||
amount: {
|
||||
type: Number,
|
||||
},
|
||||
returnedAmount: {
|
||||
type: Number,
|
||||
default: null
|
||||
},
|
||||
transactionCode: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
from:{
|
||||
type:Number,
|
||||
max: 9999999999 //!esewa && receiverNumber
|
||||
},
|
||||
isDeleted: {
|
||||
type: Date,
|
||||
default: null
|
||||
}
|
||||
|
||||
}, { timestamps: true });
|
||||
|
||||
module.exports = mongoose.model("payment", paymentSchema);
|
||||
141
server/models/Product.js
Normal file
141
server/models/Product.js
Normal file
@@ -0,0 +1,141 @@
|
||||
const mongoose = require("mongoose");
|
||||
const URLSlugs = require('mongoose-url-slugs');
|
||||
const { districts } = require("../middleware/common");
|
||||
const Schema = mongoose.Schema;
|
||||
const productSchema = mongoose.Schema({
|
||||
name: {
|
||||
type: String,
|
||||
trim: true,
|
||||
required: true,
|
||||
maxlength: 128
|
||||
},
|
||||
brand: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: 'productbrand'
|
||||
},
|
||||
quantity: {
|
||||
type: Number,
|
||||
trim: true,
|
||||
required: true,
|
||||
maxlength: 32
|
||||
},
|
||||
category: [{
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: 'category'
|
||||
}],
|
||||
averageRating:{
|
||||
type: mongoose.Decimal128
|
||||
},
|
||||
totalRatingUsers:{
|
||||
type: Number
|
||||
},
|
||||
soldBy: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: 'admin'
|
||||
},
|
||||
images: [{
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: 'productimages'
|
||||
}],
|
||||
warranty: {
|
||||
type: String,
|
||||
trim: true,
|
||||
required: true,
|
||||
maxlength: 32
|
||||
},
|
||||
return: {
|
||||
type: String,
|
||||
required: true,
|
||||
trim: true,
|
||||
maxlength: 32
|
||||
},
|
||||
size: [{
|
||||
type: String,
|
||||
trim: true,
|
||||
maxlength: 32
|
||||
}],
|
||||
model: {
|
||||
type: String,
|
||||
trim: true,
|
||||
maxlength: 128
|
||||
},
|
||||
color: [{
|
||||
type: String,
|
||||
trim: true,
|
||||
maxlength: 128
|
||||
}],
|
||||
weight: [{
|
||||
type: String,
|
||||
trim: true,
|
||||
maxlength: 128
|
||||
}],
|
||||
description: {
|
||||
type: String,
|
||||
required: true,
|
||||
trim: true,
|
||||
maxlength: 2000
|
||||
},
|
||||
highlights: {
|
||||
type: String,
|
||||
required: true,
|
||||
trim: true,
|
||||
maxlength: 2000
|
||||
},
|
||||
tags: [{
|
||||
type: String
|
||||
}],
|
||||
price: {
|
||||
type: mongoose.Decimal128,
|
||||
required:true
|
||||
},
|
||||
discountRate: {
|
||||
type: Number,//it may b float as well..
|
||||
default:0
|
||||
},
|
||||
videoURL:[{
|
||||
type:String
|
||||
}],
|
||||
isVerified: {
|
||||
type: Date,
|
||||
default: null
|
||||
},
|
||||
isRejected: {
|
||||
type: Date,
|
||||
default: null
|
||||
},
|
||||
isDeleted: {
|
||||
type: Date,
|
||||
default: null
|
||||
},
|
||||
isFeatured: {
|
||||
type: Date,
|
||||
default: null
|
||||
},
|
||||
viewsCount: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
trendingScore: {
|
||||
type: mongoose.Decimal128,
|
||||
default: 0
|
||||
},
|
||||
noOfSoldOut: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
slug: {
|
||||
type: String,
|
||||
unique: true
|
||||
},
|
||||
availableDistricts:[{
|
||||
type: String,
|
||||
enum: districts,
|
||||
required: true
|
||||
}],
|
||||
remark: [{
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: 'remark'
|
||||
}],
|
||||
}, { timestamps: true });
|
||||
productSchema.plugin(URLSlugs('name', { field: 'slug', update: true }));
|
||||
module.exports = mongoose.model("product", productSchema);
|
||||
16
server/models/ProductBrand.js
Normal file
16
server/models/ProductBrand.js
Normal file
@@ -0,0 +1,16 @@
|
||||
const mongoose = require('mongoose');
|
||||
const URLSlugs = require('mongoose-url-slugs');
|
||||
const brandSchema = new mongoose.Schema({
|
||||
brandName: {
|
||||
type : String
|
||||
},
|
||||
systemName: {
|
||||
type: String,
|
||||
unique: true
|
||||
},
|
||||
slug:{
|
||||
type: String
|
||||
}
|
||||
})
|
||||
brandSchema.plugin(URLSlugs('brandName', { field: 'slug', update: true }));
|
||||
module.exports = mongoose.model("productbrand", brandSchema);
|
||||
19
server/models/ProductImages.js
Normal file
19
server/models/ProductImages.js
Normal file
@@ -0,0 +1,19 @@
|
||||
const mongoose = require('mongoose');
|
||||
const Schema = mongoose.Schema
|
||||
const productImageSchema = mongoose.Schema({
|
||||
thumbnail: {
|
||||
type: String
|
||||
},
|
||||
medium: {
|
||||
type: String
|
||||
},
|
||||
large: {
|
||||
type:String
|
||||
},
|
||||
productLink:{
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: "product",
|
||||
default: null
|
||||
}
|
||||
}, { timestamps: true });
|
||||
module.exports = mongoose.model('productimages', productImageSchema);
|
||||
37
server/models/QnA.js
Normal file
37
server/models/QnA.js
Normal file
@@ -0,0 +1,37 @@
|
||||
const mongoose = require("mongoose");
|
||||
const Schema = mongoose.Schema
|
||||
const qnaSchema = new mongoose.Schema({
|
||||
product: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: "product",
|
||||
required: true
|
||||
},
|
||||
qna: [{
|
||||
question: {
|
||||
type: String
|
||||
},
|
||||
questionby: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: "user",
|
||||
},
|
||||
questionedDate:{
|
||||
type: Date
|
||||
},
|
||||
answer: {
|
||||
type: String
|
||||
},
|
||||
answerby: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: "admin",
|
||||
},
|
||||
answeredDate: {
|
||||
type: Date
|
||||
},
|
||||
isDeleted: {
|
||||
type: Date,
|
||||
default: null
|
||||
}
|
||||
}]
|
||||
});
|
||||
|
||||
module.exports = mongoose.model("qna", qnaSchema);
|
||||
24
server/models/RefereshToken.js
Normal file
24
server/models/RefereshToken.js
Normal file
@@ -0,0 +1,24 @@
|
||||
const mongoose = require('mongoose');
|
||||
const Schema = mongoose.Schema
|
||||
const tokenSchema = mongoose.Schema({
|
||||
//we need user ref in order to create accessToken of that user only
|
||||
// user: {
|
||||
// type: Schema.Types.ObjectId,
|
||||
// refPath: "sysUsers",
|
||||
// },
|
||||
refreshToken:{
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
userIP: {
|
||||
type: String
|
||||
},
|
||||
// expires: {
|
||||
// type : Date
|
||||
// },
|
||||
// sysUsers: {
|
||||
// type: String,
|
||||
// enum: ['user', 'admin','dispatcher']
|
||||
// },
|
||||
});
|
||||
module.exports = mongoose.model('refreshtoken', tokenSchema);
|
||||
27
server/models/Remark.js
Normal file
27
server/models/Remark.js
Normal file
@@ -0,0 +1,27 @@
|
||||
const mongoose = require('mongoose');
|
||||
const Schema = mongoose.Schema;
|
||||
const remarkSchema = mongoose.Schema({
|
||||
comment: {
|
||||
type: String
|
||||
},
|
||||
isDeleted: {
|
||||
type: Date,
|
||||
default: null
|
||||
},
|
||||
// createdBy: {
|
||||
// type: Schema.Types.ObjectId,
|
||||
// refPath: "deletedByModel"
|
||||
// },
|
||||
// deletedBy: {
|
||||
// type: Schema.Types.ObjectId,
|
||||
// refPath: "deletedByModel"
|
||||
// },
|
||||
// deleteByModel: {
|
||||
// type: String,
|
||||
// enum: ['dispatcher', 'admin', 'user', 'superadmin']
|
||||
// },
|
||||
// reason: {
|
||||
// type: String//product_tobereturned,cancel_order_by_admin, cancel_order_by_user, disapprove_product
|
||||
// }
|
||||
}, { timestamps: true });
|
||||
module.exports = mongoose.model('remark', remarkSchema);
|
||||
20
server/models/Review.js
Normal file
20
server/models/Review.js
Normal file
@@ -0,0 +1,20 @@
|
||||
const mongoose = require('mongoose');
|
||||
const Schema = mongoose.Schema;
|
||||
const reviewSchema = mongoose.Schema({
|
||||
user: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: 'user'
|
||||
},
|
||||
product: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: 'product'
|
||||
},
|
||||
comment: {
|
||||
type: String
|
||||
},
|
||||
star: {
|
||||
type: Number,
|
||||
max:5
|
||||
}
|
||||
}, { timestamps: true });
|
||||
module.exports = mongoose.model('reviews', reviewSchema);
|
||||
11
server/models/SocketMapping.js
Normal file
11
server/models/SocketMapping.js
Normal file
@@ -0,0 +1,11 @@
|
||||
const mongoose = require('mongoose');
|
||||
const Schema = mongoose.Schema
|
||||
//later we have to do mapping through redis server
|
||||
const socketMappingSchema = new mongoose.Schema({
|
||||
user: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: "admin",
|
||||
},
|
||||
socketId: String
|
||||
});
|
||||
module.exports = mongoose.model('socketmapping', socketMappingSchema);
|
||||
12
server/models/SuggestKeywords.js
Normal file
12
server/models/SuggestKeywords.js
Normal file
@@ -0,0 +1,12 @@
|
||||
const mongoose = require('mongoose');
|
||||
const suggestKeywordSchema = mongoose.Schema({
|
||||
keyword: {
|
||||
type: String,
|
||||
unique: true
|
||||
},
|
||||
isDeleted: {
|
||||
type: Date,
|
||||
default: null
|
||||
}
|
||||
}, { timestamps: true });
|
||||
module.exports = mongoose.model('suggestkeyword', suggestKeywordSchema);
|
||||
100
server/models/User.js
Normal file
100
server/models/User.js
Normal file
@@ -0,0 +1,100 @@
|
||||
const mongoose = require("mongoose");
|
||||
const crypto = require("crypto");
|
||||
const Schema = mongoose.Schema
|
||||
const userSchema = new mongoose.Schema({
|
||||
name: {
|
||||
type: String,
|
||||
trim: true,
|
||||
required: true,
|
||||
maxlength: 32
|
||||
},
|
||||
email: {
|
||||
type: String,
|
||||
trim: true,
|
||||
// unique:true
|
||||
},
|
||||
userID: {
|
||||
type: String,
|
||||
trim: true,
|
||||
unique: true
|
||||
},
|
||||
loginDomain: {
|
||||
type: String,
|
||||
default: "system",//can be facebook, google as well
|
||||
enum:['system', 'facebook', 'google']
|
||||
},
|
||||
password: {
|
||||
type: String,
|
||||
// required: true
|
||||
},
|
||||
location: [{
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: "address"
|
||||
}],
|
||||
photo: {
|
||||
type: String
|
||||
},
|
||||
socialPhoto: {
|
||||
type: String
|
||||
},
|
||||
dob:{
|
||||
type: String
|
||||
},
|
||||
gender:{
|
||||
type:String,
|
||||
enum:['male','female','other']
|
||||
},
|
||||
resetPasswordLink: {
|
||||
type: String,
|
||||
default: ""
|
||||
},
|
||||
emailVerifyLink: {
|
||||
type: String,
|
||||
default: ""
|
||||
},
|
||||
salt: String,
|
||||
isBlocked: {
|
||||
type: Date,
|
||||
default: null
|
||||
}
|
||||
}, { timestamps: true });
|
||||
userSchema.index({ geolocation: "2dsphere" });
|
||||
|
||||
const sha512 = function (password, salt) {
|
||||
let hash = crypto.createHmac('sha512', salt);
|
||||
hash.update(password);
|
||||
let value = hash.digest('hex');
|
||||
return {
|
||||
passwordHash: value
|
||||
};
|
||||
};
|
||||
userSchema.pre('save', function (next) {
|
||||
let user = this;
|
||||
if (user.isModified('password')) {
|
||||
// salt
|
||||
const ranStr = function (n) {
|
||||
return crypto.randomBytes(Math.ceil(8))
|
||||
.toString('hex')
|
||||
.slice(0, n);
|
||||
};
|
||||
// applying sha512 alogrithm
|
||||
let salt = ranStr(16);
|
||||
let passwordData = sha512(user.password, salt);
|
||||
user.password = passwordData.passwordHash;
|
||||
user.salt = salt;
|
||||
next();
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
})
|
||||
userSchema.statics.findByCredentials = async function (email, password) {
|
||||
let User = this;
|
||||
const user = await User.findOne({ email, loginDomain:'system' })
|
||||
if (!user) return ''
|
||||
let passwordData = sha512(password, user.salt)
|
||||
if (passwordData.passwordHash == user.password) {
|
||||
return user
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = mongoose.model("user", userSchema);
|
||||
20
server/models/WishList.js
Normal file
20
server/models/WishList.js
Normal file
@@ -0,0 +1,20 @@
|
||||
const mongoose = require('mongoose');
|
||||
const Schema = mongoose.Schema;
|
||||
const wishSchema = mongoose.Schema({
|
||||
user: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: 'user'
|
||||
},
|
||||
product: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: 'product'
|
||||
},
|
||||
quantity: {
|
||||
type: Number,
|
||||
},
|
||||
isDeleted: {
|
||||
type: Date,
|
||||
default: null
|
||||
}
|
||||
}, { timestamps: true });
|
||||
module.exports = mongoose.model('wishlist', wishSchema);
|
||||
18
server/models/minedProduct.js
Normal file
18
server/models/minedProduct.js
Normal file
@@ -0,0 +1,18 @@
|
||||
const mongoose = require("mongoose");
|
||||
const Schema = mongoose.Schema
|
||||
const forYouSchema = new mongoose.Schema({
|
||||
forYou: [{
|
||||
user:{
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: 'user',
|
||||
unique: true
|
||||
},
|
||||
products: [{
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: 'product',
|
||||
unique: true
|
||||
}]
|
||||
}]
|
||||
});
|
||||
|
||||
module.exports = mongoose.model("minedproduct", forYouSchema);
|
||||
92
server/models/orderModel.js
Normal file
92
server/models/orderModel.js
Normal file
@@ -0,0 +1,92 @@
|
||||
const mongoose = require('mongoose');
|
||||
|
||||
const orderSchema = new mongoose.Schema({
|
||||
shippingInfo: {
|
||||
address: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
city: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
state: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
country: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
pincode: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
phoneNo: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
},
|
||||
orderItems: [
|
||||
{
|
||||
name: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
price: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
quantity: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
image: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
product: {
|
||||
type: mongoose.Schema.ObjectId,
|
||||
ref: "Product",
|
||||
required: true
|
||||
},
|
||||
},
|
||||
],
|
||||
user: {
|
||||
type: mongoose.Schema.ObjectId,
|
||||
ref: "User",
|
||||
required: true
|
||||
},
|
||||
paymentInfo: {
|
||||
id: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
status: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
},
|
||||
paidAt: {
|
||||
type: Date,
|
||||
required: true
|
||||
},
|
||||
totalPrice: {
|
||||
type: Number,
|
||||
required: true,
|
||||
default: 0
|
||||
},
|
||||
orderStatus: {
|
||||
type: String,
|
||||
required: true,
|
||||
default: "Processing",
|
||||
},
|
||||
deliveredAt: Date,
|
||||
shippedAt: Date,
|
||||
createdAt: {
|
||||
type: Date,
|
||||
default: Date.now
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = mongoose.model("Order", orderSchema);
|
||||
68
server/models/paymentModel.js
Normal file
68
server/models/paymentModel.js
Normal file
@@ -0,0 +1,68 @@
|
||||
const mongoose = require('mongoose');
|
||||
|
||||
const paymentSchema = new mongoose.Schema({
|
||||
resultInfo: {
|
||||
resultStatus: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
resultCode: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
resultMsg: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
},
|
||||
txnId: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
bankTxnId: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
orderId: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
txnAmount: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
txnType: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
gatewayName: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
bankName: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
mid: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
paymentMode: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
refundAmt: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
txnDate: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
createdAt: {
|
||||
type: Date,
|
||||
default: Date.now
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = mongoose.model("Payment", paymentSchema);
|
||||
122
server/models/productModel.js
Normal file
122
server/models/productModel.js
Normal file
@@ -0,0 +1,122 @@
|
||||
const mongoose = require('mongoose');
|
||||
|
||||
const productSchema = new mongoose.Schema({
|
||||
name: {
|
||||
type: String,
|
||||
required: [true, "Please enter product name"],
|
||||
trim: true
|
||||
},
|
||||
description: {
|
||||
type: String,
|
||||
required: [true, "Please enter product description"]
|
||||
},
|
||||
highlights: [
|
||||
{
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
],
|
||||
specifications: [
|
||||
{
|
||||
title: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
description: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
}
|
||||
],
|
||||
price: {
|
||||
type: Number,
|
||||
required: [true, "Please enter product price"]
|
||||
},
|
||||
cuttedPrice: {
|
||||
type: Number,
|
||||
required: [true, "Please enter cutted price"]
|
||||
},
|
||||
images: [
|
||||
{
|
||||
public_id: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
url: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
}
|
||||
],
|
||||
brand: {
|
||||
name: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
logo: {
|
||||
public_id: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
url: {
|
||||
type: String,
|
||||
required: true,
|
||||
}
|
||||
}
|
||||
},
|
||||
category: {
|
||||
type: String,
|
||||
required: [true, "Please enter product category"]
|
||||
},
|
||||
stock: {
|
||||
type: Number,
|
||||
required: [true, "Please enter product stock"],
|
||||
maxlength: [4, "Stock cannot exceed limit"],
|
||||
default: 1
|
||||
},
|
||||
warranty: {
|
||||
type: Number,
|
||||
default: 1
|
||||
},
|
||||
ratings: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
numOfReviews: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
reviews: [
|
||||
{
|
||||
user: {
|
||||
type: mongoose.Schema.ObjectId,
|
||||
ref: "User",
|
||||
required: true
|
||||
},
|
||||
name: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
rating: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
comment: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
user: {
|
||||
type: mongoose.Schema.ObjectId,
|
||||
ref: "User",
|
||||
required: true
|
||||
},
|
||||
createdAt: {
|
||||
type: Date,
|
||||
default: Date.now
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = mongoose.model('Product', productSchema);
|
||||
78
server/models/userModel.js
Normal file
78
server/models/userModel.js
Normal file
@@ -0,0 +1,78 @@
|
||||
const mongoose = require('mongoose');
|
||||
const validator = require('validator');
|
||||
const bcrypt = require('bcryptjs');
|
||||
const jwt = require('jsonwebtoken');
|
||||
const crypto = require('crypto');
|
||||
|
||||
const userSchema = new mongoose.Schema({
|
||||
name: {
|
||||
type: String,
|
||||
required: [true, "Please Enter Your Name"],
|
||||
},
|
||||
email: {
|
||||
type: String,
|
||||
required: [true, "Please Enter Your Email"],
|
||||
unique: true,
|
||||
},
|
||||
gender: {
|
||||
type: String,
|
||||
required: [true, "Please Enter Gender"]
|
||||
},
|
||||
password: {
|
||||
type: String,
|
||||
required: [true, "Please Enter Your Password"],
|
||||
minLength: [8, "Password should have atleast 8 chars"],
|
||||
select: false,
|
||||
},
|
||||
avatar: {
|
||||
public_id: {
|
||||
type: String,
|
||||
},
|
||||
url: {
|
||||
type: String,
|
||||
}
|
||||
},
|
||||
role: {
|
||||
type: String,
|
||||
default: "user",
|
||||
},
|
||||
createdAt: {
|
||||
type: Date,
|
||||
default: Date.now,
|
||||
},
|
||||
resetPasswordToken: String,
|
||||
resetPasswordExpire: Date,
|
||||
});
|
||||
|
||||
userSchema.pre("save", async function (next) {
|
||||
|
||||
if (!this.isModified("password")) {
|
||||
next();
|
||||
}
|
||||
|
||||
this.password = await bcrypt.hash(this.password, 10);
|
||||
});
|
||||
|
||||
userSchema.methods.getJWTToken = function () {
|
||||
return jwt.sign({ id: this._id }, process.env.JWT_SECRET, {
|
||||
expiresIn: process.env.JWT_EXPIRE
|
||||
});
|
||||
}
|
||||
|
||||
userSchema.methods.comparePassword = async function (enteredPassword) {
|
||||
return await bcrypt.compare(enteredPassword, this.password);
|
||||
}
|
||||
|
||||
userSchema.methods.getResetPasswordToken = async function () {
|
||||
|
||||
// generate token
|
||||
const resetToken = crypto.randomBytes(20).toString("hex");
|
||||
|
||||
// generate hash token and add to db
|
||||
this.resetPasswordToken = crypto.createHash("sha256").update(resetToken).digest("hex");
|
||||
this.resetPasswordExpire = Date.now() + 15 * 60 * 1000;
|
||||
|
||||
return resetToken;
|
||||
}
|
||||
|
||||
module.exports = mongoose.model('User', userSchema);
|
||||
Reference in New Issue
Block a user