signal-desktop/app/permissions.ts

94 lines
2.8 KiB
TypeScript
Raw Normal View History

2023-01-03 19:55:46 +00:00
// Copyright 2018 Signal Messenger, LLC
2020-10-30 20:34:04 +00:00
// SPDX-License-Identifier: AGPL-3.0-only
// The list of permissions is here:
// https://electronjs.org/docs/api/session#sessetpermissionrequesthandlerhandler
2023-04-20 15:59:17 +00:00
import type { session as ElectronSession, Session } from 'electron';
2021-10-01 18:49:59 +00:00
import type { ConfigType } from './base_config';
const PERMISSIONS: Record<string, boolean> = {
// Allowed
fullscreen: true, // required to show videos in full-screen
notifications: true, // required to show OS notifications for new messages
2022-12-19 18:23:53 +00:00
'clipboard-sanitized-write': true, // required to copy text into clipboard
// Off by default, can be enabled by user
2020-06-04 18:16:19 +00:00
media: false, // required for access to microphone and camera, used for voice notes and calling
// Not allowed
geolocation: false,
midiSysex: false,
openExternal: false, // we don't need this; we open links via 'will-navigate' event
pointerLock: false,
};
function _createPermissionHandler(
2021-08-18 20:08:14 +00:00
userConfig: Pick<ConfigType, 'get'>
): Parameters<typeof ElectronSession.prototype.setPermissionRequestHandler>[0] {
return (_webContents, permission, callback, details): void => {
2020-06-04 18:16:19 +00:00
// We default 'media' permission to false, but the user can override that for
// the microphone and camera.
if (permission === 'media') {
2024-05-15 16:48:54 +00:00
// Pacifying typescript because it is always there for 'media' permission
if (!('mediaTypes' in details)) {
callback(false);
return;
}
if (
details.mediaTypes?.includes('audio') ||
details.mediaTypes?.includes('video')
) {
if (
details.mediaTypes?.includes('audio') &&
userConfig.get('mediaPermissions')
) {
callback(true);
return;
}
if (
details.mediaTypes?.includes('video') &&
userConfig.get('mediaCameraPermissions')
) {
callback(true);
return;
}
callback(false);
return;
}
// If it doesn't have 'video' or 'audio', it's probably screenshare.
// TODO: DESKTOP-1611
callback(true);
return;
}
if (PERMISSIONS[permission]) {
console.log(`Approving request for permission '${permission}'`);
callback(true);
return;
}
console.log(`Denying request for permission '${permission}'`);
callback(false);
};
}
export function installPermissionsHandler({
session,
userConfig,
}: {
2023-04-20 15:59:17 +00:00
session: Session;
2021-08-18 20:08:14 +00:00
userConfig: Pick<ConfigType, 'get'>;
}): void {
// Setting the permission request handler to null first forces any permissions to be
// requested again. Without this, revoked permissions might still be available if
// they've already been used successfully.
2023-04-20 15:59:17 +00:00
session.setPermissionRequestHandler(null);
2023-04-20 15:59:17 +00:00
session.setPermissionRequestHandler(_createPermissionHandler(userConfig));
}