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 callback for 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://callback URLs 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:

  1. External Service Initiates: User clicks “Connect with OpenWork” button
  2. Redirect to Protocol: Service redirects to accomplish://callback
  3. OS Routing: Operating system routes to OpenWork application
  4. App Handling: Main process receives and forwards to renderer
  5. 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

  1. Protocol not registered: Reinstall application
  2. Multiple instances: Ensure single instance is running
  3. URL not intercepted: Check OS default application associations

Security Best Practices

  1. URL Validation: Always validate and sanitize incoming URLs
  2. Event Prevention: Never omit event.preventDefault()
  3. State Validation: Use OAuth state parameters to prevent CSRF
  4. Error Handling: Gracefully handle malformed URLs
  5. 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.


Back to top

OpenWork Documentation - Community documentation for accomplish-ai/openwork