ngx-webauthn 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,412 @@
1
+ # ngx-webauthn
2
+
3
+ A comprehensive Angular library that provides a clean, type-safe abstraction over the WebAuthn API. This library simplifies the implementation of passwordless authentication using passkeys, security keys, and biometric authentication.
4
+
5
+ ## Features
6
+
7
+ - ๐Ÿ” **Complete WebAuthn Support** - Registration and authentication flows
8
+ - ๐Ÿ›ก๏ธ **Type Safety** - Full TypeScript support with comprehensive interfaces
9
+ - ๐ŸŽฏ **Clean API** - Simplified abstraction over complex WebAuthn APIs
10
+ - ๐Ÿ“ฑ **Cross-Platform** - Works with platform authenticators (Face ID, Touch ID, Windows Hello)
11
+ - ๐Ÿ”‘ **Security Keys** - Support for external authenticators (YubiKey, etc.)
12
+ - โšก **RxJS Integration** - Observable-based API that fits naturally into Angular
13
+ - ๐Ÿงช **Well Tested** - Comprehensive unit test coverage
14
+ - ๐Ÿ“– **Browser Support** - Works in all modern browsers with WebAuthn support
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ npm install ngx-webauthn
20
+ ```
21
+
22
+ ## Quick Start
23
+
24
+ ### 1. Configure the Service
25
+
26
+ First, configure the WebAuthn service with your relying party information:
27
+
28
+ ```typescript
29
+ // main.ts (standalone app)
30
+ import { bootstrapApplication } from '@angular/platform-browser';
31
+ import { provideWebAuthn } from 'ngx-webauthn';
32
+ import { AppComponent } from './app/app.component';
33
+
34
+ bootstrapApplication(AppComponent, {
35
+ providers: [
36
+ provideWebAuthn(
37
+ { name: 'My App', id: 'myapp.com' }, // Required relying party config
38
+ { defaultTimeout: 30000 } // Optional overrides
39
+ ),
40
+ // ... other providers
41
+ ],
42
+ });
43
+ ```
44
+
45
+ ```typescript
46
+ // app.module.ts (module-based app)
47
+ import { NgModule } from '@angular/core';
48
+ import { BrowserModule } from '@angular/platform-browser';
49
+ import { WEBAUTHN_CONFIG, createWebAuthnConfig } from 'ngx-webauthn';
50
+
51
+ @NgModule({
52
+ imports: [BrowserModule],
53
+ providers: [
54
+ {
55
+ provide: WEBAUTHN_CONFIG,
56
+ useValue: createWebAuthnConfig({ name: 'My App', id: 'myapp.com' }, { defaultTimeout: 30000 }),
57
+ },
58
+ ],
59
+ // ...
60
+ })
61
+ export class AppModule {}
62
+ ```
63
+
64
+ ### 2. Use the Service with Presets
65
+
66
+ ```typescript
67
+ import { Component, inject } from '@angular/core';
68
+ import { WebAuthnService, WebAuthnError, WebAuthnErrorType } from 'ngx-webauthn';
69
+
70
+ @Component({
71
+ selector: 'app-auth',
72
+ template: `
73
+ <div>
74
+ <button (click)="register()" [disabled]="!isSupported">Register</button>
75
+ <button (click)="authenticate()" [disabled]="!isSupported">Authenticate</button>
76
+ <p *ngIf="!isSupported">WebAuthn is not supported in this browser</p>
77
+ </div>
78
+ `,
79
+ })
80
+ export class AuthComponent {
81
+ private webAuthnService = inject(WebAuthnService);
82
+
83
+ isSupported = this.webAuthnService.isSupported();
84
+
85
+ register() {
86
+ this.webAuthnService
87
+ .register({
88
+ username: 'john.doe@example.com',
89
+ preset: 'passkey', // Easy preset configuration!
90
+ })
91
+ .subscribe({
92
+ next: (result) => {
93
+ console.log('Registration successful:', result);
94
+ // Send result.credentialId, result.publicKey, etc. to your server
95
+ },
96
+ error: (error: WebAuthnError) => {
97
+ console.error('Registration failed:', error.message);
98
+ if (error.type === WebAuthnErrorType.USER_CANCELLED) {
99
+ // User cancelled or denied permission
100
+ }
101
+ },
102
+ });
103
+ }
104
+
105
+ authenticate() {
106
+ this.webAuthnService
107
+ .authenticate({
108
+ preset: 'passkey', // Uses the same preset for consistency
109
+ // Optional: specify allowed credentials
110
+ allowCredentials: ['credential-id-from-registration'],
111
+ })
112
+ .subscribe({
113
+ next: (result) => {
114
+ console.log('Authentication successful:', result);
115
+ // Send result to your server for verification
116
+ },
117
+ error: (error: WebAuthnError) => {
118
+ console.error('Authentication failed:', error.message);
119
+ },
120
+ });
121
+ }
122
+ }
123
+ ```
124
+
125
+ ### 2. Check Browser Support
126
+
127
+ ```typescript
128
+ import { Component, OnInit, inject } from '@angular/core';
129
+ import { WebAuthnService } from 'ngx-webauthn';
130
+
131
+ @Component({
132
+ selector: 'app-support-check',
133
+ template: `
134
+ <div *ngIf="support">
135
+ <p>WebAuthn Support: {{ support.isSupported ? 'Yes' : 'No' }}</p>
136
+ <p>Platform Authenticator: {{ support.isPlatformAuthenticatorAvailable ? 'Available' : 'Not Available' }}</p>
137
+ <p>Supported Transports: {{ support.supportedTransports.join(', ') }}</p>
138
+ </div>
139
+ `,
140
+ })
141
+ export class SupportCheckComponent implements OnInit {
142
+ private webAuthnService = inject(WebAuthnService);
143
+ support: any;
144
+
145
+ ngOnInit() {
146
+ this.webAuthnService.getSupport().subscribe({
147
+ next: (support) => {
148
+ this.support = support;
149
+ },
150
+ error: (error) => {
151
+ console.error('Failed to check WebAuthn support:', error);
152
+ },
153
+ });
154
+ }
155
+ }
156
+ ```
157
+
158
+ ## Features Overview
159
+
160
+ ### ๐ŸŽฏ **Preset System**
161
+
162
+ The library includes intelligent presets for common WebAuthn use cases:
163
+
164
+ - **`passkey`** - Modern passwordless authentication with credential syncing
165
+ - **`secondFactor`** - Traditional 2FA with hardware security keys
166
+ - **`deviceBound`** - High-security single-device authentication
167
+
168
+ ```typescript
169
+ // Simple preset usage
170
+ this.webAuthnService.register({ username: 'user@example.com', preset: 'passkey' });
171
+
172
+ // Preset with custom overrides
173
+ this.webAuthnService.register({
174
+ username: 'user@example.com',
175
+ preset: 'passkey',
176
+ authenticatorSelection: { userVerification: 'required' },
177
+ });
178
+ ```
179
+
180
+ ### ๐Ÿ”ง **Enhanced Configuration**
181
+
182
+ The new configuration system ensures proper security defaults:
183
+
184
+ ```typescript
185
+ interface WebAuthnConfig {
186
+ relyingParty: {
187
+ name: string; // Required: Your app name
188
+ id?: string; // Optional: Your domain
189
+ };
190
+ defaultTimeout?: number; // Default: 60000ms
191
+ defaultAlgorithms?: PublicKeyCredentialParameters[];
192
+ enforceUserVerification?: boolean; // Default: false
193
+ defaultAttestation?: AttestationConveyancePreference;
194
+ defaultAuthenticatorSelection?: AuthenticatorSelectionCriteria;
195
+ }
196
+ ```
197
+
198
+ ### ๐Ÿ”„ **Flexible Input Types**
199
+
200
+ Supports multiple input formats for maximum flexibility:
201
+
202
+ ```typescript
203
+ // High-level config (recommended)
204
+ service.register({ username: 'user@example.com', preset: 'passkey' });
205
+
206
+ // Native WebAuthn options
207
+ service.register(nativeCreationOptions);
208
+
209
+ // JSON WebAuthn options (base64url strings)
210
+ service.register(jsonCreationOptions);
211
+ ```
212
+
213
+ ## API Reference
214
+
215
+ ### WebAuthnService
216
+
217
+ #### Methods
218
+
219
+ ##### `isSupported(): boolean`
220
+
221
+ Synchronously checks if WebAuthn is supported in the current browser.
222
+
223
+ ##### `getSupport(): Observable<WebAuthnSupport>`
224
+
225
+ Returns detailed information about WebAuthn support including platform authenticator availability.
226
+
227
+ ##### `register(input: RegisterInput): Observable<RegistrationResponse>`
228
+
229
+ Registers a new WebAuthn credential. Accepts either high-level config objects or direct WebAuthn options.
230
+
231
+ ##### `authenticate(input: AuthenticateInput): Observable<AuthenticationResponse>`
232
+
233
+ Authenticates using an existing WebAuthn credential. Accepts either high-level config objects or direct WebAuthn options.
234
+
235
+ ### Response Types
236
+
237
+ #### RegistrationResponse
238
+
239
+ ```typescript
240
+ interface RegistrationResponse {
241
+ success: boolean;
242
+ credentialId: string; // Base64url encoded
243
+ publicKey?: string; // Base64url encoded (if available)
244
+ transports?: AuthenticatorTransport[];
245
+ rawResponse?: WebAuthnRegistrationResult; // For advanced usage
246
+ }
247
+ ```
248
+
249
+ #### AuthenticationResponse
250
+
251
+ ```typescript
252
+ interface AuthenticationResponse {
253
+ success: boolean;
254
+ credentialId: string; // Base64url encoded
255
+ userHandle?: string; // Base64url encoded
256
+ rawResponse?: WebAuthnAuthenticationResult; // For advanced usage
257
+ }
258
+ ```
259
+
260
+ #### WebAuthnRegistrationResult
261
+
262
+ ```typescript
263
+ interface WebAuthnRegistrationResult {
264
+ credentialId: string; // Base64url encoded
265
+ publicKey: string; // Base64url encoded
266
+ attestationObject: string; // Base64url encoded
267
+ clientDataJSON: string; // Base64url encoded
268
+ transports?: AuthenticatorTransport[];
269
+ }
270
+ ```
271
+
272
+ #### WebAuthnAuthenticationResult
273
+
274
+ ```typescript
275
+ interface WebAuthnAuthenticationResult {
276
+ credentialId: string; // Base64url encoded
277
+ authenticatorData: string; // Base64url encoded
278
+ clientDataJSON: string; // Base64url encoded
279
+ signature: string; // Base64url encoded
280
+ userHandle?: string; // Base64url encoded
281
+ }
282
+ ```
283
+
284
+ ### Error Handling
285
+
286
+ The library provides structured error handling through the `WebAuthnError` class:
287
+
288
+ ```typescript
289
+ enum WebAuthnErrorType {
290
+ NOT_SUPPORTED = 'NOT_SUPPORTED',
291
+ NOT_ALLOWED = 'NOT_ALLOWED',
292
+ INVALID_STATE = 'INVALID_STATE',
293
+ CONSTRAINT = 'CONSTRAINT',
294
+ SECURITY = 'SECURITY',
295
+ NETWORK = 'NETWORK',
296
+ ABORT = 'ABORT',
297
+ TIMEOUT = 'TIMEOUT',
298
+ ENCODING = 'ENCODING',
299
+ UNKNOWN = 'UNKNOWN',
300
+ }
301
+
302
+ class WebAuthnError extends Error {
303
+ constructor(public readonly type: WebAuthnErrorType, message: string, public readonly originalError?: Error);
304
+ }
305
+ ```
306
+
307
+ ## Advanced Usage
308
+
309
+ ### Using Direct WebAuthn Options
310
+
311
+ ```typescript
312
+ // Native creation options
313
+ const creationOptions: PublicKeyCredentialCreationOptions = {
314
+ rp: { name: 'My App' },
315
+ user: {
316
+ id: new Uint8Array([1, 2, 3, 4]),
317
+ name: 'john.doe@example.com',
318
+ displayName: 'John Doe',
319
+ },
320
+ challenge: new Uint8Array([5, 6, 7, 8]),
321
+ pubKeyCredParams: [{ type: 'public-key', alg: -7 }],
322
+ };
323
+
324
+ this.webAuthnService.register(creationOptions).subscribe((result) => {
325
+ console.log('Registration complete:', result);
326
+ });
327
+ ```
328
+
329
+ ### JSON WebAuthn Options
330
+
331
+ ```typescript
332
+ // JSON options also work (base64url strings instead of ArrayBuffers)
333
+ const jsonOptions: PublicKeyCredentialCreationOptionsJSON = {
334
+ rp: { name: 'My App' },
335
+ user: {
336
+ id: 'dXNlcklk',
337
+ name: 'john.doe@example.com',
338
+ displayName: 'John Doe',
339
+ },
340
+ challenge: 'Y2hhbGxlbmdl',
341
+ pubKeyCredParams: [{ type: 'public-key', alg: -7 }],
342
+ };
343
+
344
+ this.webAuthnService.register(jsonOptions).subscribe((result) => {
345
+ console.log('Registration complete:', result);
346
+ });
347
+ ```
348
+
349
+ ### Config with Custom Challenge
350
+
351
+ ```typescript
352
+ // High-level config with custom challenge
353
+ this.webAuthnService
354
+ .register({
355
+ username: 'john.doe@example.com',
356
+ preset: 'passkey',
357
+ challenge: 'your-base64url-encoded-challenge',
358
+ authenticatorSelection: {
359
+ authenticatorAttachment: 'platform',
360
+ userVerification: 'required',
361
+ },
362
+ })
363
+ .subscribe((result) => {
364
+ console.log('Passkey registered:', result);
365
+ });
366
+ ```
367
+
368
+ ## Server-Side Integration
369
+
370
+ This library handles the client-side WebAuthn flow. You'll need a server-side implementation to:
371
+
372
+ 1. **Generate challenges** (optional - library can generate them)
373
+ 2. **Verify registration responses**
374
+ 3. **Store public keys and credential metadata**
375
+ 4. **Verify authentication responses**
376
+
377
+ Popular server-side libraries:
378
+
379
+ - **Node.js**: `@simplewebauthn/server`
380
+ - **.NET**: `Fido2NetLib`
381
+ - **Java**: `webauthn4j`
382
+ - **Python**: `py_webauthn`
383
+ - **Go**: `go-webauthn`
384
+
385
+ ## Browser Support
386
+
387
+ WebAuthn is supported in all modern browsers:
388
+
389
+ - Chrome 67+
390
+ - Firefox 60+
391
+ - Safari 14+
392
+ - Edge 18+
393
+
394
+ Check current support at [caniuse.com/webauthn](https://caniuse.com/webauthn).
395
+
396
+ ## Development
397
+
398
+ ### Running unit tests
399
+
400
+ Run `nx test ngx-webauthn` to execute the unit tests.
401
+
402
+ ### Building the library
403
+
404
+ Run `nx build ngx-webauthn` to build the library.
405
+
406
+ ## Contributing
407
+
408
+ Contributions are welcome! Please read our contributing guidelines and submit pull requests to our repository.
409
+
410
+ ## License
411
+
412
+ MIT License - see LICENSE file for details.