Native Touch ID Authentication for TypeScript - A TypeScript library that provides native Touch ID authentication for macOS applications with strict coding standards and comprehensive type safety.
This library is inspired by and builds upon the excellent work of node-mac-auth by @codebytere (Shelley Vohr). The authentication flow and LocalAuthentication framework usage patterns are based on the node-mac-auth implementation, which provides a clean and reliable approach to Touch ID integration on macOS.
- ✅ Persistent caching across process restarts
- ✅ Device identifiers (hardware UUID, serial, model)
- ✅ TypeScript support with full type safety
- ✅ Modern ES modules and async/await patterns
- ✅ Enhanced error handling and detailed error messages
- ✅ Event System for real-time monitoring and debugging
This library provides native Touch ID authentication for TypeScript applications on macOS. Built with strict TypeScript coding standards, it offers a clean, type-safe API for biometric authentication with comprehensive event monitoring.
import { touchID } from '@neabyte/touchid'
// Check if Touch ID is available
const available = await touchID.isAvailable()
console.log(`Touch ID available: ${available ? '✅' : '❌'}`)
// Direct authentication (always prompts)
const result = await touchID.authenticate({
reason: 'Authenticate to access secure data',
method: 'direct'
})
// Cached authentication (reuses recent auth)
const cachedResult = await touchID.authenticate({
reason: 'Cached authentication',
method: 'cached',
ttl: 30000 // 30 seconds cache
})
if (result.success) {
console.log('✅ Authentication successful!')
console.log('Device:', result.data?.deviceModel)
console.log('UUID:', result.data?.hardwareUUID)
} else {
console.log(`❌ Authentication failed: ${result.error}`)
}
// Real-time monitoring of authentication events
touchID.events.on('authentication:success', (event) => {
console.log(`✅ Auth successful in ${event.duration}ms`)
console.log(`Device: ${event.data?.deviceModel}`)
})
// Monitor device status
touchID.events.on('device:lockout', (event) => {
console.log(`🔒 Device locked for ${event.duration}ms`)
})
// Track cache usage
touchID.events.on('cache:created', (event) => {
console.log(`💾 Cache created with ${event.ttl}ms TTL`)
})
// One-time initialization listener
touchID.events.once('initialization:complete', (event) => {
console.log(`✅ Service ready in ${event.duration}ms`)
})
- Native C++ addon for maximum performance
- Direct macOS API access via LocalAuthentication framework
- Minimal overhead - no Electron or heavy dependencies
- Type-safe TypeScript interface
- Biometric authentication using Touch ID
- Secure error handling with detailed error messages
- Graceful fallbacks when Touch ID is unavailable
- Promise-based API for async operations
# Install from npm
npm install @neabyte/touchid
# Or clone the repository
git clone https://github.com/NeaByteLab/TouchID.git
cd TouchID
# Install dependencies
npm install
# Build native addon
npm run build:native
# Run examples
npm run example:direct
npm run example:cached
npm run example:events
import { TouchIDService, createTouchIDService } from '@neabyte/touchid'
// Use default instance
const touchID = createTouchIDService()
// Or create custom instance
const customTouchID = new TouchIDService()
// Check availability
const available = await touchID.isAvailable()
if (available) {
// Authenticate with device data
const result = await touchID.authenticate({
reason: 'Access secure application',
method: 'direct'
})
if (result.success) {
console.log('Access granted!')
console.log('Device info:', result.data)
}
}
TouchID/
├── src/ # Source code
│ ├── native/ # Native C++ addon
│ │ └── touchid.mm # Touch ID implementation
│ ├── types/ # TypeScript type definitions
│ │ ├── touchid.ts # Touch ID types
│ │ └── index.ts # Common types
│ ├── utils/ # Utility functions
│ │ ├── event-emitter.ts # Event system implementation
│ │ └── index.ts # Common utilities
│ ├── touchid.ts # Touch ID service
│ └── index.ts # Main entry point
├── examples/ # Usage examples
│ ├── example-direct.ts # Direct authentication example
│ ├── example-cached.ts # Cached authentication example
│ └── example-events.ts # Event system example
├── build/ # Native addon build output
├── dist/ # TypeScript build output
└── docs/ # Auto-generated documentation
Check if Touch ID is available on the device.
const available = await touchID.isAvailable()
Authenticate using Touch ID.
const result = await touchID.authenticate({
reason: 'Authenticate to access secure data',
method: 'direct',
ttl: 30000
})
Run a test of Touch ID functionality.
await touchID.test()
Access the event emitter for monitoring and debugging.
// Listen for authentication events
touchID.events.on('authentication:success', (event) => {
console.log(`Success in ${event.duration}ms`)
})
// Remove event listener
touchID.events.off('authentication:success', handler)
// One-time listener
touchID.events.once('initialization:complete', (event) => {
console.log('Service ready!')
})
authentication:start
- Authentication process startedauthentication:success
- Authentication completed successfullyauthentication:failure
- Authentication failedauthentication:cancel
- User cancelled authentication
device:available
- Touch ID device is availabledevice:unavailable
- Touch ID device is unavailabledevice:lockout
- Device is locked out
cache:created
- New cache entry createdcache:expired
- Cache entry expiredcache:used
- Existing cache used
initialization:start
- Service initialization startedinitialization:complete
- Service initialization completedinitialization:error
- Service initialization failed
interface TouchIDOptions {
readonly reason?: string
readonly method?: 'direct' | 'cached'
readonly ttl?: number // Time to live in milliseconds
}
interface TouchIDResult {
readonly success: boolean
readonly error?: string
readonly data?: DeviceData
}
interface DeviceData {
readonly biometryType: 'TouchID' | 'FaceID' | 'None' | 'Unsupported'
readonly hardwareUUID: string
readonly deviceSerial: string
readonly deviceModel: string
}
interface TouchIDEventEmitter {
on<T extends TouchIDEventType>(event: T, handler: TouchIDEventHandler<T>): void
off<T extends TouchIDEventType>(event: T, handler: TouchIDEventHandler<T>): void
once<T extends TouchIDEventType>(event: T, handler: TouchIDEventHandler<T>): void
removeAllListeners(event?: TouchIDEventType): void
}
# Run direct authentication example
npm run example:direct
# Run cached authentication example
npm run example:cached
# Run event system example
npm run example:events
# Build native addon
npm run build:native
# Build TypeScript
npm run build
# Development mode
npm run dev
# Quality checks
npm run check-all
- Edit C++ code in
src/native/touchid.mm
- Build native addon with
npm run build:native
- Edit TypeScript in
src/touchid.ts
- Test functionality with
npm run example:direct
,npm run example:cached
, ornpm run example:events
- Node.js 22+
- macOS 10.15+ (Catalina or later)
- Touch ID enabled device (MacBook Pro with Touch Bar, etc.)
- Xcode Command Line Tools
- C++ compiler
- TypeScript 5.9+
- Touch ID data never leaves the device
- No biometric data is stored or transmitted
- Uses Apple's secure LocalAuthentication framework
- Follows macOS security best practices
- Fork the repository
- Create a feature branch
- Make your changes
- Run
npm run check-all
- Submit a pull request
MIT License - see LICENSE file for details.