e50eb96ea514b876232a18a2f7076762a1d8772b
[oweals/peertube.git] / server / models / user.js
1 const modelUtils = require('./utils')
2 const peertubeCrypto = require('../helpers/peertube-crypto')
3
4 // ---------------------------------------------------------------------------
5
6 module.exports = function (sequelize, DataTypes) {
7   const User = sequelize.define('User',
8     {
9       password: {
10         type: DataTypes.STRING
11       },
12       username: {
13         type: DataTypes.STRING
14       },
15       role: {
16         type: DataTypes.STRING
17       }
18     },
19     {
20       classMethods: {
21         associate,
22
23         countTotal,
24         getByUsername,
25         list,
26         listForApi,
27         loadById,
28         loadByUsername
29       },
30       instanceMethods: {
31         isPasswordMatch,
32         toFormatedJSON
33       },
34       hooks: {
35         beforeCreate: beforeCreateOrUpdate,
36         beforeUpdate: beforeCreateOrUpdate
37       }
38     }
39   )
40
41   return User
42 }
43
44 // TODO: Validation
45 // UserSchema.path('password').required(customUsersValidators.isUserPasswordValid)
46 // UserSchema.path('username').required(customUsersValidators.isUserUsernameValid)
47 // UserSchema.path('role').validate(customUsersValidators.isUserRoleValid)
48
49 function beforeCreateOrUpdate (user, options, next) {
50   peertubeCrypto.cryptPassword(user.password, function (err, hash) {
51     if (err) return next(err)
52
53     user.password = hash
54
55     return next()
56   })
57 }
58
59 // ------------------------------ METHODS ------------------------------
60
61 function isPasswordMatch (password, callback) {
62   return peertubeCrypto.comparePassword(password, this.password, callback)
63 }
64
65 function toFormatedJSON () {
66   return {
67     id: this.id,
68     username: this.username,
69     role: this.role,
70     createdAt: this.createdAt
71   }
72 }
73 // ------------------------------ STATICS ------------------------------
74
75 function associate (models) {
76   this.hasMany(models.OAuthToken, {
77     foreignKey: 'userId',
78     onDelete: 'cascade'
79   })
80 }
81
82 function countTotal (callback) {
83   return this.count().asCallback(callback)
84 }
85
86 function getByUsername (username) {
87   const query = {
88     where: {
89       username: username
90     }
91   }
92
93   return this.findOne(query)
94 }
95
96 function list (callback) {
97   return this.find().asCallback(callback)
98 }
99
100 function listForApi (start, count, sort, callback) {
101   const query = {
102     offset: start,
103     limit: count,
104     order: [ modelUtils.getSort(sort) ]
105   }
106
107   return this.findAndCountAll(query).asCallback(function (err, result) {
108     if (err) return callback(err)
109
110     return callback(null, result.rows, result.count)
111   })
112 }
113
114 function loadById (id, callback) {
115   return this.findById(id).asCallback(callback)
116 }
117
118 function loadByUsername (username, callback) {
119   const query = {
120     where: {
121       username: username
122     }
123   }
124
125   return this.findOne(query).asCallback(callback)
126 }