feat(automation): add macOS permission check before automation start

This commit is contained in:
2025-11-22 14:52:48 +01:00
parent 98baa1c3bc
commit c0e0e00c4c
6 changed files with 510 additions and 9 deletions

View File

@@ -11,8 +11,62 @@ export function setupIpcHandlers(mainWindow: BrowserWindow): void {
const startAutomationUseCase = container.getStartAutomationUseCase();
const sessionRepository = container.getSessionRepository();
const automationEngine = container.getAutomationEngine();
const permissionService = container.getPermissionService();
const logger = container.getLogger();
// Permission handlers
ipcMain.handle('automation:checkPermissions', async () => {
try {
const result = await permissionService.checkPermissions();
return {
success: true,
granted: result.granted,
status: result.status,
missingPermissions: result.missingPermissions,
};
} catch (error) {
const err = error instanceof Error ? error : new Error('Unknown error');
logger.error('Permission check failed', err);
return {
success: false,
error: err.message,
granted: false,
status: {
accessibility: false,
screenRecording: false,
platform: process.platform,
},
missingPermissions: ['Accessibility', 'Screen Recording'],
};
}
});
ipcMain.handle('automation:requestAccessibility', async () => {
try {
const granted = permissionService.requestAccessibilityPermission();
return { success: true, granted };
} catch (error) {
const err = error instanceof Error ? error : new Error('Unknown error');
logger.error('Accessibility permission request failed', err);
return { success: false, granted: false, error: err.message };
}
});
ipcMain.handle('automation:openPermissionSettings', async (_event: IpcMainInvokeEvent, pane?: 'accessibility' | 'screenRecording') => {
try {
if (pane) {
await permissionService.openSystemPreferences(pane);
} else {
await permissionService.openPermissionsSettings();
}
return { success: true };
} catch (error) {
const err = error instanceof Error ? error : new Error('Unknown error');
logger.error('Failed to open permission settings', err);
return { success: false, error: err.message };
}
});
ipcMain.handle('start-automation', async (_event: IpcMainInvokeEvent, config: HostedSessionConfig) => {
try {
logger.info('Starting automation', { sessionName: config.sessionName });
@@ -22,6 +76,20 @@ export function setupIpcHandlers(mainWindow: BrowserWindow): void {
clearInterval(progressMonitorInterval);
progressMonitorInterval = null;
}
// Check permissions before starting automation (macOS only)
const permissionResult = await permissionService.checkPermissions();
if (!permissionResult.granted) {
logger.warn('Automation blocked due to missing permissions', {
missingPermissions: permissionResult.missingPermissions,
});
return {
success: false,
error: `Missing required permissions: ${permissionResult.missingPermissions.join(', ')}. Please grant permissions in System Preferences and try again.`,
permissionError: true,
missingPermissions: permissionResult.missingPermissions,
};
}
// Connect to browser first (required for dev mode)
const connectionResult = await container.initializeBrowserConnection();