]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/models/user.ts
First typescript iteration
[github/Chocobozzz/PeerTube.git] / server / models / user.ts
1 import { values } from 'lodash'
2
3 import { getSort } from './utils'
4 import { USER_ROLES } from '../initializers'
5 import {
6 cryptPassword,
7 comparePassword,
8 isUserPasswordValid,
9 isUserUsernameValid,
10 isUserDisplayNSFWValid
11 } from '../helpers'
12
13 // ---------------------------------------------------------------------------
14
15 module.exports = function (sequelize, DataTypes) {
16 const User = sequelize.define('User',
17 {
18 password: {
19 type: DataTypes.STRING,
20 allowNull: false,
21 validate: {
22 passwordValid: function (value) {
23 const res = isUserPasswordValid(value)
24 if (res === false) throw new Error('Password not valid.')
25 }
26 }
27 },
28 username: {
29 type: DataTypes.STRING,
30 allowNull: false,
31 validate: {
32 usernameValid: function (value) {
33 const res = isUserUsernameValid(value)
34 if (res === false) throw new Error('Username not valid.')
35 }
36 }
37 },
38 email: {
39 type: DataTypes.STRING(400),
40 allowNull: false,
41 validate: {
42 isEmail: true
43 }
44 },
45 displayNSFW: {
46 type: DataTypes.BOOLEAN,
47 allowNull: false,
48 defaultValue: false,
49 validate: {
50 nsfwValid: function (value) {
51 const res = isUserDisplayNSFWValid(value)
52 if (res === false) throw new Error('Display NSFW is not valid.')
53 }
54 }
55 },
56 role: {
57 type: DataTypes.ENUM(values(USER_ROLES)),
58 allowNull: false
59 }
60 },
61 {
62 indexes: [
63 {
64 fields: [ 'username' ],
65 unique: true
66 },
67 {
68 fields: [ 'email' ],
69 unique: true
70 }
71 ],
72 classMethods: {
73 associate,
74
75 countTotal,
76 getByUsername,
77 list,
78 listForApi,
79 loadById,
80 loadByUsername,
81 loadByUsernameOrEmail
82 },
83 instanceMethods: {
84 isPasswordMatch,
85 toFormatedJSON,
86 isAdmin
87 },
88 hooks: {
89 beforeCreate: beforeCreateOrUpdate,
90 beforeUpdate: beforeCreateOrUpdate
91 }
92 }
93 )
94
95 return User
96 }
97
98 function beforeCreateOrUpdate (user, options, next) {
99 cryptPassword(user.password, function (err, hash) {
100 if (err) return next(err)
101
102 user.password = hash
103
104 return next()
105 })
106 }
107
108 // ------------------------------ METHODS ------------------------------
109
110 function isPasswordMatch (password, callback) {
111 return comparePassword(password, this.password, callback)
112 }
113
114 function toFormatedJSON () {
115 return {
116 id: this.id,
117 username: this.username,
118 email: this.email,
119 displayNSFW: this.displayNSFW,
120 role: this.role,
121 createdAt: this.createdAt
122 }
123 }
124
125 function isAdmin () {
126 return this.role === USER_ROLES.ADMIN
127 }
128
129 // ------------------------------ STATICS ------------------------------
130
131 function associate (models) {
132 this.hasOne(models.Author, {
133 foreignKey: 'userId',
134 onDelete: 'cascade'
135 })
136
137 this.hasMany(models.OAuthToken, {
138 foreignKey: 'userId',
139 onDelete: 'cascade'
140 })
141 }
142
143 function countTotal (callback) {
144 return this.count().asCallback(callback)
145 }
146
147 function getByUsername (username) {
148 const query = {
149 where: {
150 username: username
151 }
152 }
153
154 return this.findOne(query)
155 }
156
157 function list (callback) {
158 return this.find().asCallback(callback)
159 }
160
161 function listForApi (start, count, sort, callback) {
162 const query = {
163 offset: start,
164 limit: count,
165 order: [ getSort(sort) ]
166 }
167
168 return this.findAndCountAll(query).asCallback(function (err, result) {
169 if (err) return callback(err)
170
171 return callback(null, result.rows, result.count)
172 })
173 }
174
175 function loadById (id, callback) {
176 return this.findById(id).asCallback(callback)
177 }
178
179 function loadByUsername (username, callback) {
180 const query = {
181 where: {
182 username: username
183 }
184 }
185
186 return this.findOne(query).asCallback(callback)
187 }
188
189 function loadByUsernameOrEmail (username, email, callback) {
190 const query = {
191 where: {
192 $or: [ { username }, { email } ]
193 }
194 }
195
196 return this.findOne(query).asCallback(callback)
197 }