aboutsummaryrefslogtreecommitdiffhomepage
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/controllers/api/users/me.ts18
-rw-r--r--server/controllers/api/video-channel.ts19
-rw-r--r--server/lib/activitypub/actor.ts14
-rw-r--r--server/lib/avatar.ts22
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'
10import { MIMETYPES } from '../../../initializers/constants' 10import { MIMETYPES } from '../../../initializers/constants'
11import { sequelizeTypescript } from '../../../initializers/database' 11import { sequelizeTypescript } from '../../../initializers/database'
12import { sendUpdateActor } from '../../../lib/activitypub/send' 12import { sendUpdateActor } from '../../../lib/activitypub/send'
13import { updateActorAvatarFile } from '../../../lib/avatar' 13import { deleteActorAvatarFile, updateActorAvatarFile } from '../../../lib/avatar'
14import { getOriginalVideoFileTotalDailyFromUser, getOriginalVideoFileTotalFromUser, sendVerifyUserEmail } from '../../../lib/user' 14import { getOriginalVideoFileTotalDailyFromUser, getOriginalVideoFileTotalFromUser, sendVerifyUserEmail } from '../../../lib/user'
15import { 15import {
16 asyncMiddleware, 16 asyncMiddleware,
@@ -89,6 +89,11 @@ meRouter.post('/me/avatar/pick',
89 asyncRetryTransactionMiddleware(updateMyAvatar) 89 asyncRetryTransactionMiddleware(updateMyAvatar)
90) 90)
91 91
92meRouter.delete('/me/avatar',
93 authenticate,
94 asyncRetryTransactionMiddleware(deleteMyAvatar)
95)
96
92// --------------------------------------------------------------------------- 97// ---------------------------------------------------------------------------
93 98
94export { 99export {
@@ -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
238async 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'
13import { sequelizeTypescript } from '../../initializers/database' 13import { sequelizeTypescript } from '../../initializers/database'
14import { setAsyncActorKeys } from '../../lib/activitypub/actor' 14import { setAsyncActorKeys } from '../../lib/activitypub/actor'
15import { sendUpdateActor } from '../../lib/activitypub/send' 15import { sendUpdateActor } from '../../lib/activitypub/send'
16import { updateActorAvatarFile } from '../../lib/avatar' 16import { deleteActorAvatarFile, updateActorAvatarFile } from '../../lib/avatar'
17import { JobQueue } from '../../lib/job-queue' 17import { JobQueue } from '../../lib/job-queue'
18import { createLocalVideoChannel, federateAllVideosOfChannel } from '../../lib/video-channel' 18import { createLocalVideoChannel, federateAllVideosOfChannel } from '../../lib/video-channel'
19import { 19import {
@@ -70,6 +70,13 @@ videoChannelRouter.post('/:nameWithHost/avatar/pick',
70 asyncMiddleware(updateVideoChannelAvatar) 70 asyncMiddleware(updateVideoChannelAvatar)
71) 71)
72 72
73videoChannelRouter.delete('/:nameWithHost/avatar',
74 authenticate,
75 // Check the rights
76 asyncMiddleware(videoChannelsUpdateValidator),
77 asyncMiddleware(deleteVideoChannelAvatar)
78)
79
73videoChannelRouter.put('/:nameWithHost', 80videoChannelRouter.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
154async 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
147async function addVideoChannel (req: express.Request, res: express.Response) { 162async 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
202async 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
202async function fetchActorTotalItems (url: string) { 215async 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 @@
1import 'multer' 1import 'multer'
2import { sendUpdateActor } from './activitypub/send' 2import { sendUpdateActor } from './activitypub/send'
3import { AVATARS_SIZE, LRU_CACHE, QUEUE_CONCURRENCY } from '../initializers/constants' 3import { AVATARS_SIZE, LRU_CACHE, QUEUE_CONCURRENCY } from '../initializers/constants'
4import { updateActorAvatarInstance } from './activitypub/actor' 4import { updateActorAvatarInstance, deleteActorAvatarInstance } from './activitypub/actor'
5import { processImage } from '../helpers/image-utils' 5import { processImage } from '../helpers/image-utils'
6import { extname, join } from 'path' 6import { extname, join } from 'path'
7import { retryTransactionWrapper } from '../helpers/database-utils' 7import { retryTransactionWrapper } from '../helpers/database-utils'
@@ -14,8 +14,8 @@ import { downloadImage } from '../helpers/requests'
14import { MAccountDefault, MChannelDefault } from '../types/models' 14import { MAccountDefault, MChannelDefault } from '../types/models'
15 15
16async function updateActorAvatarFile ( 16async 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
43async 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
43type DownloadImageQueueTask = { fileUrl: string, filename: string } 58type DownloadImageQueueTask = { fileUrl: string, filename: string }
44 59
45const downloadImageQueue = queue<DownloadImageQueueTask, Error>((task, cb) => { 60const downloadImageQueue = queue<DownloadImageQueueTask, Error>((task, cb) => {
@@ -64,5 +79,6 @@ const avatarPathUnsafeCache = new LRUCache<string, string>({ max: LRU_CACHE.AVAT
64export { 79export {
65 avatarPathUnsafeCache, 80 avatarPathUnsafeCache,
66 updateActorAvatarFile, 81 updateActorAvatarFile,
82 deleteActorAvatarFile,
67 pushAvatarProcessInQueue 83 pushAvatarProcessInQueue
68} 84}