1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-12-24 10:27:10 +02:00

Electron: Prevent URLs added via A tag from being opened inside app

This commit is contained in:
Laurent Cozic 2018-10-05 18:21:23 +00:00
parent 5ed458f634
commit 57fd1a7588
4 changed files with 24 additions and 5 deletions

View File

@ -6,6 +6,7 @@ const Search = require('lib/models/Search.js');
const { time } = require('lib/time-utils.js');
const Setting = require('lib/models/Setting.js');
const { IconButton } = require('./IconButton.min.js');
const { urlDecode } = require('lib/string-utils');
const Toolbar = require('./Toolbar.min.js');
const { connect } = require('react-redux');
const { _ } = require('lib/locale.js');
@ -569,7 +570,12 @@ class NoteTextComponent extends React.Component {
throw new Error('Unsupported item type: ' + item.type_);
}
} else if (urlUtils.urlProtocol(msg)) {
require('electron').shell.openExternal(msg);
if (msg.indexOf('file://') === 0) {
// When using the file:// protocol, openExternal doesn't work (does nothing) with URL-encoded paths
require('electron').shell.openExternal(urlDecode(msg));
} else {
require('electron').shell.openExternal(msg);
}
} else {
bridge().showErrorMessageBox(_('Unsupported link or message: %s', msg));
}

View File

@ -276,6 +276,15 @@
}
});
// Prevent URLs added via <a> tags from being opened within the application itself
document.addEventListener('click', function(event) {
const t = event.target;
if (t && t.nodeName === 'A' && !t.hasAttribute('data-from-md')) {
event.preventDefault();
ipcProxySendToHost(t.getAttribute('href'));
}
});
// Disable drag and drop otherwise it's possible to drop a URL
// on it and it will open in the view as a website.
document.addEventListener('drop', function(e) {

View File

@ -102,7 +102,7 @@ class MdToHtml {
const href = this.getAttr_(attrs, 'src');
if (!Resource.isResourceUrl(href)) {
return '<img title="' + htmlentities(title) + '" src="' + href + '"/>';
return '<img data-from-md title="' + htmlentities(title) + '" src="' + href + '"/>';
}
const resourceId = Resource.urlToId(href);
@ -118,7 +118,7 @@ class MdToHtml {
if (Resource.isSupportedImageMimeType(mime)) {
let src = './' + Resource.filename(resource);
if (this.resourceBaseUrl_ !== null) src = this.resourceBaseUrl_ + src;
let output = '<img data-resource-id="' + resource.id + '" title="' + htmlentities(title) + '" src="' + src + '"/>';
let output = '<img data-from-md data-resource-id="' + resource.id + '" title="' + htmlentities(title) + '" src="' + src + '"/>';
return output;
}
@ -167,7 +167,7 @@ class MdToHtml {
}
const js = options.postMessageSyntax + "(" + JSON.stringify(href) + "); return false;";
let output = "<a " + resourceIdAttr + " title='" + htmlentities(title) + "' href='" + hrefAttr + "' onclick='" + js + "'>" + icon;
let output = "<a data-from-md " + resourceIdAttr + " title='" + htmlentities(title) + "' href='" + hrefAttr + "' onclick='" + js + "'>" + icon;
return output;
}
@ -487,7 +487,7 @@ class MdToHtml {
while (renderedBody.indexOf('mJOPm') >= 0) {
renderedBody = renderedBody.replace(/mJOPmCHECKBOXm([A-Z]+)m(\d+)m/, function(v, type, index) {
const js = options.postMessageSyntax + "('checkboxclick:" + type + ':' + index + "'); this.classList.contains('tick') ? this.classList.remove('tick') : this.classList.add('tick'); return false;";
return '<a href="#" onclick="' + js + '" class="checkbox ' + (type == 'NOTICK' ? '' : 'tick') + '"><span>' + '' + '</span></a>';
return '<a data-from-md href="#" onclick="' + js + '" class="checkbox ' + (type == 'NOTICK' ? '' : 'tick') + '"><span>' + '' + '</span></a>';
});
if (loopCount++ >= 9999) break;
}

View File

@ -206,4 +206,8 @@ function toTitleCase(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
function urlDecode(string) {
return decodeURIComponent((string+'').replace(/\+/g, '%20'));
}
module.exports = { removeDiacritics, escapeFilename, wrap, splitCommandString, padLeft, toTitleCase };