-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest.js
More file actions
128 lines (115 loc) · 3.1 KB
/
test.js
File metadata and controls
128 lines (115 loc) · 3.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
const mongoose = require("mongoose");
const crypto = require("crypto");
const validator = require("validator");
const bcrypt = require("bcryptjs");
const userSchema = new mongoose.Schema(
{
name: {
type: String,
required: [true, "Please tell us you name"],
trim: true,
maxlength: [40, "User name must be bellow 40 characters."],
minlength: [3, "User name must be above 3 characters."],
unique: true,
},
email: {
type: String,
required: [true, "Please tell us your email"],
validate: [validator.isEmail, "Please provide a valid email"],
trim: true,
unique: true,
lowercase: true,
},
password: {
type: String,
select: false,
required: [true, "Please provide a password"],
trim: true,
minlength: [8, "The password needs to be greater than 8 characters"],
},
passwordConfirm: {
type: String,
required: [true, "Please confirm your password"],
validate: {
validator: function (val) {
return val === this.password;
},
message: "The passwords doesn´t match",
},
trim: true,
},
photo: {
type: String,
default: "default.jpg",
},
role: {
type: String,
default: "student",
enum: ["student", "teacher", "admin"],
},
passwordChangedAt: Date,
passwordResetToken: String,
passwordResetExpires: Date,
active: {
default: "true",
type: Boolean,
select: false,
},
},
{ toJSON: { virtuals: true }, toObject: { virtuals: true } }
);
// Document middlewares:
userSchema.pre("save", async function (next) {
if (!this.isModified("password")) return next;
this.password = await bcrypt.hash(this.password, 10);
this.passwordConfirm = undefined;
next();
});
userSchema.pre("save", function (next) {
if (!this.isModified("password") || this.isNew) return next();
this.passwordChangedAt = Date.now() - 1000;
next();
});
userSchema.pre(/^find/, function (next) {
this.find({ active: { $ne: false } });
next();
});
// Virtual Populate
userSchema.virtual("courses", {
ref: "CourseMerge",
localField: "_id",
foreignField: "students",
});
userSchema.virtual("createdCourses", {
ref: "CourseMerge",
localField: "_id",
foreignField: "professor",
});
// Instance methods:
userSchema.methods.correctPassword = async function (
candidatePassword,
userPassword
) {
return await bcrypt.compare(candidatePassword, userPassword);
};
userSchema.methods.changedPasswordAfter = function (JWTTimestamp) {
if (this.passwordChangedAt) {
const changedTimestamp = parseInt(
this.passwordChangedAt.getTime() / 1000,
10
);
return JWTTimestamp < changedTimestamp;
}
return false;
};
userSchema.methods.createPasswordResetToken = function () {
const resetToken = crypto.randomBytes(32).toString("hex");
this.passwordResetToken = crypto
.createHash("sha256")
.update(resetToken)
.digest("hex");
this.passwordResetExpires = Date.now() + 10 * 60 * 1000;
return resetToken;
};
const User = mongoose.model("User", userSchema);
module.exports = User;