feat(oauth): enhance Rowboat sign-in process to prevent duplicate users

Added billing information checks during the Rowboat OAuth connection and onboarding process to ensure user and Stripe customer existence before proceeding. This change mitigates the risk of creating duplicate users due to parallel API calls. Updated error handling for better debugging in case of failures.
This commit is contained in:
tusharmagar 2026-04-13 14:08:22 +05:30
parent 1da3223f7d
commit f6562a9895
2 changed files with 20 additions and 0 deletions

View file

@ -11,6 +11,7 @@ import { triggerSync as triggerGmailSync } from '@x/core/dist/knowledge/sync_gma
import { triggerSync as triggerCalendarSync } from '@x/core/dist/knowledge/sync_calendar.js';
import { triggerSync as triggerFirefliesSync } from '@x/core/dist/knowledge/sync_fireflies.js';
import { emitOAuthEvent } from './ipc.js';
import { getBillingInfo } from '@x/core/dist/billing/billing.js';
const REDIRECT_URI = 'http://localhost:8080/oauth/callback';
@ -271,6 +272,17 @@ export async function connectProvider(provider: string, credentials?: { clientId
triggerFirefliesSync();
}
// For Rowboat sign-in, ensure user + Stripe customer exist before
// notifying the renderer. Without this, parallel API calls from
// multiple renderer hooks race to create the user, causing duplicates.
if (provider === 'rowboat') {
try {
await getBillingInfo();
} catch (meError) {
console.error('[OAuth] Failed to initialize user via /v1/me:', meError);
}
}
// Emit success event to renderer
emitOAuthEvent({ provider, success: true });
} catch (error) {

View file

@ -535,6 +535,14 @@ export function useOnboardingState(open: boolean, onComplete: () => void) {
const cleanup = window.ipc.on('oauth:didConnect', async (event) => {
if (event.provider === 'rowboat' && event.success) {
// Ensure user record exists before advancing (prevents duplicate
// Stripe customers from parallel API calls in later steps)
try {
await window.ipc.invoke('billing:getInfo', null)
} catch (error) {
console.error('Failed to fetch billing info during onboarding:', error)
}
// Re-check composio flags now that the account is connected
try {
const [googleResult, calendarResult] = await Promise.all([