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