diff --git a/keyserver/src/endpoints.js b/keyserver/src/endpoints.js --- a/keyserver/src/endpoints.js +++ b/keyserver/src/endpoints.js @@ -19,7 +19,10 @@ } from './responders/entry-responders.js'; import type { JSONResponder } from './responders/handlers.js'; import { getSessionPublicKeysResponder } from './responders/keys-responders.js'; -import { inviteLinkVerificationResponder } from './responders/link-responders.js'; +import { + fetchPrimaryInviteLinksResponder, + inviteLinkVerificationResponder, +} from './responders/link-responders.js'; import { messageReportCreationResponder } from './responders/message-report-responder.js'; import { textMessageCreationResponder, @@ -150,6 +153,10 @@ responder: fetchPinnedMessagesResponder, requiredPolicies: baseLegalPolicies, }, + fetch_primary_invite_links: { + responder: fetchPrimaryInviteLinksResponder, + requiredPolicies: baseLegalPolicies, + }, fetch_thread_media: { responder: threadFetchMediaResponder, requiredPolicies: baseLegalPolicies, diff --git a/keyserver/src/fetchers/link-fetchers.js b/keyserver/src/fetchers/link-fetchers.js --- a/keyserver/src/fetchers/link-fetchers.js +++ b/keyserver/src/fetchers/link-fetchers.js @@ -1,6 +1,7 @@ // @flow import type { + InviteLink, InviteLinkVerificationRequest, InviteLinkVerificationResponse, } from 'lib/types/link-types.js'; @@ -55,4 +56,28 @@ return result.length === 1; } -export { verifyInviteLink, checkIfInviteLinkIsValid }; +async function fetchPrimaryInviteLinks( + viewer: Viewer, +): Promise<$ReadOnlyArray> { + const query = SQL` + SELECT i.name, i.role, i.community, i.expiration_time AS expirationTime, + i.limit_of_uses AS limitOfUses, i.number_of_uses AS numberOfUses, + i.\`primary\` + FROM invite_links i + INNER JOIN memberships m + ON i.community = m.thread AND m.user = ${viewer.userID} + WHERE i.\`primary\` = 1 AND m.role > 0 + `; + const [result] = await dbQuery(query); + return result.map(row => ({ + name: row.name, + primary: row.primary, + role: row.role.toString(), + communityID: row.community.toString(), + expirationTime: row.expirationTime, + limitOfUses: row.limitOfUses, + numberOfUses: row.numberOfUses, + })); +} + +export { verifyInviteLink, checkIfInviteLinkIsValid, fetchPrimaryInviteLinks }; diff --git a/keyserver/src/responders/link-responders.js b/keyserver/src/responders/link-responders.js --- a/keyserver/src/responders/link-responders.js +++ b/keyserver/src/responders/link-responders.js @@ -5,10 +5,14 @@ import type { InviteLinkVerificationRequest, InviteLinkVerificationResponse, + FetchInviteLinksResponse, } from 'lib/types/link-types.js'; import { tShape } from 'lib/utils/validation-utils.js'; -import { verifyInviteLink } from '../fetchers/link-fetchers.js'; +import { + fetchPrimaryInviteLinks, + verifyInviteLink, +} from '../fetchers/link-fetchers.js'; import { Viewer } from '../session/viewer.js'; import { validateInput } from '../utils/validation-utils.js'; @@ -29,4 +33,13 @@ return await verifyInviteLink(viewer, request); } -export { inviteLinkVerificationResponder }; +async function fetchPrimaryInviteLinksResponder( + viewer: Viewer, +): Promise { + const primaryLinks = await fetchPrimaryInviteLinks(viewer); + return { + links: primaryLinks, + }; +} + +export { inviteLinkVerificationResponder, fetchPrimaryInviteLinksResponder }; diff --git a/lib/types/endpoints.js b/lib/types/endpoints.js --- a/lib/types/endpoints.js +++ b/lib/types/endpoints.js @@ -63,6 +63,7 @@ FETCH_ERROR_REPORT_INFOS: 'fetch_error_report_infos', FETCH_MESSAGES: 'fetch_messages', FETCH_PINNED_MESSAGES: 'fetch_pinned_messages', + FETCH_PRIMARY_INVITE_LINKS: 'fetch_primary_invite_links', FETCH_THREAD_MEDIA: 'fetch_thread_media', GET_SESSION_PUBLIC_KEYS: 'get_session_public_keys', JOIN_THREAD: 'join_thread', diff --git a/lib/types/link-types.js b/lib/types/link-types.js --- a/lib/types/link-types.js +++ b/lib/types/link-types.js @@ -15,3 +15,17 @@ | { +status: 'invalid' | 'expired', }; + +export type InviteLink = { + +name: string, + +primary: boolean, + +role: string, + +communityID: string, + +expirationTime: number, + +limitOfUses: number, + +numberOfUses: number, +}; + +export type FetchInviteLinksResponse = { + +links: $ReadOnlyArray, +};