diff --git a/keyserver/src/deleters/link-deleters.js b/keyserver/src/deleters/link-deleters.js new file mode 100644 --- /dev/null +++ b/keyserver/src/deleters/link-deleters.js @@ -0,0 +1,32 @@ +// @flow + +import type { DisableInviteLinkRequest } from 'lib/types/link-types.js'; +import { threadPermissions } from 'lib/types/thread-permission-types.js'; +import { ServerError } from 'lib/utils/errors.js'; + +import { dbQuery, SQL } from '../database/database.js'; +import { checkThreadPermission } from '../fetchers/thread-permission-fetchers.js'; +import { Viewer } from '../session/viewer.js'; + +async function deleteInviteLink( + viewer: Viewer, + request: DisableInviteLinkRequest, +): Promise { + const hasPermission = await checkThreadPermission( + viewer, + request.communityID, + threadPermissions.MANAGE_INVITE_LINKS, + ); + if (!hasPermission) { + throw new ServerError('invalid_credentials'); + } + + const query = SQL` + DELETE FROM invite_links + WHERE name = ${request.name} AND community = ${request.communityID} + `; + + await dbQuery(query); +} + +export { deleteInviteLink }; diff --git a/keyserver/src/endpoints.js b/keyserver/src/endpoints.js --- a/keyserver/src/endpoints.js +++ b/keyserver/src/endpoints.js @@ -21,6 +21,7 @@ import { getSessionPublicKeysResponder } from './responders/keys-responders.js'; import { createOrUpdatePublicLinkResponder, + disableInviteLinkResponder, fetchPrimaryInviteLinksResponder, inviteLinkVerificationResponder, } from './responders/link-responders.js'; @@ -105,6 +106,10 @@ responder: reactionMessageCreationResponder, requiredPolicies: baseLegalPolicies, }, + disable_invite_link: { + responder: disableInviteLinkResponder, + requiredPolicies: baseLegalPolicies, + }, edit_message: { responder: editMessageCreationResponder, requiredPolicies: baseLegalPolicies, 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 @@ -13,6 +13,7 @@ import { tShape, tID } from 'lib/utils/validation-utils.js'; import { createOrUpdatePublicLink } from '../creators/invite-link-creator.js'; +import { deleteInviteLink } from '../deleters/link-deleters.js'; import { fetchPrimaryInviteLinks, verifyInviteLink, @@ -93,8 +94,26 @@ return validateOutput(viewer.platformDetails, inviteLinkValidator, response); } +const disableInviteLinkInputValidator = tShape({ + name: t.String, + communityID: tID, +}); + +async function disableInviteLinkResponder( + viewer: Viewer, + input: mixed, +): Promise { + const request = await validateInput( + viewer, + disableInviteLinkInputValidator, + input, + ); + await deleteInviteLink(viewer, request); +} + export { inviteLinkVerificationResponder, fetchPrimaryInviteLinksResponder, createOrUpdatePublicLinkResponder, + disableInviteLinkResponder, }; diff --git a/lib/types/endpoints.js b/lib/types/endpoints.js --- a/lib/types/endpoints.js +++ b/lib/types/endpoints.js @@ -59,6 +59,7 @@ DELETE_ENTRY: 'delete_entry', DELETE_THREAD: 'delete_thread', DELETE_UPLOAD: 'delete_upload', + DISABLE_INVITE_LINK: 'disable_invite_link', EXACT_SEARCH_USER: 'exact_search_user', FETCH_ENTRIES: 'fetch_entries', FETCH_ENTRY_REVISIONS: 'fetch_entry_revisions', 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 @@ -60,3 +60,8 @@ +name: string, +communityID: string, }; + +export type DisableInviteLinkRequest = { + +name: string, + +communityID: string, +};