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 @@ -1,12 +1,14 @@ // @flow import blobService from 'lib/facts/blob-service.js'; +import type { BlobHashAndHolder } from 'lib/types/holder-types.js'; import { getBlobFetchableURL, makeBlobServiceEndpointURL, } from 'lib/utils/blob-service.js'; import { uploadBlob, + removeMultipleHolders, type BlobOperationResult, } from 'lib/utils/blob-service.js'; import { createHTTPAuthorizationHeader } from 'lib/utils/services-utils.js'; @@ -139,6 +141,11 @@ }); } +async function removeBlobHolders(holders: $ReadOnlyArray) { + const headers = await createRequestHeaders(false); + await removeMultipleHolders(holders, headers); +} + export { upload, uploadBlob, @@ -146,4 +153,5 @@ download, deleteBlob, uploadBlobKeyserverWrapper, + removeBlobHolders, }; diff --git a/lib/utils/blob-service.js b/lib/utils/blob-service.js --- a/lib/utils/blob-service.js +++ b/lib/utils/blob-service.js @@ -7,6 +7,7 @@ import { replacePathParams, type URLPathParams } from './url-utils.js'; import type { BlobServiceHTTPEndpoint } from '../facts/blob-service.js'; import blobServiceConfig from '../facts/blob-service.js'; +import type { BlobHashAndHolder } from '../types/holder-types.js'; const BLOB_SERVICE_URI_PREFIX = 'comm-blob-service://'; @@ -154,6 +155,45 @@ return { success: true }; } +async function removeMultipleHolders( + holders: $ReadOnlyArray, + headers: { [string]: string }, + instantDelete?: boolean, +): Promise< + | { +result: 'success' } + | { +result: 'error', +status: number, +statusText: string } + | { + +result: 'failed_requests', + +failedRequests: $ReadOnlyArray, + }, +> { + const response = await fetch( + makeBlobServiceEndpointURL( + blobServiceConfig.httpEndpoints.REMOVE_MULTIPLE_HOLDERS, + ), + { + method: blobServiceConfig.httpEndpoints.REMOVE_MULTIPLE_HOLDERS.method, + headers: { ...headers, 'Content-Type': 'application/json' }, + body: JSON.stringify({ + requests: holders, + instantDelete: !!instantDelete, + }), + }, + ); + + if (!response.ok) { + const { status, statusText } = response; + return { result: 'error', status, statusText }; + } + + const { failedRequests } = await response.json(); + if (failedRequests.length !== 0) { + return { result: 'failed_requests', failedRequests }; + } + + return { result: 'success' }; +} + export { makeBlobServiceURI, isBlobServiceURI, @@ -164,4 +204,5 @@ makeBlobServiceEndpointURL, uploadBlob, assignMultipleHolders, + removeMultipleHolders, };