]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blobdiff - server/models/user.js
Server: add unique to unique indexes
[github/Chocobozzz/PeerTube.git] / server / models / user.js
index 130b49b55268cbc4d60705d3081a61a665aef83d..6cb9eec3fd435ba247061e24194b764c34722796 100644 (file)
-const mongoose = require('mongoose')
+'use strict'
+
+const values = require('lodash/values')
+
+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({
-  password: String,
-  username: String
-})
+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.')
+          }
+        }
+      },
+      role: {
+        type: DataTypes.ENUM(values(constants.USER_ROLES)),
+        allowNull: false
+      }
+    },
+    {
+      indexes: [
+        {
+          fields: [ 'username' ],
+          unique: true
+        }
+      ],
+      classMethods: {
+        associate,
 
-UserSchema.path('password').required(true)
-UserSchema.path('username').required(true)
+        countTotal,
+        getByUsername,
+        list,
+        listForApi,
+        loadById,
+        loadByUsername
+      },
+      instanceMethods: {
+        isPasswordMatch,
+        toFormatedJSON
+      },
+      hooks: {
+        beforeCreate: beforeCreateOrUpdate,
+        beforeUpdate: beforeCreateOrUpdate
+      }
+    }
+  )
 
-UserSchema.statics = {
-  list: list,
-  loadByUsernameAndPassword: loadByUsernameAndPassword
+  return User
 }
 
-mongoose.model('User', UserSchema)
+function beforeCreateOrUpdate (user, options, next) {
+  peertubeCrypto.cryptPassword(user.password, function (err, hash) {
+    if (err) return next(err)
 
-// ---------------------------------------------------------------------------
+    user.password = hash
+
+    return next()
+  })
+}
+
+// ------------------------------ METHODS ------------------------------
+
+function isPasswordMatch (password, callback) {
+  return peertubeCrypto.comparePassword(password, this.password, callback)
+}
+
+function toFormatedJSON () {
+  return {
+    id: this.id,
+    username: this.username,
+    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().asCallback(callback)
+}
+
+function getByUsername (username) {
+  const query = {
+    where: {
+      username: username
+    }
+  }
+
+  return this.findOne(query)
+}
 
 function list (callback) {
-  return this.find(callback)
+  return this.find().asCallback(callback)
+}
+
+function listForApi (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 loadByUsernameAndPassword (username, password, callback) {
-  return this.findOne({ username: username, password: password }, callback)
+function loadById (id, callback) {
+  return this.findById(id).asCallback(callback)
+}
+
+function loadByUsername (username, callback) {
+  const query = {
+    where: {
+      username: username
+    }
+  }
+
+  return this.findOne(query).asCallback(callback)
 }