Use async/await in controllers
[oweals/peertube.git] / server / controllers / api / users.ts
1 import * as express from 'express'
2
3 import { database as db } from '../../initializers/database'
4 import { USER_ROLES, CONFIG } from '../../initializers'
5 import { logger, getFormattedObjects, retryTransactionWrapper } from '../../helpers'
6 import {
7   authenticate,
8   ensureIsAdmin,
9   ensureUserRegistrationAllowed,
10   usersAddValidator,
11   usersRegisterValidator,
12   usersUpdateValidator,
13   usersUpdateMeValidator,
14   usersRemoveValidator,
15   usersVideoRatingValidator,
16   usersGetValidator,
17   paginationValidator,
18   setPagination,
19   usersSortValidator,
20   setUsersSort,
21   token,
22   asyncMiddleware
23 } from '../../middlewares'
24 import {
25   UserVideoRate as FormattedUserVideoRate,
26   UserCreate,
27   UserUpdate,
28   UserUpdateMe
29 } from '../../../shared'
30 import { createUserAuthorAndChannel } from '../../lib'
31 import { UserInstance } from '../../models'
32
33 const usersRouter = express.Router()
34
35 usersRouter.get('/me',
36   authenticate,
37   asyncMiddleware(getUserInformation)
38 )
39
40 usersRouter.get('/me/videos/:videoId/rating',
41   authenticate,
42   usersVideoRatingValidator,
43   asyncMiddleware(getUserVideoRating)
44 )
45
46 usersRouter.get('/',
47   paginationValidator,
48   usersSortValidator,
49   setUsersSort,
50   setPagination,
51   asyncMiddleware(listUsers)
52 )
53
54 usersRouter.get('/:id',
55   usersGetValidator,
56   getUser
57 )
58
59 usersRouter.post('/',
60   authenticate,
61   ensureIsAdmin,
62   usersAddValidator,
63   createUserRetryWrapper
64 )
65
66 usersRouter.post('/register',
67   ensureUserRegistrationAllowed,
68   usersRegisterValidator,
69   asyncMiddleware(registerUser)
70 )
71
72 usersRouter.put('/me',
73   authenticate,
74   usersUpdateMeValidator,
75   asyncMiddleware(updateMe)
76 )
77
78 usersRouter.put('/:id',
79   authenticate,
80   ensureIsAdmin,
81   usersUpdateValidator,
82   asyncMiddleware(updateUser)
83 )
84
85 usersRouter.delete('/:id',
86   authenticate,
87   ensureIsAdmin,
88   usersRemoveValidator,
89   asyncMiddleware(removeUser)
90 )
91
92 usersRouter.post('/token', token, success)
93 // TODO: Once https://github.com/oauthjs/node-oauth2-server/pull/289 is merged, implement revoke token route
94
95 // ---------------------------------------------------------------------------
96
97 export {
98   usersRouter
99 }
100
101 // ---------------------------------------------------------------------------
102
103 async function createUserRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
104   const options = {
105     arguments: [ req, res ],
106     errorMessage: 'Cannot insert the user with many retries.'
107   }
108
109   await retryTransactionWrapper(createUser, options)
110
111   // TODO : include Location of the new user -> 201
112   return res.type('json').status(204).end()
113 }
114
115 async function createUser (req: express.Request, res: express.Response, next: express.NextFunction) {
116   const body: UserCreate = req.body
117   const user = db.User.build({
118     username: body.username,
119     password: body.password,
120     email: body.email,
121     displayNSFW: false,
122     role: USER_ROLES.USER,
123     videoQuota: body.videoQuota
124   })
125
126   await createUserAuthorAndChannel(user)
127
128   logger.info('User %s with its channel and author created.', body.username)
129 }
130
131 async function registerUser (req: express.Request, res: express.Response, next: express.NextFunction) {
132   const body: UserCreate = req.body
133
134   const user = db.User.build({
135     username: body.username,
136     password: body.password,
137     email: body.email,
138     displayNSFW: false,
139     role: USER_ROLES.USER,
140     videoQuota: CONFIG.USER.VIDEO_QUOTA
141   })
142
143   await createUserAuthorAndChannel(user)
144   return res.type('json').status(204).end()
145 }
146
147 async function getUserInformation (req: express.Request, res: express.Response, next: express.NextFunction) {
148   const user = await db.User.loadByUsernameAndPopulateChannels(res.locals.oauth.token.user.username)
149
150   return res.json(user.toFormattedJSON())
151 }
152
153 function getUser (req: express.Request, res: express.Response, next: express.NextFunction) {
154   return res.json(res.locals.user.toFormattedJSON())
155 }
156
157 async function getUserVideoRating (req: express.Request, res: express.Response, next: express.NextFunction) {
158   const videoId = +req.params.videoId
159   const userId = +res.locals.oauth.token.User.id
160
161   db.UserVideoRate.load(userId, videoId, null)
162     .then(ratingObj => {
163       const rating = ratingObj ? ratingObj.type : 'none'
164       const json: FormattedUserVideoRate = {
165         videoId,
166         rating
167       }
168       res.json(json)
169     })
170     .catch(err => next(err))
171 }
172
173 async function listUsers (req: express.Request, res: express.Response, next: express.NextFunction) {
174   const resultList = await db.User.listForApi(req.query.start, req.query.count, req.query.sort)
175
176   return res.json(getFormattedObjects(resultList.data, resultList.total))
177 }
178
179 async function removeUser (req: express.Request, res: express.Response, next: express.NextFunction) {
180   const user = await db.User.loadById(req.params.id)
181
182   await user.destroy()
183
184   return res.sendStatus(204)
185 }
186
187 async function updateMe (req: express.Request, res: express.Response, next: express.NextFunction) {
188   const body: UserUpdateMe = req.body
189
190   // FIXME: user is not already a Sequelize instance?
191   const user = res.locals.oauth.token.user
192
193   if (body.password !== undefined) user.password = body.password
194   if (body.email !== undefined) user.email = body.email
195   if (body.displayNSFW !== undefined) user.displayNSFW = body.displayNSFW
196
197   await user.save()
198
199   return await res.sendStatus(204)
200 }
201
202 async function updateUser (req: express.Request, res: express.Response, next: express.NextFunction) {
203   const body: UserUpdate = req.body
204   const user: UserInstance = res.locals.user
205
206   if (body.email !== undefined) user.email = body.email
207   if (body.videoQuota !== undefined) user.videoQuota = body.videoQuota
208
209   await user.save()
210
211   return res.sendStatus(204)
212 }
213
214 function success (req: express.Request, res: express.Response, next: express.NextFunction) {
215   res.end()
216 }