]>
Commit | Line | Data |
---|---|---|
67bf9b96 C |
1 | 'use strict' |
2 | ||
3 | const values = require('lodash/values') | |
4 | ||
5c39adb7 | 5 | const modelUtils = require('./utils') |
67bf9b96 | 6 | const constants = require('../initializers/constants') |
26d7d31b | 7 | const peertubeCrypto = require('../helpers/peertube-crypto') |
67bf9b96 | 8 | const customUsersValidators = require('../helpers/custom-validators').users |
9bd26629 | 9 | |
69b0a27c C |
10 | // --------------------------------------------------------------------------- |
11 | ||
feb4bdfd C |
12 | module.exports = function (sequelize, DataTypes) { |
13 | const User = sequelize.define('User', | |
14 | { | |
15 | password: { | |
67bf9b96 C |
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 | } | |
feb4bdfd C |
24 | }, |
25 | username: { | |
67bf9b96 C |
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 | } | |
feb4bdfd | 34 | }, |
ad4a8a1c | 35 | email: { |
5804c0db | 36 | type: DataTypes.STRING(400), |
ad4a8a1c C |
37 | allowNull: false, |
38 | validate: { | |
39 | isEmail: true | |
40 | } | |
41 | }, | |
1d49e1e2 C |
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 | }, | |
feb4bdfd | 53 | role: { |
67bf9b96 C |
54 | type: DataTypes.ENUM(values(constants.USER_ROLES)), |
55 | allowNull: false | |
feb4bdfd C |
56 | } |
57 | }, | |
58 | { | |
319d072e C |
59 | indexes: [ |
60 | { | |
5d67f289 C |
61 | fields: [ 'username' ], |
62 | unique: true | |
ad4a8a1c C |
63 | }, |
64 | { | |
65 | fields: [ 'email' ], | |
66 | unique: true | |
319d072e C |
67 | } |
68 | ], | |
feb4bdfd C |
69 | classMethods: { |
70 | associate, | |
71 | ||
72 | countTotal, | |
73 | getByUsername, | |
74 | list, | |
75 | listForApi, | |
76 | loadById, | |
ad4a8a1c C |
77 | loadByUsername, |
78 | loadByUsernameOrEmail | |
feb4bdfd C |
79 | }, |
80 | instanceMethods: { | |
81 | isPasswordMatch, | |
198b205c GS |
82 | toFormatedJSON, |
83 | isAdmin | |
feb4bdfd C |
84 | }, |
85 | hooks: { | |
86 | beforeCreate: beforeCreateOrUpdate, | |
87 | beforeUpdate: beforeCreateOrUpdate | |
88 | } | |
89 | } | |
90 | ) | |
91 | ||
92 | return User | |
9bd26629 | 93 | } |
69b0a27c | 94 | |
feb4bdfd C |
95 | function beforeCreateOrUpdate (user, options, next) { |
96 | peertubeCrypto.cryptPassword(user.password, function (err, hash) { | |
26d7d31b C |
97 | if (err) return next(err) |
98 | ||
99 | user.password = hash | |
100 | ||
101 | return next() | |
102 | }) | |
feb4bdfd | 103 | } |
69b0a27c | 104 | |
26d7d31b C |
105 | // ------------------------------ METHODS ------------------------------ |
106 | ||
107 | function isPasswordMatch (password, callback) { | |
108 | return peertubeCrypto.comparePassword(password, this.password, callback) | |
109 | } | |
110 | ||
111 | function toFormatedJSON () { | |
112 | return { | |
feb4bdfd | 113 | id: this.id, |
26d7d31b | 114 | username: this.username, |
ad4a8a1c | 115 | email: this.email, |
1d49e1e2 | 116 | displayNSFW: this.displayNSFW, |
d74a0680 | 117 | role: this.role, |
feb4bdfd | 118 | createdAt: this.createdAt |
26d7d31b C |
119 | } |
120 | } | |
198b205c GS |
121 | |
122 | function isAdmin () { | |
123 | return this.role === constants.USER_ROLES.ADMIN | |
124 | } | |
125 | ||
26d7d31b | 126 | // ------------------------------ STATICS ------------------------------ |
69b0a27c | 127 | |
feb4bdfd | 128 | function associate (models) { |
4712081f C |
129 | this.hasOne(models.Author, { |
130 | foreignKey: 'userId', | |
131 | onDelete: 'cascade' | |
132 | }) | |
133 | ||
feb4bdfd C |
134 | this.hasMany(models.OAuthToken, { |
135 | foreignKey: 'userId', | |
136 | onDelete: 'cascade' | |
137 | }) | |
138 | } | |
139 | ||
5c39adb7 | 140 | function countTotal (callback) { |
feb4bdfd | 141 | return this.count().asCallback(callback) |
089ff2f2 C |
142 | } |
143 | ||
26d7d31b | 144 | function getByUsername (username) { |
feb4bdfd C |
145 | const query = { |
146 | where: { | |
147 | username: username | |
148 | } | |
149 | } | |
150 | ||
151 | return this.findOne(query) | |
9bd26629 C |
152 | } |
153 | ||
00d6b0dd | 154 | function list (callback) { |
feb4bdfd | 155 | return this.find().asCallback(callback) |
00d6b0dd C |
156 | } |
157 | ||
5c39adb7 | 158 | function listForApi (start, count, sort, callback) { |
feb4bdfd C |
159 | const query = { |
160 | offset: start, | |
161 | limit: count, | |
162 | order: [ modelUtils.getSort(sort) ] | |
163 | } | |
164 | ||
165 | return this.findAndCountAll(query).asCallback(function (err, result) { | |
166 | if (err) return callback(err) | |
167 | ||
168 | return callback(null, result.rows, result.count) | |
169 | }) | |
69b0a27c C |
170 | } |
171 | ||
68a3b9f2 | 172 | function loadById (id, callback) { |
feb4bdfd | 173 | return this.findById(id).asCallback(callback) |
68a3b9f2 C |
174 | } |
175 | ||
9bd26629 | 176 | function loadByUsername (username, callback) { |
feb4bdfd C |
177 | const query = { |
178 | where: { | |
179 | username: username | |
180 | } | |
181 | } | |
182 | ||
183 | return this.findOne(query).asCallback(callback) | |
9bd26629 | 184 | } |
ad4a8a1c C |
185 | |
186 | function loadByUsernameOrEmail (username, email, callback) { | |
187 | const query = { | |
188 | where: { | |
189 | $or: [ { username }, { email } ] | |
190 | } | |
191 | } | |
192 | ||
193 | return this.findOne(query).asCallback(callback) | |
194 | } |