X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=server%2Fmodels%2Fuser.js;h=e64bab8abc54061778968453e6a7ff0caff71e84;hb=00871a261787ae1ed8446861ba2bd5eea9faca6d;hp=130b49b55268cbc4d60705d3081a61a665aef83d;hpb=69b0a27cbbd69ca019eb7db5f917b1dd06dc82cd;p=github%2FChocobozzz%2FPeerTube.git diff --git a/server/models/user.js b/server/models/user.js index 130b49b55..e64bab8ab 100644 --- a/server/models/user.js +++ b/server/models/user.js @@ -1,28 +1,188 @@ -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.') + } + } + }, + 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, -UserSchema.path('password').required(true) -UserSchema.path('username').required(true) + countTotal, + getByUsername, + list, + listForApi, + loadById, + loadByUsername, + loadByUsernameOrEmail + }, + 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, + 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().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 loadById (id, callback) { + return this.findById(id).asCallback(callback) } -function loadByUsernameAndPassword (username, password, callback) { - return this.findOne({ username: username, password: password }, callback) +function loadByUsername (username, callback) { + const query = { + where: { + username: username + } + } + + return this.findOne(query).asCallback(callback) +} + +function loadByUsernameOrEmail (username, email, callback) { + const query = { + where: { + $or: [ { username }, { email } ] + } + } + + return this.findOne(query).asCallback(callback) }