123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- import { Schema, model, Model, models } from 'mongoose';
- import {
- hashPassword,
- verifyPassword,
- } from '../utils/helpers/hashPasswordHelpers';
- import { IUser } from '../utils/interface/userInterface';
- const validator = require('validator');
-
- interface UserModel extends Model<IUser, {}, {}> {
- findByCredentials(username: string, password: string): object;
- }
-
- const UserSchema = new Schema<IUser, UserModel>(
- {
- fullName: {
- type: String,
- required: [true, 'Please provide a name.'],
- maxlength: [60, 'Name cannot be more than 60 characters'],
- trim: true,
- },
- username: {
- type: String,
- required: [true, 'Please provide an username.'],
- unique: true,
- maxlength: [60, 'Name cannot be more than 60 characters'],
- trim: true,
- },
- email: {
- type: String,
- unique: true,
- required: [true, 'Please provide an email.'],
- trim: true,
- lowercase: true,
- validate(value: string) {
- if (!validator.isEmail(value)) {
- throw new Error('Email is invalid');
- }
- },
- },
- password: {
- type: String,
- required: [true, 'Please provide a password.'],
- minlength: 7,
- trim: true,
- validate(value: string) {
- if (value.toLowerCase().includes('password')) {
- throw new Error('Password cannot contain "password"');
- }
- },
- },
- country: {
- type: String,
- required: [true, 'Please provide a country.'],
- trim: true,
- },
- city: {
- type: String,
- required: [true, 'Please provide a city.'],
- trim: true,
- },
- address: {
- type: String,
- required: [true, 'Please provide an address.'],
- trim: true,
- },
- address2: {
- type: String,
- trim: true,
- },
- postcode: {
- type: String,
- required: [true, 'Please provide a postal code.'],
- },
- },
- {
- toJSON: { virtuals: true }, // So `res.json()` and other `JSON.stringify()` functions include virtuals
- toObject: { virtuals: true }, // So `console.log()` and other functions that use `toObject()` include virtuals
- }
- );
-
- UserSchema.virtual('orders', {
- ref: 'Order',
- localField: '_id',
- foreignField: 'owner',
- });
-
- UserSchema.static(
- 'findByCredentials',
- async function findByCredentials(username: string, password: string) {
- const user = await User.findOne({ username });
-
- if (!user) {
- throw new Error('Unable to login');
- }
-
- const isMatch = await verifyPassword(password, user.password);
-
- if (!isMatch) {
- throw new Error('Unable to login');
- }
-
- const userData = {
- fullName: user.fullName,
- email: user.email,
- address: user.address,
- address2: user.address2,
- city: user.city,
- country: user.country,
- postcode: user.postcode,
- orders: user.orders,
- _id: user._id,
- };
- return userData;
- }
- );
-
- UserSchema.pre('save', async function (next) {
- const user = this;
-
- if (user.isModified('password')) {
- user.password = await hashPassword(user.password);
- }
-
- next();
- });
-
- const User = models.User || model<IUser, UserModel>('User', UserSchema, 'User');
- module.exports = User;
|