From c7cfcd00563dc377b0368f1e2adc0ad973bcb20b Mon Sep 17 00:00:00 2001 From: nd0ut Date: Thu, 16 May 2024 14:26:36 +0300 Subject: [PATCH] feat: add `secureDeliveryProxyUrlResolver` option --- abstract/Block.js | 28 ++++++++++----- blocks/Config/Config.js | 9 +++-- blocks/Config/initialConfig.js | 1 + blocks/Config/normalizeConfigValue.js | 3 ++ .../secure-delivery-proxy-url-resolver.html | 35 +++++++++++++++++++ .../secure-delivery-proxy-url-template.html | 34 ++++++++++++++++++ .../preview-proxy/secure-delivery-proxy.js | 0 types/exported.d.ts | 7 +++- 8 files changed, 106 insertions(+), 11 deletions(-) create mode 100644 demo/preview-proxy/secure-delivery-proxy-url-resolver.html create mode 100644 demo/preview-proxy/secure-delivery-proxy-url-template.html rename secure-delivery-proxy.js => demo/preview-proxy/secure-delivery-proxy.js (100%) diff --git a/abstract/Block.js b/abstract/Block.js index 3940b37a2..e60d1818a 100644 --- a/abstract/Block.js +++ b/abstract/Block.js @@ -11,6 +11,7 @@ import { LocaleManager, localeStateKey } from './LocaleManager.js'; import { l10nProcessor } from './l10nProcessor.js'; import { sharedConfigKey } from './sharedConfigKey.js'; import { initialConfig } from '../blocks/Config/initialConfig.js'; +import { extractFilename, extractOperations, extractUuid } from '../utils/cdn-utils.js'; const TAG_PREFIX = 'lr-'; @@ -242,15 +243,26 @@ export class Block extends BaseComponent { * @returns {String} */ proxyUrl(url) { - let previewProxy = this.cfg.secureDeliveryProxy; - if (!previewProxy) { - return url; + if (this.cfg.secureDeliveryProxy && this.cfg.secureDeliveryProxyUrlResolver) { + console.warn( + 'Both secureDeliveryProxy and secureDeliveryProxyUrlResolver are set. Using secureDeliveryProxyUrlResolver.', + ); } - return applyTemplateData( - previewProxy, - { previewUrl: url }, - { transform: (value) => window.encodeURIComponent(value) }, - ); + if (this.cfg.secureDeliveryProxyUrlResolver) { + return this.cfg.secureDeliveryProxyUrlResolver(url, { + uuid: extractUuid(url), + cdnUrlModifiers: extractOperations(url), + fileName: extractFilename(url), + }); + } + if (this.cfg.secureDeliveryProxy) { + return applyTemplateData( + this.cfg.secureDeliveryProxy, + { previewUrl: url }, + { transform: (value) => window.encodeURIComponent(value) }, + ); + } + return url; } /** @returns {import('../types').ConfigType} } */ diff --git a/blocks/Config/Config.js b/blocks/Config/Config.js index 1e8a80d37..921b62ccc 100644 --- a/blocks/Config/Config.js +++ b/blocks/Config/Config.js @@ -13,9 +13,14 @@ const allConfigKeys = /** @type {(keyof import('../../types').ConfigType)[]} */ /** * Config keys that can't be passed as attribute (because they are object or function) * - * @type {['metadata', 'localeDefinitionOverride', 'secureUploadsSignatureResolver']} + * @type {['metadata', 'localeDefinitionOverride', 'secureUploadsSignatureResolver', 'secureDeliveryProxyUrlResolver']} */ -export const complexConfigKeys = ['metadata', 'localeDefinitionOverride', 'secureUploadsSignatureResolver']; +export const complexConfigKeys = [ + 'metadata', + 'localeDefinitionOverride', + 'secureUploadsSignatureResolver', + 'secureDeliveryProxyUrlResolver', +]; /** @type {(key: keyof import('../../types').ConfigType) => key is keyof import('../../types').ConfigComplexType} */ const isComplexKey = (key) => complexConfigKeys.includes(key); diff --git a/blocks/Config/initialConfig.js b/blocks/Config/initialConfig.js index b0ee12374..64baed07d 100644 --- a/blocks/Config/initialConfig.js +++ b/blocks/Config/initialConfig.js @@ -61,4 +61,5 @@ export const initialConfig = { localeName: 'en', localeDefinitionOverride: null, secureUploadsSignatureResolver: null, + secureDeliveryProxyUrlResolver: null, }; diff --git a/blocks/Config/normalizeConfigValue.js b/blocks/Config/normalizeConfigValue.js index 281f8a45c..d9534b9d1 100644 --- a/blocks/Config/normalizeConfigValue.js +++ b/blocks/Config/normalizeConfigValue.js @@ -136,6 +136,9 @@ const mapping = { localeDefinitionOverride: /** @type {typeof asObject} */ (asObject), secureUploadsSignatureResolver: /** @type {typeof asFunction} */ (asFunction), + secureDeliveryProxyUrlResolver: + /** @type {typeof asFunction} */ (asFunction), + }; /** diff --git a/demo/preview-proxy/secure-delivery-proxy-url-resolver.html b/demo/preview-proxy/secure-delivery-proxy-url-resolver.html new file mode 100644 index 000000000..71a8fb2d2 --- /dev/null +++ b/demo/preview-proxy/secure-delivery-proxy-url-resolver.html @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + diff --git a/demo/preview-proxy/secure-delivery-proxy-url-template.html b/demo/preview-proxy/secure-delivery-proxy-url-template.html new file mode 100644 index 000000000..1a9a42603 --- /dev/null +++ b/demo/preview-proxy/secure-delivery-proxy-url-template.html @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + diff --git a/secure-delivery-proxy.js b/demo/preview-proxy/secure-delivery-proxy.js similarity index 100% rename from secure-delivery-proxy.js rename to demo/preview-proxy/secure-delivery-proxy.js diff --git a/types/exported.d.ts b/types/exported.d.ts index 2419b7ea4..62b66b594 100644 --- a/types/exported.d.ts +++ b/types/exported.d.ts @@ -8,6 +8,10 @@ export type UploadcareGroup = import('@uploadcare/upload-client').UploadcareGrou export type Metadata = import('@uploadcare/upload-client').Metadata; export type MetadataCallback = (fileEntry: OutputFileEntry) => Promise | Metadata; export type LocaleDefinitionOverride = Record; +export type SecureDeliveryProxyUrlResolver = ( + previewUrl: string, + { uuid: string, cdnUrlModifiers: string, fileName: string }, +) => string; export type SecureUploadsSignatureAndExpire = { secureSignature: string; secureExpire: string }; export type SecureUploadsSignatureResolver = () => Promise; @@ -60,8 +64,9 @@ export type ConfigType = { metadata: Metadata | MetadataCallback | null; localeDefinitionOverride: LocaleDefinitionOverride | null; secureUploadsSignatureResolver: SecureUploadsSignatureResolver | null; + secureDeliveryProxyUrlResolver: SecureDeliveryProxyUrlResolver | null; }; -export type ConfigComplexType = Pick; +export type ConfigComplexType = Pick; export type ConfigPlainType = Omit; export type ConfigAttributesType = KebabCaseKeys & LowerCaseKeys;