]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/controllers/api/users/me.ts
Retrieve user by id instead of username
[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 { 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 // ---------------------------------------------------------------------------
93
94 export {
95 meRouter
96 }
97
98 // ---------------------------------------------------------------------------
99
100 async function getUserVideos (req: express.Request, res: express.Response) {
101 const user = res.locals.oauth.token.User
102 const resultList = await VideoModel.listUserVideosForApi(
103 user.Account.id,
104 req.query.start as number,
105 req.query.count as number,
106 req.query.sort as VideoSortField,
107 req.query.search as string
108 )
109
110 const additionalAttributes = {
111 waitTranscoding: true,
112 state: true,
113 scheduledUpdate: true,
114 blacklistInfo: true
115 }
116 return res.json(getFormattedObjects(resultList.data, resultList.total, { additionalAttributes }))
117 }
118
119 async function getUserVideoImports (req: express.Request, res: express.Response) {
120 const user = res.locals.oauth.token.User
121 const resultList = await VideoImportModel.listUserVideoImportsForApi(
122 user.id,
123 req.query.start as number,
124 req.query.count as number,
125 req.query.sort
126 )
127
128 return res.json(getFormattedObjects(resultList.data, resultList.total))
129 }
130
131 async function getUserInformation (req: express.Request, res: express.Response) {
132 // We did not load channels in res.locals.user
133 const user = await UserModel.loadForMeAPI(res.locals.oauth.token.user.id)
134
135 return res.json(user.toMeFormattedJSON())
136 }
137
138 async function getUserVideoQuotaUsed (req: express.Request, res: express.Response) {
139 const user = res.locals.oauth.token.user
140 const videoQuotaUsed = await getOriginalVideoFileTotalFromUser(user)
141 const videoQuotaUsedDaily = await getOriginalVideoFileTotalDailyFromUser(user)
142
143 const data: UserVideoQuota = {
144 videoQuotaUsed,
145 videoQuotaUsedDaily
146 }
147 return res.json(data)
148 }
149
150 async function getUserVideoRating (req: express.Request, res: express.Response) {
151 const videoId = res.locals.videoId.id
152 const accountId = +res.locals.oauth.token.User.Account.id
153
154 const ratingObj = await AccountVideoRateModel.load(accountId, videoId, null)
155 const rating = ratingObj ? ratingObj.type : 'none'
156
157 const json: FormattedUserVideoRate = {
158 videoId,
159 rating
160 }
161 return res.json(json)
162 }
163
164 async function deleteMe (req: express.Request, res: express.Response) {
165 const user = await UserModel.loadByIdWithChannels(res.locals.oauth.token.User.id)
166
167 auditLogger.delete(getAuditIdFromRes(res), new UserAuditView(user.toFormattedJSON()))
168
169 await user.destroy()
170
171 return res.sendStatus(HttpStatusCode.NO_CONTENT_204)
172 }
173
174 async function updateMe (req: express.Request, res: express.Response) {
175 const body: UserUpdateMe = req.body
176 let sendVerificationEmail = false
177
178 const user = res.locals.oauth.token.user
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.autoPlayNextVideo !== undefined) user.autoPlayNextVideo = body.autoPlayNextVideo
185 if (body.autoPlayNextVideoPlaylist !== undefined) user.autoPlayNextVideoPlaylist = body.autoPlayNextVideoPlaylist
186 if (body.videosHistoryEnabled !== undefined) user.videosHistoryEnabled = body.videosHistoryEnabled
187 if (body.videoLanguages !== undefined) user.videoLanguages = body.videoLanguages
188 if (body.theme !== undefined) user.theme = body.theme
189 if (body.noInstanceConfigWarningModal !== undefined) user.noInstanceConfigWarningModal = body.noInstanceConfigWarningModal
190 if (body.noWelcomeModal !== undefined) user.noWelcomeModal = body.noWelcomeModal
191
192 if (body.email !== undefined) {
193 if (CONFIG.SIGNUP.REQUIRES_EMAIL_VERIFICATION) {
194 user.pendingEmail = body.email
195 sendVerificationEmail = true
196 } else {
197 user.email = body.email
198 }
199 }
200
201 await sequelizeTypescript.transaction(async t => {
202 await user.save({ transaction: t })
203
204 if (body.displayName !== undefined || body.description !== undefined) {
205 const userAccount = await AccountModel.load(user.Account.id, t)
206
207 if (body.displayName !== undefined) userAccount.name = body.displayName
208 if (body.description !== undefined) userAccount.description = body.description
209 await userAccount.save({ transaction: t })
210
211 await sendUpdateActor(userAccount, t)
212 }
213 })
214
215 if (sendVerificationEmail === true) {
216 await sendVerifyUserEmail(user, true)
217 }
218
219 return res.sendStatus(HttpStatusCode.NO_CONTENT_204)
220 }
221
222 async function updateMyAvatar (req: express.Request, res: express.Response) {
223 const avatarPhysicalFile = req.files['avatarfile'][0]
224 const user = res.locals.oauth.token.user
225
226 const userAccount = await AccountModel.load(user.Account.id)
227
228 const avatar = await updateActorAvatarFile(avatarPhysicalFile, userAccount)
229
230 return res.json({ avatar: avatar.toFormattedJSON() })
231 }