# How Fluxer Implements Desktop Handoff for Seamless Authentication Between Instances

> Discover how Fluxer implements desktop handoff with a temporary code system for seamless authentication between instances. Learn about caching, polling, and Electron IPC integration.

- Repository: [Fluxer/fluxer](https://github.com/fluxerapp/fluxer)
- Tags: internals
- Published: 2026-03-17

---

**Fluxer implements desktop handoff using a cache-backed temporary code system where the source instance generates an 8-character code, stores it in cache for 5 minutes, and the target instance polls for completion to receive a one-time authentication token via Electron IPC.**

Fluxer's desktop handoff feature enables users to start an authentication flow in one desktop instance and seamlessly finish it in another without re-entering credentials. This architecture relies on a three-layer system comprising the `DesktopHandoffService` for business logic, a generic `ICacheService` for temporary state storage, and Electron IPC handlers for cross-instance communication.

## Generating the Handoff Code

The process begins in [`packages/api/src/auth/services/DesktopHandoffService.tsx`](https://github.com/fluxerapp/fluxer/blob/main/packages/api/src/auth/services/DesktopHandoffService.tsx) where the `initiateHandoff` method creates a human-readable code and stores it in cache.

```typescript
// packages/api/src/auth/services/DesktopHandoffService.tsx
export class DesktopHandoffService {
  async initiateHandoff(userAgent?: string): Promise<{code: string; expiresAt: Date}> {
    const code = generateHandoffCode();                     // 8-character code, formatted as XXXX-XXXX
    const normalizedCode = normalizeHandoffCode(code);      // removes hyphens/spaces, forces upper-case
    const handoffData: HandoffData = { createdAt: Date.now(), userAgent };
    await this.cacheService.set(
      `${HANDOFF_CODE_PREFIX}${normalizedCode}`,          // "desktop-handoff:{CODE}"
      handoffData,
      seconds('5 minutes')                               // expiration
    );
    return { code, expiresAt: new Date(Date.now() + ms('5 minutes')) };
  }
}

```

The `generateHandoffCode` function uses a restricted alphabet (`ABCDEFGHJKMNPQRSTUVWXYZ23456789`) to eliminate ambiguous characters like "I", "1", "O", and "0". The service stores metadata including `createdAt` and optional `userAgent` under the `desktop-handoff:` prefix with a **5-minute TTL**.

## Completing the Handoff on the Source Instance

Once the user confirms the handoff, the source instance calls `completeHandoff` to validate the code and prepare the authentication token for the target instance.

```typescript
// packages/api/src/auth/services/DesktopHandoffService.tsx
async completeHandoff(code: string, token: string, userId: string): Promise<void> {
  const normalizedCode = normalizeHandoffCode(code);
  assertValidHandoffCode(normalizedCode);
  const handoffData = await this.cacheService.get<HandoffData>(`${HANDOFF_CODE_PREFIX}${normalizedCode}`);
  if (!handoffData) throw new InvalidHandoffCodeError();

  const remainingSeconds = Math.max(
    0,
    seconds('5 minutes') - Math.floor((Date.now() - handoffData.createdAt) / 1000),
  );
  if (remainingSeconds <= 0) throw new HandoffCodeExpiredError();

  // Store a one-time token that the target instance can later retrieve
  await this.cacheService.set(
    `${HANDOFF_TOKEN_PREFIX}${normalizedCode}`,        // "desktop-handoff-token:{CODE}"
    { token, userId },
    remainingSeconds,
  );
  await this.cacheService.delete(`${HANDOFF_CODE_PREFIX}${normalizedCode}`);
}

```

This method validates the code has not expired, stores the one-time token under `desktop-handoff-token:{CODE}`, and immediately deletes the pending code entry to prevent reuse.

## Polling for Handoff Status

The target instance monitors progress via `getHandoffStatus`, which the `AuthController` exposes at `GET /auth/handoff/:code/status`.

```typescript
// packages/api/src/auth/services/DesktopHandoffService.tsx
async getHandoffStatus(code: string) {
  const normalizedCode = normalizeHandoffCode(code);
  assertValidHandoffCode(normalizedCode);
  const tokenData = await this.cacheService.getAndDelete<HandoffTokenData>(`${HANDOFF_TOKEN_PREFIX}${normalizedCode}`);
  if (tokenData) {
    return { status: 'completed', token: tokenData.token, userId: tokenData.userId };
  }
  const handoffData = await this.cacheService.get<HandoffData>(`${HANDOFF_CODE_PREFIX}${normalizedCode}`);
  return handoffData ? { status: 'pending' } : { status: 'expired' };
}

```

The method uses `getAndDelete` to ensure the token can only be retrieved once, preventing replay attacks. It returns one of three statuses: `pending`, `completed`, or `expired`.

## API Orchestration and HTTP Endpoints

The `AuthRequestService` in [`packages/api/src/auth/AuthRequestService.tsx`](https://github.com/fluxerapp/fluxer/blob/main/packages/api/src/auth/AuthRequestService.tsx) bridges the handoff service with the broader authentication stack and session management.

```typescript
// packages/api/src/auth/AuthRequestService.tsx
async completeHandoff({data, request}: AuthHandoffCompleteRequest): Promise<void> {
  const {token: handoffToken, userId} = await this.authService.createAdditionalAuthSessionFromToken({
    token: data.token,
    expectedUserId: data.user_id,
    request,
  });
  await this.desktopHandoffService.completeHandoff(data.code, handoffToken, userId);
}

```

Before calling `DesktopHandoffService.completeHandoff`, this service creates an additional authentication session from the source token using `createAdditionalAuthSessionFromToken`, which verifies that the supplied source token matches the expected `user_id` to prevent unauthorized handoffs.

The `AuthController` located at [`packages/api/src/auth/AuthController.tsx`](https://github.com/fluxerapp/fluxer/blob/main/packages/api/src/auth/AuthController.tsx) registers four HTTP endpoints:

- **POST `/auth/handoff/initiate`** – Generates a new handoff code and returns it with expiration
- **POST `/auth/handoff/complete`** – Source instance validates code and deposits the one-time token
- **GET `/auth/handoff/:code/status`** – Target instance polls for completion status
- **DELETE `/auth/handoff/:code`** – Cancels a pending handoff and cleans up cache entries

## Desktop Client Integration via Electron IPC

In the Electron desktop app, the handoff code transfers between instances through IPC handlers defined in [`fluxer_desktop/src/main/IpcHandlers.tsx`](https://github.com/fluxerapp/fluxer/blob/main/fluxer_desktop/src/main/IpcHandlers.tsx).

When a user selects "Switch Instance," the main process stores the code in a module-level variable:

```typescript
// fluxer_desktop/src/main/IpcHandlers.tsx
let pendingDesktopHandoffCode: string | null = null;

ipcMain.handle('switch-instance-url', async (_event, options) => {
  // … window management logic …
  pendingDesktopHandoffCode = options.desktopHandoffCode ?? null;
  // … load the new instance URL …
});

```

The target instance retrieves this code through the preload script exposed to the renderer:

```typescript
// fluxer_desktop/src/preload/index.tsx
consumeDesktopHandoffCode: (): Promise<string | null> =>
  ipcRenderer.invoke('consume-desktop-handoff-code'),

```

A typical React implementation in the target instance polls the API after retrieving the code:

```typescript
// Target instance implementation
const handoffCode = await window.electron.consumeDesktopHandoffCode();

if (handoffCode) {
  let status = 'pending';
  while (status === 'pending') {
    const resp = await fetch(`/auth/handoff/${handoffCode}/status`);
    const data = await resp.json();
    status = data.status;
    
    if (status === 'completed') {
      localStorage.setItem('authToken', data.token);
      // Authentication complete - proceed as authenticated user
    }
    await new Promise(r => setTimeout(r, 1000));
  }
}

```

## Security Architecture

Fluxer's desktop handoff implements several security layers to protect the authentication flow:

- **Code entropy**: 8-character codes from a 32-character alphabet provide approximately 32^8 possible combinations while remaining human-readable
- **Single-use tokens**: The `getAndDelete` operation in `getHandoffStatus` prevents token replay attacks
- **Time-bound validity**: 5-minute expiration with explicit `HandoffCodeExpiredError` handling prevents stale code exploitation
- **User verification**: `createAdditionalAuthSessionFromToken` validates that the source token matches the expected `user_id` before completing the handoff
- **Cleanup**: Both the `DELETE` endpoint and automatic cache deletion in `completeHandoff` ensure no orphaned entries remain

## Summary

Fluxer's desktop handoff implementation provides seamless cross-instance authentication through:

- **Short-lived codes**: 8-character alphanumeric codes stored for 5 minutes in `DesktopHandoffService` under the `desktop-handoff:` prefix
- **Orchestrated flow**: `AuthRequestService` coordinates between the handoff service and session management via `createAdditionalAuthSessionFromToken`
- **HTTP polling**: Target instances poll `/auth/handoff/:code/status` until receiving `status: "completed"` with the one-time token
- **Electron IPC**: [`IpcHandlers.tsx`](https://github.com/fluxerapp/fluxer/blob/main/IpcHandlers.tsx) and [`preload/index.tsx`](https://github.com/fluxerapp/fluxer/blob/main/preload/index.tsx) enable secure code transfer between browser windows using `switch-instance-url` and `consumeDesktopHandoffCode`
- **Security**: Single-use tokens, time limits, and user verification prevent unauthorized access while maintaining a frictionless user experience

## Frequently Asked Questions

### How long does a Fluxer desktop handoff code remain valid?

The handoff code expires after **5 minutes** from creation. The `DesktopHandoffService` sets a TTL on the cache entry when calling `initiateHandoff` and validates the remaining time in `completeHandoff`, throwing `HandoffCodeExpiredError` if the window has passed.

### Can the same handoff code be used multiple times?

No. Once the source instance calls `completeHandoff`, the service deletes the pending code entry using `cacheService.delete`. When the target instance retrieves the token via `getHandoffStatus`, the implementation uses `getAndDelete` to atomically retrieve and remove the token from cache, ensuring it cannot be reused.

### What prevents unauthorized users from guessing a handoff code?

The code uses an 8-character string from a restricted alphabet of 32 characters (deliberately excluding ambiguous characters like I, 1, O, and 0), providing approximately 1.1 trillion possible combinations. Additionally, codes are single-use and expire after 5 minutes, making brute-force attacks computationally infeasible within the validity window.

### How does the desktop client transfer the code between instances?

The Electron main process stores the code in a module-level variable via the `switch-instance-url` IPC handler when the user initiates a switch. When the target instance loads, it calls `consumeDesktopHandoffCode` through the preload script, which retrieves and immediately clears the pending code from the main process memory, ensuring secure one-time delivery.