Comparing version 0.3.0 to 0.4.0
@@ -7,5 +7,18 @@ /* jshint evil: true */ | ||
var childrenSize = require('./childrensize.js'); | ||
var pluginCore = require('gardr-core-plugin'); | ||
var pluginCore = require('gardr-core-plugin'); | ||
var defineOpts = require('define-options'); | ||
var extend = require('util-extend'); | ||
function readParams () { | ||
var defaultOpts = { | ||
allowedDomains: [] | ||
}; | ||
var rDomainName = /^[a-zA-Z0-9.-]+$/; | ||
function isDomainValid (domainName) { | ||
if (!rDomainName.test(domainName)) { | ||
throw new Error('allowedDomains should only contain the hostname. Invalid domain: ' + domainName); | ||
} | ||
} | ||
function readParams (allowedDomains) { | ||
// Params are passed as a JSON in the url fragment by default. IE has a limit for URLs longer than 2083 bytes, so | ||
@@ -16,12 +29,34 @@ // fallback to iframe.name if there is no url fragment. | ||
var urlFragment = decodeURIComponent(document.location.hash.substring(1)); | ||
return JSON.parse(urlFragment || window.name); | ||
var params = JSON.parse(urlFragment || window.name); | ||
checkAllowedDomains(allowedDomains, params); | ||
return params; | ||
} | ||
var bootStrap = function () { | ||
var gardr = global.gardr || {}; | ||
function checkAllowedDomains (allowedDomains, params) { | ||
var a=document.createElement('a'); | ||
a.href=params.url; | ||
if (a.protocol.indexOf('http') === -1) { | ||
throw new Error('url protocol is ' + a.protocol.replace(':','') + ', but have to be http/https'); | ||
} | ||
var sameDomain = (!a.hostname || a.hostname == location.hostname); | ||
if (!sameDomain && allowedDomains.indexOf(a.hostname) == -1) { | ||
throw new Error('Script ' + params.url + ' is not on a allowed domain.'); | ||
} | ||
} | ||
var validate = defineOpts({ | ||
allowedDomains : '?|string[] - Required array with allowed domains' | ||
}); | ||
function validateOpts (options) { | ||
validate(options); | ||
options.allowedDomains.forEach(isDomainValid); | ||
} | ||
var bootStrap = function (options) { | ||
options = extend(extend({}, defaultOpts), options); | ||
validateOpts(options); | ||
var gardr = global.gardr = {}; | ||
var pluginApi = new pluginCore.PluginApi(); | ||
if (!global.gardr) { | ||
global.gardr = gardr; | ||
gardr.params = readParams(); | ||
} | ||
gardr.params = readParams(options.allowedDomains); | ||
pluginCore.pluginHandler.initPlugins(pluginApi); | ||
@@ -28,0 +63,0 @@ |
{ | ||
"name": "gardr-ext", | ||
"version": "0.3.0", | ||
"version": "0.4.0", | ||
"description": "The js part of Gardr which embeds external content inside the iframe", | ||
@@ -54,4 +54,5 @@ "main": "./lib/index.js", | ||
"computed-style": "~0.1.3", | ||
"gardr-core-plugin": "0.0.1" | ||
"gardr-core-plugin": "0.0.1", | ||
"define-options": "0.1.3" | ||
} | ||
} |
@@ -11,7 +11,11 @@ /* jshint evil: true, expr: true */ | ||
timeout: 200, | ||
url: 'data:text/javascript;plain,void(0);', | ||
url: 'http://gardr.github.io/foobar.js', | ||
height: 225, | ||
origin: 'http://gardr.github.io' | ||
origin: 'http://github.com' | ||
}; | ||
var extOpts = { | ||
allowedDomains: ['gardr.github.io', 'foobar.com'] | ||
}; | ||
function paramsStr (data) { | ||
@@ -75,4 +79,35 @@ return JSON.stringify(extend(extend({}, defaultParams), data)); | ||
it('should throw an error if url is not on a valid domain', function () { | ||
expect(bootStrap.bind(null, {allowedDomains: ['example.com']})).to.throw(); | ||
}); | ||
it('should throw an error if url is a data-uri', function () { | ||
setUrlFragment({ | ||
url: 'data:text/javascript;plain,void(0);' | ||
}); | ||
expect(bootStrap).to.throw('protocol'); | ||
}); | ||
it('should not throw an error if a relative url', function () { | ||
setUrlFragment({ | ||
url: '/foo/bar.js' | ||
}); | ||
expect(bootStrap).not.to.throw(); | ||
}); | ||
it('should throw if one of the validDomains contains something else than just the hostname', function () { | ||
['http://foobar.com', '//foobar.com', 'https://foobar.com', 'foobar.com/'].forEach(function (domain) { | ||
expect(bootStrap.bind(null, {allowedDomains: [domain]})).to.throw('Invalid domain'); | ||
}); | ||
}); | ||
it('should not throw an error if url is on a valid domain', function () { | ||
setUrlFragment({ | ||
url: 'http://foobar.com/foo/bar' | ||
}); | ||
expect(bootStrap.bind(null, extOpts)).not.to.throw(); | ||
}); | ||
it('should define ‘gardr’ in global scope', function () { | ||
bootStrap(); | ||
bootStrap(extOpts); | ||
@@ -84,7 +119,7 @@ expect(window.gardr).to.exist; | ||
setUrlFragment({url: 'http://gardr.github.io/ad|123'}); | ||
bootStrap(); | ||
bootStrap(extOpts); | ||
expect(gardr.params).to.exist; | ||
expect(gardr.id).to.equal('pos-id'); | ||
expect(gardr.params.origin).to.equal('http://gardr.github.io'); | ||
expect(gardr.params.origin).to.equal('http://github.com'); | ||
expect(gardr.params.url).to.equal('http://gardr.github.io/ad|123'); | ||
@@ -97,7 +132,7 @@ expect(gardr.params.timeout).to.equal(200); | ||
setName({url: 'http://gardr.github.io/ad|123'}); | ||
bootStrap(); | ||
bootStrap(extOpts); | ||
expect(gardr.params).to.exist; | ||
expect(gardr.id).to.equal('pos-id'); | ||
expect(gardr.params.origin).to.equal('http://gardr.github.io'); | ||
expect(gardr.params.origin).to.equal('http://github.com'); | ||
expect(gardr.params.url).to.equal('http://gardr.github.io/ad|123'); | ||
@@ -109,3 +144,3 @@ expect(gardr.params.timeout).to.equal(200); | ||
setUrlFragment({loglevel: 4}); | ||
bootStrap(); | ||
bootStrap(extOpts); | ||
gardr.log.debug('test'); | ||
@@ -117,3 +152,3 @@ var logDiv = document.getElementById('logoutput'); | ||
it('should document.write out a gardr container to the document', function () { | ||
bootStrap(); | ||
bootStrap(extOpts); | ||
document.write.should.have.been.calledWithMatch(/<span id="gardr"><scr.pt src=".*"\s*><\/scr.pt><\/span>/); | ||
@@ -123,5 +158,5 @@ }); | ||
it('should document.write a script tag with src equal to the input url', function() { | ||
var scriptUrl = 'http://external.com/script.js?q=1'; | ||
var scriptUrl = 'http://gardr.github.io/script.js?q=1'; | ||
setUrlFragment({url: scriptUrl}); | ||
bootStrap(); | ||
bootStrap(extOpts); | ||
@@ -134,6 +169,6 @@ document.write.should.have.been.calledWithMatch(function (value) { | ||
it('should trigger comClient.rendered when all resources are loaded', function () { | ||
bootStrap(); | ||
bootStrap(extOpts); | ||
expect(comClient).to.have.been.calledOnce; | ||
expect(comClient).to.have.been.calledWith(gardr.id, window.parent, 'http://gardr.github.io'); | ||
expect(comClient).to.have.been.calledWith(gardr.id, window.parent, 'http://github.com'); | ||
@@ -146,3 +181,3 @@ triggerOnLoad(); | ||
it('should detect the size of the rendered banner', function () { | ||
bootStrap(); | ||
bootStrap(extOpts); | ||
var el = document.getElementById('gardr'); | ||
@@ -168,3 +203,3 @@ var span = document.createElement('span'); | ||
bootStrap.plugin(spy); | ||
bootStrap(); | ||
bootStrap(extOpts); | ||
expect(spy).to.have.been.calledOnce; | ||
@@ -182,3 +217,3 @@ expect(spy).to.have.been.calledWithMatch(function (api) { | ||
setUrlFragment({foo: 'bar'}); | ||
bootStrap(); | ||
bootStrap(extOpts); | ||
expect(spy).to.have.been.calledOnce; | ||
@@ -196,3 +231,3 @@ expect(spy).to.have.been.calledWithMatch(function (data) { | ||
setUrlFragment({foo: 'bar'}); | ||
bootStrap(); | ||
bootStrap(extOpts); | ||
expect(spy).to.have.been.calledOnce; | ||
@@ -209,3 +244,3 @@ expect(spy).to.have.been.calledWithMatch(function (el) { | ||
}); | ||
bootStrap(); | ||
bootStrap(extOpts); | ||
triggerOnLoad(); | ||
@@ -212,0 +247,0 @@ expect(spy).to.have.been.calledOnce; |
Sorry, the diff of this file is not supported yet
36363
823
6
+ Addeddefine-options@0.1.3
+ Addeddefine-options@0.1.3(transitive)