]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/models/user.js
Update README features
[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 email: {
36 type: DataTypes.STRING(400),
37 allowNull: false,
38 validate: {
39 isEmail: true
40 }
41 },
42 displayNSFW: {
43 type: DataTypes.BOOLEAN,
44 allowNull: false,
45 defaultValue: false,
46 validate: {
47 nsfwValid: function (value) {
48 const res = customUsersValidators.isUserDisplayNSFWValid(value)
49 if (res === false) throw new Error('Display NSFW is not valid.')
50 }
51 }
52 },
53 role: {
54 type: DataTypes.ENUM(values(constants.USER_ROLES)),
55 allowNull: false
56 }
57 },
58 {
59 indexes: [
60 {
61 fields: [ 'username' ],
62 unique: true
63 },
64 {
65 fields: [ 'email' ],
66 unique: true
67 }
68 ],
69 classMethods: {
70 associate,
71
72 countTotal,
73 getByUsername,
74 list,
75 listForApi,
76 loadById,
77 loadByUsername,
78 loadByUsernameOrEmail
79 },
80 instanceMethods: {
81 isPasswordMatch,
82 toFormatedJSON
83 },
84 hooks: {
85 beforeCreate: beforeCreateOrUpdate,
86 beforeUpdate: beforeCreateOrUpdate
87 }
88 }
89 )
90
91 return User
92 }
93
94 function beforeCreateOrUpdate (user, options, next) {
95 peertubeCrypto.cryptPassword(user.password, function (err, hash) {
96 if (err) return next(err)
97
98 user.password = hash
99
100 return next()
101 })
102 }
103
104 // ------------------------------ METHODS ------------------------------
105
106 function isPasswordMatch (password, callback) {
107 return peertubeCrypto.comparePassword(password, this.password, callback)
108 }
109
110 function toFormatedJSON () {
111 return {
112 id: this.id,
113 username: this.username,
114 email: this.email,
115 displayNSFW: this.displayNSFW,
116 role: this.role,
117 createdAt: this.createdAt
118 }
119 }
120 // ------------------------------ STATICS ------------------------------
121
122 function associate (models) {
123 this.hasOne(models.Author, {
124 foreignKey: 'userId',
125 onDelete: 'cascade'
126 })
127
128 this.hasMany(models.OAuthToken, {
129 foreignKey: 'userId',
130 onDelete: 'cascade'
131 })
132 }
133
134 function countTotal (callback) {
135 return this.count().asCallback(callback)
136 }
137
138 function getByUsername (username) {
139 const query = {
140 where: {
141 username: username
142 }
143 }
144
145 return this.findOne(query)
146 }
147
148 function list (callback) {
149 return this.find().asCallback(callback)
150 }
151
152 function listForApi (start, count, sort, callback) {
153 const query = {
154 offset: start,
155 limit: count,
156 order: [ modelUtils.getSort(sort) ]
157 }
158
159 return this.findAndCountAll(query).asCallback(function (err, result) {
160 if (err) return callback(err)
161
162 return callback(null, result.rows, result.count)
163 })
164 }
165
166 function loadById (id, callback) {
167 return this.findById(id).asCallback(callback)
168 }
169
170 function loadByUsername (username, callback) {
171 const query = {
172 where: {
173 username: username
174 }
175 }
176
177 return this.findOne(query).asCallback(callback)
178 }
179
180 function loadByUsernameOrEmail (username, email, callback) {
181 const query = {
182 where: {
183 $or: [ { username }, { email } ]
184 }
185 }
186
187 return this.findOne(query).asCallback(callback)
188 }