From 696de8ea50ec43e06a39de55466f6454319e4ed1 Mon Sep 17 00:00:00 2001 From: Hongbo Wu Date: Fri, 22 Dec 2023 08:08:15 +0800 Subject: [PATCH 1/2] check both user provided url and parsed feed url when looking for existing subscription --- .../api/src/resolvers/subscriptions/index.ts | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/packages/api/src/resolvers/subscriptions/index.ts b/packages/api/src/resolvers/subscriptions/index.ts index 120dedc95..98dd23e3f 100644 --- a/packages/api/src/resolvers/subscriptions/index.ts +++ b/packages/api/src/resolvers/subscriptions/index.ts @@ -193,9 +193,18 @@ export const subscribeResolver = authorized< }, }) + // validate rss feed + const feed = await parseFeed(input.url) + if (!feed) { + return { + errorCodes: [SubscribeErrorCode.NotFound], + } + } + const feedUrl = feed.url + // find existing subscription const existingSubscription = await getRepository(Subscription).findOneBy({ - url: input.url, + url: feedUrl, user: { id: uid }, type: SubscriptionType.Rss, }) @@ -218,7 +227,7 @@ export const subscribeResolver = authorized< // create a cloud task to fetch rss feed item for resub subscription await enqueueRssFeedFetch({ userIds: [uid], - url: input.url, + url: feedUrl, subscriptionIds: [updatedSubscription.id], scheduledDates: [new Date()], // fetch immediately fetchedDates: [updatedSubscription.lastFetchedAt || null], @@ -234,13 +243,6 @@ export const subscribeResolver = authorized< // create new rss subscription const MAX_RSS_SUBSCRIPTIONS = env.subscription.feed.max - // validate rss feed - const feed = await parseFeed(input.url) - if (!feed) { - return { - errorCodes: [SubscribeErrorCode.NotFound], - } - } // limit number of rss subscriptions to max const results = (await getRepository(Subscription).query( @@ -251,7 +253,7 @@ export const subscribeResolver = authorized< returning *;`, [ feed.title, - feed.url, + feedUrl, feed.description, SubscriptionType.Rss, uid, @@ -275,7 +277,7 @@ export const subscribeResolver = authorized< // create a cloud task to fetch rss feed item for the new subscription await enqueueRssFeedFetch({ userIds: [uid], - url: feed.url, + url: feedUrl, subscriptionIds: [newSubscription.id], scheduledDates: [new Date()], // fetch immediately fetchedDates: [null], From f6e04daf6006ec8472e6b03a531da7ed57b2f3a2 Mon Sep 17 00:00:00 2001 From: Hongbo Wu Date: Fri, 22 Dec 2023 09:05:43 +0800 Subject: [PATCH 2/2] return invalid url if feed url is different from user provided url --- packages/api/src/generated/graphql.ts | 1 + packages/api/src/generated/schema.graphql | 1 + packages/api/src/resolvers/subscriptions/index.ts | 14 ++++++++++++-- packages/api/src/schema.ts | 1 + 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/packages/api/src/generated/graphql.ts b/packages/api/src/generated/graphql.ts index 62ba7be07..f2fa24d95 100644 --- a/packages/api/src/generated/graphql.ts +++ b/packages/api/src/generated/graphql.ts @@ -2790,6 +2790,7 @@ export enum SubscribeErrorCode { AlreadySubscribed = 'ALREADY_SUBSCRIBED', BadRequest = 'BAD_REQUEST', ExceededMaxSubscriptions = 'EXCEEDED_MAX_SUBSCRIPTIONS', + InvalidUrl = 'INVALID_URL', NotFound = 'NOT_FOUND', Unauthorized = 'UNAUTHORIZED' } diff --git a/packages/api/src/generated/schema.graphql b/packages/api/src/generated/schema.graphql index cbcdc1808..ac0db6c82 100644 --- a/packages/api/src/generated/schema.graphql +++ b/packages/api/src/generated/schema.graphql @@ -2190,6 +2190,7 @@ enum SubscribeErrorCode { ALREADY_SUBSCRIBED BAD_REQUEST EXCEEDED_MAX_SUBSCRIPTIONS + INVALID_URL NOT_FOUND UNAUTHORIZED } diff --git a/packages/api/src/resolvers/subscriptions/index.ts b/packages/api/src/resolvers/subscriptions/index.ts index 98dd23e3f..5ec3adc9f 100644 --- a/packages/api/src/resolvers/subscriptions/index.ts +++ b/packages/api/src/resolvers/subscriptions/index.ts @@ -1,6 +1,6 @@ import axios from 'axios' import { parseHTML } from 'linkedom' -import { Brackets } from 'typeorm' +import { Brackets, In } from 'typeorm' import { DEFAULT_SUBSCRIPTION_FOLDER, Subscription, @@ -204,7 +204,7 @@ export const subscribeResolver = authorized< // find existing subscription const existingSubscription = await getRepository(Subscription).findOneBy({ - url: feedUrl, + url: In([feedUrl, input.url]), // check both user provided url and parsed url user: { id: uid }, type: SubscriptionType.Rss, }) @@ -241,6 +241,16 @@ export const subscribeResolver = authorized< } } + if (feedUrl !== input.url) { + log.info('feed url is different from user provided url', { + feedUrl, + inputUrl: input.url, + }) + return { + errorCodes: [SubscribeErrorCode.InvalidUrl], + } + } + // create new rss subscription const MAX_RSS_SUBSCRIPTIONS = env.subscription.feed.max diff --git a/packages/api/src/schema.ts b/packages/api/src/schema.ts index 4df9a5b35..ac1fdd125 100755 --- a/packages/api/src/schema.ts +++ b/packages/api/src/schema.ts @@ -1737,6 +1737,7 @@ const schema = gql` NOT_FOUND ALREADY_SUBSCRIBED EXCEEDED_MAX_SUBSCRIPTIONS + INVALID_URL } union AddPopularReadResult = AddPopularReadSuccess | AddPopularReadError