77 lines
2.5 KiB
TypeScript
77 lines
2.5 KiB
TypeScript
import type {
|
|
BrowserWindow,
|
|
MediaAccessPermissionRequest,
|
|
PermissionCheckHandlerHandlerDetails,
|
|
Session,
|
|
WebContents,
|
|
} from 'electron';
|
|
|
|
type MediaPermissionMainWindow = Pick<BrowserWindow, 'isDestroyed'> & {
|
|
webContents: Pick<WebContents, 'id'> & {
|
|
session: Pick<Session, 'setPermissionCheckHandler' | 'setPermissionRequestHandler'>;
|
|
};
|
|
};
|
|
|
|
type MediaPermissionWebContents = Pick<WebContents, 'id'>;
|
|
type MediaPermissionDetails = Pick<MediaAccessPermissionRequest, 'mediaTypes'>;
|
|
type MediaPermissionCheckDetails = Pick<PermissionCheckHandlerHandlerDetails, 'mediaType'>;
|
|
|
|
function isMainWindowWebContents(
|
|
webContents: MediaPermissionWebContents | null | undefined,
|
|
mainWindow: MediaPermissionMainWindow,
|
|
): boolean {
|
|
return Boolean(
|
|
webContents
|
|
&& !mainWindow.isDestroyed()
|
|
&& webContents.id === mainWindow.webContents.id,
|
|
);
|
|
}
|
|
|
|
function requestIncludesAudio(details: MediaPermissionDetails | undefined): boolean {
|
|
const mediaTypes = details?.mediaTypes;
|
|
return !mediaTypes || mediaTypes.length === 0 || mediaTypes.includes('audio');
|
|
}
|
|
|
|
function checkIncludesAudio(details: MediaPermissionCheckDetails | undefined): boolean {
|
|
const mediaType = details?.mediaType;
|
|
return !mediaType || mediaType === 'audio';
|
|
}
|
|
|
|
export function isAllowedMediaPermissionCheck(
|
|
webContents: MediaPermissionWebContents | null | undefined,
|
|
permission: string,
|
|
mainWindow: MediaPermissionMainWindow,
|
|
details?: MediaPermissionCheckDetails,
|
|
): boolean {
|
|
return (
|
|
permission === 'media'
|
|
&& isMainWindowWebContents(webContents, mainWindow)
|
|
&& checkIncludesAudio(details)
|
|
);
|
|
}
|
|
|
|
export function isAllowedMediaPermissionRequest(
|
|
webContents: MediaPermissionWebContents | null | undefined,
|
|
permission: string,
|
|
details: MediaPermissionDetails | undefined,
|
|
mainWindow: MediaPermissionMainWindow,
|
|
): boolean {
|
|
return (
|
|
permission === 'media'
|
|
&& isMainWindowWebContents(webContents, mainWindow)
|
|
&& requestIncludesAudio(details)
|
|
);
|
|
}
|
|
|
|
export function installMediaPermissionHandler(mainWindow: MediaPermissionMainWindow): void {
|
|
const permissionSession = mainWindow.webContents.session;
|
|
|
|
permissionSession.setPermissionCheckHandler((webContents, permission, _requestingOrigin, details) => (
|
|
isAllowedMediaPermissionCheck(webContents, permission, mainWindow, details)
|
|
));
|
|
|
|
permissionSession.setPermissionRequestHandler((webContents, permission, callback, details) => {
|
|
callback(isAllowedMediaPermissionRequest(webContents, permission, details, mainWindow));
|
|
});
|
|
}
|