Protocol Handler
OpenWork registers a custom protocol handler (accomplish://) to enable deep linking functionality. This allows external applications and web services to initiate actions with OpenWork, such as OAuth callbacks and future integration workflows.
Implementation
The protocol handler is registered in the main process and integrated with the single-instance enforcement system.
Source: /Users/nateb/openwork-repo/apps/desktop/src/main/index.ts
// Handle custom protocol (accomplish://)
app.setAsDefaultProtocolClient('accomplish');
app.on('open-url', (event, url) => {
event.preventDefault();
console.log('[Main] Received protocol URL:', url);
// Handle protocol URL
if (url.startsWith('accomplish://callback')) {
mainWindow?.webContents?.send('auth:callback', url);
}
});
Protocol Format
Base URL Structure
accomplish://<action>?<parameters>
Current Implementation
- Protocol:
accomplish:// - Supported Actions: Currently supports
callbackfor OAuth authentication - Scheme Registration: Set as default protocol client on installation
Example URLs
# OAuth callback from external services
accomplish://callback?code=AUTH_CODE&state=SECURE_STATE
# Future deep link examples (planned)
accomplish://open?file=/path/to/document.txt
accomplish://new-task?description=Create%20a%20report
accomplish://settings?tab=api-keys
Workflow
1. Protocol Registration
// Register the protocol handler
app.setAsDefaultProtocolClient('accomplish');
2. Incoming URL Processing
// Handle incoming URLs
app.on('open-url', (event, url) => {
event.preventDefault(); // Prevent default browser handling
console.log('[Main] Received protocol URL:', url);
// Route based on URL path
if (url.startsWith('accomplish://callback')) {
mainWindow?.webContents?.send('auth:callback', url);
}
// Future handlers can be added here
});
3. Single Instance Integration
When a URL is received while OpenWork is already running:
- The second instance automatically quits
- The main window is focused and brought to front
- The URL is processed by the running instance
Security Considerations
URL Validation
- URLs are logged for debugging purposes
- Only
accomplish://callbackURLs are currently processed - Event prevention stops malicious browser interception
Event Handling
event.preventDefault(); // Critical security measure
This prevents the URL from being opened by the default browser, ensuring only OpenWork processes the deep link.
Authentication Flow Integration
The primary use case is OAuth authentication flow:
- External Service Initiates: User clicks “Connect with OpenWork” button
- Redirect to Protocol: Service redirects to
accomplish://callback - OS Routing: Operating system routes to OpenWork application
- App Handling: Main process receives and forwards to renderer
- Renderer Processing: Authentication component processes callback data
IPC Communication
// Forward callback to renderer process
mainWindow?.webContents?.send('auth:callback', url);
The renderer process listens for these events and handles the actual authentication logic.
Platform Behavior
macOS
- Shows custom protocol confirmation dialog on first launch
- Deep links appear in recent applications menu
- Can be associated with OpenWork.app bundle
Windows
- Protocol registration handled during installation
- Deep links work from command line, run dialog, and file associations
- Shows OpenWork as handler application
Linux
- Requires desktop file for protocol registration
- MIME type associations configure protocol handling
- Behavior varies by desktop environment
Configuration
Development Mode
In development, the protocol handler works with both:
- Built application (
dist/index.html) - Vite dev server (
VITE_DEV_SERVER_URL)
Production Mode
- Protocol fully registered during app installation
- Deep links work even when app is not currently running
Future Extensions
The protocol handler is designed for future expansion:
Planned Features
// Future route handlers
if (url.startsWith('accomplish://open')) {
// Open specific file or workspace
} else if (url.startsWith('accomplish://new-task')) {
// Create new task with pre-filled data
} else if (url.startsWith('accomplish://settings')) {
// Navigate to specific settings section
}
Integration Opportunities
- IDE plugins for seamless workflow integration
- Browser extensions for web-to-desktop actions
- Command-line interface for scripted operations
- Calendar integration for meeting-based task creation
Debugging Protocol Issues
Manual Testing
# Test protocol handler from terminal
open "accomplish://callback?test=true"
# On Windows
start accomplish://callback?test=true
# On Linux (using xdg-open)
xdg-open "accomplish://callback?test=true"
Log Output
[Main] Received protocol URL: accomplish://callback?code=AUTH_CODE&state=SECURE_STATE
Common Issues
- Protocol not registered: Reinstall application
- Multiple instances: Ensure single instance is running
- URL not intercepted: Check OS default application associations
Security Best Practices
- URL Validation: Always validate and sanitize incoming URLs
- Event Prevention: Never omit
event.preventDefault() - State Validation: Use OAuth state parameters to prevent CSRF
- Error Handling: Gracefully handle malformed URLs
- User Feedback: Provide clear feedback when protocol actions complete
The protocol handler provides a secure foundation for deep linking while maintaining the single-instance enforcement and security requirements of the application.