Implement asynchronous permission requests
This commit is contained in:
@@ -15,6 +15,7 @@ const AppConfig = require('./config/AppConfig.js');
|
|||||||
const url = require('url');
|
const url = require('url');
|
||||||
|
|
||||||
const badge = require('./js/badge');
|
const badge = require('./js/badge');
|
||||||
|
const utils = require('../utils/util');
|
||||||
|
|
||||||
remote.getCurrentWindow().removeAllListeners('focus');
|
remote.getCurrentWindow().removeAllListeners('focus');
|
||||||
|
|
||||||
@@ -86,12 +87,59 @@ function showUnreadBadge(unreadCount, mentionCount) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const permissionRequestQueue = [];
|
||||||
|
const requestingPermission = new Array(AppConfig.data.teams.length);
|
||||||
|
|
||||||
function teamConfigChange(teams) {
|
function teamConfigChange(teams) {
|
||||||
AppConfig.set('teams', teams);
|
AppConfig.set('teams', teams);
|
||||||
|
requestingPermission.length = teams.length;
|
||||||
ipcRenderer.send('update-menu', AppConfig.data);
|
ipcRenderer.send('update-menu', AppConfig.data);
|
||||||
ipcRenderer.send('update-config');
|
ipcRenderer.send('update-config');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function feedPermissionRequest() {
|
||||||
|
const webviews = document.getElementsByTagName('webview');
|
||||||
|
const webviewOrigins = Array.from(webviews).map((w) => utils.getDomain(w.getAttribute('src')));
|
||||||
|
for (let index = 0; index < requestingPermission.length; index++) {
|
||||||
|
if (requestingPermission[index]) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for (const request of permissionRequestQueue) {
|
||||||
|
if (request.origin === webviewOrigins[index]) {
|
||||||
|
requestingPermission[index] = request;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleClickPermissionDialog(index, status) {
|
||||||
|
const requesting = requestingPermission[index];
|
||||||
|
ipcRenderer.send('update-permission', requesting.origin, requesting.permission, status);
|
||||||
|
if (status === 'allow' || status === 'block') {
|
||||||
|
const newRequests = permissionRequestQueue.filter((request) => {
|
||||||
|
if (request.permission === requesting.permission && request.origin === requesting.origin) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
permissionRequestQueue.splice(0, permissionRequestQueue.length, ...newRequests);
|
||||||
|
} else if (status === 'close') {
|
||||||
|
const i = permissionRequestQueue.findIndex((e) => e.permission === requesting.permission && e.origin === requesting.origin);
|
||||||
|
permissionRequestQueue.splice(i, 1);
|
||||||
|
}
|
||||||
|
requestingPermission[index] = null;
|
||||||
|
feedPermissionRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
ipcRenderer.on('request-permission', (event, origin, permission) => {
|
||||||
|
if (permissionRequestQueue.length >= 100) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
permissionRequestQueue.push({origin, permission});
|
||||||
|
feedPermissionRequest();
|
||||||
|
});
|
||||||
|
|
||||||
function handleSelectSpellCheckerLocale(locale) {
|
function handleSelectSpellCheckerLocale(locale) {
|
||||||
console.log(locale);
|
console.log(locale);
|
||||||
AppConfig.set('spellCheckerLocale', locale);
|
AppConfig.set('spellCheckerLocale', locale);
|
||||||
@@ -117,6 +165,8 @@ ReactDOM.render(
|
|||||||
onSelectSpellCheckerLocale={handleSelectSpellCheckerLocale}
|
onSelectSpellCheckerLocale={handleSelectSpellCheckerLocale}
|
||||||
deeplinkingUrl={deeplinkingUrl}
|
deeplinkingUrl={deeplinkingUrl}
|
||||||
showAddServerButton={AppConfig.data.enableServerManagement}
|
showAddServerButton={AppConfig.data.enableServerManagement}
|
||||||
|
requestingPermission={requestingPermission}
|
||||||
|
onClickPermissionDialog={handleClickPermissionDialog}
|
||||||
/>,
|
/>,
|
||||||
document.getElementById('content')
|
document.getElementById('content')
|
||||||
);
|
);
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
const {dialog} = require('electron');
|
const {ipcMain} = require('electron');
|
||||||
const {URL} = require('url');
|
const {URL} = require('url');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
|
|
||||||
@@ -54,8 +54,41 @@ class PermissionManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function dequeueRequests(requestQueue, permissionManager, origin, permission, status) {
|
||||||
|
switch (status) {
|
||||||
|
case 'allow':
|
||||||
|
permissionManager.grant(origin, permission);
|
||||||
|
break;
|
||||||
|
case 'block':
|
||||||
|
permissionManager.deny(origin, permission);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (status === 'allow' || status === 'block') {
|
||||||
|
const newQueue = requestQueue.filter((request) => {
|
||||||
|
if (request.origin === origin && request.permission === permission) {
|
||||||
|
request.callback(status === 'allow');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
requestQueue.splice(0, requestQueue.length, ...newQueue);
|
||||||
|
} else {
|
||||||
|
const index = requestQueue.findIndex((request) => {
|
||||||
|
return request.origin === origin && request.permission === permission;
|
||||||
|
});
|
||||||
|
requestQueue[index].callback(false);
|
||||||
|
requestQueue.splice(index, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function permissionRequestHandler(mainWindow, permissionFile) {
|
function permissionRequestHandler(mainWindow, permissionFile) {
|
||||||
const permissionManager = new PermissionManager(permissionFile);
|
const permissionManager = new PermissionManager(permissionFile);
|
||||||
|
const requestQueue = [];
|
||||||
|
ipcMain.on('update-permission', (event, origin, permission, status) => {
|
||||||
|
dequeueRequests(requestQueue, permissionManager, origin, permission, status);
|
||||||
|
});
|
||||||
return (webContents, permission, callback) => {
|
return (webContents, permission, callback) => {
|
||||||
const targetURL = new URL(webContents.getURL());
|
const targetURL = new URL(webContents.getURL());
|
||||||
if (permissionManager.isDenied(targetURL.origin, permission)) {
|
if (permissionManager.isDenied(targetURL.origin, permission)) {
|
||||||
@@ -67,28 +100,12 @@ function permissionRequestHandler(mainWindow, permissionFile) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const buttons = ['Allow', 'Deny', 'Skip'];
|
requestQueue.push({
|
||||||
const result = dialog.showMessageBox(mainWindow, {
|
origin: targetURL.origin,
|
||||||
type: 'warning',
|
permission,
|
||||||
buttons,
|
callback
|
||||||
title: 'Permission Required',
|
|
||||||
message: `${targetURL.host} is requesting "${permission}" permission`,
|
|
||||||
cancelId: 2,
|
|
||||||
noLink: false
|
|
||||||
});
|
});
|
||||||
switch (result) {
|
mainWindow.webContents.send('request-permission', targetURL.origin, permission);
|
||||||
case buttons.indexOf('Allow'):
|
|
||||||
permissionManager.grant(targetURL.origin, permission);
|
|
||||||
callback(true);
|
|
||||||
return;
|
|
||||||
case buttons.indexOf('Deny'):
|
|
||||||
permissionManager.deny(targetURL.origin, permission);
|
|
||||||
callback(false);
|
|
||||||
return;
|
|
||||||
default:
|
|
||||||
callback(false);
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user