New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

webauthn-authenticator

Package Overview
Dependencies
Maintainers
1
Versions
2
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

webauthn-authenticator

A standalone TypeScript library for mocking WebAuthn in browsers, particularly useful for Playwright testing and headless browser automation

latest
Source
npmnpm
Version
0.0.2-alpha.1
Version published
Maintainers
1
Created
Source

WebAuthn Authenticator Standalone

A standalone TypeScript library for mocking WebAuthn in browsers, particularly useful for Playwright testing and headless browser automation.

Features

  • Complete WebAuthn Mock: Replaces navigator.credentials.create and navigator.credentials.get with in-memory implementations
  • ES256/P-256 Support: Full support for ECDSA with SHA-256 cryptographic operations
  • Request Queue Management: New modular architecture with pending request control for advanced testing scenarios
  • Test Control: Fine-grained control over request approval, rejection, and timeouts
  • Playwright Integration: Designed to work seamlessly with Playwright test fixtures
  • Modern TypeScript: Built with Vite, includes TypeScript definitions
  • Browser Compatible: Runs in modern browsers with proper polyfills

Architecture

The library has been refactored into a modular architecture:

  • Authenticator: Main facade implementing navigator.credentials API
  • RequestManager: Manages queued requests with test control capabilities
  • CredentialStore: Handles credential storage and retrieval
  • CryptoEngine: Performs all cryptographic operations
  • PendingRequest: Individual request objects with approval/rejection control

Quick Start

Installation

npm install

Development

# Start development server with demo
npm run dev

# Run unit tests
npm test

# Run Playwright tests
npm run playwright

# Build the library
npm run build:lib

Demo Application

The project includes a demo application that showcases the WebAuthn authenticator in action. Visit the development server to see:

  • Creating WebAuthn credentials
  • Retrieving existing credentials
  • Managing multiple credentials
  • Different relying party ID handling

Usage

Request-Based API

The architecture provides fine-grained control over WebAuthn requests for advanced testing scenarios:

import { Authenticator, RequestManager, CredentialStore, CryptoEngine, installWebAuthnMock } from 'webauthn-authenticator'

// Create modules
const credentialStore = new CredentialStore()
const cryptoEngine = new CryptoEngine()
const requestManager = new RequestManager(credentialStore, cryptoEngine)
const authenticator = new Authenticator(requestManager)

// In your test setup (e.g., Playwright)
await context.exposeFunction('createCredential', (options) => 
  authenticator.create(options)
)
await context.exposeFunction('getCredential', (options) => 
  authenticator.get(options)
)

// Install the WebAuthn mock
await context.addInitScript(() => {
  installWebAuthnMock({
    exposedCreateCredFuncName: 'createCredential',
    exposedGetCredFuncName: 'getCredential'
  })
})

// In your test - control request flow
test('should create credential with user approval', async ({ page }) => {
  // Start credential creation (won't complete until approved)
  const createPromise = page.evaluate(() => {
    return navigator.credentials.create({ publicKey: options })
  })

  // Get the pending request
  const pendingRequest = await authenticator.requestManager.waitForNextRequest()
  expect(pendingRequest.type).toBe('create')

  // Approve the request
  await pendingRequest.approve({ userVerification: true })

  // Now the browser promise resolves
  const credential = await createPromise
  expect(credential).toBeDefined()
})

// Simulate user rejection
test('should handle user cancellation', async ({ page }) => {
  const createPromise = page.evaluate(() => {
    return navigator.credentials.create({ publicKey: options })
  })

  const request = await authenticator.requestManager.waitForNextRequest()
  await request.reject(new DOMException('User cancelled', 'NotAllowedError'))

  await expect(createPromise).rejects.toThrow('User cancelled')
})

Browser Integration

import { Authenticator, RequestManager, CredentialStore, CryptoEngine, installWebAuthnMock } from 'webauthn-authenticator'

// Create the modular authenticator
const credentialStore = new CredentialStore()
const cryptoEngine = new CryptoEngine()
const requestManager = new RequestManager(credentialStore, cryptoEngine)
const authenticator = new Authenticator(requestManager)

// Expose functions to browser window
window.createCredential = authenticator.create.bind(authenticator)
window.getCredential = authenticator.get.bind(authenticator)

// Install the WebAuthn mock
installWebAuthnMock({
  exposedCreateCredFuncName: 'createCredential',
  exposedGetCredFuncName: 'getCredential'
})

// Now navigator.credentials.create() and navigator.credentials.get() work!
// But they create pending requests that need manual approval

Playwright Test Integration

import { test as base } from '@playwright/test'
import { Authenticator } from 'webauthn-authenticator'

const test = base.extend<{ authenticator: Authenticator }>({
  authenticator: async ({}, use) => {
    const authenticator = new Authenticator()
    await use(authenticator)
  },
  
  context: async ({ context, authenticator }, use) => {
    // Expose authenticator functions
    await context.exposeFunction('createCredential', 
      authenticator.createPublicKeyCredential.bind(authenticator))
    await context.exposeFunction('getCredential', 
      authenticator.getPublicKeyCredential.bind(authenticator))
    
    // Add preload script
    await context.addInitScript(() => {
      // Install WebAuthn mock (include the installWebAuthnMock code here)
    })
    
    await use(context)
  }
})

test('should create WebAuthn credential', async ({ page, authenticator }) => {
  // Your test code here - navigator.credentials.create() will work!
})

API Reference

Authenticator Class

Methods

  • createPublicKeyCredential(options) - Creates a new WebAuthn credential
  • getPublicKeyCredential(options) - Retrieves an existing credential
  • cancelNextOperation() - Cancels the next create/get operation (throws NotAllowedError)

Properties

  • credentials - Object containing all created credentials keyed by credential ID

Utility Functions

  • installWebAuthnMock(options) - Installs the WebAuthn mock in browser
  • deserializePublicKeyCredentialAttestion(credential) - Converts serialized attestation to browser format
  • deserializePublicKeyCredentialAssertion(credential) - Converts serialized assertion to browser format

Architecture

This library is based on the WebAuthn authenticator from the SendApp monorepo, specifically the @0xsend/webauthn-authenticator package. It has been extracted and modernized as a standalone library.

Key Components

  • Authenticator: Core class that manages credential lifecycle and cryptographic operations
  • Preload Script: Browser-side code that replaces the native WebAuthn API
  • Type Definitions: Complete TypeScript definitions for WebAuthn operations
  • Utilities: Helper functions for serialization and browser compatibility

Cryptographic Implementation

  • Uses Node.js crypto module for key generation and signing
  • Implements ECDSA with P-256 curve (ES256)
  • Generates proper CBOR-encoded attestation objects
  • Supports signature counters and authenticator data

Testing

The project includes comprehensive tests:

  • Unit Tests (Vitest): Test core authenticator functionality
  • Integration Tests (Playwright): Test browser integration and WebAuthn API mocking
  • Demo Tests: Validate the demo application works correctly

Building

# Build library for distribution
npm run build:lib

# Build demo application
npm run build

License

This project is derived from the SendApp monorepo and maintains compatibility with its WebAuthn implementation.

Contributing

This is a workspace for developing a standalone version of the SendApp WebAuthn authenticator. When contributing:

  • Maintain compatibility with the original SendApp implementation
  • Follow TypeScript best practices
  • Include tests for new features
  • Update documentation as needed

Troubleshooting

Common Issues

  • Import Errors: Make sure all dependencies are installed and TypeScript is configured correctly
  • Crypto Warnings: The "externalized for browser compatibility" warning is expected for Node.js crypto usage
  • Test Timeouts: Ensure the development server is running for Playwright tests

Browser Compatibility

The library requires modern browsers with support for:

  • WebCrypto API
  • ArrayBuffer/TypedArrays
  • ES2020+ features# Test commit to trigger CI/CD with updated permissions

Keywords

webauthn

FAQs

Package last updated on 06 Jul 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts