diff --git a/keyserver/src/creators/invite-link-creator.js b/keyserver/src/creators/invite-link-creator.js --- a/keyserver/src/creators/invite-link-creator.js +++ b/keyserver/src/creators/invite-link-creator.js @@ -19,6 +19,7 @@ import { fetchPrimaryInviteLinks } from '../fetchers/link-fetchers.js'; import { fetchServerThreadInfos } from '../fetchers/thread-fetchers.js'; import { checkThreadPermission } from '../fetchers/thread-permission-fetchers.js'; +import { download, type BlobDownloadResult } from '../services/blob.js'; import { Viewer } from '../session/viewer.js'; const secretRegex = /^[a-zA-Z0-9]+$/; @@ -47,15 +48,24 @@ const fetchThreadInfoPromise = fetchServerThreadInfos({ threadID: request.communityID, }); - const [hasPermission, existingPrimaryLinks, { threadInfos }] = - await Promise.all([ - permissionPromise, - existingPrimaryLinksPromise, - fetchThreadInfoPromise, - ]); + const blobDownloadPromise = getInviteLinkBlob(request); + const [ + hasPermission, + existingPrimaryLinks, + { threadInfos }, + blobDownloadResult, + ] = await Promise.all([ + permissionPromise, + existingPrimaryLinksPromise, + fetchThreadInfoPromise, + blobDownloadPromise, + ]); if (!hasPermission) { throw new ServerError('invalid_credentials'); } + if (blobDownloadResult.found) { + throw new ServerError('already_in_use'); + } const threadInfo = threadInfos[request.communityID]; if (!threadInfo) { throw new ServerError('invalid_parameters'); @@ -139,4 +149,11 @@ }; } +function getInviteLinkBlob( + request: CreateOrUpdatePublicLinkRequest, +): Promise { + const hash = `invite_${request.name}`; + return download(hash); +} + export { createOrUpdatePublicLink }; diff --git a/keyserver/src/services/blob.js b/keyserver/src/services/blob.js --- a/keyserver/src/services/blob.js +++ b/keyserver/src/services/blob.js @@ -61,15 +61,15 @@ } } -async function download(hash: string): Promise< +export type BlobDownloadResult = | { +found: false, } | { +found: true, +blob: Blob, - }, -> { + }; +async function download(hash: string): Promise { const url = getBlobFetchableURL(hash); const response = await fetch(url, { method: blobService.httpEndpoints.GET_BLOB.method,