diff --git a/src/editor/ConfigObj.js b/src/editor/ConfigObj.js index 225c9673..2c5927e6 100644 --- a/src/editor/ConfigObj.js +++ b/src/editor/ConfigObj.js @@ -150,8 +150,7 @@ export default class ConfigObj { // EXTENSION (CLIENT VS. SERVER SAVING/OPENING) avoidClientSide: false, // Deprecated in favor of `avoidClientSideDownload` avoidClientSideDownload: false, - avoidClientSideOpen: false, - userExtensions: [] + avoidClientSideOpen: false }; this.curPrefs = {}; @@ -176,6 +175,27 @@ export default class ConfigObj { 'ext-star', 'ext-storage' ]; + this.curConfig = { + // We do not put on defaultConfig to simplify object copying + // procedures (we obtain instead from defaultExtensions) + extensions: [], + userExtensions: [], + /** + * Can use `location.origin` to indicate the current + * origin. Can contain a '*' to allow all domains or 'null' (as + * a string) to support all `file:///` URLs. Cannot be set by + * URL for security reasons (not safe, at least for + * privacy or data integrity of SVG content). + * Might have been fairly safe to allow + * `new URL(location.href).origin` by default but + * avoiding it ensures some more security that even third + * party apps on the same domain also cannot communicate + * with this app by default. + * For use with `ext-xdomain-messaging.js` + * @todo We might instead make as a user-facing preference. + */ + allowedOrigins: [] + }; this.editor = editor; } /** @@ -192,7 +212,7 @@ export default class ConfigObj { * @returns {void} */ setupCurConfig () { - const curConfig = {...this.defaultConfig, ...this.editor.configObj.curConfig}; // Now safe to merge with priority for curConfig in the event any are already set + const curConfig = {...this.defaultConfig, ...this.curConfig}; // Now safe to merge with priority for curConfig in the event any are already set // Now deal with extensions and other array config if (!curConfig.noDefaultExtensions) { @@ -207,7 +227,7 @@ export default class ConfigObj { }); */ // Export updated config - this.editor.configObj.curConfig = curConfig; + this.curConfig = curConfig; } /** * @function loadFromURL Load config/data from URL if given @@ -259,7 +279,7 @@ export default class ConfigObj { this.setConfig(this.urldata, {overwrite: false}); this.setupCurConfig(); - if (!this.editor.configObj.curConfig.preventURLContentLoading) { + if (!this.curConfig.preventURLContentLoading) { let {source} = this.urldata; if (!source) { // urldata.source may have been null if it ended with '=' const src = searchParams.get('source'); @@ -280,7 +300,7 @@ export default class ConfigObj { return; } } - if (!this.urldata.noStorageOnLoad || this.editor.configObj.curConfig.forceStorage) { + if (!this.urldata.noStorageOnLoad || this.curConfig.forceStorage) { this.loadContentAndPrefs(); } } else { @@ -303,8 +323,8 @@ export default class ConfigObj { * @returns {void} */ loadContentAndPrefs () { - if (!this.editor.configObj.curConfig.forceStorage && - (this.editor.configObj.curConfig.noStorageOnLoad || + if (!this.curConfig.forceStorage && + (this.curConfig.noStorageOnLoad || !document.cookie.match(/(?:^|;\s*)svgeditstore=(?:prefsAndContent|prefsOnly)/) ) ) { @@ -313,12 +333,12 @@ export default class ConfigObj { // LOAD CONTENT if (this.editor.storage && // Cookies do not have enough available memory to hold large documents - (this.editor.configObj.curConfig.forceStorage || - (!this.editor.configObj.curConfig.noStorageOnLoad && + (this.curConfig.forceStorage || + (!this.curConfig.noStorageOnLoad && document.cookie.match(/(?:^|;\s*)svgeditstore=prefsAndContent/)) ) ) { - const name = 'svgedit-' + this.editor.configObj.curConfig.canvasName; + const name = 'svgedit-' + this.curConfig.canvasName; const cached = this.editor.storage.getItem(name); if (cached) { this.editor.loadFromString(cached); @@ -386,7 +406,7 @@ export default class ConfigObj { // Only allow prefs defined in configObj.defaultPrefs or... if (this.defaultPrefs[key]) { if (cfgCfg.overwrite === false && ( - this.editor.configObj.curConfig.preventAllURLConfig || + this.curConfig.preventAllURLConfig || this.curPrefs[key]) ) { return; @@ -399,35 +419,35 @@ export default class ConfigObj { } else if (['extensions', 'userExtensions', 'allowedOrigins'].includes(key)) { if (cfgCfg.overwrite === false && ( - this.editor.configObj.curConfig.preventAllURLConfig || + this.curConfig.preventAllURLConfig || ['allowedOrigins'].includes(key) || - (key === 'extensions' && this.editor.configObj.curConfig.lockExtensions) + (key === 'extensions' && this.curConfig.lockExtensions) ) ) { return; } - this.editor.configObj.curConfig[key] = this.editor.configObj.curConfig[key].concat(val); // We will handle any dupes later + this.curConfig[key] = this.curConfig[key].concat(val); // We will handle any dupes later // Only allow other configObj.curConfig if defined in configObj.defaultConfig } else if ({}.hasOwnProperty.call(this.defaultConfig, key)) { if (cfgCfg.overwrite === false && ( - this.editor.configObj.curConfig.preventAllURLConfig || - {}.hasOwnProperty.call(this.editor.configObj.curConfig, key) + this.curConfig.preventAllURLConfig || + {}.hasOwnProperty.call(this.curConfig, key) )) { return; } // Potentially overwriting of previously set config - if ({}.hasOwnProperty.call(this.editor.configObj.curConfig, key)) { + if ({}.hasOwnProperty.call(this.curConfig, key)) { if (cfgCfg.overwrite === false) { return; } - extendOrAdd(this.editor.configObj.curConfig, key, val); + extendOrAdd(this.curConfig, key, val); } else if (cfgCfg.allowInitialUserOverride === true) { extendOrAdd(this.defaultConfig, key, val); } else if (this.defaultConfig[key] && typeof this.defaultConfig[key] === 'object') { - this.editor.configObj.curConfig[key] = Array.isArray(this.defaultConfig[key]) ? [] : {}; - $.extend(true, this.editor.configObj.curConfig[key], val); // Merge properties recursively, e.g., on initFill, initStroke objects + this.curConfig[key] = Array.isArray(this.defaultConfig[key]) ? [] : {}; + $.extend(true, this.curConfig[key], val); // Merge properties recursively, e.g., on initFill, initStroke objects } else { - this.editor.configObj.curConfig[key] = val; + this.curConfig[key] = val; } } });