diff --git a/keyserver/src/fetchers/community-fetchers.js b/keyserver/src/fetchers/community-fetchers.js --- a/keyserver/src/fetchers/community-fetchers.js +++ b/keyserver/src/fetchers/community-fetchers.js @@ -37,4 +37,18 @@ return communityInfos; } -export { fetchCommunityInfos }; +async function checkIfFarcasterChannelTagIsValid( + farcasterChannelID: string, +): Promise { + const query = SQL` + SELECT id + FROM communities + WHERE farcaster_channel_id = ${farcasterChannelID} + `; + + const [result] = await dbQuery(query); + + return result.length === 1; +} + +export { fetchCommunityInfos, checkIfFarcasterChannelTagIsValid }; diff --git a/keyserver/src/responders/thread-responders.js b/keyserver/src/responders/thread-responders.js --- a/keyserver/src/responders/thread-responders.js +++ b/keyserver/src/responders/thread-responders.js @@ -179,6 +179,7 @@ threadID: tID, calendarQuery: t.maybe(entryQueryInputValidator), inviteLinkSecret: t.maybe(t.String), + farcasterChannelID: t.maybe(t.String), }); async function threadJoinResponder( diff --git a/keyserver/src/updaters/thread-updaters.js b/keyserver/src/updaters/thread-updaters.js --- a/keyserver/src/updaters/thread-updaters.js +++ b/keyserver/src/updaters/thread-updaters.js @@ -45,6 +45,7 @@ import createMessages from '../creators/message-creator.js'; import { createUpdates } from '../creators/update-creator.js'; import { dbQuery, SQL } from '../database/database.js'; +import { checkIfFarcasterChannelTagIsValid } from '../fetchers/community-fetchers.js'; import { checkIfInviteLinkIsValid } from '../fetchers/link-fetchers.js'; import { fetchMessageInfoByID } from '../fetchers/message-fetchers.js'; import { @@ -816,17 +817,28 @@ throw new ServerError('not_logged_in'); } - const permissionCheck = request.inviteLinkSecret - ? checkIfInviteLinkIsValid(request.inviteLinkSecret, request.threadID) - : checkThreadPermission( - viewer, - request.threadID, - threadPermissions.JOIN_THREAD, - ); + let permissionCheckPromise = checkThreadPermission( + viewer, + request.threadID, + threadPermissions.JOIN_THREAD, + ); + + if (request.inviteLinkSecret) { + permissionCheckPromise = checkIfInviteLinkIsValid( + request.inviteLinkSecret, + request.threadID, + ); + } else if (request.farcasterChannelID) { + permissionCheckPromise = checkIfFarcasterChannelTagIsValid( + request.farcasterChannelID, + ); + } + const [isMember, hasPermission] = await Promise.all([ fetchViewerIsMember(viewer, request.threadID), - permissionCheck, + permissionCheckPromise, ]); + if (!hasPermission) { throw new ServerError('invalid_parameters'); } diff --git a/lib/types/thread-types.js b/lib/types/thread-types.js --- a/lib/types/thread-types.js +++ b/lib/types/thread-types.js @@ -302,11 +302,13 @@ +threadID: string, +calendarQuery?: ?CalendarQuery, +inviteLinkSecret?: string, + +farcasterChannelID?: string, }; export type ClientThreadJoinRequest = { +threadID: string, +calendarQuery: CalendarQuery, +inviteLinkSecret?: string, + +farcasterChannelID?: string, }; export type ThreadJoinResult = { +updatesResult: {