diff options
Diffstat (limited to 'server/controllers/api/users/me.ts')
-rw-r--r-- | server/controllers/api/users/me.ts | 277 |
1 files changed, 0 insertions, 277 deletions
diff --git a/server/controllers/api/users/me.ts b/server/controllers/api/users/me.ts deleted file mode 100644 index 26811136e..000000000 --- a/server/controllers/api/users/me.ts +++ /dev/null | |||
@@ -1,277 +0,0 @@ | |||
1 | import 'multer' | ||
2 | import express from 'express' | ||
3 | import { auditLoggerFactory, getAuditIdFromRes, UserAuditView } from '@server/helpers/audit-logger' | ||
4 | import { Hooks } from '@server/lib/plugins/hooks' | ||
5 | import { pick } from '@shared/core-utils' | ||
6 | import { ActorImageType, HttpStatusCode, UserUpdateMe, UserVideoQuota, UserVideoRate as FormattedUserVideoRate } from '@shared/models' | ||
7 | import { AttributesOnly } from '@shared/typescript-utils' | ||
8 | import { createReqFiles } from '../../../helpers/express-utils' | ||
9 | import { getFormattedObjects } from '../../../helpers/utils' | ||
10 | import { CONFIG } from '../../../initializers/config' | ||
11 | import { MIMETYPES } from '../../../initializers/constants' | ||
12 | import { sequelizeTypescript } from '../../../initializers/database' | ||
13 | import { sendUpdateActor } from '../../../lib/activitypub/send' | ||
14 | import { deleteLocalActorImageFile, updateLocalActorImageFiles } from '../../../lib/local-actor' | ||
15 | import { getOriginalVideoFileTotalDailyFromUser, getOriginalVideoFileTotalFromUser, sendVerifyUserEmail } from '../../../lib/user' | ||
16 | import { | ||
17 | asyncMiddleware, | ||
18 | asyncRetryTransactionMiddleware, | ||
19 | authenticate, | ||
20 | paginationValidator, | ||
21 | setDefaultPagination, | ||
22 | setDefaultSort, | ||
23 | setDefaultVideosSort, | ||
24 | usersUpdateMeValidator, | ||
25 | usersVideoRatingValidator | ||
26 | } from '../../../middlewares' | ||
27 | import { | ||
28 | deleteMeValidator, | ||
29 | getMyVideoImportsValidator, | ||
30 | usersVideosValidator, | ||
31 | videoImportsSortValidator, | ||
32 | videosSortValidator | ||
33 | } from '../../../middlewares/validators' | ||
34 | import { updateAvatarValidator } from '../../../middlewares/validators/actor-image' | ||
35 | import { AccountModel } from '../../../models/account/account' | ||
36 | import { AccountVideoRateModel } from '../../../models/account/account-video-rate' | ||
37 | import { UserModel } from '../../../models/user/user' | ||
38 | import { VideoModel } from '../../../models/video/video' | ||
39 | import { VideoImportModel } from '../../../models/video/video-import' | ||
40 | |||
41 | const auditLogger = auditLoggerFactory('users') | ||
42 | |||
43 | const reqAvatarFile = createReqFiles([ 'avatarfile' ], MIMETYPES.IMAGE.MIMETYPE_EXT) | ||
44 | |||
45 | const meRouter = express.Router() | ||
46 | |||
47 | meRouter.get('/me', | ||
48 | authenticate, | ||
49 | asyncMiddleware(getUserInformation) | ||
50 | ) | ||
51 | meRouter.delete('/me', | ||
52 | authenticate, | ||
53 | deleteMeValidator, | ||
54 | asyncMiddleware(deleteMe) | ||
55 | ) | ||
56 | |||
57 | meRouter.get('/me/video-quota-used', | ||
58 | authenticate, | ||
59 | asyncMiddleware(getUserVideoQuotaUsed) | ||
60 | ) | ||
61 | |||
62 | meRouter.get('/me/videos/imports', | ||
63 | authenticate, | ||
64 | paginationValidator, | ||
65 | videoImportsSortValidator, | ||
66 | setDefaultSort, | ||
67 | setDefaultPagination, | ||
68 | getMyVideoImportsValidator, | ||
69 | asyncMiddleware(getUserVideoImports) | ||
70 | ) | ||
71 | |||
72 | meRouter.get('/me/videos', | ||
73 | authenticate, | ||
74 | paginationValidator, | ||
75 | videosSortValidator, | ||
76 | setDefaultVideosSort, | ||
77 | setDefaultPagination, | ||
78 | asyncMiddleware(usersVideosValidator), | ||
79 | asyncMiddleware(getUserVideos) | ||
80 | ) | ||
81 | |||
82 | meRouter.get('/me/videos/:videoId/rating', | ||
83 | authenticate, | ||
84 | asyncMiddleware(usersVideoRatingValidator), | ||
85 | asyncMiddleware(getUserVideoRating) | ||
86 | ) | ||
87 | |||
88 | meRouter.put('/me', | ||
89 | authenticate, | ||
90 | asyncMiddleware(usersUpdateMeValidator), | ||
91 | asyncRetryTransactionMiddleware(updateMe) | ||
92 | ) | ||
93 | |||
94 | meRouter.post('/me/avatar/pick', | ||
95 | authenticate, | ||
96 | reqAvatarFile, | ||
97 | updateAvatarValidator, | ||
98 | asyncRetryTransactionMiddleware(updateMyAvatar) | ||
99 | ) | ||
100 | |||
101 | meRouter.delete('/me/avatar', | ||
102 | authenticate, | ||
103 | asyncRetryTransactionMiddleware(deleteMyAvatar) | ||
104 | ) | ||
105 | |||
106 | // --------------------------------------------------------------------------- | ||
107 | |||
108 | export { | ||
109 | meRouter | ||
110 | } | ||
111 | |||
112 | // --------------------------------------------------------------------------- | ||
113 | |||
114 | async function getUserVideos (req: express.Request, res: express.Response) { | ||
115 | const user = res.locals.oauth.token.User | ||
116 | |||
117 | const apiOptions = await Hooks.wrapObject({ | ||
118 | accountId: user.Account.id, | ||
119 | start: req.query.start, | ||
120 | count: req.query.count, | ||
121 | sort: req.query.sort, | ||
122 | search: req.query.search, | ||
123 | channelId: res.locals.videoChannel?.id, | ||
124 | isLive: req.query.isLive | ||
125 | }, 'filter:api.user.me.videos.list.params') | ||
126 | |||
127 | const resultList = await Hooks.wrapPromiseFun( | ||
128 | VideoModel.listUserVideosForApi, | ||
129 | apiOptions, | ||
130 | 'filter:api.user.me.videos.list.result' | ||
131 | ) | ||
132 | |||
133 | const additionalAttributes = { | ||
134 | waitTranscoding: true, | ||
135 | state: true, | ||
136 | scheduledUpdate: true, | ||
137 | blacklistInfo: true | ||
138 | } | ||
139 | return res.json(getFormattedObjects(resultList.data, resultList.total, { additionalAttributes })) | ||
140 | } | ||
141 | |||
142 | async function getUserVideoImports (req: express.Request, res: express.Response) { | ||
143 | const user = res.locals.oauth.token.User | ||
144 | const resultList = await VideoImportModel.listUserVideoImportsForApi({ | ||
145 | userId: user.id, | ||
146 | |||
147 | ...pick(req.query, [ 'targetUrl', 'start', 'count', 'sort', 'search', 'videoChannelSyncId' ]) | ||
148 | }) | ||
149 | |||
150 | return res.json(getFormattedObjects(resultList.data, resultList.total)) | ||
151 | } | ||
152 | |||
153 | async function getUserInformation (req: express.Request, res: express.Response) { | ||
154 | // We did not load channels in res.locals.user | ||
155 | const user = await UserModel.loadForMeAPI(res.locals.oauth.token.user.id) | ||
156 | |||
157 | return res.json(user.toMeFormattedJSON()) | ||
158 | } | ||
159 | |||
160 | async function getUserVideoQuotaUsed (req: express.Request, res: express.Response) { | ||
161 | const user = res.locals.oauth.token.user | ||
162 | const videoQuotaUsed = await getOriginalVideoFileTotalFromUser(user) | ||
163 | const videoQuotaUsedDaily = await getOriginalVideoFileTotalDailyFromUser(user) | ||
164 | |||
165 | const data: UserVideoQuota = { | ||
166 | videoQuotaUsed, | ||
167 | videoQuotaUsedDaily | ||
168 | } | ||
169 | return res.json(data) | ||
170 | } | ||
171 | |||
172 | async function getUserVideoRating (req: express.Request, res: express.Response) { | ||
173 | const videoId = res.locals.videoId.id | ||
174 | const accountId = +res.locals.oauth.token.User.Account.id | ||
175 | |||
176 | const ratingObj = await AccountVideoRateModel.load(accountId, videoId, null) | ||
177 | const rating = ratingObj ? ratingObj.type : 'none' | ||
178 | |||
179 | const json: FormattedUserVideoRate = { | ||
180 | videoId, | ||
181 | rating | ||
182 | } | ||
183 | return res.json(json) | ||
184 | } | ||
185 | |||
186 | async function deleteMe (req: express.Request, res: express.Response) { | ||
187 | const user = await UserModel.loadByIdWithChannels(res.locals.oauth.token.User.id) | ||
188 | |||
189 | auditLogger.delete(getAuditIdFromRes(res), new UserAuditView(user.toFormattedJSON())) | ||
190 | |||
191 | await user.destroy() | ||
192 | |||
193 | return res.status(HttpStatusCode.NO_CONTENT_204).end() | ||
194 | } | ||
195 | |||
196 | async function updateMe (req: express.Request, res: express.Response) { | ||
197 | const body: UserUpdateMe = req.body | ||
198 | let sendVerificationEmail = false | ||
199 | |||
200 | const user = res.locals.oauth.token.user | ||
201 | |||
202 | const keysToUpdate: (keyof UserUpdateMe & keyof AttributesOnly<UserModel>)[] = [ | ||
203 | 'password', | ||
204 | 'nsfwPolicy', | ||
205 | 'p2pEnabled', | ||
206 | 'autoPlayVideo', | ||
207 | 'autoPlayNextVideo', | ||
208 | 'autoPlayNextVideoPlaylist', | ||
209 | 'videosHistoryEnabled', | ||
210 | 'videoLanguages', | ||
211 | 'theme', | ||
212 | 'noInstanceConfigWarningModal', | ||
213 | 'noAccountSetupWarningModal', | ||
214 | 'noWelcomeModal', | ||
215 | 'emailPublic', | ||
216 | 'p2pEnabled' | ||
217 | ] | ||
218 | |||
219 | for (const key of keysToUpdate) { | ||
220 | if (body[key] !== undefined) user.set(key, body[key]) | ||
221 | } | ||
222 | |||
223 | if (body.email !== undefined) { | ||
224 | if (CONFIG.SIGNUP.REQUIRES_EMAIL_VERIFICATION) { | ||
225 | user.pendingEmail = body.email | ||
226 | sendVerificationEmail = true | ||
227 | } else { | ||
228 | user.email = body.email | ||
229 | } | ||
230 | } | ||
231 | |||
232 | await sequelizeTypescript.transaction(async t => { | ||
233 | await user.save({ transaction: t }) | ||
234 | |||
235 | if (body.displayName === undefined && body.description === undefined) return | ||
236 | |||
237 | const userAccount = await AccountModel.load(user.Account.id, t) | ||
238 | |||
239 | if (body.displayName !== undefined) userAccount.name = body.displayName | ||
240 | if (body.description !== undefined) userAccount.description = body.description | ||
241 | await userAccount.save({ transaction: t }) | ||
242 | |||
243 | await sendUpdateActor(userAccount, t) | ||
244 | }) | ||
245 | |||
246 | if (sendVerificationEmail === true) { | ||
247 | await sendVerifyUserEmail(user, true) | ||
248 | } | ||
249 | |||
250 | return res.status(HttpStatusCode.NO_CONTENT_204).end() | ||
251 | } | ||
252 | |||
253 | async function updateMyAvatar (req: express.Request, res: express.Response) { | ||
254 | const avatarPhysicalFile = req.files['avatarfile'][0] | ||
255 | const user = res.locals.oauth.token.user | ||
256 | |||
257 | const userAccount = await AccountModel.load(user.Account.id) | ||
258 | |||
259 | const avatars = await updateLocalActorImageFiles( | ||
260 | userAccount, | ||
261 | avatarPhysicalFile, | ||
262 | ActorImageType.AVATAR | ||
263 | ) | ||
264 | |||
265 | return res.json({ | ||
266 | avatars: avatars.map(avatar => avatar.toFormattedJSON()) | ||
267 | }) | ||
268 | } | ||
269 | |||
270 | async function deleteMyAvatar (req: express.Request, res: express.Response) { | ||
271 | const user = res.locals.oauth.token.user | ||
272 | |||
273 | const userAccount = await AccountModel.load(user.Account.id) | ||
274 | await deleteLocalActorImageFile(userAccount, ActorImageType.AVATAR) | ||
275 | |||
276 | return res.json({ avatars: [] }) | ||
277 | } | ||