Bulk Messaging System

An Electron Desktop app for marketing campaign & broadcast management, using either whatsapp, gmail or a SMTP server

Gmail OAuth 2 security

Introduction#

Security choices in the Gmail OAuth flow: isolated BrowserWindow, limited scopes, encrypted token store, IPC-only secrets.

Project structure#

The Gmail OAuth2 implementation spans multiple layers of the application architecture:

Core components#

The Gmail OAuth2 implementation consists of several key components working together to provide secure authentication and email sending capabilities:

OAuth2 configuration#

The system uses a minimal scope focused solely on email sending functionality:

  • Scope: https://www.googleapis.com/auth/gmail.send
  • Redirect URI: http://localhost:3000/oauth/callback
  • Access type: offline for refresh token acquisition
  • Consent prompt: consent so Google returns a refresh token

Token storage mechanism#

Credentials are persisted using electron-store with automatic encryption:

  • Storage location: Application-specific storage directory
  • Encryption: Automatic encryption provided by electron-store
  • Token structure: Complete OAuth2 token object including access_token, refresh_token, expires_in, and token_type

BrowserWindow-Based authentication flow#

The authentication process uses Electron’s BrowserWindow with improved security:

  • Context isolation enabled
  • Node.js integration disabled
  • Web security enabled
  • Window timeout protection (5 minutes)

Architecture overview#

OAuth2 across main, preload, and renderer:

Detailed component analysis#

Gmail authentication handler#

The core authentication logic is implemented in the gmail-handler.js module:

OAuth2 client configuration#

The handler creates a Google OAuth2 client with specific security parameters:

  • Client ID and Secret loaded from environment variables
  • Redirect URI configured for local development
  • Scope limited to email sending operations only
  • Offline access type for refresh token acquisition

BrowserWindow implementation#

The authentication flow uses a dedicated BrowserWindow with improved security:

  • Context isolation enabled to prevent renderer process compromise
  • Node.js integration disabled for security isolation
  • Web security enabled to prevent XSS attacks
  • Window timeout protection prevents hanging authentication
  • ready-to-show waits until content is ready before showing the window

Redirect handling and error management#

The handler implements reliable redirect handling:

  • Redirect URL validation against configured redirect URI
  • Authorization code extraction from URL parameters
  • OAuth error handling with descriptive error messages
  • Timeout management with automatic cleanup
  • Window closure on completion or failure

Token storage and retrieval#

Token persistence uses electron-store with automatic encryption:

  • Token stored under ‘gmail_token’ key
  • Complete token object stored for future use
  • Token retrieval for subsequent email operations
  • Automatic encryption provided by electron-store

Electron main process integration#

The main.js file integrates the Gmail handler through IPC handlers:

IPC handler registration#

The main process registers three key IPC handlers:

  • gmail-auth: Initiates Gmail authentication flow
  • gmail-token: Checks for existing authentication
  • send-email: Sends bulk emails using stored credentials

Security configuration#

The main process maintains security through:

  • Context isolation in BrowserWindow creation
  • Node.js integration disabled in BrowserWindow
  • Web security enabled for protection against XSS
  • Proper error handling and cleanup

Frontend integration components#

The React components provide user interface and integration points:

GmailForm component#

The GmailForm component manages the user-facing authentication interface:

  • Authentication status display with visual indicators
  • Email list import functionality
  • Form validation and error handling
  • Real-time progress tracking during email sending

BulkMailer integration#

The BulkMailer component coordinates the overall application flow:

  • Authentication state management
  • Form validation and preparation
  • Error handling and user feedback
  • Integration with Electron IPC for authentication

Preload script security bridge#

The preload.js script establishes a secure IPC bridge:

  • Exposes only necessary methods to renderer process
  • Implements proper error handling and validation
  • Provides structured API for authentication operations
  • Maintains context isolation while enabling functionality

Dependency analysis#

The Gmail OAuth2 implementation relies on several key dependencies and external services:

External dependencies#

The implementation depends on:

  • googleapis. Google API client library for OAuth2 and Gmail API
  • electron-store. Secure credential storage with automatic encryption
  • dotenv. Environment variable loading for client credentials
  • electron. Desktop application framework with BrowserWindow

Security dependencies#

The security model relies on:

  • Context isolation. Prevents renderer process compromise
  • Node.js integration disabled. Reduces attack surface
  • Web security enabled. Protection against XSS attacks
  • Automatic token encryption. electron-store encryption for credential protection

Performance considerations#

The OAuth2 implementation incorporates several performance and scalability considerations:

Token management efficiency#

  • Single token storage reduces database queries
  • Automatic token encryption handled by electron-store
  • Minimal memory footprint for token objects
  • Efficient redirect handling with timeout protection

Rate limiting and throttling#

  • Configurable delay between email sends (default 1000ms)
  • Progress tracking enables user feedback
  • Batch processing with individual error handling
  • Failures do not crash the auth window

Resource management#

  • BrowserWindow cleanup on completion or timeout
  • Memory-efficient token storage
  • Proper error handling prevents resource leaks
  • Timeout protection prevents hanging processes

Troubleshooting guide#

Common authentication issues#

Missing Environment Variables

  • Symptom: Authentication returns error about missing client credentials
  • Solution: Ensure GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET are set in .env file
  • Prevention: Validate environment variables before OAuth2 initialization

OAuth2 Redirect Problems

  • Symptom: Authentication window closes without completing flow
  • Solution: Verify redirect URI matches Google OAuth2 console configuration
  • Prevention: Ensure localhost:3000/oauth/callback is whitelisted in OAuth2 consent screen

Token Storage Failures

  • Symptom: Authentication succeeds but emails fail to send
  • Solution: Check electron-store permissions and application data directory
  • Prevention: Implement token validation before email operations

Security considerations#

Scope limitations#

The implementation uses minimal required scope:

  • Only requests https://www.googleapis.com/auth/gmail.send
  • Avoids broader scopes that could increase security risk
  • Follows principle of least privilege for API access

Refresh token management#

  • Uses offline access type to acquire refresh tokens
  • Stores complete token objects for clean renewal
  • Handles token expiration transparently through Google API client
  • Implements proper cleanup on authentication failures

Secure transmission#

  • All OAuth2 communication occurs over HTTPS
  • Token storage uses electron-store encryption
  • BrowserWindow security settings prevent credential leakage
  • Context isolation protects against renderer process attacks

Error handling and recovery#

  • Detailed error handling throughout OAuth2 flow
  • Timeout protection prevents hanging authentication
  • Network failures do not crash the auth window
  • Clear error messages with actionable guidance

Conclusion#

Keep scopes minimal and the auth window short-lived. The refresh token is the long-term secret; protect the store that holds it.