fix: Add abort mechanism for conditional UI to prevent pending request errors
- Add global AbortController for conditional UI requests - Call abortConditionalUI() at start of registerPasskey and authenticatePasskey - Export abortConditionalUI from index for manual use if needed Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
20a51e7dce
commit
8e10f5cb03
|
|
@ -16,6 +16,7 @@ export {
|
|||
registerPasskey,
|
||||
authenticatePasskey,
|
||||
startConditionalUI,
|
||||
abortConditionalUI,
|
||||
isConditionalMediationAvailable,
|
||||
detectCapabilities,
|
||||
bufferToBase64url,
|
||||
|
|
|
|||
|
|
@ -44,6 +44,21 @@ const DEFAULT_CONFIG: EncryptIDConfig = {
|
|||
timeout: 60000,
|
||||
};
|
||||
|
||||
// Global abort controller for conditional UI
|
||||
let conditionalUIAbortController: AbortController | null = null;
|
||||
|
||||
/**
|
||||
* Abort any pending conditional UI request
|
||||
* Call this before starting registration or authentication
|
||||
*/
|
||||
export function abortConditionalUI(): void {
|
||||
if (conditionalUIAbortController) {
|
||||
conditionalUIAbortController.abort();
|
||||
conditionalUIAbortController = null;
|
||||
console.log('EncryptID: Conditional UI aborted');
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// UTILITY FUNCTIONS
|
||||
// ============================================================================
|
||||
|
|
@ -108,6 +123,9 @@ export async function registerPasskey(
|
|||
displayName: string,
|
||||
config: Partial<EncryptIDConfig> = {}
|
||||
): Promise<EncryptIDCredential> {
|
||||
// Abort any pending conditional UI to prevent "request already pending" error
|
||||
abortConditionalUI();
|
||||
|
||||
const cfg = { ...DEFAULT_CONFIG, ...config };
|
||||
|
||||
// Check WebAuthn support
|
||||
|
|
@ -237,6 +255,9 @@ export async function authenticatePasskey(
|
|||
credentialId?: string, // Optional: specify credential, or let user choose
|
||||
config: Partial<EncryptIDConfig> = {}
|
||||
): Promise<AuthenticationResult> {
|
||||
// Abort any pending conditional UI to prevent "request already pending" error
|
||||
abortConditionalUI();
|
||||
|
||||
const cfg = { ...DEFAULT_CONFIG, ...config };
|
||||
|
||||
// Check WebAuthn support
|
||||
|
|
@ -358,6 +379,12 @@ export async function startConditionalUI(
|
|||
return null;
|
||||
}
|
||||
|
||||
// Abort any existing conditional UI request
|
||||
abortConditionalUI();
|
||||
|
||||
// Create new abort controller for this request
|
||||
conditionalUIAbortController = new AbortController();
|
||||
|
||||
const cfg = { ...DEFAULT_CONFIG, ...config };
|
||||
const challenge = generateChallenge();
|
||||
const prfSalt = await generatePRFSalt('master-key');
|
||||
|
|
@ -380,8 +407,12 @@ export async function startConditionalUI(
|
|||
},
|
||||
// @ts-ignore - conditional mediation
|
||||
mediation: 'conditional',
|
||||
signal: conditionalUIAbortController.signal,
|
||||
}) as PublicKeyCredential;
|
||||
|
||||
// Clear abort controller on success
|
||||
conditionalUIAbortController = null;
|
||||
|
||||
if (!credential) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue