@modernman00/shared-js-lib 1.2.89 โ†’ 1.2.90

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.
@@ -0,0 +1,125 @@
1
+ /**
2
+ * WebAuthnClient.js
3
+ *
4
+ * Handles client-side WebAuthn interactions (FaceID, TouchID, Passcodes).
5
+ * Implements David's Gatewatcher mandate: Defensive Degradation.
6
+ */
7
+
8
+ export class WebAuthnClient {
9
+ /**
10
+ * Checks if the device supports WebAuthn (Biometrics/Passkeys)
11
+ * @returns {boolean}
12
+ */
13
+ static isSupported() {
14
+ return window.PublicKeyCredential !== undefined
15
+ && typeof window.PublicKeyCredential === 'function';
16
+ }
17
+
18
+ /**
19
+ * Base64URL to ArrayBuffer converter
20
+ */
21
+ static base64URLStringToBuffer(base64URLString) {
22
+ const base64 = base64URLString.replace(/-/g, '+').replace(/_/g, '/');
23
+ const padLength = (4 - (base64.length % 4)) % 4;
24
+ const padded = base64.padEnd(base64.length + padLength, '=');
25
+ const binary = atob(padded);
26
+ const buffer = new ArrayBuffer(binary.length);
27
+ const bytes = new Uint8Array(buffer);
28
+ for (let i = 0; i < binary.length; i++) {
29
+ bytes[i] = binary.charCodeAt(i);
30
+ }
31
+ return buffer;
32
+ }
33
+
34
+ /**
35
+ * ArrayBuffer to Base64URL converter
36
+ */
37
+ static bufferToBase64URLString(buffer) {
38
+ const bytes = new Uint8Array(buffer);
39
+ let str = '';
40
+ for (let i = 0; i < bytes.byteLength; i++) {
41
+ str += String.fromCharCode(bytes[i]);
42
+ }
43
+ return btoa(str).replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
44
+ }
45
+
46
+ /**
47
+ * Initiates the registration of a new Passkey
48
+ * @param {Object} optionsFromServer JSON options from /webauthn/register/options
49
+ */
50
+ static async registerDevice(optionsFromServer) {
51
+ if (!this.isSupported()) {
52
+ throw new Error("Device does not support biometrics/passkeys.");
53
+ }
54
+
55
+ try {
56
+ const publicKey = {
57
+ ...optionsFromServer,
58
+ challenge: this.base64URLStringToBuffer(optionsFromServer.challenge),
59
+ user: {
60
+ ...optionsFromServer.user,
61
+ id: this.base64URLStringToBuffer(optionsFromServer.user.id)
62
+ }
63
+ };
64
+
65
+ const credential = await navigator.credentials.create({ publicKey });
66
+
67
+ return {
68
+ id: credential.id,
69
+ rawId: this.bufferToBase64URLString(credential.rawId),
70
+ type: credential.type,
71
+ response: {
72
+ attestationObject: this.bufferToBase64URLString(credential.response.attestationObject),
73
+ clientDataJSON: this.bufferToBase64URLString(credential.response.clientDataJSON),
74
+ }
75
+ };
76
+ } catch (error) {
77
+ // David's Rule: Defensive Degradation. If it fails or is canceled, log and swallow politely.
78
+ console.warn("WebAuthn Registration failed or was canceled:", error);
79
+ throw new Error("Passkey registration was canceled or failed.");
80
+ }
81
+ }
82
+
83
+ /**
84
+ * Initiates login using an existing Passkey
85
+ * @param {Object} optionsFromServer JSON options from /webauthn/login/options
86
+ */
87
+ static async loginWithDevice(optionsFromServer) {
88
+ if (!this.isSupported()) {
89
+ throw new Error("Device does not support biometrics/passkeys.");
90
+ }
91
+
92
+ try {
93
+ const publicKey = {
94
+ ...optionsFromServer,
95
+ challenge: this.base64URLStringToBuffer(optionsFromServer.challenge)
96
+ };
97
+
98
+ // Convert allowed credentials to buffers if they exist
99
+ if (publicKey.allowCredentials) {
100
+ publicKey.allowCredentials = publicKey.allowCredentials.map(cred => ({
101
+ ...cred,
102
+ id: this.base64URLStringToBuffer(cred.id)
103
+ }));
104
+ }
105
+
106
+ const assertion = await navigator.credentials.get({ publicKey });
107
+
108
+ return {
109
+ id: assertion.id,
110
+ rawId: this.bufferToBase64URLString(assertion.rawId),
111
+ type: assertion.type,
112
+ response: {
113
+ authenticatorData: this.bufferToBase64URLString(assertion.response.authenticatorData),
114
+ clientDataJSON: this.bufferToBase64URLString(assertion.response.clientDataJSON),
115
+ signature: this.bufferToBase64URLString(assertion.response.signature),
116
+ userHandle: assertion.response.userHandle ? this.bufferToBase64URLString(assertion.response.userHandle) : null,
117
+ }
118
+ };
119
+ } catch (error) {
120
+ // David's Rule: Defensive Degradation.
121
+ console.warn("WebAuthn Login failed or was canceled:", error);
122
+ throw new Error("Passkey login was canceled or failed. Please use your password.");
123
+ }
124
+ }
125
+ }
@@ -1,3 +1,3 @@
1
1
  <?php
2
- define('APP_VERSION', 'v1.2.89');
2
+ define('APP_VERSION', 'v1.2.90');
3
3
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@modernman00/shared-js-lib",
3
- "version": "1.2.89",
3
+ "version": "1.2.90",
4
4
  "description": "Reusable JS utilities for numerous js problems",
5
5
  "homepage": "https://github.com/modernman00/shared-js-lib#readme",
6
6
  "keywords": [
@@ -48,6 +48,7 @@
48
48
  "InlineValidation.js",
49
49
  "Clipboard.js",
50
50
  "AuthInterceptor.js",
51
+ "WebAuthnClient.js",
51
52
  "ShowResponse.js",
52
53
  "Utility.js",
53
54
  "UtilityHtml.js",
@@ -172,3 +172,9 @@
172
172
  - ๐Ÿงน Auto-commit before release _(by modernman00)_
173
173
  - ๐Ÿ”– Release v1.2.88 _(by modernman00)_
174
174
  - ๐Ÿงน Auto-commit before release _(by modernman00)_
175
+
176
+ ## v1.2.90 โ€” 2026-10-23 17:34
177
+ ### Changelog for v1.2.90
178
+
179
+ - fix(package): ship WebAuthnClient.js in the published files list _(by modernman00)_
180
+ - ci: drop npm publish step from release workflow _(by modernman00)_