Skip to content

Commit 98b6403

Browse files
authored
feat: correctly identify permissions when using setPermissionRequestHandler (electron#26172) (electron#26353)
(cherry picked from commit 7f9b21d)
1 parent e9c1268 commit 98b6403

File tree

3 files changed

+97
-1
lines changed

3 files changed

+97
-1
lines changed

docs/api/session.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,7 @@ win.webContents.session.setCertificateVerifyProc((request, callback) => {
349349
* `handler` Function | null
350350
* `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.
351351
* `permission` String - The type of requested permission.
352+
* `clipboard-read` - Request access to read from the clipboard.
352353
* `media` - Request access to media devices such as camera, microphone and speakers.
353354
* `mediaKeySystem` - Request access to DRM protected content.
354355
* `geolocation` - Request access to user's current location.

shell/common/gin_converters/content_converter.cc

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,11 +174,41 @@ v8::Local<v8::Value> Converter<content::PermissionType>::ToV8(
174174
v8::Isolate* isolate,
175175
const content::PermissionType& val) {
176176
using PermissionType = electron::WebContentsPermissionHelper::PermissionType;
177+
// Based on mappings from content/browser/devtools/protocol/browser_handler.cc
178+
// Not all permissions are currently used by Electron but this will future
179+
// proof these conversions.
177180
switch (val) {
181+
case content::PermissionType::ACCESSIBILITY_EVENTS:
182+
return StringToV8(isolate, "accessibility-events");
183+
case content::PermissionType::AR:
184+
return StringToV8(isolate, "ar");
185+
case content::PermissionType::BACKGROUND_FETCH:
186+
return StringToV8(isolate, "background-fetch");
187+
case content::PermissionType::BACKGROUND_SYNC:
188+
return StringToV8(isolate, "background-sync");
189+
case content::PermissionType::CLIPBOARD_READ_WRITE:
190+
return StringToV8(isolate, "clipboard-read");
191+
case content::PermissionType::CLIPBOARD_SANITIZED_WRITE:
192+
return StringToV8(isolate, "clipboard-sanitized-write");
193+
case content::PermissionType::FLASH:
194+
return StringToV8(isolate, "flash");
195+
case content::PermissionType::CAMERA_PAN_TILT_ZOOM:
196+
case content::PermissionType::FONT_ACCESS:
197+
return StringToV8(isolate, "font-access");
198+
case content::PermissionType::IDLE_DETECTION:
199+
return StringToV8(isolate, "idle-detection");
178200
case content::PermissionType::MIDI_SYSEX:
179201
return StringToV8(isolate, "midiSysex");
202+
case content::PermissionType::NFC:
203+
return StringToV8(isolate, "nfc");
180204
case content::PermissionType::NOTIFICATIONS:
181205
return StringToV8(isolate, "notifications");
206+
case content::PermissionType::PAYMENT_HANDLER:
207+
return StringToV8(isolate, "payment-handler");
208+
case content::PermissionType::PERIODIC_BACKGROUND_SYNC:
209+
return StringToV8(isolate, "periodic-background-sync");
210+
case content::PermissionType::DURABLE_STORAGE:
211+
return StringToV8(isolate, "persistent-storage");
182212
case content::PermissionType::GEOLOCATION:
183213
return StringToV8(isolate, "geolocation");
184214
case content::PermissionType::AUDIO_CAPTURE:
@@ -188,7 +218,19 @@ v8::Local<v8::Value> Converter<content::PermissionType>::ToV8(
188218
return StringToV8(isolate, "mediaKeySystem");
189219
case content::PermissionType::MIDI:
190220
return StringToV8(isolate, "midi");
191-
default:
221+
case content::PermissionType::WAKE_LOCK_SCREEN:
222+
return StringToV8(isolate, "screen-wake-lock");
223+
case content::PermissionType::SENSORS:
224+
return StringToV8(isolate, "sensors");
225+
case content::PermissionType::STORAGE_ACCESS_GRANT:
226+
return StringToV8(isolate, "storage-access");
227+
case content::PermissionType::VR:
228+
return StringToV8(isolate, "vr");
229+
case content::PermissionType::WAKE_LOCK_SYSTEM:
230+
return StringToV8(isolate, "system-wake-lock");
231+
case content::PermissionType::WINDOW_PLACEMENT:
232+
return StringToV8(isolate, "window-placement");
233+
case content::PermissionType::NUM:
192234
break;
193235
}
194236

spec-main/chromium-spec.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1463,3 +1463,56 @@ describe('iframe using HTML fullscreen API while window is OS-fullscreened', ()
14631463
expect(width).to.equal(0);
14641464
});
14651465
});
1466+
1467+
describe('navigator.clipboard', () => {
1468+
let w: BrowserWindow;
1469+
before(async () => {
1470+
w = new BrowserWindow({
1471+
show: false,
1472+
webPreferences: {
1473+
enableBlinkFeatures: 'Serial'
1474+
}
1475+
});
1476+
await w.loadFile(path.join(fixturesPath, 'pages', 'blank.html'));
1477+
});
1478+
1479+
const readClipboard: any = () => {
1480+
return w.webContents.executeJavaScript(`
1481+
navigator.clipboard.read().then(clipboard => clipboard.toString()).catch(err => err.message);
1482+
`, true);
1483+
};
1484+
1485+
after(closeAllWindows);
1486+
afterEach(() => {
1487+
session.defaultSession.setPermissionRequestHandler(null);
1488+
});
1489+
1490+
it('returns clipboard contents when a PermissionRequestHandler is not defined', async () => {
1491+
const clipboard = await readClipboard();
1492+
expect(clipboard).to.not.equal('Read permission denied.');
1493+
});
1494+
1495+
it('returns an error when permission denied', async () => {
1496+
session.defaultSession.setPermissionRequestHandler((wc, permission, callback) => {
1497+
if (permission === 'clipboard-read') {
1498+
callback(false);
1499+
} else {
1500+
callback(true);
1501+
}
1502+
});
1503+
const clipboard = await readClipboard();
1504+
expect(clipboard).to.equal('Read permission denied.');
1505+
});
1506+
1507+
it('returns clipboard contents when permission is granted', async () => {
1508+
session.defaultSession.setPermissionRequestHandler((wc, permission, callback) => {
1509+
if (permission === 'clipboard-read') {
1510+
callback(true);
1511+
} else {
1512+
callback(false);
1513+
}
1514+
});
1515+
const clipboard = await readClipboard();
1516+
expect(clipboard).to.not.equal('Read permission denied.');
1517+
});
1518+
});

0 commit comments

Comments
 (0)