]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/models/user.js
Server: add unique to unique indexes
[github/Chocobozzz/PeerTube.git] / server / models / user.js
1 'use strict'
2
3 const values = require('lodash/values')
4
5 const modelUtils = require('./utils')
6 const constants = require('../initializers/constants')
7 const peertubeCrypto = require('../helpers/peertube-crypto')
8 const customUsersValidators = require('../helpers/custom-validators').users
9
10 // ---------------------------------------------------------------------------
11
12 module.exports = function (sequelize, DataTypes) {
13 const User = sequelize.define('User',
14 {
15 password: {
16 type: DataTypes.STRING,
17 allowNull: false,
18 validate: {
19 passwordValid: function (value) {
20 const res = customUsersValidators.isUserPasswordValid(value)
21 if (res === false) throw new Error('Password not valid.')
22 }
23 }
24 },
25 username: {
26 type: DataTypes.STRING,
27 allowNull: false,
28 validate: {
29 usernameValid: function (value) {
30 const res = customUsersValidators.isUserUsernameValid(value)
31 if (res === false) throw new Error('Username not valid.')
32 }
33 }
34 },
35 role: {
36 type: DataTypes.ENUM(values(constants.USER_ROLES)),
37 allowNull: false
38 }
39 },
40 {
41 indexes: [
42 {
43 fields: [ 'username' ],
44 unique: true
45 }
46 ],
47 classMethods: {
48 associate,
49
50 countTotal,
51 getByUsername,
52 list,
53 listForApi,
54 loadById,
55 loadByUsername
56 },
57 instanceMethods: {
58 isPasswordMatch,
59 toFormatedJSON
60 },
61 hooks: {
62 beforeCreate: beforeCreateOrUpdate,
63 beforeUpdate: beforeCreateOrUpdate
64 }
65 }
66 )
67
68 return User
69 }
70
71 function beforeCreateOrUpdate (user, options, next) {
72 peertubeCrypto.cryptPassword(user.password, function (err, hash) {
73 if (err) return next(err)
74
75 user.password = hash
76
77 return next()
78 })
79 }
80
81 // ------------------------------ METHODS ------------------------------
82
83 function isPasswordMatch (password, callback) {
84 return peertubeCrypto.comparePassword(password, this.password, callback)
85 }
86
87 function toFormatedJSON () {
88 return {
89 id: this.id,
90 username: this.username,
91 role: this.role,
92 createdAt: this.createdAt
93 }
94 }
95 // ------------------------------ STATICS ------------------------------
96
97 function associate (models) {
98 this.hasOne(models.Author, {
99 foreignKey: 'userId',
100 onDelete: 'cascade'
101 })
102
103 this.hasMany(models.OAuthToken, {
104 foreignKey: 'userId',
105 onDelete: 'cascade'
106 })
107 }
108
109 function countTotal (callback) {
110 return this.count().asCallback(callback)
111 }
112
113 function getByUsername (username) {
114 const query = {
115 where: {
116 username: username
117 }
118 }
119
120 return this.findOne(query)
121 }
122
123 function list (callback) {
124 return this.find().asCallback(callback)
125 }
126
127 function listForApi (start, count, sort, callback) {
128 const query = {
129 offset: start,
130 limit: count,
131 order: [ modelUtils.getSort(sort) ]
132 }
133
134 return this.findAndCountAll(query).asCallback(function (err, result) {
135 if (err) return callback(err)
136
137 return callback(null, result.rows, result.count)
138 })
139 }
140
141 function loadById (id, callback) {
142 return this.findById(id).asCallback(callback)
143 }
144
145 function loadByUsername (username, callback) {
146 const query = {
147 where: {
148 username: username
149 }
150 }
151
152 return this.findOne(query).asCallback(callback)
153 }