dphelper 4.2.0 → 4.2.3

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.
Files changed (59) hide show
  1. package/README.md +6 -5
  2. package/index.cjs +1 -1
  3. package/index.js +1 -1
  4. package/package.json +3 -3
  5. package/markdown/ai.md +0 -345
  6. package/markdown/anchor.md +0 -156
  7. package/markdown/array.md +0 -208
  8. package/markdown/audio.md +0 -113
  9. package/markdown/avoid.md +0 -53
  10. package/markdown/biometric.md +0 -338
  11. package/markdown/browser.md +0 -203
  12. package/markdown/check.md +0 -65
  13. package/markdown/color.md +0 -159
  14. package/markdown/compress.md +0 -310
  15. package/markdown/cookie.md +0 -115
  16. package/markdown/coords.md +0 -127
  17. package/markdown/credits.md +0 -56
  18. package/markdown/date.md +0 -260
  19. package/markdown/disable.md +0 -109
  20. package/markdown/dispatch.md +0 -108
  21. package/markdown/element.md +0 -53
  22. package/markdown/event.md +0 -85
  23. package/markdown/fetch.md +0 -122
  24. package/markdown/form.md +0 -302
  25. package/markdown/format.md +0 -122
  26. package/markdown/i18n.md +0 -292
  27. package/markdown/image.md +0 -298
  28. package/markdown/json.md +0 -269
  29. package/markdown/load.md +0 -133
  30. package/markdown/logging.md +0 -99
  31. package/markdown/math.md +0 -172
  32. package/markdown/memory.md +0 -85
  33. package/markdown/navigation.md +0 -152
  34. package/markdown/net.md +0 -60
  35. package/markdown/obj.md +0 -242
  36. package/markdown/path.md +0 -46
  37. package/markdown/promise.md +0 -94
  38. package/markdown/sanitize.md +0 -118
  39. package/markdown/screen.md +0 -78
  40. package/markdown/scrollbar.md +0 -82
  41. package/markdown/security.md +0 -289
  42. package/markdown/shortcut.md +0 -100
  43. package/markdown/socket.md +0 -134
  44. package/markdown/sse.md +0 -120
  45. package/markdown/svg.md +0 -167
  46. package/markdown/sync.md +0 -147
  47. package/markdown/system.md +0 -78
  48. package/markdown/terminal.md +0 -73
  49. package/markdown/text.md +0 -245
  50. package/markdown/timer.md +0 -98
  51. package/markdown/tools.md +0 -111
  52. package/markdown/translators.md +0 -65
  53. package/markdown/trigger.md +0 -99
  54. package/markdown/triggers.md +0 -133
  55. package/markdown/type.md +0 -109
  56. package/markdown/types.md +0 -102
  57. package/markdown/ui.md +0 -45
  58. package/markdown/window.md +0 -211
  59. package/markdown/worker.md +0 -223
package/markdown/array.md DELETED
@@ -1,208 +0,0 @@
1
- # array
2
-
3
- Advanced utilities for JavaScript array manipulation with support for nested structures, merging, filtering, and more.
4
-
5
- ## Functions
6
-
7
- | Function | Description | Example |
8
- |----------|-------------|---------|
9
- | `find` | Finds an element recursively in nested arrays | `dphelper.array.find(array, 'key')` |
10
- | `delete` | Deletes an element recursively by key | `dphelper.array.delete(array, 'key')` |
11
- | `merge` | Deep merges two objects/arrays (safe from prototype pollution) | `dphelper.array.merge(arrA, arrB)` |
12
- | `mergeByKey` | Merges two arrays of objects via a specific key | `dphelper.array.mergeByKey(arrA, arrB, 'id')` |
13
- | `unique` | Removes duplicate values from an array | `dphelper.array.unique(array)` |
14
- | `asc` | Sorts array in ascending order | `dphelper.array.asc(array)` |
15
- | `desc` | Sorts array in descending order | `dphelper.array.desc(array)` |
16
- | `duplicates` | Finds duplicate elements in an array | `dphelper.array.duplicates(array)` |
17
- | `even` | Filters even numbers from an array | `dphelper.array.even(array)` |
18
- | `odd` | Filters odd numbers from an array | `dphelper.array.odd(array)` |
19
- | `toObj` | Converts an array to an object | `dphelper.array.toObj(array)` |
20
- | `sumColumn` | Sums values of a column in a multidimensional array | `dphelper.array.sumColumn(arr, 0)` |
21
- | `shuffle` | Randomly shuffles elements (Fisher-Yates algorithm) | `dphelper.array.shuffle(array)` |
22
- | `generate` | Generates an array of random numbers (1 to n) | `dphelper.array.generate(10)` |
23
- | `testArrayInt` | Checks for missing numbers in a consecutive sequence | `dphelper.array.testArrayInt([1,2,4])` |
24
- | `rand32` | Generates an array of random 32-bit unsigned integers | `dphelper.array.rand32(5)` |
25
- | `findindex` | Finds the index of an element by key | `dphelper.array.findindex(array, 'name')` |
26
- | `pathToJson` | Converts an array of paths into a JSON object | `dphelper.array.pathToJson(paths, '/')` |
27
- | `deepClone` | Creates a deep clone using structuredClone | `dphelper.array.deepClone(array)` |
28
- | `match` | Finds intersection between two arrays | `dphelper.array.match(arrA, arrB)` |
29
-
30
- ## Description
31
-
32
- Comprehensive array manipulation library that provides utilities for:
33
- - **Recursive operations** - Find, delete in nested structures
34
- - **Merging** - Deep merge with prototype pollution protection
35
- - **Filtering** - Even/odd numbers, duplicates
36
- - **Sorting** - Ascending/descending order
37
- - **Generation** - Random numbers, sequences
38
- - **Conversion** - Array to object, paths to JSON
39
-
40
- ## Usage Examples
41
-
42
- ### Finding Elements in Nested Arrays
43
-
44
- ```javascript
45
- const data = [
46
- { id: 1, name: 'John', children: [{ id: 2, name: 'Jane' }] },
47
- { id: 3, name: 'Bob', children: [{ id: 4, name: 'Alice' }] }
48
- ];
49
-
50
- // Find element with id 2
51
- const found = dphelper.array.find(data, 2);
52
- console.log(found); // { id: 2, name: 'Jane' }
53
- ```
54
-
55
- ### Deep Merging Objects
56
-
57
- ```javascript
58
- const obj1 = { a: 1, b: { c: 2 } };
59
- const obj2 = { b: { d: 3 }, e: 4 };
60
-
61
- const merged = dphelper.array.merge(obj1, obj2);
62
- console.log(merged); // { a: 1, b: { c: 2, d: 3 }, e: 4 }
63
-
64
- // Safe from prototype pollution
65
- const dangerous = { '__proto__': { dangerous: true } };
66
- const safe = dphelper.array.merge({}, dangerous);
67
- console.log(safe); // { __proto__: { dangerous: true } } - safe!
68
- ```
69
-
70
- ### Merging Arrays by Key
71
-
72
- ```javascript
73
- const users = [
74
- { id: 1, name: 'John', age: 30 },
75
- { id: 2, name: 'Jane', age: 25 }
76
- ];
77
-
78
- const details = [
79
- { id: 1, email: 'john@example.com' },
80
- { id: 2, email: 'jane@example.com' }
81
- ];
82
-
83
- const merged = dphelper.array.mergeByKey(users, details, 'id');
84
- // Result: [{ id: 1, name: 'John', age: 30, email: 'john@example.com' }, ...]
85
- ```
86
-
87
- ### Finding Duplicates
88
-
89
- ```javascript
90
- const numbers = [1, 2, 3, 2, 4, 3, 5, 1];
91
- const dups = dphelper.array.duplicates(numbers);
92
- console.log(dups); // [2, 3, 1]
93
- ```
94
-
95
- ### Filtering Even/Odd Numbers
96
-
97
- ```javascript
98
- const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
99
-
100
- console.log(dphelper.array.even(numbers)); // [2, 4, 6, 8, 10]
101
- console.log(dphelper.array.odd(numbers)); // [1, 3, 5, 7, 9]
102
- ```
103
-
104
- ### Sum Column in Multidimensional Array
105
-
106
- ```javascript
107
- const matrix = [
108
- [1, 2, 3], // row 0
109
- [4, 5, 6], // row 1
110
- [7, 8, 9] // row 2
111
- ];
112
-
113
- // Sum first column (index 0)
114
- console.log(dphelper.array.sumColumn(matrix, 0)); // 12 (1+4+7)
115
-
116
- // Sum second column (index 1)
117
- console.log(dphelper.array.sumColumn(matrix, 1)); // 15 (2+5+8)
118
- ```
119
-
120
- ### Shuffle Array (Fisher-Yates)
121
-
122
- ```javascript
123
- const cards = ['A', 'B', 'C', 'D', 'E'];
124
- const shuffled = dphelper.array.shuffle([...cards]);
125
- console.log(shuffled); // Random order, e.g., ['C', 'A', 'E', 'D', 'B']
126
- ```
127
-
128
- ### Generate Random Number Sequence
129
-
130
- ```javascript
131
- // Generate numbers 1-10 in random order
132
- const sequence = dphelper.array.generate(10);
133
- console.log(sequence); // e.g., [3, 1, 8, 5, 2, 9, 4, 7, 6, 10]
134
- ```
135
-
136
- ### Test for Consecutive Integers
137
-
138
- ```javascript
139
- // Check for missing numbers in sequence [1, 2, 3, 4, 5]
140
- console.log(dphelper.array.testArrayInt([1, 2, 3, 4, 5])); // [] (complete)
141
-
142
- // Check for missing numbers in [1, 2, 4, 5]
143
- console.log(dphelper.array.testArrayInt([1, 2, 4, 5])); // [3] (missing 3)
144
- ```
145
-
146
- ### Generate Random 32-bit Integers
147
-
148
- ```javascript
149
- const randomNumbers = dphelper.array.rand32(5);
150
- console.log(randomNumbers.nums); // [random1, random2, random3, random4, random5]
151
- console.log(randomNumbers.time); // [execution time in ms]
152
- ```
153
-
154
- ### Path to JSON Conversion
155
-
156
- ```javascript
157
- const paths = [
158
- '/users/John',
159
- '/users/John/profile',
160
- '/users/John/settings',
161
- '/users/Jane'
162
- ];
163
-
164
- const json = dphelper.array.pathToJson(paths, '/');
165
- // Result:
166
- // {
167
- // users: {
168
- // John: {
169
- // profile: null,
170
- // settings: null
171
- // },
172
- // Jane: null
173
- // }
174
- // }
175
- ```
176
-
177
- ### Deep Clone Array
178
-
179
- ```javascript
180
- const original = [{ a: 1 }, { b: 2 }];
181
- const cloned = dphelper.array.deepClone(original);
182
-
183
- cloned[0].a = 99;
184
- console.log(original[0].a); // 1 (original unchanged)
185
- console.log(cloned[0].a); // 99
186
- ```
187
-
188
- ### Find Array Intersection
189
-
190
- ```javascript
191
- const words = ['apple', 'banana', 'cherry', 'date'];
192
- const check = ['banana', 'date', 'elderberry'];
193
-
194
- const matches = dphelper.array.match(words, check);
195
- console.log(matches); // ['banana', 'date']
196
- ```
197
-
198
- ## Details
199
-
200
- - **Author:** Dario Passariello
201
- - **Version:** 0.0.2
202
- - **Creation Date:** 20210101
203
- - **Last Modified:** 20260220
204
- - **Environment:** Works in both client and server environments
205
-
206
- ---
207
-
208
- *Automatically generated document*
package/markdown/audio.md DELETED
@@ -1,113 +0,0 @@
1
- # audio
2
-
3
- Audio playback utilities for managing sound effects and background music in web applications.
4
-
5
- ## Functions
6
-
7
- | Function | Description | Example |
8
- |----------|-------------|---------|
9
- | `play` | Plays an audio file or removes all audio elements | `dphelper.audio.play('notification.mp3', '/sounds/')` |
10
-
11
- ## Description
12
-
13
- Simple audio management for web applications:
14
- - **Play Sound** - Load and play audio files with optional looping
15
- - **Stop All** - Remove all dpHelper audio elements from the DOM
16
- - **Multiple Sounds** - Play different sounds simultaneously (each gets unique ID)
17
-
18
- ## Usage Examples
19
-
20
- ### Playing Sound Effects
21
-
22
- ```javascript
23
- // Play a simple notification sound
24
- dphelper.audio.play('notification.mp3');
25
-
26
- // Play with custom path
27
- dphelper.audio.play('click.mp3', '/assets/sounds/');
28
-
29
- // Loop background music
30
- dphelper.audio.play('music.mp3', '/assets/audio/', true);
31
- ```
32
-
33
- ### Stopping Audio
34
-
35
- ```javascript
36
- // Stop all dpHelper audio elements
37
- dphelper.audio.play();
38
-
39
- // This removes all audio tags created by dphelper.audio
40
- ```
41
-
42
- ### Complete Example
43
-
44
- ```javascript
45
- // Sound manager class
46
- class SoundManager {
47
- constructor(soundPath = '/sounds/') {
48
- this.path = soundPath;
49
- this.enabled = true;
50
- }
51
-
52
- playSound(name, loop = false) {
53
- if (!this.enabled) return;
54
- dphelper.audio.play(name, this.path, loop);
55
- }
56
-
57
- stopAll() {
58
- dphelper.audio.play(); // No args = remove all
59
- }
60
-
61
- toggle(enabled) {
62
- this.enabled = enabled;
63
- if (!enabled) this.stopAll();
64
- }
65
- }
66
-
67
- // Usage
68
- const sounds = new SoundManager('/assets/sounds/');
69
-
70
- // Play various sounds
71
- sounds.playSound('click.mp3');
72
- sounds.playSound('notification.mp3');
73
- sounds.playSound('background.mp3', true); // Loop
74
-
75
- // Mute all
76
- sounds.toggle(false);
77
-
78
- // Unmute
79
- sounds.toggle(true);
80
- ```
81
-
82
- ### UI Sound Effects
83
-
84
- ```javascript
85
- // Add sounds to UI interactions
86
- document.querySelectorAll('button').forEach(btn => {
87
- btn.addEventListener('click', () => {
88
- dphelper.audio.play('click.mp3', '/sounds/');
89
- });
90
- });
91
-
92
- // Form submission
93
- document.querySelector('form').addEventListener('submit', () => {
94
- dphelper.audio.play('success.mp3', '/sounds/');
95
- });
96
-
97
- // Error handling
98
- function showError() {
99
- dphelper.audio.play('error.mp3', '/sounds/');
100
- }
101
- ```
102
-
103
- ## Details
104
-
105
- - **Author:** Dario Passariello
106
- - **Version:** 0.0.2
107
- - **Creation Date:** 20240924
108
- - **Last Modified:** 20240924
109
- - **Environment:** Client-side only (browser)
110
-
111
- ---
112
-
113
- *Automatically generated document*
package/markdown/avoid.md DELETED
@@ -1,53 +0,0 @@
1
- # avoid
2
-
3
- Utilities for preventing caching issues in web applications.
4
-
5
- ## Functions
6
-
7
- | Function | Description | Example |
8
- |----------|-------------|---------|
9
- | `cache` | Appends cache-busting query parameter to URL | `dphelper.avoid.cache('/api/data')` |
10
-
11
- ## Description
12
-
13
- Prevents browser caching issues:
14
- - **Cache Busting** - Add unique query params to URLs
15
-
16
- ## Usage Examples
17
-
18
- ### Cache Busting
19
-
20
- ```javascript
21
- // Add unique query parameter to prevent caching
22
- const url = '/api/users';
23
- const uncachedUrl = dphelper.avoid.cache(url);
24
- console.log(uncachedUrl); // "/api/users?t=abc123xyz"
25
-
26
- // Useful for:
27
- // - API calls that need fresh data
28
- // - Dynamic content
29
- // - Debugging (force reload)
30
- dphelper.avoid.cache('/api/latest-data');
31
- ```
32
-
33
- ### Using with Fetch
34
-
35
- ```javascript
36
- // Fetch with cache busting
37
- async function fetchFresh(url) {
38
- const response = await fetch(dphelper.avoid.cache(url));
39
- return response.json();
40
- }
41
- ```
42
-
43
- ## Details
44
-
45
- - **Author:** Dario Passariello
46
- - **Version:** 0.0.2
47
- - **Creation Date:** 20210101
48
- - **Last Modified:** 20260220
49
- - **Environment:** Works in both client and server environments
50
-
51
- ---
52
-
53
- *Automatically generated document*
@@ -1,338 +0,0 @@
1
- # biometric
2
-
3
- WebAuthn and biometric authentication utilities for secure passwordless login using fingerprint, face recognition, and hardware security keys.
4
-
5
- ## Functions
6
-
7
- | Function | Description | Example |
8
- |----------|-------------|---------|
9
- | `isAvailable` | Check if WebAuthn is available | `dphelper.biometric.isAvailable()` |
10
- | `getWebAuthnSupport` | Get detailed support info | `dphelper.biometric.getWebAuthnSupport()` |
11
- | `isSensorAvailable` | Check specific sensor (fingerprint/face/iris) | `await dphelper.biometric.isSensorAvailable('fingerprint')` |
12
- | `register` | Register new credential | `await dphelper.biometric.register('user123', 'example.com')` |
13
- | `authenticate` | Authenticate with credential | `await dphelper.biometric.authenticate('user123', 'example.com')` |
14
- | `getCredential` | Get stored credential by ID | `dphelper.biometric.getCredential(credentialId)` |
15
- | `deleteCredential` | Delete stored credential | `dphelper.biometric.deleteCredential(credentialId)` |
16
- | `listCredentials` | List all stored credentials | `dphelper.biometric.listCredentials()` |
17
-
18
- ## Description
19
-
20
- Secure biometric authentication module providing:
21
- - **WebAuthn/FIDO2** - Industry-standard passwordless authentication
22
- - **Platform Authenticators** - Fingerprint, Face ID, Windows Hello
23
- - **Cross-platform** - Works with hardware security keys (YubiKey, etc.)
24
- - **Credential Management** - Store, retrieve, and delete credentials
25
- - **Sensor Detection** - Check availability of specific biometric types
26
-
27
- ## Usage Examples
28
-
29
- ### Checking Availability
30
-
31
- ```javascript
32
- // Simple availability check
33
- if (dphelper.biometric.isAvailable()) {
34
- console.log('Biometric authentication is available!');
35
- } else {
36
- console.log('Biometric auth not supported');
37
- }
38
-
39
- // Get detailed support information
40
- const support = dphelper.biometric.getWebAuthnSupport();
41
- console.log(support);
42
- // {
43
- // supported: true,
44
- // platformAuthenticator: true,
45
- // hybridTransport: false,
46
- // uvToken: false
47
- // }
48
-
49
- // Check specific sensor
50
- const hasFingerprint = await dphelper.biometric.isSensorAvailable('fingerprint');
51
- const hasFace = await dphelper.biometric.isSensorAvailable('face');
52
- console.log('Fingerprint:', hasFingerprint, 'Face:', hasFace);
53
- ```
54
-
55
- ### Registration (Enrolling a Credential)
56
-
57
- ```javascript
58
- // Register a new biometric credential
59
- async function registerUser(userId) {
60
- if (!dphelper.biometric.isAvailable()) {
61
- return { success: false, error: 'WebAuthn not supported' };
62
- }
63
-
64
- const result = await dphelper.biometric.register(
65
- userId, // User ID
66
- 'example.com', // Relying Party ID (your domain)
67
- 'My App', // Relying Party Name
68
- 'john@example.com' // Display name
69
- );
70
-
71
- if (result.success) {
72
- console.log('Registered! Credential ID:', result.credentialId);
73
- // Store credentialId in your database for this user
74
- } else {
75
- console.error('Registration failed:', result.error);
76
- }
77
-
78
- return result;
79
- }
80
-
81
- // Usage
82
- const result = await registerUser('user_123');
83
- ```
84
-
85
- ### Authentication (Login)
86
-
87
- ```javascript
88
- // Authenticate with stored credential
89
- async function loginUser(userId, credentialId) {
90
- if (!dphelper.biometric.isAvailable()) {
91
- return { success: false, error: 'WebAuthn not supported' };
92
- }
93
-
94
- const result = await dphelper.biometric.authenticate(
95
- userId, // User ID
96
- 'example.com', // Relying Party ID
97
- credentialId // Optional: specific credential to use
98
- );
99
-
100
- if (result.success) {
101
- console.log('Authentication successful!');
102
- } else {
103
- console.error('Authentication failed:', result.error);
104
- }
105
-
106
- return result;
107
- }
108
-
109
- // Usage - login with known credential
110
- const result = await loginUser('user_123', 'stored_credential_id');
111
- ```
112
-
113
- ### Credential Management
114
-
115
- ```javascript
116
- // List all stored credentials
117
- const credentials = dphelper.biometric.listCredentials();
118
- console.log('Stored credentials:', credentials);
119
-
120
- // Get a specific credential
121
- const cred = dphelper.biometric.getCredential('credential_id_123');
122
- console.log('Credential:', cred);
123
-
124
- // Delete a credential
125
- const deleted = dphelper.biometric.deleteCredential('credential_id_123');
126
- console.log('Deleted:', deleted);
127
-
128
- // After deletion
129
- console.log('Remaining:', dphelper.biometric.listCredentials());
130
- ```
131
-
132
- ## Advanced Usage
133
-
134
- ### Complete Authentication System
135
-
136
- ```javascript
137
- class BiometricAuth {
138
- constructor(rpId, rpName) {
139
- this.rpId = rpId;
140
- this.rpName = rpName;
141
- this.available = dphelper.biometric.isAvailable();
142
- }
143
-
144
- async checkSupport() {
145
- if (!this.available) {
146
- return { supported: false, reason: 'WebAuthn not supported' };
147
- }
148
-
149
- const support = dphelper.biometric.getWebAuthnSupport();
150
- const fingerprint = await dphelper.biometric.isSensorAvailable('fingerprint');
151
- const face = await dphelper.biometric.isSensorAvailable('face');
152
-
153
- return {
154
- supported: true,
155
- platformAuthenticator: support.platformAuthenticator,
156
- fingerprint,
157
- face
158
- };
159
- }
160
-
161
- async register(userId, userName) {
162
- if (!this.available) {
163
- throw new Error('Biometric authentication not available');
164
- }
165
-
166
- const result = await dphelper.biometric.register(
167
- userId,
168
- this.rpId,
169
- this.rpName,
170
- userName
171
- );
172
-
173
- if (result.success) {
174
- // In production: save credentialId to your backend
175
- console.log('Biometric registered:', result.credentialId);
176
- }
177
-
178
- return result;
179
- }
180
-
181
- async login(userId, credentialId) {
182
- if (!this.available) {
183
- throw new Error('Biometric authentication not available');
184
- }
185
-
186
- return await dphelper.biometric.authenticate(
187
- userId,
188
- this.rpId,
189
- credentialId
190
- );
191
- }
192
-
193
- getStoredCredentials() {
194
- return dphelper.biometric.listCredentials();
195
- }
196
-
197
- removeCredential(credentialId) {
198
- return dphelper.biometric.deleteCredential(credentialId);
199
- }
200
- }
201
-
202
- // Usage
203
- const auth = new BiometricAuth('example.com', 'My Application');
204
-
205
- // Check if biometric is available
206
- const support = await auth.checkSupport();
207
- if (support.supported) {
208
- console.log('Biometric types available:', support);
209
- }
210
-
211
- // Register new user
212
- await auth.register('user_123', 'john@example.com');
213
-
214
- // Login
215
- const loginResult = await auth.login('user_123');
216
- if (loginResult.success) {
217
- console.log('Logged in with biometric!');
218
- }
219
- ```
220
-
221
- ### Passwordless Login Flow
222
-
223
- ```javascript
224
- // Frontend: Initiate passwordless login
225
- async function initiatePasswordlessLogin() {
226
- // 1. Check if biometric is available
227
- if (!dphelper.biometric.isAvailable()) {
228
- alert('Please use a supported browser');
229
- return;
230
- }
231
-
232
- // 2. Get available credentials for this user
233
- const credentials = dphelper.biometric.listCredentials();
234
-
235
- if (credentials.length === 0) {
236
- // No credentials - prompt to register
237
- const register = confirm('No biometric credentials found. Register now?');
238
- if (register) {
239
- await registerNewUser();
240
- }
241
- return;
242
- }
243
-
244
- // 3. Attempt authentication with any stored credential
245
- for (const credId of credentials) {
246
- const result = await dphelper.biometric.authenticate(
247
- 'current_user',
248
- window.location.hostname,
249
- credId
250
- );
251
-
252
- if (result.success) {
253
- // 4. Verify with server
254
- await verifyWithServer(credId);
255
- return;
256
- }
257
- }
258
-
259
- console.log('All credentials failed');
260
- }
261
-
262
- // Server verification (pseudo-code)
263
- async function verifyWithServer(credentialId) {
264
- const response = await fetch('/api/auth/verify', {
265
- method: 'POST',
266
- headers: { 'Content-Type': 'application/json' },
267
- body: JSON.stringify({ credentialId })
268
- });
269
-
270
- if (response.ok) {
271
- const { token } = await response.json();
272
- localStorage.setItem('auth_token', token);
273
- window.location.href = '/dashboard';
274
- }
275
- }
276
- ```
277
-
278
- ### Progressive Registration
279
-
280
- ```javascript
281
- // Offer biometric as an option during existing login
282
- async function offerBiometricUpgrade(userId, userName) {
283
- const support = await dphelper.biometric.checkSupport();
284
-
285
- if (!support.supported) {
286
- console.log('Biometric not available on this device');
287
- return;
288
- }
289
-
290
- // Show modal or prompt
291
- const shouldRegister = confirm(
292
- `Enable ${support.fingerprint ? 'fingerprint' : 'biometric'} login for faster access?`
293
- );
294
-
295
- if (shouldRegister) {
296
- const result = await dphelper.biometric.register(
297
- userId,
298
- window.location.hostname,
299
- 'My App',
300
- userName
301
- );
302
-
303
- if (result.success) {
304
- // Save credential to user account
305
- await saveCredentialToUser(userId, result.credentialId);
306
- alert('Biometric authentication enabled!');
307
- } else {
308
- alert('Registration failed: ' + result.error);
309
- }
310
- }
311
- }
312
- ```
313
-
314
- ## Security Notes
315
-
316
- ### WebAuthn Security Features
317
- - **Public-key cryptography** - Uses asymmetric keys, never transmitted
318
- - **User presence** - Requires user action (touch/face) to authenticate
319
- - **Platform binding** - Credentials bound to specific device
320
- - **Phishing resistance** - Relying Party ID must match exactly
321
-
322
- ### Best Practices
323
- - Always verify authentication on the server side
324
- - Store credential IDs in your database, not the credentials themselves
325
- - Support multiple credentials per user (different devices)
326
- - Provide fallback for unsupported browsers
327
-
328
- ## Details
329
-
330
- - **Author:** Dario Passariello
331
- - **Version:** 0.0.1
332
- - **Creation Date:** 20260313
333
- - **Last Modified:** 20260313
334
- - **Environment:** Client-side only (browser with WebAuthn support)
335
-
336
- ---
337
-
338
- *Automatically generated document*