Skip to content

Latest commit

 

History

History
721 lines (605 loc) · 54.6 KB

File metadata and controls

721 lines (605 loc) · 54.6 KB

Модели

Модели формируют схему данных, которые заполняются, изменяются или извлекаются из базы данных. Согласно паттерну MVC доступ к моделям имеют или простые контроллеры или контроллеры с подключением промежуточных обработчиков.

⬅️ Подробную информацию обо всех контроллерах смотреть в разделе Контроллеры
⬅️ Подробную информацию обо всех промежуточных обработчиках смотреть в разделе Промежуточные обработчики)
↩️ К оглавлению документации

Оглавление раздела

Структура моделей

Каждая модель интегрируется в соответствующие контроллеры, связанные с запросами к конкретной модели. Каждая модель при этом - это экземпляр объекта Schema библиотеки mongoose, которая описывает все параметры сущностей, такие как пользователи или товары. Исходя из этих параметров, определяются и строятся зависимости между моделями, а так же перечень свойств самой модели.

⬆️ К оглавлению раздела "Модели"
↩️ К оглавлению документации

Таблица всех моделей

Ниже представлены все модели которые применяются в приложении:

Модель Предназначение
course Структура сущности одного курса
order Структура сущности одного заказа
user Структура сущности одного уникального пользователя

⬆️ К оглавлению раздела "Модели"
↩️ К оглавлению документации

Модель "Course"

Модель курса Сourse используется для создания, редактирования, обновления или удаление одного курса. Поскольку в дальнейшем права на редактирование курса сможет лишь только тот пользователь, который его создал, то модель курса Course предполагает связывание с моделью пользователя User для привязки конкретного курса к определенному пользователю.

Схема курса Course:

const {Schema, model} = require('mongoose')

const courseSchema = new Schema({
  title: {
    type: String,
    required: true
  },
  price: {
    type: Number,
    required: true
  },
  img: String,
  userId: {
    type: Schema.Types.ObjectId,
    ref: 'User'
  }
})

module.exports = model('Course', courseSchema)

Где:

  • Schema, model - получение с помощью деструктуризации объекта схемы Schema и объект модели model из библиотеки mongoose.
  • new Schema({}) - экземпляр схемы Schema.
  • title - поле заголовка, тип которого определён как строка`type: String, с атрибутом определяющим обязательность наличия заполнености этого поля required: true.
  • price - поле цены, тип которого определено как объект type: Number, с атрибутом определяющим обязательность наличия заполнености этого поля required: true.
  • userId - тип поля ID пользователя,тип которого определён как реферальный ключ type: Schema.Types.ObjectId, а сам ключ ссылается на модель ref: 'User'.

Также модель курса Course наличивает метод, для успешной работы с объектом одного курса. Метод меняет значение уникального ID пользователя _id из базы данных MongoDB на значение ID принимающее cреда разработки Node.js:

courseSchema.method('toClient', function() {
  const course = this.toObject()

  course.id = course._id
  delete course._id

  return course
})

Где:

  • courseSchema.method('toClient', function() {}) - функция-обработчик, изменяющая формат ID _id приходящий из MongoDB в формат ID определяющимся в среде разработки node.js - id.
  • const course = this.toObject() - присваем переменной course объект приходящего курса.
  • course.id course._id - присванием значение ID _id из базы данных - ID id курса.
  • delete course._id - удаляем ID _id курса приходящего из базы данных как ликвидация мусора.

⬆️ К оглавлению раздела "Модели".
↩️ К оглавлению документации.

Реализация модели курса "Course" в контроллерах приложения


Контроллер "Добавить курс" с типом запроса post маршрутизатора '/add'

Контроллер с типом запроса post маршрутизатора '/add' реализовывает создание нового курса. Часть кода контроллера работающий с моделью:

const Course = require('../models/course')
...
  const course = new Course({
    title: req.body.title,
    price: req.body.price,
    img: req.body.img,
    userId: req.user
  })
...

Где:

  • new Course({}) - новый экземпляр модели Course.
  • title: req.body.title - ключ заголовка, который принимает значение заголовка, который приходит в теле объекта запроса req.body.
  • price: req.body.price - ключ цены, который принимает значение цены, который приходит в теле объекта запроса req.body.
  • img: req.body.img - ключ картинки, который принимает значение картинки, который приходит в теле объекта запроса req.body.
  • userId: req.user - ключ пользователя, который принимает значение ID пользователя создавшего курс.

⬅️ Подробнее о данном контролере смотрите Метод запроса post по маршруту '/add'.


Контроллер "Корзина" с типом запроса post маршрутизатора '/card/add'

Контроллер с типом запроса post маршрутизатора '/card/add' реализовывает добавление одного курса в корзину пользователя. Часть кода контроллера работающий с моделью:

const Course = require('../models/course')
...
  const course = await Course.findById(req.body.id)
  await req.user.addToCart(course)
  res.redirect('/card')
})

Где:

  • req.user.addToCart() - функция модели User - addToCart принимающая аргумент - course.
  • res.redirect() - метод redirect объекта ответа response, который перенаправляет пользователя на страницу с маршрутом '/card'.

⬅️ Подробнee о функции addToCart смотрите в разделе Модель "User".
⬅️ Подробнее о данном контролере смотрите Метод запроса post по маршруту '/card/add'.


Контроллер "Курсы" с типом запроса get маршрутизатора '/courses'

Контроллер с типом запроса get маршрутизатора '/courses' реализовывает получение всех курсов на странице "Курсы". Часть кода контроллера работающий с моделью:

const Course = require('../models/course')

...
    const courses = await Course.find()
    .populate('userId', 'email name')
    .select('price title img')
  ...

Где:

  • Course.find() - метод find модели Course, который ищет все курсы из коллекции Course и возвращает эти данные.
  • populate - метод проверяющий, включают ли данные userId и email name после чего возвращает только те документы, в которых наявны userId и email name.
  • select - метод возвращающий только значения ключей: price, title и img.

⬅️ Подробнее о данном контролере смотрите Метод запроса get по маршруту '/courses'.


Контроллер "Курсы" с типом запроса get маршрутизатора '/courses/:id/edit'

Контроллер с типом запроса get маршрутизатора '/courses/:id/edit', реализовывает редактирование одного курса. Часть кода контроллера работающий с моделью:

const Course = require('../models/course')
...
const course = await Course.findById(req.params.id)

  if (course.userId.toString() !== req.user._id.toString()) {
        return res.redirect('/courses')
      }

  res.render('course-edit', {
      title: `Редактировать ${course.title}`,
      course
...

Где:

  • Course.findById() - метод findById модели Course, который ищет курс по входящему запросу с ID req.params.id из коллекции Course и возвращает эти данные.
  • course.userId.toString() !== req.user._id.toString() - проверка, которая сравнивает ID курса с ID пользователя, который создал этот курс.
  • redirect() - метод redirect объекта ответа response перенаправление на страницу с маршрутом '/courses'.
  • res.render('course-edit', {}) - метод render объекта response, который визуализирует данные приходящие из файла course-edit.hbs.
  • course - ключ принимающий одноименное значение, в котором хранится данные одного курса определенного по ID.

⬅️ Подробнее о данном контролере смотрите Метод запроса get по маршруту '/courses/:id/edit'.


Контроллер "Курсы" с типом запроса post маршрутизатора '/courses/edit'

Контроллер с типом запроса post маршрутизатора '/courses/edit' реализовывет отправку отредактируемых данных одного курса. Часть кода контроллера работающий с моделью:

const Course = require('../models/course')
...
const course = await Course.findById(id)
    if (course.userId.toString() !== req.user._id.toString()) {
      res.redirect('/courses')
    }
    Object.assign(course, req.body)
    await course.save()
  ...

Где:

  • Course.findById() - метод findById модели Course, который ищет курс по входящему запросу с ID req.params.id из коллекции Course и возвращает эти данные.
  • course.userId.toString() !== req.user._id.toString() - проверка, которая сравнивает ID курса с ID пользователя, который создал этот курс.
  • redirect() - метод redirect объекта ответа response перенаправление на страницу с маршрутом '/courses'.
  • Object.assign() - метод assign глобального объекта Object, который принимает объект курса course с опредённым ID и коппирует все перечислимые свойста course в целевой объект - req.body.
  • course.save() - метод save объекта course сохраняющий данные в базе данных MongoDB.

⬅️ Подробнее о данном контролере смотрите Метод запроса get по маршруту '/courses/:id/edit'.


Контроллер "Курсы" с типом запроса post маршрутизатора '/courses/delete'

Контроллер с типом запроса post маршрутизатора '/courses/delete' реализовывет удаление одного курса. Часть кода контроллера работающий с моделью:

const Course = require('../models/course')
...
    await Course.deleteOne({
      _id: req.body.id, 
      userId: req.user._id
    })
    res.redirect('/courses')
...

Где:

  • Course.deleteOne({}) - метод deleteOne модели Course, который ищет курс по ID у определенного пользователя. Метод принимает 2 аргумента:
    • _id - значение ID курса сравнивающее значение ID курса в получаемом запросе - req.body.id.
    • userId - значение ID пользователя сравнивающее значение ID пользователя в получаемом запросе - req.user._id.
  • res.redirect() - метод redirect объекта ответа response перенаправление на страницу с маршрутом '/courses'.

⬅️ Подробнее о данном контролере смотрите Метод запроса post по маршруту '/courses/remove'.


Контроллер "Курсы" с типом запроса get маршрутизатора '/courses/:id'

Контроллер с типом запроса post маршрутизатора '/courses/:id' реализовывет получение одного курса. Часть кода контроллера работающий с моделью:

const Course = require('../models/course')
...
  const course = await Course.findById(req.params.id)
    res.render('course', {
      layout: 'empty',
      title: `Курс ${course.title}`,
      course
...

Где:

  • Course.findById(req.params.id) - метод findById модели Course, который ищет курс по входящему запросу с ID req.params.id из коллекции Course и возвращает эти данные.
  • res.render('course', {}) - метод render объекта response, который визуализирует данные приходящие из файла course.hbs.
  • course - ключ принимающий одноименное значение, в котором хранится данные одного курса определённого по ID.

⬅️ Подробнее о данном контролере смотрите Метод запроса post по маршруту '/courses/remove'.
⬆️ К оглавлению раздела "Модели".
↩️ К оглавлению документации.

Модель "Order"

Модель заказа Order используется для формивание и отправки заказов пользователя, которые формируются из товаров, выбранные пользователям в объект корзины.

Схема заказа Order:

const {Schema, model} = require('mongoose')

const orderSchema = new Schema({
  courses: [
    {
      course: {
        type: Object,
        required: true
      },
      count: {
        type: Number,
        required: true
      }
    }
  ],
  user: {
    name: String,
    userId: {
      type: Schema.Types.ObjectId,
      ref: 'User',
      required: true
    }
  },
  date: {
    type: Date,
    default: Date.now
  }
})

module.exports = model('Order', orderSchema)

Где:

  • {Schema, model} - получение с помощью деструктуризации объекта схемы Schema и объект модели model из библиотеки mongoose.
  • new Schema({}) - экземпляр класса Schema.
  • courses: [{}] - поле массива курсов.
  • course - поле курса, тип которого определено как объект type: Object, с атрибутом определяющим обязательность наличия заполнености этого поля required: true.
  • count - поле количества едениц одного курса, тип которого определено как объект type: Number, с атрибутом определяющим обязательность наличия заполнености этого поля required: true.
  • user - тип поля ID пользователя,тип которого определён как реферальный ключ type: Schema.Types.ObjectId, а сам ключ ссылается на модель ref: 'User'.
  • date - поле времени, тип которого определён как специальный объект type: Date, а время определения типа данных date является действенное время на момент создания данных default: Date.now.

⬆️ К оглавлению раздела "Модели".
↩️ К оглавлению документации.

Реализация модели заказа "Order" в контроллерах приложения


Контроллер "Заказы" с типом запроса get маршрутизатора /orders

Контроллер с типом запроса get маршрутизатора /orders реализовывает получение всех заказов пользователя. Часть кода контроллера работающий с моделью:

const Order = require('../models/order')
  ...
    const orders = await Order.find({'user.userId': req.user._id})
      .populate('user.userId')
  ...
  orders: orders.map(o => {
        return {
          ...o._doc,
          price: o.courses.reduce((total, c) => {
            return total += c.count * c.course.price
          }, 0)
        }
      })
  ...

Где:

  • Order.find({}) - метод find модели Order, который находит данные, в которых ID 'user.userId' является таким же как ID запроса req.user._id.
    • user.userId - ID пользователя, который есть в базе данных MongoDB.
    • req.user._id - ID запроса, который приходит с объектом запроса request.
  • populate() - метод проверяющий, включение user.userId в результат.
  • orders: orders.map(o => {}) - ключ принимающий значение результата метода map выражения orders.map(o => {}). Метод возвращает результат разворачивание массива o объекта заказов orders, после чего выполняет тело метода.
  • ...o._doc - метод spread ... результатом которого является развёртывание элемента o в виде простого объекта.
  • o.courses.reduce((total, c) => {}) - метод reduce есть у каждого массива. Метод позволяет свернуть сумму каждого элемента массива в общую сумму.
  • return total += c.count * c.course.price - выражение вычисляющее итоговую сумму с расчёта количество определенного курса умноженное на стоимость этого курса.
    • c.price - цена курса.
    • c.count - количество курсов покупаемых пользователем.

⬅️ Подробнее о данном контролере смотрите Метод запроса get по маршруту '/orders'.


Контроллер "Заказы" с типом запроса post маршрутизатора '/orders'

Контроллер с типом запроса post маршрутизатора /orders реализовывает формирование и отправку одного заказа, с массивом курсов, пользователю. Часть кода контроллера работающий с моделью:

const Order = require('../models/order')
  ...
  const order = new Order({
      user: {
        name: req.user.name,
        userId: req.user
      },
      courses: courses
    })
  ...
  await order.save()
...

Где:

  • const order = new Order({}) - order экземпляр объекта Order, в тело которого включены все свойства объекта Order.
  • user: {} - объект пользователя входящий в объект заказа Order.
    • name - ключ принимающий значение запроса имени пользователя req.user.name.
    • userId - ключ принимающий значение запроса ID пользователя req.user.
  • courses - ключ принимающий одноименный массив курсов courses.
  • order.save() - метод save объекта order сохраняющий данные в базе данных MongoDB.

⬅️ Подробнее о данном контролере смотрите Метод запроса post по маршруту '/orders'.
⬆️ К оглавлению раздела "Модели".
↩️ К оглавлению документации.

Модель "User"

Модель пользователя User используется для обработки прав доступа к курсам, формирования, привязки и сохраненние определёных данных, таких как история заказов, курсы покупаемые пользователем или же сформированый блок корзины за конкретным пользователям.

Схема пользователя User:

const {Schema, model} = require('mongoose')

const userSchema = new Schema({
  email: {
    type: String,
    required: true
  },
  name: String,
  password: {
    type: String,
    required: true
  },
  avatarUrl: String,
  resetToken: String,
  resetTokenExp: Date,
  cart: {
    items: [
      {
        count: {
          type: Number,
          required: true,
          default: 1
        },
        courseId: {
          type: Schema.Types.ObjectId,
          ref: 'Course',
          required: true
        }
      }
    ]
  }
})

module.exports = model('User', userSchema)

Где:

  • {Schema, model} - получение с помощью деструктуризации объекта схемы Schema и объект модели model из библиотеки mongoose.
  • new Schema({}) - экземпляр класса Schema.
  • email: {} - поле email, тип которого определён как строка type: String, с атрибутом определяющим обязательность наличия заполнености этого поля required: true.
  • name - поле имени, тип которого определён как строка type: String.
  • password - поле пароля, тип которого определён как строка type: String, с атрибутом определяющим обязательность наличия заполнености этого поля required: true.
  • avatarUrl - поле пути аватара пользователя, тип которого определён как строка type: String.
  • resetToken - поле токена, для сброса пароля, тип которого определён как строка type: String.
  • resetTokenExp - поле определяющий срок годности токена, тип которого определён как специальный объект type: Date.
  • cart:{} - поле объекта с массивом курсов.
  • items: [{}] - поле с массивом курсов.
  • count: {} - поле количества едениц одного курса, тип которого определено как число type: Number, с атрибутом определяющим обязательность наличия заполнености этого поля required: true, и который по умолчанию имеет значение default: 1`.
  • courseId: {} - тип поля ID курса, тип которого определён как реферальный ключ type: Schema.Types.ObjectId, а сам ключ ссылается на модель ref: 'Course'.

Также модель пользователя User наличивает методы, для различных задач работы с моделью User. Модель наличивает следующие методы:

  • addToCart - метод добавляющий курсы в массив корзины пользователя.
  • removeFromCart - метод удаляющий курс из массива корзины.
  • clearCart - метод очищающий корзину пользователя после сформирование и отправки заказа пользователя.

Функция addToCart:

userSchema.methods.addToCart = function(course) {
  const items = [...this.cart.items]
  const idx = items.findIndex(c => {
    return c.courseId.toString() === course._id.toString()
  })

  if (idx >= 0) {
    items[idx].count = items[idx].count + 1
  } else {
    items.push({
      courseId: course._id,
      count: 1
    })
  }

  this.cart = {items}
  return this.save()
}

Где:

  • userSchema.methods.addToCart - метод methods, который есть у каждой схемы Schema в том числе и userSchema позволяющий создать метод для конкретной схемы. Название метода указывается после точки: .addToCart.
  • function(course) {} - функция принимающая объект курса course.
  • const items = [...this.cart.items] - метод spread ... результатом которого является развёртывание всех данных из массива items вложенного в объект cart, который передаётся контекстом this, где this это получаемый функцией курс course.
  • const idx = items.findIndex(c => {}) - метод findIndex возвращает индексированый элемент массива после чего обрабатывает его в теле функции.
  • return c.courseId.toString() === course._id.toString() - возвращает значение ID приведенного к строке course._id.toString() и приводит строгое сравнение с ID курсом запроса c.courseId.toString().
  • if (idx >= 0) {} - условие, которое выполняется, если элемент больше или равен 0.
  • items[idx].count = items[idx].count + 1 - элемент по индексу idx, который увеличивается на 1 количество определенного курса в массиве items.
  • items.push({}) - метод push добавляющий вконец списка тело объекта, состоящие из 2 ключей: courseId и count.
  • courseId - ключ принимающий значение ID course._id. ID с нижним подчёркиванием _id является уникальными идентификаторами в базе данных MongoDB.
  • count - ключ принимающий значение количества одного курса в количестве - 1.
  • this.cart - ключ переопределяющий значение объекта {items}, как новый объект контекста корзины, где this.cart является равным записи course.cart.
  • return this.save() - метод save сохроняет состояние корзины в базе данных у модели User, а именно оновленный массив в поле cart = [] модели User после чего return возвращает сохранённое значение как результат выполнения функции.

Функция removeFromCart:

userSchema.methods.removeFromCart = function(id) {
  let items = [...this.cart.items]
  const idx = items.findIndex(c => c.courseId.toString() === id.toString())

  if (items[idx].count === 1) {
    items = items.filter(c => c.courseId.toString() !== id.toString())
  } else {
    items[idx].count--
  }

  this.cart = {items}
  return this.save()
}

Где:

  • userSchema.methods.removeFromCart - метод methods, который есть у каждой схемы Schema в том числе и userSchema позволяющий создать метод для конкретной схемы. Название метода указывается после точки: .removeFromCart.
  • function() - функция принимающая ID запроса req.user.id, который принимается аргументов id функции.
  • let items = [...this.cart.items] - метод spread ... результатом которого является развёртывание всех данных из массива items вложенного в объект cart, который передаётся контекстом this, где this это получаемый функцией курс course.
  • const idx = items.findIndex(c => c.courseId.toString() === id.toString()) - возвращает индексируемый єлемент массива после чего сравнивает приведенный к строке ID объекта с и сравнивает строгим сравнением с ID запроса request, который также приводится к строке. Уникальный ID является и так строкой, но во избежания ошибок, принимается явное преобразование ID в строку.
  • if (items[idx].count === 1) {} - условие при котором индексированный элемент idx в массиве items находится в количестве 1, то выполнится тело условия.
  • items = items.filter(c => c.courseId.toString() !== id.toString()) - метод filter перебирает элементы массива c и создаёт новый массив в который отбирает те элементы c, где ID курса не равняется ID курса находиящийся в запросе req.user.id.
  • items[idx].count-- - производит декремент (уменьшает значение на 1) у свойства count элемента idx массива items.
  • this.cart - ключ переопределяющий значение объекта {items}, как новый объект контекста корзины, где this.cart является аналогичным записи course.cart.
  • return this.save() - метод save сохроняет состояние корзины в базе данных у модели User, а именно оновленный массив в поле cart = [] модели User после чего return возвращает сохранённое значение как результат выполнения функции.

Функции clearCart:

userSchema.methods.clearCart = function() {
  this.cart = {items: []}
  return this.save()
}

Где:

  • userSchema.methods.clearCart - метод methods, который есть у каждой схемы Schema в том числе и userSchema позволяющий создать метод для конкретной схемы. Название метода указывается после точки: .clearCart.
  • function() {} - функция не принимающая никаких аргументов.
  • this.cart - {items: []} переопределение массива items пустого значение массива в объекте this.cart, где this.cart аналогично user.cart.
  • return this.save() - возврат сохранённого результата в базе данных MongoDB массива cart модели user.

⬆️ К оглавлению раздела "Модели".
↩️ К оглавлению документации.

Реализация модели заказа "User" в контроллерах приложения


Контроллер "Профиль" с типом запроса post маршрутизатора '/profile'

Контроллер с типом запроса post маршрутизатора '/profile' реализовывает сохранение новых данных пользователя. Часть кода контроллера работающий с моделью:

const User = require('../models/user')
...
    const user = await User.findById(req.user._id)
    Object.assign(user, toChange)
    await user.save()
...

Где:

  • User.findById() - метод findById модели User, который ищет пользователя по входящему запросу с ID req.user._id из коллекции User и возвращает эти данные.
  • Object.assign() - метод assign глобального объекта Object, который включает данные документа user, которые подставляются в целевой объект toChange и который принимает два аргумента:
    • user - объект пользователя найденого в базе данных по ID пользователя.
    • toChange - объект, внутри которого определны ряд клюей пользователя в том числе, name, который принимает значение req.body.name.
  • user.save() - метод save объекта user сохраняющий данные в базе данных MongoDB.

⬅️ Подробнее о данном контролере смотрите Метод запроса post по маршруту '/auth/password'.


Контроллер "Авторизация" с типом запроса post маршрутизатора '/auth/login'

Контроллер с типом запроса post маршрутизатора '/auth/login' реализовывает получение доступа, если пользователь зарегестрирован. Часть кода контроллера работающий с моделью:

const User = require('../models/user')
...
    const candidate = await User.findOne({ email })

    if (candidate) {
          const areSame = await bcrypt.compare(password, candidate.password)
    if (areSame) {
        req.session.user = candidate
        req.session.isAuthenticated = true
        req.session.save(err => {
    ...

Где:

  • User.findOne({ email }) - метод findOne модели User, который ищет первый объект по значению одноименного ключа email.
  • bcrypt.compare(password, candidate.password) - метод compare библиотеки bcrypt, который проверяет пароль пользователя с паролем пользователя полученного запросом от базы данных MongoDB.
  • req.session.user - свойство пользователя user в обЪекте сессии session, которой присваиваются данные авторизированного пользователя candidate.
  • req.session.isAuthenticated - свойство авторизации isAuthenticated, объекта сессии session, которое принимает boolean значение true, что определяет активность сессии.
  • req.session.save(err => {}) - функция save сохраняющая состояние сессии session.

⬅️ Подробнее о данном контролере смотрите Метод запроса post по маршруту '/auth/login'.


Контроллер "Авторизация" с типом запроса post маршрутизатора '/auth/register'

Контроллер с типом запроса post маршрутизатора '/auth/register' реализовывает регистрацию пользователя. Часть кода контроллера работающий с моделью:

const User = require('../models/user')
...
    const user = new User({
        email, name, password: hashPassword, cart: {items: []}
      })
      await user.save()
    ...

Где:

  • const user = new User({}) - создание нового экземпляра объекта User, которому присваиваются свойства указаны в теле экземпляра объекта.
  • email, name, password: hashPassword, cart: {items: []} - перечень как одноименных свойств ключ-значение(к примеру email) так и разноименных password: hashPassword.
  • user.save() - метод save объекта course сохраняющий данные в базе данных MongoDB.

⬅️ Подробнее о данном контролере смотрите Метод запроса post по маршруту '/auth/register'.


Контроллер "Авторизация" с типом запроса post маршрутизатора '/auth/password/:token'

Контроллер с типом запроса post маршрутизатора '/auth/password/:token' реализовывает сброс пароля пользователя. Часть кода контроллера работающий с моделью:

const User = require('../models/user')
...
  const user = await User.findOne({
      resetToken: req.params.token,
      resetTokenExp: {$gt: Date.now()}
    })
...

Где:

  • User.findOne({}) - метод findOne модели User, который ищет первый объект который подпадает под выполнение условий, заложених в тело метода.
  • resetToken - ключ-условие, которое заложено в тело метода и которое сравнивает resetToken с токеном req.params.token, который приходит с телом запроса request.
  • resetTokenExp - ключ-условие, которое заложено в тело метода и которое сравнивает с помощью оператора $gt не привышает ли срок токена больше, чем время в которое выполняется запрос {Date.now()}.

⬅️ Подробнее о данном контролере смотрите Метод запроса get по маршруту '/auth/password/:token'.


Контроллер "Авторизация" с типом запроса post маршрутизатора '/auth/reset'

Контроллер с типом запроса post маршрутизатора '/auth/reset' реализовывает смену пароля. Часть кода контроллера работающий с моделью:

const User = require('../models/user')
...
const candidate = await User.findOne({email: req.body.email})
    if (candidate) {
        candidate.resetToken = token
        candidate.resetTokenExp = Date.now() + 60 * 60 * 1000
        await candidate.save()
    ...

Где:

  • User.findOne({email: req.body.email}) - метод findOne модели User, который сравнивает почту пользвателя email с почтой отправленой в теле запроса req.body.email.
  • candidate - объект пользователя найденный методом findOne из модели User.
  • candidate.resetToken - присвание свойству resetTokent объекта candidate значение временного токена token.
  • candidate.resetTokenExp - присвание свойству resetTokenExp объекта candidate значение срока жизни токена - Date.now() + 60 * 60 * 1000.
  • candidate.save() - метод save сохраняющий объект пользователя candidate в базе данных.

⬅️ Подробнее о данном контролере смотрите Метод запроса post по маршруту '/auth/reset'.


Контроллер "Авторизация" с типом запроса post маршрутизатора '/auth/password'

Контроллер с типом запроса post маршрутизатора '/auth/password' реализовывает сохранение нового пароля пользователя. Часть кода контроллера работающий с моделью:

    const user = await User.findOne({
        _id: req.body.userId,
        resetToken: req.body.token,
        resetTokenExp: {$gt: Date.now()}
    ...
    if (user) {
        user.password = await bcrypt.hash(req.body.password, 10)
        user.resetToken = undefined
        user.resetTokenExp = undefined
        await user.save()
    ...

Где:

  • User.findOne({}) - метод findOne модели User, который ищет первый объект который подпадает под выполнение условий, заложених в тело метода.
  • _id - ключ принимающий значение ID пользователя приходящий в теле запроса req.body.userId.
  • resetToken - ключ-условие, которое заложено в тело метода и которое сравнивает resetToken с токеном req.body.token, который приходит с телом запроса request.
  • resetTokenExp - ключ-условие, которое заложено в тело метода и которое сравнивает с помощью оператора $gt не привышает ли срок токена больше, чем время в которое выполняется запрос {Date.now()}.
  • bcrypt.hash(req.body.password, 10) - метод hash объекта bcrypt, который шифрует пароля, приходящий в запросе req.body.password в количестве - 10 символов.
  • user.resetToken - переопределение свойства resetToken объекта user на значение - undefined.
  • user.resetTokenExp - переопределение свойства resetTokenExp объекта user на значение - undefined.
  • user.save() - метод save сохраняющий объект пользователя user в базе данных.

⬅️ Подробнее о данном контролере смотрите Метод запроса post по маршруту '/auth/password'.


Реализация модели заказа "User" в промежуточных обработчиках приложения


Промежуточный обработчик registerValidators

Промежуточный обработчик registerValidators валидирует данные при регистрации нового пользователя. Часть кода промежуточного обработчика работающий с моделью:

const User = require('../models/user')
...
    const user = await User.findOne({email: value})
        if (user) {
            ...
        }
...

Где:

  • User.findOne({}) - метод findOne модели User, который ищет первый объект который подпадает под выполнение условия email: value.
  • if (user) {} - условие, которое срабатывает, если объёкт user был найден.

Промежуточный обработчик userMiddleware

Промежуточный обработчик userMiddleware проверяет наличие сессии авторизированного пользователя. Часть кода промежуточного обработчика работающий с моделью:

const User = require('../models/user')
...
    req.user = await User.findById(req.session.user._id)
    next()
...

Где:

  • User.findById() - метод findById модели User, который выдаёт результат найденного ID пользователя req.session.user._id в теле запроса req.session.

⬆️ К оглавлению раздела "Модели"
↩️ К оглавлению документации