How Fluxer Implements Desktop Handoff for Seamless Authentication Between Instances
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 where the initiateHandoff method creates a human-readable code and stores it in cache.
// 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.
// 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.
// 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 bridges the handoff service with the broader authentication stack and session management.
// 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 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.
When a user selects "Switch Instance," the main process stores the code in a module-level variable:
// 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:
// 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:
// 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
getAndDeleteoperation ingetHandoffStatusprevents token replay attacks - Time-bound validity: 5-minute expiration with explicit
HandoffCodeExpiredErrorhandling prevents stale code exploitation - User verification:
createAdditionalAuthSessionFromTokenvalidates that the source token matches the expecteduser_idbefore completing the handoff - Cleanup: Both the
DELETEendpoint and automatic cache deletion incompleteHandoffensure 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
DesktopHandoffServiceunder thedesktop-handoff:prefix - Orchestrated flow:
AuthRequestServicecoordinates between the handoff service and session management viacreateAdditionalAuthSessionFromToken - HTTP polling: Target instances poll
/auth/handoff/:code/statusuntil receivingstatus: "completed"with the one-time token - Electron IPC:
IpcHandlers.tsxandpreload/index.tsxenable secure code transfer between browser windows usingswitch-instance-urlandconsumeDesktopHandoffCode - 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.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →