diff options
Diffstat (limited to 'server')
-rw-r--r-- | server/controllers/api/users/me.ts | 18 | ||||
-rw-r--r-- | server/controllers/api/video-channel.ts | 19 | ||||
-rw-r--r-- | server/lib/activitypub/actor.ts | 14 | ||||
-rw-r--r-- | server/lib/avatar.ts | 22 |
4 files changed, 66 insertions, 7 deletions
diff --git a/server/controllers/api/users/me.ts b/server/controllers/api/users/me.ts index 7ab089713..009cf42b7 100644 --- a/server/controllers/api/users/me.ts +++ b/server/controllers/api/users/me.ts | |||
@@ -10,7 +10,7 @@ import { CONFIG } from '../../../initializers/config' | |||
10 | import { MIMETYPES } from '../../../initializers/constants' | 10 | import { MIMETYPES } from '../../../initializers/constants' |
11 | import { sequelizeTypescript } from '../../../initializers/database' | 11 | import { sequelizeTypescript } from '../../../initializers/database' |
12 | import { sendUpdateActor } from '../../../lib/activitypub/send' | 12 | import { sendUpdateActor } from '../../../lib/activitypub/send' |
13 | import { updateActorAvatarFile } from '../../../lib/avatar' | 13 | import { deleteActorAvatarFile, updateActorAvatarFile } from '../../../lib/avatar' |
14 | import { getOriginalVideoFileTotalDailyFromUser, getOriginalVideoFileTotalFromUser, sendVerifyUserEmail } from '../../../lib/user' | 14 | import { getOriginalVideoFileTotalDailyFromUser, getOriginalVideoFileTotalFromUser, sendVerifyUserEmail } from '../../../lib/user' |
15 | import { | 15 | import { |
16 | asyncMiddleware, | 16 | asyncMiddleware, |
@@ -89,6 +89,11 @@ meRouter.post('/me/avatar/pick', | |||
89 | asyncRetryTransactionMiddleware(updateMyAvatar) | 89 | asyncRetryTransactionMiddleware(updateMyAvatar) |
90 | ) | 90 | ) |
91 | 91 | ||
92 | meRouter.delete('/me/avatar', | ||
93 | authenticate, | ||
94 | asyncRetryTransactionMiddleware(deleteMyAvatar) | ||
95 | ) | ||
96 | |||
92 | // --------------------------------------------------------------------------- | 97 | // --------------------------------------------------------------------------- |
93 | 98 | ||
94 | export { | 99 | export { |
@@ -225,7 +230,16 @@ async function updateMyAvatar (req: express.Request, res: express.Response) { | |||
225 | 230 | ||
226 | const userAccount = await AccountModel.load(user.Account.id) | 231 | const userAccount = await AccountModel.load(user.Account.id) |
227 | 232 | ||
228 | const avatar = await updateActorAvatarFile(avatarPhysicalFile, userAccount) | 233 | const avatar = await updateActorAvatarFile(userAccount, avatarPhysicalFile) |
229 | 234 | ||
230 | return res.json({ avatar: avatar.toFormattedJSON() }) | 235 | return res.json({ avatar: avatar.toFormattedJSON() }) |
231 | } | 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 | } | ||
diff --git a/server/controllers/api/video-channel.ts b/server/controllers/api/video-channel.ts index c48e00232..7ac01b0ef 100644 --- a/server/controllers/api/video-channel.ts +++ b/server/controllers/api/video-channel.ts | |||
@@ -13,7 +13,7 @@ import { MIMETYPES } from '../../initializers/constants' | |||
13 | import { sequelizeTypescript } from '../../initializers/database' | 13 | import { sequelizeTypescript } from '../../initializers/database' |
14 | import { setAsyncActorKeys } from '../../lib/activitypub/actor' | 14 | import { setAsyncActorKeys } from '../../lib/activitypub/actor' |
15 | import { sendUpdateActor } from '../../lib/activitypub/send' | 15 | import { sendUpdateActor } from '../../lib/activitypub/send' |
16 | import { updateActorAvatarFile } from '../../lib/avatar' | 16 | import { deleteActorAvatarFile, updateActorAvatarFile } from '../../lib/avatar' |
17 | import { JobQueue } from '../../lib/job-queue' | 17 | import { JobQueue } from '../../lib/job-queue' |
18 | import { createLocalVideoChannel, federateAllVideosOfChannel } from '../../lib/video-channel' | 18 | import { createLocalVideoChannel, federateAllVideosOfChannel } from '../../lib/video-channel' |
19 | import { | 19 | import { |
@@ -70,6 +70,13 @@ videoChannelRouter.post('/:nameWithHost/avatar/pick', | |||
70 | asyncMiddleware(updateVideoChannelAvatar) | 70 | asyncMiddleware(updateVideoChannelAvatar) |
71 | ) | 71 | ) |
72 | 72 | ||
73 | videoChannelRouter.delete('/:nameWithHost/avatar', | ||
74 | authenticate, | ||
75 | // Check the rights | ||
76 | asyncMiddleware(videoChannelsUpdateValidator), | ||
77 | asyncMiddleware(deleteVideoChannelAvatar) | ||
78 | ) | ||
79 | |||
73 | videoChannelRouter.put('/:nameWithHost', | 80 | videoChannelRouter.put('/:nameWithHost', |
74 | authenticate, | 81 | authenticate, |
75 | asyncMiddleware(videoChannelsUpdateValidator), | 82 | asyncMiddleware(videoChannelsUpdateValidator), |
@@ -133,7 +140,7 @@ async function updateVideoChannelAvatar (req: express.Request, res: express.Resp | |||
133 | const videoChannel = res.locals.videoChannel | 140 | const videoChannel = res.locals.videoChannel |
134 | const oldVideoChannelAuditKeys = new VideoChannelAuditView(videoChannel.toFormattedJSON()) | 141 | const oldVideoChannelAuditKeys = new VideoChannelAuditView(videoChannel.toFormattedJSON()) |
135 | 142 | ||
136 | const avatar = await updateActorAvatarFile(avatarPhysicalFile, videoChannel) | 143 | const avatar = await updateActorAvatarFile(videoChannel, avatarPhysicalFile) |
137 | 144 | ||
138 | auditLogger.update(getAuditIdFromRes(res), new VideoChannelAuditView(videoChannel.toFormattedJSON()), oldVideoChannelAuditKeys) | 145 | auditLogger.update(getAuditIdFromRes(res), new VideoChannelAuditView(videoChannel.toFormattedJSON()), oldVideoChannelAuditKeys) |
139 | 146 | ||
@@ -144,6 +151,14 @@ async function updateVideoChannelAvatar (req: express.Request, res: express.Resp | |||
144 | .end() | 151 | .end() |
145 | } | 152 | } |
146 | 153 | ||
154 | async function deleteVideoChannelAvatar (req: express.Request, res: express.Response) { | ||
155 | const videoChannel = res.locals.videoChannel | ||
156 | |||
157 | await deleteActorAvatarFile(videoChannel) | ||
158 | |||
159 | return res.sendStatus(HttpStatusCode.NO_CONTENT_204) | ||
160 | } | ||
161 | |||
147 | async function addVideoChannel (req: express.Request, res: express.Response) { | 162 | async function addVideoChannel (req: express.Request, res: express.Response) { |
148 | const videoChannelInfo: VideoChannelCreate = req.body | 163 | const videoChannelInfo: VideoChannelCreate = req.body |
149 | 164 | ||
diff --git a/server/lib/activitypub/actor.ts b/server/lib/activitypub/actor.ts index 52547536c..086d656f9 100644 --- a/server/lib/activitypub/actor.ts +++ b/server/lib/activitypub/actor.ts | |||
@@ -199,6 +199,19 @@ async function updateActorAvatarInstance (actor: MActorDefault, info: AvatarInfo | |||
199 | return actor | 199 | return actor |
200 | } | 200 | } |
201 | 201 | ||
202 | async function deleteActorAvatarInstance (actor: MActorDefault, t: Transaction) { | ||
203 | try { | ||
204 | await actor.Avatar.destroy({ transaction: t }) | ||
205 | } catch (err) { | ||
206 | logger.error('Cannot remove old avatar of actor %s.', actor.url, { err }) | ||
207 | } | ||
208 | |||
209 | actor.avatarId = null | ||
210 | actor.Avatar = null | ||
211 | |||
212 | return actor | ||
213 | } | ||
214 | |||
202 | async function fetchActorTotalItems (url: string) { | 215 | async function fetchActorTotalItems (url: string) { |
203 | const options = { | 216 | const options = { |
204 | uri: url, | 217 | uri: url, |
@@ -337,6 +350,7 @@ export { | |||
337 | fetchActorTotalItems, | 350 | fetchActorTotalItems, |
338 | getAvatarInfoIfExists, | 351 | getAvatarInfoIfExists, |
339 | updateActorInstance, | 352 | updateActorInstance, |
353 | deleteActorAvatarInstance, | ||
340 | refreshActorIfNeeded, | 354 | refreshActorIfNeeded, |
341 | updateActorAvatarInstance, | 355 | updateActorAvatarInstance, |
342 | addFetchOutboxJob | 356 | addFetchOutboxJob |
diff --git a/server/lib/avatar.ts b/server/lib/avatar.ts index be6657b6f..9d59a4966 100644 --- a/server/lib/avatar.ts +++ b/server/lib/avatar.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | import 'multer' | 1 | import 'multer' |
2 | import { sendUpdateActor } from './activitypub/send' | 2 | import { sendUpdateActor } from './activitypub/send' |
3 | import { AVATARS_SIZE, LRU_CACHE, QUEUE_CONCURRENCY } from '../initializers/constants' | 3 | import { AVATARS_SIZE, LRU_CACHE, QUEUE_CONCURRENCY } from '../initializers/constants' |
4 | import { updateActorAvatarInstance } from './activitypub/actor' | 4 | import { updateActorAvatarInstance, deleteActorAvatarInstance } from './activitypub/actor' |
5 | import { processImage } from '../helpers/image-utils' | 5 | import { processImage } from '../helpers/image-utils' |
6 | import { extname, join } from 'path' | 6 | import { extname, join } from 'path' |
7 | import { retryTransactionWrapper } from '../helpers/database-utils' | 7 | import { retryTransactionWrapper } from '../helpers/database-utils' |
@@ -14,8 +14,8 @@ import { downloadImage } from '../helpers/requests' | |||
14 | import { MAccountDefault, MChannelDefault } from '../types/models' | 14 | import { MAccountDefault, MChannelDefault } from '../types/models' |
15 | 15 | ||
16 | async function updateActorAvatarFile ( | 16 | async function updateActorAvatarFile ( |
17 | avatarPhysicalFile: Express.Multer.File, | 17 | accountOrChannel: MAccountDefault | MChannelDefault, |
18 | accountOrChannel: MAccountDefault | MChannelDefault | 18 | avatarPhysicalFile: Express.Multer.File |
19 | ) { | 19 | ) { |
20 | const extension = extname(avatarPhysicalFile.filename) | 20 | const extension = extname(avatarPhysicalFile.filename) |
21 | const avatarName = uuidv4() + extension | 21 | const avatarName = uuidv4() + extension |
@@ -40,6 +40,21 @@ async function updateActorAvatarFile ( | |||
40 | }) | 40 | }) |
41 | } | 41 | } |
42 | 42 | ||
43 | async function deleteActorAvatarFile ( | ||
44 | accountOrChannel: MAccountDefault | MChannelDefault | ||
45 | ) { | ||
46 | return retryTransactionWrapper(() => { | ||
47 | return sequelizeTypescript.transaction(async t => { | ||
48 | const updatedActor = await deleteActorAvatarInstance(accountOrChannel.Actor, t) | ||
49 | await updatedActor.save({ transaction: t }) | ||
50 | |||
51 | await sendUpdateActor(accountOrChannel, t) | ||
52 | |||
53 | return updatedActor.Avatar | ||
54 | }) | ||
55 | }) | ||
56 | } | ||
57 | |||
43 | type DownloadImageQueueTask = { fileUrl: string, filename: string } | 58 | type DownloadImageQueueTask = { fileUrl: string, filename: string } |
44 | 59 | ||
45 | const downloadImageQueue = queue<DownloadImageQueueTask, Error>((task, cb) => { | 60 | const downloadImageQueue = queue<DownloadImageQueueTask, Error>((task, cb) => { |
@@ -64,5 +79,6 @@ const avatarPathUnsafeCache = new LRUCache<string, string>({ max: LRU_CACHE.AVAT | |||
64 | export { | 79 | export { |
65 | avatarPathUnsafeCache, | 80 | avatarPathUnsafeCache, |
66 | updateActorAvatarFile, | 81 | updateActorAvatarFile, |
82 | deleteActorAvatarFile, | ||
67 | pushAvatarProcessInQueue | 83 | pushAvatarProcessInQueue |
68 | } | 84 | } |