diff --git a/resources/js/index.js b/resources/js/index.js index 4f99d97..48c1a39 100644 --- a/resources/js/index.js +++ b/resources/js/index.js @@ -384,24 +384,56 @@ function loadService(serviceId, service) { setContextMenu(webContents); // Set permission request handler - session.fromPartition(service.view.partition) - .setPermissionRequestHandler(((webContents, permission, callback, details) => { - dialog.showMessageBox(remote.getCurrentWindow(), { - type: 'question', - title: 'Grant ' + permission + ' permission', - message: 'Do you wish to grant the ' + permission + ' permission to ' + details.requestingUrl + '?', - buttons: ['Deny', 'Authorize'], - cancelId: 0, - }).then(result => { - if (result.response === 1) { - console.log('Granted', permission, 'for service', details.requestingUrl); - callback(true); - } else { - console.log('Denied', permission, 'for service', details.requestingUrl); - callback(false); - } - }).catch(console.error); - })); + function getUrlDomain(url) { + let domain = url.match(/^https?:\/\/((.+?)\/|(.+))/i)[1]; + if (domain.endsWith('/')) domain = domain.substr(0, domain.length - 1); + return domain; + } + + function getDomainPermissions(domain) { + let domainPermissions = service.permissions[domain]; + if (!domainPermissions) domainPermissions = service.permissions[domain] = []; + return domainPermissions; + } + + let serviceSession = session.fromPartition(service.view.partition); + serviceSession.setPermissionRequestHandler(((webContents, permissionName, callback, details) => { + let domain = getUrlDomain(details.requestingUrl); + let domainPermissions = getDomainPermissions(domain); + + let existingPermissions = domainPermissions.filter(p => p.name === permissionName); + if (existingPermissions.length > 0) { + callback(existingPermissions[0].authorized); + return; + } + + dialog.showMessageBox(remote.getCurrentWindow(), { + type: 'question', + title: 'Grant ' + permissionName + ' permission', + message: 'Do you wish to grant the ' + permissionName + ' permission to ' + domain + '?', + buttons: ['Deny', 'Authorize'], + cancelId: 0, + }).then(result => { + const authorized = result.response === 1; + + domainPermissions.push({ + name: permissionName, + authorized: authorized, + }); + updateServicePermissions(serviceId); + + console.log(authorized ? 'Granted' : 'Denied', permissionName, 'for domain', domain); + callback(authorized); + }).catch(console.error); + })); + serviceSession.setPermissionCheckHandler((webContents1, permissionName, requestingOrigin, details) => { + console.log('Permission check', permissionName, requestingOrigin, details); + let domain = getUrlDomain(details.requestingUrl); + let domainPermissions = getDomainPermissions(domain); + + let existingPermissions = domainPermissions.filter(p => p.name === permissionName); + return existingPermissions.length > 0 && existingPermissions[0].authorized; + }); service.view.setAttribute('src', service.url); }); @@ -469,6 +501,11 @@ function reloadService(serviceId) { } } +function updateServicePermissions(serviceId) { + const service = services[serviceId]; + ipcRenderer.send('updateServicePermissions', serviceId, service.permissions); +} + function updateNavigation() { console.debug('Updating navigation'); // Update active list element diff --git a/src/Service.js b/src/Service.js index 54667ac..5d3a9d2 100644 --- a/src/Service.js +++ b/src/Service.js @@ -36,6 +36,7 @@ Service.requiredProperties = { 'autoLoad': false, 'customCSS': null, 'customUserAgent': null, + 'permissions': {}, }; export default Service; diff --git a/src/main.js b/src/main.js index cd18d6c..8b2a4aa 100644 --- a/src/main.js +++ b/src/main.js @@ -183,6 +183,11 @@ function createWindow() { config.save(); }); + ipcMain.on('updateServicePermissions', (e, serviceId, permissions) => { + config.services[serviceId].permissions = permissions; + config.save(); + }); + ipcMain.on('updateWindowTitle', (event, serviceId, viewTitle) => { if (serviceId === null) { window.setTitle(Meta.title);