]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/controllers/api/users/me.ts
WIP plugins: add theme support
[github/Chocobozzz/PeerTube.git] / server / controllers / api / users / me.ts
1 import * as express from 'express'
2 import 'multer'
3 import { UserUpdateMe, UserVideoRate as FormattedUserVideoRate } from '../../../../shared'
4 import { getFormattedObjects } from '../../../helpers/utils'
5 import { MIMETYPES } from '../../../initializers/constants'
6 import { sendUpdateActor } from '../../../lib/activitypub/send'
7 import {
8 asyncMiddleware,
9 asyncRetryTransactionMiddleware,
10 authenticate,
11 paginationValidator,
12 setDefaultPagination,
13 setDefaultSort,
14 usersUpdateMeValidator,
15 usersVideoRatingValidator
16 } from '../../../middlewares'
17 import { deleteMeValidator, videoImportsSortValidator, videosSortValidator } from '../../../middlewares/validators'
18 import { AccountVideoRateModel } from '../../../models/account/account-video-rate'
19 import { UserModel } from '../../../models/account/user'
20 import { VideoModel } from '../../../models/video/video'
21 import { VideoSortField } from '../../../../client/src/app/shared/video/sort-field.type'
22 import { createReqFiles } from '../../../helpers/express-utils'
23 import { UserVideoQuota } from '../../../../shared/models/users/user-video-quota.model'
24 import { updateAvatarValidator } from '../../../middlewares/validators/avatar'
25 import { updateActorAvatarFile } from '../../../lib/avatar'
26 import { auditLoggerFactory, getAuditIdFromRes, UserAuditView } from '../../../helpers/audit-logger'
27 import { VideoImportModel } from '../../../models/video/video-import'
28 import { AccountModel } from '../../../models/account/account'
29 import { CONFIG } from '../../../initializers/config'
30 import { sequelizeTypescript } from '../../../initializers/database'
31 import { sendVerifyUserEmail } from '../../../lib/user'
32
33 const auditLogger = auditLoggerFactory('users-me')
34
35 const reqAvatarFile = createReqFiles([ 'avatarfile' ], MIMETYPES.IMAGE.MIMETYPE_EXT, { avatarfile: CONFIG.STORAGE.TMP_DIR })
36
37 const meRouter = express.Router()
38
39 meRouter.get('/me',
40 authenticate,
41 asyncMiddleware(getUserInformation)
42 )
43 meRouter.delete('/me',
44 authenticate,
45 asyncMiddleware(deleteMeValidator),
46 asyncMiddleware(deleteMe)
47 )
48
49 meRouter.get('/me/video-quota-used',
50 authenticate,
51 asyncMiddleware(getUserVideoQuotaUsed)
52 )
53
54 meRouter.get('/me/videos/imports',
55 authenticate,
56 paginationValidator,
57 videoImportsSortValidator,
58 setDefaultSort,
59 setDefaultPagination,
60 asyncMiddleware(getUserVideoImports)
61 )
62
63 meRouter.get('/me/videos',
64 authenticate,
65 paginationValidator,
66 videosSortValidator,
67 setDefaultSort,
68 setDefaultPagination,
69 asyncMiddleware(getUserVideos)
70 )
71
72 meRouter.get('/me/videos/:videoId/rating',
73 authenticate,
74 asyncMiddleware(usersVideoRatingValidator),
75 asyncMiddleware(getUserVideoRating)
76 )
77
78 meRouter.put('/me',
79 authenticate,
80 asyncMiddleware(usersUpdateMeValidator),
81 asyncRetryTransactionMiddleware(updateMe)
82 )
83
84 meRouter.post('/me/avatar/pick',
85 authenticate,
86 reqAvatarFile,
87 updateAvatarValidator,
88 asyncRetryTransactionMiddleware(updateMyAvatar)
89 )
90
91 // ---------------------------------------------------------------------------
92
93 export {
94 meRouter
95 }
96
97 // ---------------------------------------------------------------------------
98
99 async function getUserVideos (req: express.Request, res: express.Response) {
100 const user = res.locals.oauth.token.User
101 const resultList = await VideoModel.listUserVideosForApi(
102 user.Account.id,
103 req.query.start as number,
104 req.query.count as number,
105 req.query.sort as VideoSortField
106 )
107
108 const additionalAttributes = {
109 waitTranscoding: true,
110 state: true,
111 scheduledUpdate: true,
112 blacklistInfo: true
113 }
114 return res.json(getFormattedObjects(resultList.data, resultList.total, { additionalAttributes }))
115 }
116
117 async function getUserVideoImports (req: express.Request, res: express.Response) {
118 const user = res.locals.oauth.token.User
119 const resultList = await VideoImportModel.listUserVideoImportsForApi(
120 user.id,
121 req.query.start as number,
122 req.query.count as number,
123 req.query.sort
124 )
125
126 return res.json(getFormattedObjects(resultList.data, resultList.total))
127 }
128
129 async function getUserInformation (req: express.Request, res: express.Response) {
130 // We did not load channels in res.locals.user
131 const user = await UserModel.loadByUsernameAndPopulateChannels(res.locals.oauth.token.user.username)
132
133 return res.json(user.toFormattedJSON({}))
134 }
135
136 async function getUserVideoQuotaUsed (req: express.Request, res: express.Response) {
137 // We did not load channels in res.locals.user
138 const user = await UserModel.loadByUsernameAndPopulateChannels(res.locals.oauth.token.user.username)
139 const videoQuotaUsed = await UserModel.getOriginalVideoFileTotalFromUser(user)
140 const videoQuotaUsedDaily = await UserModel.getOriginalVideoFileTotalDailyFromUser(user)
141
142 const data: UserVideoQuota = {
143 videoQuotaUsed,
144 videoQuotaUsedDaily
145 }
146 return res.json(data)
147 }
148
149 async function getUserVideoRating (req: express.Request, res: express.Response) {
150 const videoId = res.locals.video.id
151 const accountId = +res.locals.oauth.token.User.Account.id
152
153 const ratingObj = await AccountVideoRateModel.load(accountId, videoId, null)
154 const rating = ratingObj ? ratingObj.type : 'none'
155
156 const json: FormattedUserVideoRate = {
157 videoId,
158 rating
159 }
160 return res.json(json)
161 }
162
163 async function deleteMe (req: express.Request, res: express.Response) {
164 const user = res.locals.oauth.token.User
165
166 await user.destroy()
167
168 auditLogger.delete(getAuditIdFromRes(res), new UserAuditView(user.toFormattedJSON({})))
169
170 return res.sendStatus(204)
171 }
172
173 async function updateMe (req: express.Request, res: express.Response) {
174 const body: UserUpdateMe = req.body
175 let sendVerificationEmail = false
176
177 const user = res.locals.oauth.token.user
178 const oldUserAuditView = new UserAuditView(user.toFormattedJSON({}))
179
180 if (body.password !== undefined) user.password = body.password
181 if (body.nsfwPolicy !== undefined) user.nsfwPolicy = body.nsfwPolicy
182 if (body.webTorrentEnabled !== undefined) user.webTorrentEnabled = body.webTorrentEnabled
183 if (body.autoPlayVideo !== undefined) user.autoPlayVideo = body.autoPlayVideo
184 if (body.videosHistoryEnabled !== undefined) user.videosHistoryEnabled = body.videosHistoryEnabled
185 if (body.videoLanguages !== undefined) user.videoLanguages = body.videoLanguages
186 if (body.theme !== undefined) user.theme = body.theme
187
188 if (body.email !== undefined) {
189 if (CONFIG.SIGNUP.REQUIRES_EMAIL_VERIFICATION) {
190 user.pendingEmail = body.email
191 sendVerificationEmail = true
192 } else {
193 user.email = body.email
194 }
195 }
196
197 await sequelizeTypescript.transaction(async t => {
198 const userAccount = await AccountModel.load(user.Account.id)
199
200 await user.save({ transaction: t })
201
202 if (body.displayName !== undefined) userAccount.name = body.displayName
203 if (body.description !== undefined) userAccount.description = body.description
204 await userAccount.save({ transaction: t })
205
206 await sendUpdateActor(userAccount, t)
207
208 auditLogger.update(getAuditIdFromRes(res), new UserAuditView(user.toFormattedJSON({})), oldUserAuditView)
209 })
210
211 if (sendVerificationEmail === true) {
212 await sendVerifyUserEmail(user, true)
213 }
214
215 return res.sendStatus(204)
216 }
217
218 async function updateMyAvatar (req: express.Request, res: express.Response) {
219 const avatarPhysicalFile = req.files[ 'avatarfile' ][ 0 ]
220 const user = res.locals.oauth.token.user
221 const oldUserAuditView = new UserAuditView(user.toFormattedJSON({}))
222
223 const userAccount = await AccountModel.load(user.Account.id)
224
225 const avatar = await updateActorAvatarFile(avatarPhysicalFile, userAccount)
226
227 auditLogger.update(getAuditIdFromRes(res), new UserAuditView(user.toFormattedJSON({})), oldUserAuditView)
228
229 return res.json({ avatar: avatar.toFormattedJSON() })
230 }