diff options
Diffstat (limited to 'server/controllers')
-rw-r--r-- | server/controllers/api/users/token.ts | 31 | ||||
-rw-r--r-- | server/controllers/feeds.ts | 32 |
2 files changed, 58 insertions, 5 deletions
diff --git a/server/controllers/api/users/token.ts b/server/controllers/api/users/token.ts index 41aa26769..821429358 100644 --- a/server/controllers/api/users/token.ts +++ b/server/controllers/api/users/token.ts | |||
@@ -4,6 +4,8 @@ import { CONFIG } from '@server/initializers/config' | |||
4 | import * as express from 'express' | 4 | import * as express from 'express' |
5 | import { Hooks } from '@server/lib/plugins/hooks' | 5 | import { Hooks } from '@server/lib/plugins/hooks' |
6 | import { asyncMiddleware, authenticate } from '@server/middlewares' | 6 | import { asyncMiddleware, authenticate } from '@server/middlewares' |
7 | import { ScopedToken } from '@shared/models/users/user-scoped-token' | ||
8 | import { v4 as uuidv4 } from 'uuid' | ||
7 | 9 | ||
8 | const tokensRouter = express.Router() | 10 | const tokensRouter = express.Router() |
9 | 11 | ||
@@ -23,6 +25,16 @@ tokensRouter.post('/revoke-token', | |||
23 | asyncMiddleware(handleTokenRevocation) | 25 | asyncMiddleware(handleTokenRevocation) |
24 | ) | 26 | ) |
25 | 27 | ||
28 | tokensRouter.get('/scoped-tokens', | ||
29 | authenticate, | ||
30 | getScopedTokens | ||
31 | ) | ||
32 | |||
33 | tokensRouter.post('/scoped-tokens', | ||
34 | authenticate, | ||
35 | asyncMiddleware(renewScopedTokens) | ||
36 | ) | ||
37 | |||
26 | // --------------------------------------------------------------------------- | 38 | // --------------------------------------------------------------------------- |
27 | 39 | ||
28 | export { | 40 | export { |
@@ -35,3 +47,22 @@ function tokenSuccess (req: express.Request) { | |||
35 | 47 | ||
36 | Hooks.runAction('action:api.user.oauth2-got-token', { username, ip: req.ip }) | 48 | Hooks.runAction('action:api.user.oauth2-got-token', { username, ip: req.ip }) |
37 | } | 49 | } |
50 | |||
51 | function getScopedTokens (req: express.Request, res: express.Response) { | ||
52 | const user = res.locals.oauth.token.user | ||
53 | |||
54 | return res.json({ | ||
55 | feedToken: user.feedToken | ||
56 | } as ScopedToken) | ||
57 | } | ||
58 | |||
59 | async function renewScopedTokens (req: express.Request, res: express.Response) { | ||
60 | const user = res.locals.oauth.token.user | ||
61 | |||
62 | user.feedToken = uuidv4() | ||
63 | await user.save() | ||
64 | |||
65 | return res.json({ | ||
66 | feedToken: user.feedToken | ||
67 | } as ScopedToken) | ||
68 | } | ||
diff --git a/server/controllers/feeds.ts b/server/controllers/feeds.ts index f14c0d316..6e9f7e60c 100644 --- a/server/controllers/feeds.ts +++ b/server/controllers/feeds.ts | |||
@@ -11,11 +11,14 @@ import { | |||
11 | setFeedFormatContentType, | 11 | setFeedFormatContentType, |
12 | videoCommentsFeedsValidator, | 12 | videoCommentsFeedsValidator, |
13 | videoFeedsValidator, | 13 | videoFeedsValidator, |
14 | videosSortValidator | 14 | videosSortValidator, |
15 | videoSubscriptonFeedsValidator | ||
15 | } from '../middlewares' | 16 | } from '../middlewares' |
16 | import { cacheRoute } from '../middlewares/cache' | 17 | import { cacheRoute } from '../middlewares/cache' |
17 | import { VideoModel } from '../models/video/video' | 18 | import { VideoModel } from '../models/video/video' |
18 | import { VideoCommentModel } from '../models/video/video-comment' | 19 | import { VideoCommentModel } from '../models/video/video-comment' |
20 | import { VideoFilter } from '../../shared/models/videos/video-query.type' | ||
21 | import { logger } from '../helpers/logger' | ||
19 | 22 | ||
20 | const feedsRouter = express.Router() | 23 | const feedsRouter = express.Router() |
21 | 24 | ||
@@ -44,6 +47,7 @@ feedsRouter.get('/feeds/videos.:format', | |||
44 | })(ROUTE_CACHE_LIFETIME.FEEDS)), | 47 | })(ROUTE_CACHE_LIFETIME.FEEDS)), |
45 | commonVideosFiltersValidator, | 48 | commonVideosFiltersValidator, |
46 | asyncMiddleware(videoFeedsValidator), | 49 | asyncMiddleware(videoFeedsValidator), |
50 | asyncMiddleware(videoSubscriptonFeedsValidator), | ||
47 | asyncMiddleware(generateVideoFeed) | 51 | asyncMiddleware(generateVideoFeed) |
48 | ) | 52 | ) |
49 | 53 | ||
@@ -124,6 +128,7 @@ async function generateVideoFeed (req: express.Request, res: express.Response) { | |||
124 | 128 | ||
125 | const account = res.locals.account | 129 | const account = res.locals.account |
126 | const videoChannel = res.locals.videoChannel | 130 | const videoChannel = res.locals.videoChannel |
131 | const token = req.query.token | ||
127 | const nsfw = buildNSFWFilter(res, req.query.nsfw) | 132 | const nsfw = buildNSFWFilter(res, req.query.nsfw) |
128 | 133 | ||
129 | let name: string | 134 | let name: string |
@@ -147,19 +152,36 @@ async function generateVideoFeed (req: express.Request, res: express.Response) { | |||
147 | queryString: new URL(WEBSERVER.URL + req.url).search | 152 | queryString: new URL(WEBSERVER.URL + req.url).search |
148 | }) | 153 | }) |
149 | 154 | ||
155 | /** | ||
156 | * We have two ways to query video results: | ||
157 | * - one with account and token -> get subscription videos | ||
158 | * - one with either account, channel, or nothing: just videos with these filters | ||
159 | */ | ||
160 | const options = token && token !== '' && res.locals.user | ||
161 | ? { | ||
162 | followerActorId: res.locals.user.Account.Actor.id, | ||
163 | user: res.locals.user, | ||
164 | includeLocalVideos: false | ||
165 | } | ||
166 | : { | ||
167 | accountId: account ? account.id : null, | ||
168 | videoChannelId: videoChannel ? videoChannel.id : null | ||
169 | } | ||
170 | |||
150 | const resultList = await VideoModel.listForApi({ | 171 | const resultList = await VideoModel.listForApi({ |
151 | start, | 172 | start, |
152 | count: FEEDS.COUNT, | 173 | count: FEEDS.COUNT, |
153 | sort: req.query.sort, | 174 | sort: req.query.sort, |
154 | includeLocalVideos: true, | 175 | includeLocalVideos: true, |
155 | nsfw, | 176 | nsfw, |
156 | filter: req.query.filter, | 177 | filter: req.query.filter as VideoFilter, |
157 | withFiles: true, | 178 | withFiles: true, |
158 | accountId: account ? account.id : null, | 179 | ...options |
159 | videoChannelId: videoChannel ? videoChannel.id : null | ||
160 | }) | 180 | }) |
161 | 181 | ||
162 | // Adding video items to the feed, one at a time | 182 | /** |
183 | * Adding video items to the feed object, one at a time | ||
184 | */ | ||
163 | resultList.data.forEach(video => { | 185 | resultList.data.forEach(video => { |
164 | const formattedVideoFiles = video.getFormattedVideoFilesJSON() | 186 | const formattedVideoFiles = video.getFormattedVideoFilesJSON() |
165 | 187 | ||