const mongoose = require("mongoose") const bcrypt = require('bcryptjs') const {nanoid} = require('nanoid') const userResponse = u => ({_id: u._id, email: u.email, isVerified: u.isVerified, noteList: u.noteList}) const userSchema = new mongoose.Schema({ email: { type: String, trim: true, lowercase: true, unique: true, required: true, minlength: 6, maxlength: 255, validate(value) { if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)) { throw new Error('Wrong email address') } } }, password: { type: String, required: true, minlength: 6, maxlength: 1024, }, isVerified: { type: Boolean, default: false, }, verificationKey: { type: String, default: () => nanoid(6), }, noteList: { type: mongoose.Schema.Types.ObjectId, ref: "NoteList", required: true, }, created_at: {type: Date, default: Date.now}, updated_at: {type: Date, default: Date.now} }) userSchema.statics.findByCredentials = async function (email, password){ const user = await User.findOne({email}) if (!user) { throw new Error('Unable to login') } const isMatch = await bcrypt.compare(password, user.password) if (!isMatch) { throw new Error('Unable to login') } return userResponse(user) } userSchema.statics.getVerificationKey = async function (email){ const {verificationKey: key} = await User.findOne({email}) if (!key) { throw new Error('Could not verify user') } return key } userSchema.statics.verifyUser = async function (_id, key){ const user = await User.findOneAndUpdate({_id, verificationKey: key}, {isVerified: true, verificationKey: nanoid(10)}, {new: true}) if (!user) { throw new Error('Could not verify user') } return userResponse(user) } userSchema.statics.state = async function (_id){ const user = await User.findOne({_id}) if (!user) { return {isLoggedIn: false} } else if (!user.isVerified) { return {isVerified: false} } return {} } userSchema.pre('save', async function(next){ const user = this; if (user.isModified('password')) { user.password = await bcrypt.hash(user.password, 8); } next() }) const User = mongoose.models.User || mongoose.model('User', userSchema) export default User