From afff310e50f2fa8419bb4242470cbde46ab54463 Mon Sep 17 00:00:00 2001 From: Rigel Kent Date: Thu, 13 Aug 2020 15:07:23 +0200 Subject: allow private syndication feeds via a user feedToken --- server/controllers/api/users/token.ts | 31 +++++++++++++++++++++++++++++++ server/controllers/feeds.ts | 32 +++++++++++++++++++++++++++----- 2 files changed, 58 insertions(+), 5 deletions(-) (limited to 'server/controllers') 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' import * as express from 'express' import { Hooks } from '@server/lib/plugins/hooks' import { asyncMiddleware, authenticate } from '@server/middlewares' +import { ScopedToken } from '@shared/models/users/user-scoped-token' +import { v4 as uuidv4 } from 'uuid' const tokensRouter = express.Router() @@ -23,6 +25,16 @@ tokensRouter.post('/revoke-token', asyncMiddleware(handleTokenRevocation) ) +tokensRouter.get('/scoped-tokens', + authenticate, + getScopedTokens +) + +tokensRouter.post('/scoped-tokens', + authenticate, + asyncMiddleware(renewScopedTokens) +) + // --------------------------------------------------------------------------- export { @@ -35,3 +47,22 @@ function tokenSuccess (req: express.Request) { Hooks.runAction('action:api.user.oauth2-got-token', { username, ip: req.ip }) } + +function getScopedTokens (req: express.Request, res: express.Response) { + const user = res.locals.oauth.token.user + + return res.json({ + feedToken: user.feedToken + } as ScopedToken) +} + +async function renewScopedTokens (req: express.Request, res: express.Response) { + const user = res.locals.oauth.token.user + + user.feedToken = uuidv4() + await user.save() + + return res.json({ + feedToken: user.feedToken + } as ScopedToken) +} 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 { setFeedFormatContentType, videoCommentsFeedsValidator, videoFeedsValidator, - videosSortValidator + videosSortValidator, + videoSubscriptonFeedsValidator } from '../middlewares' import { cacheRoute } from '../middlewares/cache' import { VideoModel } from '../models/video/video' import { VideoCommentModel } from '../models/video/video-comment' +import { VideoFilter } from '../../shared/models/videos/video-query.type' +import { logger } from '../helpers/logger' const feedsRouter = express.Router() @@ -44,6 +47,7 @@ feedsRouter.get('/feeds/videos.:format', })(ROUTE_CACHE_LIFETIME.FEEDS)), commonVideosFiltersValidator, asyncMiddleware(videoFeedsValidator), + asyncMiddleware(videoSubscriptonFeedsValidator), asyncMiddleware(generateVideoFeed) ) @@ -124,6 +128,7 @@ async function generateVideoFeed (req: express.Request, res: express.Response) { const account = res.locals.account const videoChannel = res.locals.videoChannel + const token = req.query.token const nsfw = buildNSFWFilter(res, req.query.nsfw) let name: string @@ -147,19 +152,36 @@ async function generateVideoFeed (req: express.Request, res: express.Response) { queryString: new URL(WEBSERVER.URL + req.url).search }) + /** + * We have two ways to query video results: + * - one with account and token -> get subscription videos + * - one with either account, channel, or nothing: just videos with these filters + */ + const options = token && token !== '' && res.locals.user + ? { + followerActorId: res.locals.user.Account.Actor.id, + user: res.locals.user, + includeLocalVideos: false + } + : { + accountId: account ? account.id : null, + videoChannelId: videoChannel ? videoChannel.id : null + } + const resultList = await VideoModel.listForApi({ start, count: FEEDS.COUNT, sort: req.query.sort, includeLocalVideos: true, nsfw, - filter: req.query.filter, + filter: req.query.filter as VideoFilter, withFiles: true, - accountId: account ? account.id : null, - videoChannelId: videoChannel ? videoChannel.id : null + ...options }) - // Adding video items to the feed, one at a time + /** + * Adding video items to the feed object, one at a time + */ resultList.data.forEach(video => { const formattedVideoFiles = video.getFormattedVideoFilesJSON() -- cgit v1.2.3