@neabyte/touchid
Version:
Native macOS Touch ID authentication with device identification, TTL caching, and TypeScript support. Features hardware UUID, device serial, and biometric type detection.
362 lines (278 loc) โข 10.1 kB
Markdown
# ๐ TouchID
[](https://www.npmjs.com/package/@neabyte/touchid)
[](https://www.npmjs.com/package/@neabyte/touchid)
[](https://nodejs.org/)
[](https://www.typescriptlang.org/)
[](https://opensource.org/licenses/MIT)
> **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.
## ๐ Credits
This library is inspired by and builds upon the excellent work of **[node-mac-auth](https://github.com/codebytere/node-mac-auth)** by [@codebytere](https://github.com/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.
### **Enhancements Over node-mac-auth :**
- โ
**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
## ๐ Overview
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.
## ๐ฏ Features
### **๐ Touch ID Authentication**
```typescript
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}`)
}
```
### **๐ก Event System**
```typescript
// 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 Performance**
- **Native C++ addon** for maximum performance
- **Direct macOS API access** via LocalAuthentication framework
- **Minimal overhead** - no Electron or heavy dependencies
- **Type-safe** TypeScript interface
### **๐ก๏ธ Security Features**
- **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
## ๐ Quick Start
### Installation
```bash
# 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
```
### Basic Usage
```typescript
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)
}
}
```
## ๐ Project Structure
```
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
```
## ๐ง API Reference
### **TouchIDService**
#### `isAvailable(): Promise<boolean>`
Check if Touch ID is available on the device.
```typescript
const available = await touchID.isAvailable()
```
#### `authenticate(options?: TouchIDOptions): Promise<TouchIDResult>`
Authenticate using Touch ID.
```typescript
const result = await touchID.authenticate({
reason: 'Authenticate to access secure data',
method: 'direct',
ttl: 30000
})
```
#### `test(): Promise<void>`
Run a test of Touch ID functionality.
```typescript
await touchID.test()
```
#### `events: TouchIDEventEmitter`
Access the event emitter for monitoring and debugging.
```typescript
// 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!')
})
```
### **Event System**
#### **Authentication Events**
- `authentication:start` - Authentication process started
- `authentication:success` - Authentication completed successfully
- `authentication:failure` - Authentication failed
- `authentication:cancel` - User cancelled authentication
#### **Device Events**
- `device:available` - Touch ID device is available
- `device:unavailable` - Touch ID device is unavailable
- `device:lockout` - Device is locked out
#### **Cache Events**
- `cache:created` - New cache entry created
- `cache:expired` - Cache entry expired
- `cache:used` - Existing cache used
#### **Initialization Events**
- `initialization:start` - Service initialization started
- `initialization:complete` - Service initialization completed
- `initialization:error` - Service initialization failed
### **Types**
#### `TouchIDOptions`
```typescript
interface TouchIDOptions {
readonly reason?: string
readonly method?: 'direct' | 'cached'
readonly ttl?: number // Time to live in milliseconds
}
```
#### `TouchIDResult`
```typescript
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
}
```
#### `TouchIDEventEmitter`
```typescript
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
}
```
## ๐งช Testing
### Test Touch ID
```bash
# Run direct authentication example
npm run example:direct
# Run cached authentication example
npm run example:cached
# Run event system example
npm run example:events
```
## ๐จ Development
### Build Commands
```bash
# Build native addon
npm run build:native
# Build TypeScript
npm run build
# Development mode
npm run dev
# Quality checks
npm run check-all
```
### Development Workflow
1. **Edit C++ code** in `src/native/touchid.mm`
2. **Build native addon** with `npm run build:native`
3. **Edit TypeScript** in `src/touchid.ts`
4. **Test functionality** with `npm run example:direct`, `npm run example:cached`, or `npm run example:events`
## ๐ Requirements
### **System Requirements**
- **Node.js 22+**
- **macOS 10.15+** (Catalina or later)
- **Touch ID enabled device** (MacBook Pro with Touch Bar, etc.)
### **Development Requirements**
- **Xcode Command Line Tools**
- **C++ compiler**
- **TypeScript 5.9+**
## ๐ก๏ธ Security Notes
- **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**
## ๐ค Contributing
1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Run `npm run check-all`
5. Submit a pull request
## ๐ License
MIT License - see [LICENSE](LICENSE) file for details.