Implement asynchronous permission requests
This commit is contained in:
@@ -15,6 +15,7 @@ const AppConfig = require('./config/AppConfig.js');
|
||||
const url = require('url');
|
||||
|
||||
const badge = require('./js/badge');
|
||||
const utils = require('../utils/util');
|
||||
|
||||
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) {
|
||||
AppConfig.set('teams', teams);
|
||||
requestingPermission.length = teams.length;
|
||||
ipcRenderer.send('update-menu', AppConfig.data);
|
||||
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) {
|
||||
console.log(locale);
|
||||
AppConfig.set('spellCheckerLocale', locale);
|
||||
@@ -117,6 +165,8 @@ ReactDOM.render(
|
||||
onSelectSpellCheckerLocale={handleSelectSpellCheckerLocale}
|
||||
deeplinkingUrl={deeplinkingUrl}
|
||||
showAddServerButton={AppConfig.data.enableServerManagement}
|
||||
requestingPermission={requestingPermission}
|
||||
onClickPermissionDialog={handleClickPermissionDialog}
|
||||
/>,
|
||||
document.getElementById('content')
|
||||
);
|
||||
|
@@ -1,4 +1,4 @@
|
||||
const {dialog} = require('electron');
|
||||
const {ipcMain} = require('electron');
|
||||
const {URL} = require('url');
|
||||
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) {
|
||||
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) => {
|
||||
const targetURL = new URL(webContents.getURL());
|
||||
if (permissionManager.isDenied(targetURL.origin, permission)) {
|
||||
@@ -67,28 +100,12 @@ function permissionRequestHandler(mainWindow, permissionFile) {
|
||||
return;
|
||||
}
|
||||
|
||||
const buttons = ['Allow', 'Deny', 'Skip'];
|
||||
const result = dialog.showMessageBox(mainWindow, {
|
||||
type: 'warning',
|
||||
buttons,
|
||||
title: 'Permission Required',
|
||||
message: `${targetURL.host} is requesting "${permission}" permission`,
|
||||
cancelId: 2,
|
||||
noLink: false
|
||||
requestQueue.push({
|
||||
origin: targetURL.origin,
|
||||
permission,
|
||||
callback
|
||||
});
|
||||
switch (result) {
|
||||
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);
|
||||
|
||||
}
|
||||
mainWindow.webContents.send('request-permission', targetURL.origin, permission);
|
||||
};
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user