diff options
Diffstat (limited to 'server/controllers/api/users')
-rw-r--r-- | server/controllers/api/users/index.ts | 3 | ||||
-rw-r--r-- | server/controllers/api/users/me.ts | 114 |
2 files changed, 107 insertions, 10 deletions
diff --git a/server/controllers/api/users/index.ts b/server/controllers/api/users/index.ts index 105244ddd..608d439ac 100644 --- a/server/controllers/api/users/index.ts +++ b/server/controllers/api/users/index.ts | |||
@@ -29,7 +29,6 @@ import { usersAskResetPasswordValidator, usersBlockingValidator, usersResetPassw | |||
29 | import { UserModel } from '../../../models/account/user' | 29 | import { UserModel } from '../../../models/account/user' |
30 | import { OAuthTokenModel } from '../../../models/oauth/oauth-token' | 30 | import { OAuthTokenModel } from '../../../models/oauth/oauth-token' |
31 | import { auditLoggerFactory, UserAuditView } from '../../../helpers/audit-logger' | 31 | import { auditLoggerFactory, UserAuditView } from '../../../helpers/audit-logger' |
32 | import { videosRouter } from '../videos' | ||
33 | import { meRouter } from './me' | 32 | import { meRouter } from './me' |
34 | 33 | ||
35 | const auditLogger = auditLoggerFactory('users') | 34 | const auditLogger = auditLoggerFactory('users') |
@@ -41,7 +40,7 @@ const loginRateLimiter = new RateLimit({ | |||
41 | }) | 40 | }) |
42 | 41 | ||
43 | const usersRouter = express.Router() | 42 | const usersRouter = express.Router() |
44 | videosRouter.use('/', meRouter) | 43 | usersRouter.use('/', meRouter) |
45 | 44 | ||
46 | usersRouter.get('/', | 45 | usersRouter.get('/', |
47 | authenticate, | 46 | authenticate, |
diff --git a/server/controllers/api/users/me.ts b/server/controllers/api/users/me.ts index 1e096a35d..403842163 100644 --- a/server/controllers/api/users/me.ts +++ b/server/controllers/api/users/me.ts | |||
@@ -7,23 +7,35 @@ import { sendUpdateActor } from '../../../lib/activitypub/send' | |||
7 | import { | 7 | import { |
8 | asyncMiddleware, | 8 | asyncMiddleware, |
9 | authenticate, | 9 | authenticate, |
10 | commonVideosFiltersValidator, | ||
10 | paginationValidator, | 11 | paginationValidator, |
11 | setDefaultPagination, | 12 | setDefaultPagination, |
12 | setDefaultSort, | 13 | setDefaultSort, |
14 | userSubscriptionAddValidator, | ||
15 | userSubscriptionRemoveValidator, | ||
13 | usersUpdateMeValidator, | 16 | usersUpdateMeValidator, |
14 | usersVideoRatingValidator | 17 | usersVideoRatingValidator |
15 | } from '../../../middlewares' | 18 | } from '../../../middlewares' |
16 | import { deleteMeValidator, videoImportsSortValidator, videosSortValidator } from '../../../middlewares/validators' | 19 | import { |
20 | deleteMeValidator, | ||
21 | userSubscriptionsSortValidator, | ||
22 | videoImportsSortValidator, | ||
23 | videosSortValidator | ||
24 | } from '../../../middlewares/validators' | ||
17 | import { AccountVideoRateModel } from '../../../models/account/account-video-rate' | 25 | import { AccountVideoRateModel } from '../../../models/account/account-video-rate' |
18 | import { UserModel } from '../../../models/account/user' | 26 | import { UserModel } from '../../../models/account/user' |
19 | import { VideoModel } from '../../../models/video/video' | 27 | import { VideoModel } from '../../../models/video/video' |
20 | import { VideoSortField } from '../../../../client/src/app/shared/video/sort-field.type' | 28 | import { VideoSortField } from '../../../../client/src/app/shared/video/sort-field.type' |
21 | import { createReqFiles } from '../../../helpers/express-utils' | 29 | import { buildNSFWFilter, createReqFiles } from '../../../helpers/express-utils' |
22 | import { UserVideoQuota } from '../../../../shared/models/users/user-video-quota.model' | 30 | import { UserVideoQuota } from '../../../../shared/models/users/user-video-quota.model' |
23 | import { updateAvatarValidator } from '../../../middlewares/validators/avatar' | 31 | import { updateAvatarValidator } from '../../../middlewares/validators/avatar' |
24 | import { updateActorAvatarFile } from '../../../lib/avatar' | 32 | import { updateActorAvatarFile } from '../../../lib/avatar' |
25 | import { auditLoggerFactory, UserAuditView } from '../../../helpers/audit-logger' | 33 | import { auditLoggerFactory, UserAuditView } from '../../../helpers/audit-logger' |
26 | import { VideoImportModel } from '../../../models/video/video-import' | 34 | import { VideoImportModel } from '../../../models/video/video-import' |
35 | import { VideoFilter } from '../../../../shared/models/videos/video-query.type' | ||
36 | import { ActorFollowModel } from '../../../models/activitypub/actor-follow' | ||
37 | import { JobQueue } from '../../../lib/job-queue' | ||
38 | import { logger } from '../../../helpers/logger' | ||
27 | 39 | ||
28 | const auditLogger = auditLoggerFactory('users-me') | 40 | const auditLogger = auditLoggerFactory('users-me') |
29 | 41 | ||
@@ -83,6 +95,40 @@ meRouter.post('/me/avatar/pick', | |||
83 | asyncMiddleware(updateMyAvatar) | 95 | asyncMiddleware(updateMyAvatar) |
84 | ) | 96 | ) |
85 | 97 | ||
98 | // ##### Subscriptions part ##### | ||
99 | |||
100 | meRouter.get('/me/subscriptions', | ||
101 | authenticate, | ||
102 | paginationValidator, | ||
103 | userSubscriptionsSortValidator, | ||
104 | setDefaultSort, | ||
105 | setDefaultPagination, | ||
106 | asyncMiddleware(getUserSubscriptions) | ||
107 | ) | ||
108 | |||
109 | meRouter.post('/me/subscriptions', | ||
110 | authenticate, | ||
111 | userSubscriptionAddValidator, | ||
112 | asyncMiddleware(addUserSubscription) | ||
113 | ) | ||
114 | |||
115 | meRouter.delete('/me/subscriptions/:uri', | ||
116 | authenticate, | ||
117 | userSubscriptionRemoveValidator, | ||
118 | asyncMiddleware(deleteUserSubscription) | ||
119 | ) | ||
120 | |||
121 | meRouter.get('/me/subscriptions/videos', | ||
122 | authenticate, | ||
123 | authenticate, | ||
124 | paginationValidator, | ||
125 | videosSortValidator, | ||
126 | setDefaultSort, | ||
127 | setDefaultPagination, | ||
128 | commonVideosFiltersValidator, | ||
129 | asyncMiddleware(getUserSubscriptionVideos) | ||
130 | ) | ||
131 | |||
86 | // --------------------------------------------------------------------------- | 132 | // --------------------------------------------------------------------------- |
87 | 133 | ||
88 | export { | 134 | export { |
@@ -91,6 +137,62 @@ export { | |||
91 | 137 | ||
92 | // --------------------------------------------------------------------------- | 138 | // --------------------------------------------------------------------------- |
93 | 139 | ||
140 | async function addUserSubscription (req: express.Request, res: express.Response) { | ||
141 | const user = res.locals.oauth.token.User as UserModel | ||
142 | const [ name, host ] = req.body.uri.split('@') | ||
143 | |||
144 | const payload = { | ||
145 | name, | ||
146 | host, | ||
147 | followerActorId: user.Account.Actor.id | ||
148 | } | ||
149 | |||
150 | JobQueue.Instance.createJob({ type: 'activitypub-follow', payload }) | ||
151 | .catch(err => logger.error('Cannot create follow job for subscription %s.', req.body.uri, err)) | ||
152 | |||
153 | return res.status(204).end() | ||
154 | } | ||
155 | |||
156 | async function deleteUserSubscription (req: express.Request, res: express.Response) { | ||
157 | const subscription: ActorFollowModel = res.locals.subscription | ||
158 | |||
159 | await sequelizeTypescript.transaction(async t => { | ||
160 | return subscription.destroy({ transaction: t }) | ||
161 | }) | ||
162 | |||
163 | return res.type('json').status(204).end() | ||
164 | } | ||
165 | |||
166 | async function getUserSubscriptions (req: express.Request, res: express.Response) { | ||
167 | const user = res.locals.oauth.token.User as UserModel | ||
168 | const actorId = user.Account.Actor.id | ||
169 | |||
170 | const resultList = await ActorFollowModel.listSubscriptionsForApi(actorId, req.query.start, req.query.count, req.query.sort) | ||
171 | |||
172 | return res.json(getFormattedObjects(resultList.data, resultList.total)) | ||
173 | } | ||
174 | |||
175 | async function getUserSubscriptionVideos (req: express.Request, res: express.Response, next: express.NextFunction) { | ||
176 | const user = res.locals.oauth.token.User as UserModel | ||
177 | const resultList = await VideoModel.listForApi({ | ||
178 | start: req.query.start, | ||
179 | count: req.query.count, | ||
180 | sort: req.query.sort, | ||
181 | includeLocalVideos: false, | ||
182 | categoryOneOf: req.query.categoryOneOf, | ||
183 | licenceOneOf: req.query.licenceOneOf, | ||
184 | languageOneOf: req.query.languageOneOf, | ||
185 | tagsOneOf: req.query.tagsOneOf, | ||
186 | tagsAllOf: req.query.tagsAllOf, | ||
187 | nsfw: buildNSFWFilter(res, req.query.nsfw), | ||
188 | filter: req.query.filter as VideoFilter, | ||
189 | withFiles: false, | ||
190 | actorId: user.Account.Actor.id | ||
191 | }) | ||
192 | |||
193 | return res.json(getFormattedObjects(resultList.data, resultList.total)) | ||
194 | } | ||
195 | |||
94 | async function getUserVideos (req: express.Request, res: express.Response, next: express.NextFunction) { | 196 | async function getUserVideos (req: express.Request, res: express.Response, next: express.NextFunction) { |
95 | const user = res.locals.oauth.token.User as UserModel | 197 | const user = res.locals.oauth.token.User as UserModel |
96 | const resultList = await VideoModel.listUserVideosForApi( | 198 | const resultList = await VideoModel.listUserVideosForApi( |
@@ -150,7 +252,7 @@ async function getUserVideoRating (req: express.Request, res: express.Response, | |||
150 | videoId, | 252 | videoId, |
151 | rating | 253 | rating |
152 | } | 254 | } |
153 | res.json(json) | 255 | return res.json(json) |
154 | } | 256 | } |
155 | 257 | ||
156 | async function deleteMe (req: express.Request, res: express.Response) { | 258 | async function deleteMe (req: express.Request, res: express.Response) { |
@@ -207,9 +309,5 @@ async function updateMyAvatar (req: express.Request, res: express.Response, next | |||
207 | oldUserAuditView | 309 | oldUserAuditView |
208 | ) | 310 | ) |
209 | 311 | ||
210 | return res | 312 | return res.json({ avatar: avatar.toFormattedJSON() }) |
211 | .json({ | ||
212 | avatar: avatar.toFormattedJSON() | ||
213 | }) | ||
214 | .end() | ||
215 | } | 313 | } |