feat(upload): extend entity manager to sign private media URLs

This commit is contained in:
Jamie Howard 2023-02-09 16:39:26 +00:00
parent aba3eba51f
commit 751c69d478
2 changed files with 69 additions and 18 deletions

View File

@ -16,7 +16,7 @@ const createAssetUrl = (asset, forThumbnail = true) => {
const backendUrl = new URL(prefixFileUrlWithBackendUrl(assetUrl)); const backendUrl = new URL(prefixFileUrlWithBackendUrl(assetUrl));
// TODO: This gives problems with presigned URLs // TODO: This gives problems with presigned URLs
backendUrl.searchParams.set('updated_at', asset.updatedAt); // backendUrl.searchParams.set('updated_at', asset.updatedAt);
return backendUrl.toString(); return backendUrl.toString();
}; };

View File

@ -32,9 +32,10 @@ const signFileUrl = async (fileIdentifier) => {
const signFileUrls = async (file) => { const signFileUrls = async (file) => {
const { provider } = strapi.plugins.upload; const { provider } = strapi.plugins.upload;
const { provider: providerConfig } = strapi.config.get('plugin.upload');
// Check file provider and if provider is private // Check file provider and if provider is private
if (file.provider === provider.name && provider.isPrivate()) { if (file.provider === providerConfig && provider.isPrivate()) {
file.url = (await provider.getSignedUrl(file)).url; file.url = (await provider.getSignedUrl(file)).url;
// Sign each file format // Sign each file format
@ -54,26 +55,76 @@ const signFileUrls = async (file) => {
return file; return file;
}; };
/**
*
* Iterate through an entity manager result
* Check which modelAttributes are media and pre sign the image URLs
* if they are from the current upload provider
* @param {Object} entity
* @param {Object} modelAttributes
* @param {String} providerConfig
* @returns
*/
const signEntityMedia = async (entity, modelAttributes, providerConfig) => {
if (!modelAttributes) {
return entity;
}
for (const [key, value] of Object.entries(entity)) {
if (!value) continue;
const isMedia = modelAttributes[key]?.type === 'media';
if (!isMedia || value.provider !== providerConfig) continue;
await signFileUrls(value);
}
return entity;
};
const addSignedFileUrlsToAdmin = () => { const addSignedFileUrlsToAdmin = () => {
const { provider } = strapi.plugins.upload; const { provider } = strapi.plugins.upload;
const { provider: providerConfig } = strapi.config.get('plugin.upload');
// We only need to sign the file urls if the provider is private
if (!provider.isPrivate()) {
return;
}
// Only if provider is private, we need to sign the file urls
if (provider.isPrivate()) {
strapi.container strapi.container
.get('services') .get('services')
.extend(`plugin::content-manager.entity-manager`, (entityManager) => { .extend(`plugin::content-manager.entity-manager`, (entityManager) => {
const find = (opts, uid) => { const findWithRelationCountsPage = async (opts, uid) => {
return entityManager.find(opts, uid).then((results) => { const entityManagerResults = await entityManager.findWithRelationCountsPage(opts, uid);
return results; const attributes = strapi.getModel(uid)?.attributes;
});
await Promise.all(
entityManagerResults.results.map(async (entity) =>
signEntityMedia(entity, attributes, providerConfig)
)
);
return entityManagerResults;
};
const findOneWithCreatorRolesAndCount = async (id, uid) => {
const entityManagerResult = await entityManager.findOneWithCreatorRolesAndCount(id, uid);
await signEntityMedia(
entityManagerResult,
strapi.getModel(uid)?.attributes,
providerConfig
);
return entityManagerResult;
}; };
return { return {
...entityManager, ...entityManager,
find, findOneWithCreatorRolesAndCount,
findWithRelationCountsPage,
}; };
}); });
}
}; };
module.exports = { module.exports = {