]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blobdiff - server/models/user.js
Update README features
[github/Chocobozzz/PeerTube.git] / server / models / user.js
index c9c35b3e2dffc0c06cbe6d35f379135998aae583..e64bab8abc54061778968453e6a7ff0caff71e84 100644 (file)
-const mongoose = require('mongoose')
+'use strict'
+
+const values = require('lodash/values')
 
-const customUsersValidators = require('../helpers/custom-validators').users
 const modelUtils = require('./utils')
+const constants = require('../initializers/constants')
+const peertubeCrypto = require('../helpers/peertube-crypto')
+const customUsersValidators = require('../helpers/custom-validators').users
 
 // ---------------------------------------------------------------------------
 
-const UserSchema = mongoose.Schema({
-  createdDate: {
-    type: Date,
-    default: Date.now
-  },
-  password: String,
-  username: String,
-  role: String
-})
-
-UserSchema.path('password').required(customUsersValidators.isUserPasswordValid)
-UserSchema.path('username').required(customUsersValidators.isUserUsernameValid)
-UserSchema.path('role').validate(customUsersValidators.isUserRoleValid)
-
-UserSchema.methods = {
-  toFormatedJSON: toFormatedJSON
+module.exports = function (sequelize, DataTypes) {
+  const User = sequelize.define('User',
+    {
+      password: {
+        type: DataTypes.STRING,
+        allowNull: false,
+        validate: {
+          passwordValid: function (value) {
+            const res = customUsersValidators.isUserPasswordValid(value)
+            if (res === false) throw new Error('Password not valid.')
+          }
+        }
+      },
+      username: {
+        type: DataTypes.STRING,
+        allowNull: false,
+        validate: {
+          usernameValid: function (value) {
+            const res = customUsersValidators.isUserUsernameValid(value)
+            if (res === false) throw new Error('Username not valid.')
+          }
+        }
+      },
+      email: {
+        type: DataTypes.STRING(400),
+        allowNull: false,
+        validate: {
+          isEmail: true
+        }
+      },
+      displayNSFW: {
+        type: DataTypes.BOOLEAN,
+        allowNull: false,
+        defaultValue: false,
+        validate: {
+          nsfwValid: function (value) {
+            const res = customUsersValidators.isUserDisplayNSFWValid(value)
+            if (res === false) throw new Error('Display NSFW is not valid.')
+          }
+        }
+      },
+      role: {
+        type: DataTypes.ENUM(values(constants.USER_ROLES)),
+        allowNull: false
+      }
+    },
+    {
+      indexes: [
+        {
+          fields: [ 'username' ],
+          unique: true
+        },
+        {
+          fields: [ 'email' ],
+          unique: true
+        }
+      ],
+      classMethods: {
+        associate,
+
+        countTotal,
+        getByUsername,
+        list,
+        listForApi,
+        loadById,
+        loadByUsername,
+        loadByUsernameOrEmail
+      },
+      instanceMethods: {
+        isPasswordMatch,
+        toFormatedJSON
+      },
+      hooks: {
+        beforeCreate: beforeCreateOrUpdate,
+        beforeUpdate: beforeCreateOrUpdate
+      }
+    }
+  )
+
+  return User
 }
 
-UserSchema.statics = {
-  countTotal: countTotal,
-  getByUsernameAndPassword: getByUsernameAndPassword,
-  listForApi: listForApi,
-  loadById: loadById,
-  loadByUsername: loadByUsername
+function beforeCreateOrUpdate (user, options, next) {
+  peertubeCrypto.cryptPassword(user.password, function (err, hash) {
+    if (err) return next(err)
+
+    user.password = hash
+
+    return next()
+  })
 }
 
-mongoose.model('User', UserSchema)
+// ------------------------------ METHODS ------------------------------
 
-// ---------------------------------------------------------------------------
+function isPasswordMatch (password, callback) {
+  return peertubeCrypto.comparePassword(password, this.password, callback)
+}
+
+function toFormatedJSON () {
+  return {
+    id: this.id,
+    username: this.username,
+    email: this.email,
+    displayNSFW: this.displayNSFW,
+    role: this.role,
+    createdAt: this.createdAt
+  }
+}
+// ------------------------------ STATICS ------------------------------
+
+function associate (models) {
+  this.hasOne(models.Author, {
+    foreignKey: 'userId',
+    onDelete: 'cascade'
+  })
+
+  this.hasMany(models.OAuthToken, {
+    foreignKey: 'userId',
+    onDelete: 'cascade'
+  })
+}
 
 function countTotal (callback) {
-  return this.count(callback)
+  return this.count().asCallback(callback)
+}
+
+function getByUsername (username) {
+  const query = {
+    where: {
+      username: username
+    }
+  }
+
+  return this.findOne(query)
 }
 
-function getByUsernameAndPassword (username, password) {
-  return this.findOne({ username: username, password: password })
+function list (callback) {
+  return this.find().asCallback(callback)
 }
 
 function listForApi (start, count, sort, callback) {
-  const query = {}
-  return modelUtils.listForApiWithCount.call(this, query, start, count, sort, callback)
+  const query = {
+    offset: start,
+    limit: count,
+    order: [ modelUtils.getSort(sort) ]
+  }
+
+  return this.findAndCountAll(query).asCallback(function (err, result) {
+    if (err) return callback(err)
+
+    return callback(null, result.rows, result.count)
+  })
 }
 
 function loadById (id, callback) {
-  return this.findById(idcallback)
+  return this.findById(id).asCallback(callback)
 }
 
 function loadByUsername (username, callback) {
-  return this.findOne({ username: username }, callback)
+  const query = {
+    where: {
+      username: username
+    }
+  }
+
+  return this.findOne(query).asCallback(callback)
 }
 
-function toFormatedJSON () {
-  return {
-    id: this._id,
-    username: this.username,
-    role: this.role
+function loadByUsernameOrEmail (username, email, callback) {
+  const query = {
+    where: {
+      $or: [ { username }, { email } ]
+    }
   }
+
+  return this.findOne(query).asCallback(callback)
 }