Configuration Guide
Before implementing a new integration, you may want to review the OAuth
configuration guide to understand how to set up the existing Google, Stripe,
and Telegram integrations.
System Architecture Overview
OpnForm’s OAuth system is built around several key architectural patterns:- Intent-based Flows: Different OAuth scopes and handling based on auth vs integration intents
- Orchestrator Pattern: Central
OAuthFlowOrchestrator
coordinates all OAuth flows - Service-Oriented Architecture: Specialized services handle context, user data, invites, and provider management
- State-based Context Management: Secure state tokens replace session-based context storage
- Driver Pattern: Abstracted OAuth provider implementations with support for redirect and widget flows
- Email Restrictions: Capability-based email restrictions for workspace invitations
- Message-based Communication: Cross-window communication for OAuth callbacks
Core Components
1. OAuthController (api/app/Http/Controllers/Auth/OAuthController.php
)
The simplified controller that delegates all OAuth logic to the orchestrator:
- Simplified Architecture: All logic delegated to
OAuthFlowOrchestrator
- Request Validation: Uses
OAuthRedirectRequest
for structured validation - Consistent Responses: Standardized JSON response format
2. OAuthFlowOrchestrator (api/app/Service/OAuth/OAuthFlowOrchestrator.php
)
The main orchestrator service that coordinates all OAuth flows:
- Centralized Coordination: Single entry point for all OAuth flows
- State Management: Handles OAuth state tokens for security
- Invite Integration: Supports workspace invitations with email restrictions
- Intent-based Routing: Routes to appropriate flow based on auth vs integration intent
3. OAuthContextService (api/app/Service/OAuth/OAuthContextService.php
)
Service that manages OAuth context using secure state tokens:
- State Token Security: Uses cryptographically secure state tokens instead of session storage
- Context Isolation: Each OAuth flow has isolated context
- Automatic Cleanup: Context automatically expires and clears after use
4. OAuthUserDataService (api/app/Service/OAuth/OAuthUserDataService.php
)
Service that extracts and normalizes user data from OAuth providers:
- Data Normalization: Standardizes user data across different OAuth providers
- Widget Support: Handles both redirect and widget-based authentication flows
- Error Handling: Validates and verifies OAuth provider responses
5. OAuthInviteService (api/app/Service/OAuth/OAuthInviteService.php
)
Service that handles workspace invitations and email restrictions:
- Invite Validation: Validates workspace invitation tokens
- Email Restrictions: Enforces email restrictions for OAuth providers that support it
- Capability-based: Uses interfaces to determine if driver supports email restrictions
6. OAuthUserService (api/app/Service/OAuth/OAuthUserService.php
)
Service that handles user-related OAuth operations:
- User Management: Creates new users or finds existing ones
- Workspace Integration: Uses
WorkspaceInviteService
for workspace assignment - UTM Tracking: Preserves UTM data for analytics
7. OAuthProviderService (api/app/Service/OAuth/OAuthProviderService.php
)
Service that handles OAuth provider record management:
- Provider Records: Manages OAuth provider connections in database
- Token Management: Stores and updates OAuth access/refresh tokens
- Scope Tracking: Records granted OAuth scopes
8. WorkspaceInviteService (api/app/Service/WorkspaceInviteService.php
)
Service extracted from RegisterController
that handles workspace creation and invitation acceptance:
- Workspace Creation: Creates new workspaces for users without invitations
- Invite Processing: Handles workspace invitation acceptance with atomic updates
- Role Assignment: Assigns appropriate roles based on invitation or default admin role
9. OAuth Drivers
Each provider implements theOAuthDriver
interface with updated methods:
WidgetOAuthDriver
:
10. Email Restrictions
For providers that support email restrictions (like Google), implementSupportsEmailRestrictions
:
- Invite Integration: Automatically configures email hints when OAuth is used for workspace invitations
- Login Hints: Providers like Google receive
login_hint
parameter to pre-fill login form - Email Validation: Validates OAuth email matches invited email during authentication
- Capability-based: Only applied to drivers that implement
SupportsEmailRestrictions
OAuth Flow Types
Authentication Flow (User Login/Registration)
Key Features of New Flow:- State Token Security: Each OAuth flow gets a unique, cryptographically secure state token
- Context Isolation: Context is stored with state token, preventing cross-request interference
- Invite Integration: Workspace invitations are validated and email restrictions applied automatically
- Automatic Cleanup: Context is cleared after successful use to prevent replay attacks
- Email Validation: For invites, OAuth email must match the invited email address
- Error Handling: Comprehensive error handling for expired contexts, invalid invites, email mismatches
Integration Flow (Connect Account)
Key Features:- Enhanced scopes: Automatically requests full permissions needed for integrations based on
getScopesForIntent()
- Context preservation: Stores
intention
,autoClose
, and other settings using secure state tokens - Provider management: Creates/updates
OAuthProvider
records with full OAuth data - State security: Uses same state token security as authentication flows
Widget Flow (e.g., Telegram)
Widget Authentication Features:- No redirect flow: Authentication happens in-place via widget, no OAuth redirect required
- Data verification: Cryptographic verification of widget data using provider-specific methods
- Direct provider creation: Immediately creates provider records without state tokens (no callback URL)
- Invite Integration: Supports workspace invitations with same email validation as redirect flows
- Orchestrated Processing: Uses same
OAuthFlowOrchestrator
as redirect flows for consistency
Frontend Integration
Window Message Communication
The frontend usesuseWindowMessage
composable for cross-window communication:
OAuth Composable (useOAuth
)
Centralized OAuth operations with TanStack Query integration:
Cache Management
The system automatically invalidates TanStack Query cache when OAuth connections change:Adding a New Integration
Follow these steps to add a new OAuth provider to OpnForm:1
Create OAuth Driver
Implement the OAuth driver class with the updated interface:
New Required Methods: All drivers must now implement
setState()
for
security. Use SupportsEmailRestrictions
interface and
HasEmailRestrictions
trait only if your provider supports email
hints/restrictions (like Google’s login_hint
parameter).The
setState()
method is required for state token security. The orchestrator will automatically call this method with a secure state token before generating the redirect URL.2
Register in Provider Service
Add your new provider to the enum:
3
Configure Services
Add configuration to Add environment variables to
api/config/services.php
:.env.example
:4
Install Socialite Provider
If using a community Socialite provider, add it to Register in
composer.json
:api/app/Providers/EventServiceProvider.php
:5
Add Frontend Service Definition
Update the frontend service configuration:
6
Add Feature Flag
Update feature flags controller to expose the provider:
7
Test the Integration
Test both authentication and integration flows with the new architecture:Authentication Test:
- Start fresh (logged out)
- Click “Sign in with New Provider”
- Verify state token is included in redirect URL
- Complete OAuth flow at provider
- Verify callback includes state token
- Check user creation and login success
- Verify context cleanup (state token should be cleared)
- Log in with existing account
- Go to Settings → Connections
- Click “Connect New Provider”
- Verify integration scopes are requested (more permissions than auth)
- Complete OAuth flow
- Verify provider appears in connected accounts
- Check that provider record includes full OAuth data
- Create a workspace invitation for a specific email
- Start OAuth flow with
invite_token
parameter - Verify email restrictions are applied (if provider supports them)
- Complete OAuth with invited email address
- Verify user is added to correct workspace with proper role
Verify state tokens are generated, used for context storage, and cleaned up after use. Check that email restrictions work correctly for invite flows.
8
Add Integration Handler (Optional)
If your provider will be used for form integrations, create an integration handler:Register the handler and add frontend integration components as needed.
Provider Normalization
Important: When creating providers that represent the same OAuth service
but with different authentication methods (like Google OAuth vs Google One
Tap), they should be normalized to the same provider name in the database.
getDatabaseProvider()
method in the enum:
- Users can’t connect multiple “Google” accounts (regular OAuth + One Tap)
- Provider scopes and permissions are properly merged
- The same OAuth provider record is updated regardless of authentication method
- Integration handlers work consistently with the normalized provider name
- Same OAuth service, different auth methods: Normalize (like Google/GoogleOneTap)
- Different OAuth services: Don’t normalize (like Google/GitHub)
Widget-Based Providers
For providers that use widget authentication (like Telegram), implementWidgetOAuthDriver
:
Advanced Configuration
Request Validation
The system now usesOAuthRedirectRequest
for structured validation:
- Intent Validation: Ensures only valid intents (
auth
orintegration
) are accepted - Invite Token: Validates workspace invitation tokens when present
- Context Parameters: Validates additional context like
intention
andautoClose
- UTM Tracking: Validates UTM data for analytics
Custom Scopes and Parameters
OAuth drivers can customize the authorization request with state tokens:Error Handling
The system includes comprehensive error handling in the orchestrator:- Provider Validation: Validates OAuth provider exists before processing
- State Token Security: Returns 419 for expired or invalid state tokens
- Context Cleanup: Automatically clears context even on errors
- Email Validation: Returns specific errors for email mismatches in invite flows
- Comprehensive Logging: All errors are logged for debugging
Troubleshooting
Provider not appearing in frontend
Provider not appearing in frontend
- Check feature flag configuration in
FeatureFlagsController
- Verify environment variables are set
- Ensure service is added to
useOAuth
services list - Check browser console for JavaScript errors
OAuth redirect URL mismatch
OAuth redirect URL mismatch
- Verify
redirect
URL inconfig/services.php
matches provider configuration - Check thatAPP_URL
environment variable is correct - Ensure provider OAuth app is configured with correct callback URL
State token errors (419 errors)
State token errors (419 errors)
- Check that the OAuth provider is returning the
state
parameter correctly - Verify that the OAuth flow completes within 5 minutes (context TTL) -
Ensure the state token is being passed correctly in
setState()
method - Check cache configuration and ensure Laravel cache is working properly
Email restrictions not working
Email restrictions not working
- Verify driver implements
SupportsEmailRestrictions
interface - Check thatHasEmailRestrictions
trait is being used correctly - EnsuregetEmailRestrictionParameters()
returns correct parameters for your provider - Test with a provider that supports login hints (like Google)
Scopes not working correctly
Scopes not working correctly
- Check
getScopesForIntent()
method returns correct scopes - Verify provider OAuth app has necessary permissions enabled - Test with minimal scopes first, then add additional ones - Ensure intent is being passed correctly (auth
vsintegration
)
Widget authentication failing
Widget authentication failing
- Verify widget data signature verification logic - Check that widget script
is loaded correctly - Ensure widget callback URL is accessible and correct -
Test widget data extraction and user creation flow - Verify all required
OAuthDriver
interface methods are implemented (includingsetState()
)
Workspace invitations not working
Workspace invitations not working
- Check that
WorkspaceInviteService
is properly handling invitations - Verify invite token validation in
OAuthInviteService
- Ensure email validation is working correctly for invite flows
- Check that workspace and role assignment is working properly
Best Practices
Security
- State Token Security: Always implement
setState()
method properly for CSRF protection - Context Cleanup: Trust the orchestrator to handle context cleanup automatically - Email Validation: UseSupportsEmailRestrictions
for workspace invitation flows - Widget Verification: Always verify widget data signatures cryptographically - Minimal Scopes: Use minimal scopes for authentication, full scopes for integrations - Error Handling: Implement comprehensive error handling and logging
User Experience
- Loading States: Provide clear loading states during OAuth flows -
Email Hints: Use email restrictions to pre-fill login forms for better
UX - Error Messages: Show specific, actionable error messages for OAuth
failures - Auto-close: Use
autoClose
parameter appropriately for integration flows - Popup Handling: Handle popup blockers gracefully with fallback options
Performance
- State Management: Trust the orchestrator’s efficient state token system - Context TTL: Keep OAuth flows under 5 minutes to avoid context expiration - Cache Integration: Use TanStack Query for efficient data fetching and cache invalidation - Service Architecture: Leverage the service-oriented architecture for better separation of concerns - Cleanup: Implement proper cleanup for event listeners and avoid memory leaks