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