Skip to content

Commit

Permalink
PDCL-7898: Fixes cases where using link that start with // was not
Browse files Browse the repository at this point in the history
finding the embed code. Stops upgrading to https all the time (respects protocol).
  • Loading branch information
Brent Hosie committed Mar 11, 2022
1 parent 4485c76 commit 06383ae
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 33 deletions.
80 changes: 73 additions & 7 deletions src/__tests__/createDynamicHostResolver.test.js
Expand Up @@ -10,7 +10,7 @@
* governing permissions and limitations under the License.
****************************************************************************************/

var createDynamicHostResolver = require('../createDynamicHostResolver');
var injectCreateDynamicHostResolver = require('inject-loader!../createDynamicHostResolver');
var createDebugController = require('../createDebugController');

var loggerSpy = jasmine.createSpy('logger');
Expand All @@ -19,10 +19,24 @@ var turbineEmbedCode;
var cdnAllowList;
var dynamicHostResolver;

var createMockWindowProtocol = function (protocol) {
return {
location: {
protocol: protocol + ':'
}
};
};
var createDynamicHostResolver;
var mockWindow;

describe('createDynamicHostResolver returns a function that when called', function () {
var debugController;
beforeEach(function () {
delete window.dynamicHostResolver;
mockWindow = createMockWindowProtocol('https');
createDynamicHostResolver = injectCreateDynamicHostResolver({
'@adobe/reactor-window': mockWindow
});
consoleSpy = spyOn(console, 'warn');
debugController = jasmine.createSpyObj('debugController', [
'onDebugChanged'
Expand Down Expand Up @@ -115,12 +129,13 @@ describe('createDynamicHostResolver returns a function that when called', functi
function () {
expect(function () {
createDynamicHostResolver(
'fake.adobeassets.com',
'//fake.adobeassets.com',
cdnAllowList,
debugController
);
}).toThrowError(
'Unable to find the Library Embed Code for Dynamic Host Resolution.'
'This library is not authorized for this domain. ' +
'Please contact your CSM for more information.'
);
}
);
Expand All @@ -143,6 +158,44 @@ describe('createDynamicHostResolver returns a function that when called', functi
);
});

describe('handles embed codes that begin with //', function () {
describe('when isDynamicEnforced=true', function () {
it('and is http', function () {
var mockWindow = createMockWindowProtocol('http');
createDynamicHostResolver = injectCreateDynamicHostResolver({
'@adobe/reactor-window': mockWindow
});
turbineEmbedCode = '//assets.adobedtm.com/lib/dev.js';
dynamicHostResolver = createDynamicHostResolver(
turbineEmbedCode,
cdnAllowList,
debugController
);

expect(consoleSpy).not.toHaveBeenCalled();
expect(dynamicHostResolver.decorateWithDynamicHost('/my/url')).toBe(
'http://assets.adobedtm.com/my/url'
);
});

it('and is https', function () {
turbineEmbedCode = '//assets.adobedtm.com/lib/dev.js';
dynamicHostResolver = createDynamicHostResolver(
turbineEmbedCode,
cdnAllowList,
debugController
);

expect(consoleSpy).not.toHaveBeenCalled();
expect(dynamicHostResolver.decorateWithDynamicHost('/my/url')).toBe(
'https://assets.adobedtm.com/my/url'
);
});
});

it('when isDynamicEnforced=false', function () {});
});

it('creates the resolver silently with a proper turbineEmbedCode', function () {
turbineEmbedCode = 'https://assets.adobedtm.com/lib/dev.js';
dynamicHostResolver = createDynamicHostResolver(
Expand Down Expand Up @@ -193,8 +246,8 @@ describe('createDynamicHostResolver returns a function that when called', functi
);
});

it('upgrades to https all the time', function () {
turbineEmbedCode = 'http://assets.adobedtm.com/lib/dev.js';
it('leaves explicit https as https', function () {
turbineEmbedCode = 'https://assets.adobedtm.com/lib/dev.js';
dynamicHostResolver = createDynamicHostResolver(
turbineEmbedCode,
cdnAllowList,
Expand All @@ -206,6 +259,19 @@ describe('createDynamicHostResolver returns a function that when called', functi
);
});

it('leaves explicit http as http', function () {
turbineEmbedCode = 'http://assets.adobedtm.com/lib/dev.js';
dynamicHostResolver = createDynamicHostResolver(
turbineEmbedCode,
cdnAllowList,
debugController
);

expect(dynamicHostResolver.decorateWithDynamicHost('my/url')).toBe(
'http://assets.adobedtm.com/my/url'
);
});

it('returns the protocol as a part of URL decoration', function () {
turbineEmbedCode = 'https://assets.adobedtm.com:8080/lib/dev.js';
dynamicHostResolver = createDynamicHostResolver(
Expand Down Expand Up @@ -346,7 +412,7 @@ describe('createDynamicHostResolver returns a function that when called', functi
);
debugController.setDebugEnabled(true); // enable output

expect(window.dynamicHostResolver).not.toBe(undefined);
expect(mockWindow.dynamicHostResolver).not.toBe(undefined);
});

it('does not add the dynamicHostResolver to the window when debug is disabled', function () {
Expand All @@ -365,7 +431,7 @@ describe('createDynamicHostResolver returns a function that when called', functi
);
debugController.setDebugEnabled(false); // disable output

expect(window.dynamicHostResolver).toBe(undefined);
expect(mockWindow.dynamicHostResolver).toBe(undefined);
});
});
});
6 changes: 3 additions & 3 deletions src/__tests__/index.test.js
Expand Up @@ -474,7 +474,7 @@ describe('index', function () {
'Unable to find the Library Embed Code for Dynamic Host Resolution.'
);

expect(logger.warn).toHaveBeenCalledWith(
expect(logger.warn).toHaveBeenCalledOnceWith(
'Please review the following error:'
);
});
Expand All @@ -493,7 +493,7 @@ describe('index', function () {
'Please contact your CSM for more information.'
);

expect(logger.warn).toHaveBeenCalledWith(
expect(logger.warn).toHaveBeenCalledOnceWith(
'Please review the following error:'
);
});
Expand All @@ -513,7 +513,7 @@ describe('index', function () {
'Please contact your CSM for more information.'
);

expect(logger.warn).toHaveBeenCalledWith(
expect(logger.warn).toHaveBeenCalledOnceWith(
'Please review the following error:'
);
});
Expand Down
71 changes: 48 additions & 23 deletions src/createDynamicHostResolver.js
Expand Up @@ -12,33 +12,58 @@

var window = require('@adobe/reactor-window');

module.exports = function (turbineEmbedCode, cdnAllowList, debugController) {
module.exports = function (
turbineEmbedCode,
cdnAllowList,
debugController,
debug
) {
// A missing list means that we are not trying to dynamic replace (archives,
// sftp, no premium CDN option enabled on the company).
// even an empty list is flagging to us that we're trying to enforce dynamic
var isDynamicEnforced = Array.isArray(cdnAllowList);
var shouldAugment = Boolean(isDynamicEnforced && turbineEmbedCode);

// TODO: web only? I think embedded TVs wouldn't have
// __satellite.container.dynamicEnforced turned on
// using document.createElement('a') because IE10/11 doesn't support new URL()
var turbineUrl = document.createElement('a');
turbineUrl.href = turbineEmbedCode;
if (
(!/^https?:\/\/.*/.test(turbineEmbedCode) || !turbineUrl.host) &&
isDynamicEnforced
) {
var missingEmbedCodeError = new Error(
'Unable to find the Library Embed Code for Dynamic Host Resolution.'
);
missingEmbedCodeError.code = 'dynamic_host_resolver_constructor_error';
throw missingEmbedCodeError;
}

if (isDynamicEnforced && cdnAllowList.indexOf(turbineUrl.hostname) === -1) {
var dynamicDeniedError = new Error(
'This library is not authorized for this domain. ' +
'Please contact your CSM for more information.'
);
dynamicDeniedError.code = 'dynamic_host_not_allowed';
throw dynamicDeniedError;
if (isDynamicEnforced) {
// throw whenever we can't determine the embed code
var throwUnavailableEmbedCode = function () {
var missingEmbedCodeError = new Error(
'Unable to find the Library Embed Code for Dynamic Host Resolution.'
);
missingEmbedCodeError.code = 'dynamic_host_resolver_constructor_error';
throw missingEmbedCodeError;
};
if (turbineEmbedCode) {
var httpsMatcher = new RegExp(/^https?:\/\/.*/);
var doubleSlashMatcher = new RegExp(/^\/\/.*/);
if (
!httpsMatcher.test(turbineEmbedCode) &&
!doubleSlashMatcher.test(turbineEmbedCode)
) {
throwUnavailableEmbedCode();
}
// try to construct the url
if (!httpsMatcher.test(turbineEmbedCode)) {
turbineUrl.href = window.location.protocol + turbineEmbedCode;
} else {
turbineUrl.href = turbineEmbedCode;
}
}
// check URL construction
if (!turbineUrl.host) {
throwUnavailableEmbedCode();
}
// is this within the allowed list of hosts?
if (cdnAllowList.indexOf(turbineUrl.hostname) === -1) {
var dynamicDeniedError = new Error(
'This library is not authorized for this domain. ' +
'Please contact your CSM for more information.'
);
dynamicDeniedError.code = 'dynamic_host_not_allowed';
throw dynamicDeniedError;
}
}

/**
Expand Down Expand Up @@ -67,7 +92,7 @@ module.exports = function (turbineEmbedCode, cdnAllowList, debugController) {
sanitizedHost = sanitizedHost.replace(':443/', '');
}

memoizedHostResult = 'https://' + sanitizedHost;
memoizedHostResult = turbineUrl.protocol + '//' + sanitizedHost;
} else {
memoizedHostResult = '';
}
Expand Down

0 comments on commit 06383ae

Please sign in to comment.