Popup Services
Popup Services
Section titled “Popup Services”The popup services provide utilities for opening popup windows, typically used for OAuth authentication flows or external integrations that require user interaction in a separate window.
Functions
Section titled “Functions”| Function | Description |
|---|---|
openPopUp(url) | Opens a popup and extracts state parameter from redirect URL |
openPopUpBlank(url) | Opens a popup and waits for it to return to same origin |
openPopUp(url)
Section titled “openPopUp(url)”Opens a centered popup window and monitors for OAuth-style redirects. When the popup navigates to a URL containing a state parameter, it extracts and returns the decoded state.
Signature
Section titled “Signature”async function openPopUp(url: string): Promise<{ type: 'integration'; data: any;}>import { openPopUp } from '@ion-components/packages/services/popup.services';
async function connectShopify() { try { const result = await openPopUp('https://api.example.com/oauth/shopify/start');
// result.data contains the decoded state from OAuth callback console.log('Integration data:', result.data);
// Typically contains: shop domain, access token, etc. saveIntegration(result.data);
} catch (error) { console.error('OAuth failed:', error); }}How It Works
Section titled “How It Works”- Opens a centered popup window (550x660 pixels)
- Monitors the popup URL every 500ms
- When the URL contains a
statequery parameter, it:- Decodes the base64-encoded state
- Parses it as JSON
- Closes the popup
- Returns the data
openPopUpBlank(url)
Section titled “openPopUpBlank(url)”Opens a popup and waits for it to return to the same origin (typically after an external process completes).
Signature
Section titled “Signature”async function openPopUpBlank(url: string): Promise<void>import { openPopUpBlank } from '@ion-components/packages/services/popup.services';
async function handleExternalAuth() { // Open external authentication page await openPopUpBlank('https://external-service.com/auth');
// Control returns here after popup closes or returns to same origin console.log('External auth completed');
// Refresh data that might have been updated externally await refreshIntegrations();}How It Works
Section titled “How It Works”- Opens a centered popup window (550x660 pixels)
- Monitors the popup every 500ms
- Resolves when:
- The popup is closed by the user, OR
- The popup navigates to the same origin as the parent window
Complete OAuth Example
Section titled “Complete OAuth Example”import { openPopUp } from '@ion-components/packages/services/popup.services';
// Component for managing integrationsconst integrations = ref([]);
async function addShopifyIntegration() { try { // 1. Start OAuth flow - opens Shopify login const result = await openPopUp('/oauth/shopify/authorize');
// 2. result.data contains the shop info after OAuth completes const { shop, accessToken, scope } = result.data;
// 3. Save the integration await apiService.create({ provider: 'shopify', shop, accessToken, scope, });
// 4. Refresh list await loadIntegrations();
showSuccess('Shopify connected successfully!');
} catch (error) { if (error.message === 'Popup closed by user') { // User cancelled - no action needed return; } showError('Failed to connect Shopify: ' + error.message); }}
async function addGoogleIntegration() { try { const result = await openPopUp('/oauth/google/authorize');
const { email, refreshToken, accessToken } = result.data;
await apiService.create({ provider: 'google', email, refreshToken, accessToken, });
await loadIntegrations(); showSuccess('Google connected successfully!');
} catch (error) { handleOAuthError(error); }}Backend Requirements
Section titled “Backend Requirements”Your backend OAuth flow should:
- Initiate the OAuth process
- Handle the callback from the OAuth provider
- Encode the result in a
stateparameter - Redirect to a page that includes this state in the URL
Example Laravel Callback
Section titled “Example Laravel Callback”public function handleCallback(Request $request){ // ... OAuth token exchange logic ...
$state = base64_encode(json_encode([ 'shop' => $shop->name, 'accessToken' => $accessToken, 'scope' => $scope, ]));
return redirect('/oauth/complete?state=' . $state);}Example Completion Page
Section titled “Example Completion Page”<!DOCTYPE html><html><head> <title>Connection Complete</title></head><body> <p>Connection successful! This window will close automatically.</p></body></html>Error Handling
Section titled “Error Handling”Both functions can throw errors in these scenarios:
| Scenario | Error |
|---|---|
| Popup blocked | Browser blocked the popup |
| User closes popup | User cancelled the flow |
| Invalid state | Cannot parse the returned state |
| Network error | OAuth provider unreachable |
try { await openPopUp(authUrl);} catch (error) { if (error.message.includes('blocked')) { showError('Please allow popups for this site'); } else if (error.message.includes('closed')) { // User cancelled - silent failure } else { showError('Authentication failed. Please try again.'); }}