feat: correctly identify permissions when using setPermissionRequestHandler (#26172)
* fix: correctly identify clipboard read permission * Update tests for variable clipboard content * chore: add all possible permission conversions * VIDEO_CAPTURE and AUDIO_CAPTURE were already defined * Handle all PermissionTypes * use skewer case for accessibility events to match permissions api https://developer.mozilla.org/en-US/docs/Web/API/Permissions_API
This commit is contained in:
parent
07ee75b745
commit
7f9b21daa0
3 changed files with 97 additions and 1 deletions
|
@ -487,6 +487,7 @@ win.webContents.session.setCertificateVerifyProc((request, callback) => {
|
||||||
* `handler` Function | null
|
* `handler` Function | null
|
||||||
* `webContents` [WebContents](web-contents.md) - WebContents requesting the permission. Please note that if the request comes from a subframe you should use `requestingUrl` to check the request origin.
|
* `webContents` [WebContents](web-contents.md) - WebContents requesting the permission. Please note that if the request comes from a subframe you should use `requestingUrl` to check the request origin.
|
||||||
* `permission` String - The type of requested permission.
|
* `permission` String - The type of requested permission.
|
||||||
|
* `clipboard-read` - Request access to read from the clipboard.
|
||||||
* `media` - Request access to media devices such as camera, microphone and speakers.
|
* `media` - Request access to media devices such as camera, microphone and speakers.
|
||||||
* `mediaKeySystem` - Request access to DRM protected content.
|
* `mediaKeySystem` - Request access to DRM protected content.
|
||||||
* `geolocation` - Request access to user's current location.
|
* `geolocation` - Request access to user's current location.
|
||||||
|
|
|
@ -174,11 +174,41 @@ v8::Local<v8::Value> Converter<content::PermissionType>::ToV8(
|
||||||
v8::Isolate* isolate,
|
v8::Isolate* isolate,
|
||||||
const content::PermissionType& val) {
|
const content::PermissionType& val) {
|
||||||
using PermissionType = electron::WebContentsPermissionHelper::PermissionType;
|
using PermissionType = electron::WebContentsPermissionHelper::PermissionType;
|
||||||
|
// Based on mappings from content/browser/devtools/protocol/browser_handler.cc
|
||||||
|
// Not all permissions are currently used by Electron but this will future
|
||||||
|
// proof these conversions.
|
||||||
switch (val) {
|
switch (val) {
|
||||||
|
case content::PermissionType::ACCESSIBILITY_EVENTS:
|
||||||
|
return StringToV8(isolate, "accessibility-events");
|
||||||
|
case content::PermissionType::AR:
|
||||||
|
return StringToV8(isolate, "ar");
|
||||||
|
case content::PermissionType::BACKGROUND_FETCH:
|
||||||
|
return StringToV8(isolate, "background-fetch");
|
||||||
|
case content::PermissionType::BACKGROUND_SYNC:
|
||||||
|
return StringToV8(isolate, "background-sync");
|
||||||
|
case content::PermissionType::CLIPBOARD_READ_WRITE:
|
||||||
|
return StringToV8(isolate, "clipboard-read");
|
||||||
|
case content::PermissionType::CLIPBOARD_SANITIZED_WRITE:
|
||||||
|
return StringToV8(isolate, "clipboard-sanitized-write");
|
||||||
|
case content::PermissionType::FLASH:
|
||||||
|
return StringToV8(isolate, "flash");
|
||||||
|
case content::PermissionType::CAMERA_PAN_TILT_ZOOM:
|
||||||
|
case content::PermissionType::FONT_ACCESS:
|
||||||
|
return StringToV8(isolate, "font-access");
|
||||||
|
case content::PermissionType::IDLE_DETECTION:
|
||||||
|
return StringToV8(isolate, "idle-detection");
|
||||||
case content::PermissionType::MIDI_SYSEX:
|
case content::PermissionType::MIDI_SYSEX:
|
||||||
return StringToV8(isolate, "midiSysex");
|
return StringToV8(isolate, "midiSysex");
|
||||||
|
case content::PermissionType::NFC:
|
||||||
|
return StringToV8(isolate, "nfc");
|
||||||
case content::PermissionType::NOTIFICATIONS:
|
case content::PermissionType::NOTIFICATIONS:
|
||||||
return StringToV8(isolate, "notifications");
|
return StringToV8(isolate, "notifications");
|
||||||
|
case content::PermissionType::PAYMENT_HANDLER:
|
||||||
|
return StringToV8(isolate, "payment-handler");
|
||||||
|
case content::PermissionType::PERIODIC_BACKGROUND_SYNC:
|
||||||
|
return StringToV8(isolate, "periodic-background-sync");
|
||||||
|
case content::PermissionType::DURABLE_STORAGE:
|
||||||
|
return StringToV8(isolate, "persistent-storage");
|
||||||
case content::PermissionType::GEOLOCATION:
|
case content::PermissionType::GEOLOCATION:
|
||||||
return StringToV8(isolate, "geolocation");
|
return StringToV8(isolate, "geolocation");
|
||||||
case content::PermissionType::AUDIO_CAPTURE:
|
case content::PermissionType::AUDIO_CAPTURE:
|
||||||
|
@ -188,7 +218,19 @@ v8::Local<v8::Value> Converter<content::PermissionType>::ToV8(
|
||||||
return StringToV8(isolate, "mediaKeySystem");
|
return StringToV8(isolate, "mediaKeySystem");
|
||||||
case content::PermissionType::MIDI:
|
case content::PermissionType::MIDI:
|
||||||
return StringToV8(isolate, "midi");
|
return StringToV8(isolate, "midi");
|
||||||
default:
|
case content::PermissionType::WAKE_LOCK_SCREEN:
|
||||||
|
return StringToV8(isolate, "screen-wake-lock");
|
||||||
|
case content::PermissionType::SENSORS:
|
||||||
|
return StringToV8(isolate, "sensors");
|
||||||
|
case content::PermissionType::STORAGE_ACCESS_GRANT:
|
||||||
|
return StringToV8(isolate, "storage-access");
|
||||||
|
case content::PermissionType::VR:
|
||||||
|
return StringToV8(isolate, "vr");
|
||||||
|
case content::PermissionType::WAKE_LOCK_SYSTEM:
|
||||||
|
return StringToV8(isolate, "system-wake-lock");
|
||||||
|
case content::PermissionType::WINDOW_PLACEMENT:
|
||||||
|
return StringToV8(isolate, "window-placement");
|
||||||
|
case content::PermissionType::NUM:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1503,3 +1503,56 @@ describe('navigator.serial', () => {
|
||||||
expect(port).to.equal('[object SerialPort]');
|
expect(port).to.equal('[object SerialPort]');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('navigator.clipboard', () => {
|
||||||
|
let w: BrowserWindow;
|
||||||
|
before(async () => {
|
||||||
|
w = new BrowserWindow({
|
||||||
|
show: false,
|
||||||
|
webPreferences: {
|
||||||
|
enableBlinkFeatures: 'Serial'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
await w.loadFile(path.join(fixturesPath, 'pages', 'blank.html'));
|
||||||
|
});
|
||||||
|
|
||||||
|
const readClipboard: any = () => {
|
||||||
|
return w.webContents.executeJavaScript(`
|
||||||
|
navigator.clipboard.read().then(clipboard => clipboard.toString()).catch(err => err.message);
|
||||||
|
`, true);
|
||||||
|
};
|
||||||
|
|
||||||
|
after(closeAllWindows);
|
||||||
|
afterEach(() => {
|
||||||
|
session.defaultSession.setPermissionRequestHandler(null);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns clipboard contents when a PermissionRequestHandler is not defined', async () => {
|
||||||
|
const clipboard = await readClipboard();
|
||||||
|
expect(clipboard).to.not.equal('Read permission denied.');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns an error when permission denied', async () => {
|
||||||
|
session.defaultSession.setPermissionRequestHandler((wc, permission, callback) => {
|
||||||
|
if (permission === 'clipboard-read') {
|
||||||
|
callback(false);
|
||||||
|
} else {
|
||||||
|
callback(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const clipboard = await readClipboard();
|
||||||
|
expect(clipboard).to.equal('Read permission denied.');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns clipboard contents when permission is granted', async () => {
|
||||||
|
session.defaultSession.setPermissionRequestHandler((wc, permission, callback) => {
|
||||||
|
if (permission === 'clipboard-read') {
|
||||||
|
callback(true);
|
||||||
|
} else {
|
||||||
|
callback(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const clipboard = await readClipboard();
|
||||||
|
expect(clipboard).to.not.equal('Read permission denied.');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
Loading…
Reference in a new issue