dauth-context-react 6.5.0 → 6.6.0
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/dist/index.d.mts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +289 -287
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +289 -287
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/DauthProfileModal.tsx +113 -291
- package/src/api/dauth.api.ts +54 -31
- package/src/api/interfaces/dauth.api.responses.ts +18 -0
- package/src/api/utils/config.ts +3 -9
- package/src/index.tsx +7 -0
- package/src/initialDauthState.ts +1 -0
- package/src/interfaces.ts +3 -6
- package/src/reducer/dauth.actions.ts +85 -28
- package/src/webauthn.ts +62 -32
package/dist/index.mjs
CHANGED
|
@@ -26,7 +26,8 @@ var initialDauthState = {
|
|
|
26
26
|
getPasskeyCredentials: () => Promise.resolve([]),
|
|
27
27
|
registerPasskey: () => Promise.resolve(null),
|
|
28
28
|
deletePasskeyCredential: () => Promise.resolve(false),
|
|
29
|
-
uploadAvatar: () => Promise.resolve(false)
|
|
29
|
+
uploadAvatar: () => Promise.resolve(false),
|
|
30
|
+
loginWithPasskey: () => Promise.resolve(false)
|
|
30
31
|
};
|
|
31
32
|
var initialDauthState_default = initialDauthState;
|
|
32
33
|
|
|
@@ -134,45 +135,59 @@ async function deleteAccountAPI(basePath) {
|
|
|
134
135
|
return { response, data };
|
|
135
136
|
}
|
|
136
137
|
async function getPasskeyCredentialsAPI(basePath) {
|
|
137
|
-
const response = await fetch(
|
|
138
|
-
|
|
139
|
-
{
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
credentials: "include"
|
|
143
|
-
}
|
|
144
|
-
);
|
|
138
|
+
const response = await fetch(`${basePath}/passkey/credentials`, {
|
|
139
|
+
method: "GET",
|
|
140
|
+
headers: { "X-CSRF-Token": getCsrfToken() },
|
|
141
|
+
credentials: "include"
|
|
142
|
+
});
|
|
145
143
|
const data = await response.json();
|
|
146
144
|
return { response, data };
|
|
147
145
|
}
|
|
148
146
|
async function startPasskeyRegistrationAPI(basePath) {
|
|
149
|
-
const response = await fetch(
|
|
150
|
-
|
|
151
|
-
{
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
credentials: "include"
|
|
158
|
-
}
|
|
159
|
-
);
|
|
147
|
+
const response = await fetch(`${basePath}/passkey/register/start`, {
|
|
148
|
+
method: "POST",
|
|
149
|
+
headers: {
|
|
150
|
+
"Content-Type": "application/json",
|
|
151
|
+
"X-CSRF-Token": getCsrfToken()
|
|
152
|
+
},
|
|
153
|
+
credentials: "include"
|
|
154
|
+
});
|
|
160
155
|
const data = await response.json();
|
|
161
156
|
return { response, data };
|
|
162
157
|
}
|
|
163
158
|
async function finishPasskeyRegistrationAPI(basePath, body) {
|
|
164
|
-
const response = await fetch(
|
|
165
|
-
|
|
166
|
-
{
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
159
|
+
const response = await fetch(`${basePath}/passkey/register/finish`, {
|
|
160
|
+
method: "POST",
|
|
161
|
+
headers: {
|
|
162
|
+
"Content-Type": "application/json",
|
|
163
|
+
"X-CSRF-Token": getCsrfToken()
|
|
164
|
+
},
|
|
165
|
+
credentials: "include",
|
|
166
|
+
body: JSON.stringify(body)
|
|
167
|
+
});
|
|
168
|
+
const data = await response.json();
|
|
169
|
+
return { response, data };
|
|
170
|
+
}
|
|
171
|
+
async function startPasskeyAuthAPI(basePath) {
|
|
172
|
+
const response = await fetch(`${basePath}/passkey/auth-start`, {
|
|
173
|
+
method: "POST",
|
|
174
|
+
headers: {
|
|
175
|
+
"Content-Type": "application/json"
|
|
176
|
+
},
|
|
177
|
+
credentials: "include"
|
|
178
|
+
});
|
|
179
|
+
const data = await response.json();
|
|
180
|
+
return { response, data };
|
|
181
|
+
}
|
|
182
|
+
async function finishPasskeyAuthAPI(basePath, body) {
|
|
183
|
+
const response = await fetch(`${basePath}/passkey/auth-finish`, {
|
|
184
|
+
method: "POST",
|
|
185
|
+
headers: {
|
|
186
|
+
"Content-Type": "application/json"
|
|
187
|
+
},
|
|
188
|
+
credentials: "include",
|
|
189
|
+
body: JSON.stringify(body)
|
|
190
|
+
});
|
|
176
191
|
const data = await response.json();
|
|
177
192
|
return { response, data };
|
|
178
193
|
}
|
|
@@ -224,17 +239,16 @@ function bufferToBase64url(buffer) {
|
|
|
224
239
|
async function createPasskeyCredential(options) {
|
|
225
240
|
const publicKey = {
|
|
226
241
|
...options,
|
|
242
|
+
rp: { ...options.rp, id: window.location.hostname },
|
|
227
243
|
challenge: base64urlToBuffer(options.challenge),
|
|
228
244
|
user: {
|
|
229
245
|
...options.user,
|
|
230
246
|
id: base64urlToBuffer(options.user.id)
|
|
231
247
|
},
|
|
232
|
-
excludeCredentials: (options.excludeCredentials ?? []).map(
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
})
|
|
237
|
-
)
|
|
248
|
+
excludeCredentials: (options.excludeCredentials ?? []).map((c) => ({
|
|
249
|
+
...c,
|
|
250
|
+
id: base64urlToBuffer(c.id)
|
|
251
|
+
}))
|
|
238
252
|
};
|
|
239
253
|
const credential = await navigator.credentials.create({
|
|
240
254
|
publicKey
|
|
@@ -248,20 +262,14 @@ async function createPasskeyCredential(options) {
|
|
|
248
262
|
rawId: bufferToBase64url(credential.rawId),
|
|
249
263
|
type: credential.type,
|
|
250
264
|
response: {
|
|
251
|
-
clientDataJSON: bufferToBase64url(
|
|
252
|
-
|
|
253
|
-
),
|
|
254
|
-
attestationObject: bufferToBase64url(
|
|
255
|
-
attestation.attestationObject
|
|
256
|
-
),
|
|
265
|
+
clientDataJSON: bufferToBase64url(attestation.clientDataJSON),
|
|
266
|
+
attestationObject: bufferToBase64url(attestation.attestationObject),
|
|
257
267
|
...attestation.getTransports ? { transports: attestation.getTransports() } : {},
|
|
258
268
|
...attestation.getPublicKeyAlgorithm ? {
|
|
259
269
|
publicKeyAlgorithm: attestation.getPublicKeyAlgorithm()
|
|
260
270
|
} : {},
|
|
261
271
|
...attestation.getPublicKey ? {
|
|
262
|
-
publicKey: bufferToBase64url(
|
|
263
|
-
attestation.getPublicKey()
|
|
264
|
-
)
|
|
272
|
+
publicKey: bufferToBase64url(attestation.getPublicKey())
|
|
265
273
|
} : {},
|
|
266
274
|
...attestation.getAuthenticatorData ? {
|
|
267
275
|
authenticatorData: bufferToBase64url(
|
|
@@ -273,6 +281,38 @@ async function createPasskeyCredential(options) {
|
|
|
273
281
|
authenticatorAttachment: credential.authenticatorAttachment ?? void 0
|
|
274
282
|
};
|
|
275
283
|
}
|
|
284
|
+
async function getPasskeyCredential(options) {
|
|
285
|
+
const publicKey = {
|
|
286
|
+
challenge: base64urlToBuffer(options.challenge),
|
|
287
|
+
timeout: options.timeout,
|
|
288
|
+
rpId: window.location.hostname,
|
|
289
|
+
userVerification: options.userVerification || "preferred",
|
|
290
|
+
allowCredentials: (options.allowCredentials || []).map(
|
|
291
|
+
(c) => ({
|
|
292
|
+
...c,
|
|
293
|
+
id: base64urlToBuffer(c.id)
|
|
294
|
+
})
|
|
295
|
+
)
|
|
296
|
+
};
|
|
297
|
+
const credential = await navigator.credentials.get({
|
|
298
|
+
publicKey
|
|
299
|
+
});
|
|
300
|
+
if (!credential) throw new Error("No credential returned");
|
|
301
|
+
const assertion = credential.response;
|
|
302
|
+
return {
|
|
303
|
+
id: credential.id,
|
|
304
|
+
rawId: bufferToBase64url(credential.rawId),
|
|
305
|
+
type: credential.type,
|
|
306
|
+
response: {
|
|
307
|
+
clientDataJSON: bufferToBase64url(assertion.clientDataJSON),
|
|
308
|
+
authenticatorData: bufferToBase64url(assertion.authenticatorData),
|
|
309
|
+
signature: bufferToBase64url(assertion.signature),
|
|
310
|
+
userHandle: assertion.userHandle ? bufferToBase64url(assertion.userHandle) : null
|
|
311
|
+
},
|
|
312
|
+
clientExtensionResults: credential.getClientExtensionResults(),
|
|
313
|
+
authenticatorAttachment: credential.authenticatorAttachment
|
|
314
|
+
};
|
|
315
|
+
}
|
|
276
316
|
|
|
277
317
|
// src/reducer/dauth.actions.ts
|
|
278
318
|
async function exchangeCodeAction(ctx, code) {
|
|
@@ -419,19 +459,15 @@ async function registerPasskeyAction(ctx, name) {
|
|
|
419
459
|
onError(new Error("Failed to start passkey registration"));
|
|
420
460
|
return null;
|
|
421
461
|
}
|
|
422
|
-
const credential = await createPasskeyCredential(
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
{ credential, name }
|
|
428
|
-
);
|
|
462
|
+
const credential = await createPasskeyCredential(startResult.data);
|
|
463
|
+
const finishResult = await finishPasskeyRegistrationAPI(authProxyPath, {
|
|
464
|
+
credential,
|
|
465
|
+
name
|
|
466
|
+
});
|
|
429
467
|
if (finishResult.response.status === 200 || finishResult.response.status === 201) {
|
|
430
468
|
return finishResult.data.credential;
|
|
431
469
|
}
|
|
432
|
-
onError(
|
|
433
|
-
new Error("Failed to finish passkey registration")
|
|
434
|
-
);
|
|
470
|
+
onError(new Error("Failed to finish passkey registration"));
|
|
435
471
|
return null;
|
|
436
472
|
} catch (error) {
|
|
437
473
|
onError(
|
|
@@ -449,9 +485,7 @@ async function deletePasskeyCredentialAction(ctx, credentialId) {
|
|
|
449
485
|
);
|
|
450
486
|
return result.response.status === 200;
|
|
451
487
|
} catch (error) {
|
|
452
|
-
onError(
|
|
453
|
-
error instanceof Error ? error : new Error("Delete passkey error")
|
|
454
|
-
);
|
|
488
|
+
onError(error instanceof Error ? error : new Error("Delete passkey error"));
|
|
455
489
|
return false;
|
|
456
490
|
}
|
|
457
491
|
}
|
|
@@ -466,16 +500,69 @@ async function uploadAvatarAction(ctx, file) {
|
|
|
466
500
|
});
|
|
467
501
|
return true;
|
|
468
502
|
}
|
|
469
|
-
onError(
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
503
|
+
onError(new Error("Avatar upload error: " + result.data.message));
|
|
504
|
+
return false;
|
|
505
|
+
} catch (error) {
|
|
506
|
+
onError(error instanceof Error ? error : new Error("Avatar upload error"));
|
|
507
|
+
return false;
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
async function loginWithPasskeyAction(ctx) {
|
|
511
|
+
const { dispatch, authProxyPath, onError } = ctx;
|
|
512
|
+
dispatch({
|
|
513
|
+
type: SET_IS_LOADING,
|
|
514
|
+
payload: { isLoading: true }
|
|
515
|
+
});
|
|
516
|
+
try {
|
|
517
|
+
const startResult = await startPasskeyAuthAPI(authProxyPath);
|
|
518
|
+
if (startResult.data.status !== "success" || !startResult.data.options) {
|
|
519
|
+
dispatch({
|
|
520
|
+
type: SET_IS_LOADING,
|
|
521
|
+
payload: { isLoading: false }
|
|
522
|
+
});
|
|
523
|
+
return false;
|
|
524
|
+
}
|
|
525
|
+
const credential = await getPasskeyCredential(
|
|
526
|
+
startResult.data.options
|
|
473
527
|
);
|
|
528
|
+
const finishResult = await finishPasskeyAuthAPI(authProxyPath, {
|
|
529
|
+
credential,
|
|
530
|
+
sessionId: startResult.data.sessionId
|
|
531
|
+
});
|
|
532
|
+
if (finishResult.data.status === "login-success" && finishResult.data.redirect) {
|
|
533
|
+
const code = new URL(finishResult.data.redirect).searchParams.get("code");
|
|
534
|
+
if (code) {
|
|
535
|
+
const exchangeResult = await exchangeCodeAPI(authProxyPath, code);
|
|
536
|
+
if (exchangeResult.response.status === 200) {
|
|
537
|
+
dispatch({
|
|
538
|
+
type: LOGIN,
|
|
539
|
+
payload: {
|
|
540
|
+
user: exchangeResult.data.user,
|
|
541
|
+
domain: exchangeResult.data.domain,
|
|
542
|
+
isAuthenticated: true
|
|
543
|
+
}
|
|
544
|
+
});
|
|
545
|
+
dispatch({
|
|
546
|
+
type: SET_IS_LOADING,
|
|
547
|
+
payload: { isLoading: false }
|
|
548
|
+
});
|
|
549
|
+
return true;
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
dispatch({
|
|
554
|
+
type: SET_IS_LOADING,
|
|
555
|
+
payload: { isLoading: false }
|
|
556
|
+
});
|
|
474
557
|
return false;
|
|
475
558
|
} catch (error) {
|
|
476
559
|
onError(
|
|
477
|
-
error instanceof Error ? error : new Error("
|
|
560
|
+
error instanceof Error ? error : new Error("Passkey authentication error")
|
|
478
561
|
);
|
|
562
|
+
dispatch({
|
|
563
|
+
type: SET_IS_LOADING,
|
|
564
|
+
payload: { isLoading: false }
|
|
565
|
+
});
|
|
479
566
|
return false;
|
|
480
567
|
}
|
|
481
568
|
}
|
|
@@ -499,13 +586,7 @@ function setDauthUrl(url) {
|
|
|
499
586
|
function checkIsLocalhost() {
|
|
500
587
|
if (typeof window === "undefined") return false;
|
|
501
588
|
const hostname = window.location.hostname;
|
|
502
|
-
return hostname === "localhost" || hostname === "[::1]" || /^127(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d\d?)){3}$/.test(
|
|
503
|
-
hostname
|
|
504
|
-
) || /^192\.168(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d\d?)){2}$/.test(
|
|
505
|
-
hostname
|
|
506
|
-
) || /^10(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d\d?)){3}$/.test(
|
|
507
|
-
hostname
|
|
508
|
-
);
|
|
589
|
+
return hostname === "localhost" || hostname === "[::1]" || /^127(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d\d?)){3}$/.test(hostname) || /^192\.168(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d\d?)){2}$/.test(hostname) || /^10(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d\d?)){3}$/.test(hostname);
|
|
509
590
|
}
|
|
510
591
|
function getClientBasePath() {
|
|
511
592
|
if (_dauthUrl) return _dauthUrl;
|
|
@@ -704,10 +785,7 @@ function useModalAnimation(open) {
|
|
|
704
785
|
}
|
|
705
786
|
if (phase === "entered" || phase === "entering") {
|
|
706
787
|
setPhase("exiting");
|
|
707
|
-
const timer = setTimeout(
|
|
708
|
-
() => setPhase("exited"),
|
|
709
|
-
MOBILE_TRANSITION_MS
|
|
710
|
-
);
|
|
788
|
+
const timer = setTimeout(() => setPhase("exited"), MOBILE_TRANSITION_MS);
|
|
711
789
|
return () => clearTimeout(timer);
|
|
712
790
|
}
|
|
713
791
|
return void 0;
|
|
@@ -857,18 +935,12 @@ function DauthProfileModal({
|
|
|
857
935
|
}, [activeTab, showSecurity, getPasskeyCredentials]);
|
|
858
936
|
useEffect(() => {
|
|
859
937
|
if (status?.type !== "success") return;
|
|
860
|
-
const timer = setTimeout(
|
|
861
|
-
() => setStatus(null),
|
|
862
|
-
SUCCESS_TIMEOUT_MS
|
|
863
|
-
);
|
|
938
|
+
const timer = setTimeout(() => setStatus(null), SUCCESS_TIMEOUT_MS);
|
|
864
939
|
return () => clearTimeout(timer);
|
|
865
940
|
}, [status]);
|
|
866
941
|
useEffect(() => {
|
|
867
942
|
if (passkeyStatus?.type !== "success") return;
|
|
868
|
-
const timer = setTimeout(
|
|
869
|
-
() => setPasskeyStatus(null),
|
|
870
|
-
SUCCESS_TIMEOUT_MS
|
|
871
|
-
);
|
|
943
|
+
const timer = setTimeout(() => setPasskeyStatus(null), SUCCESS_TIMEOUT_MS);
|
|
872
944
|
return () => clearTimeout(timer);
|
|
873
945
|
}, [passkeyStatus]);
|
|
874
946
|
useFocusTrap(modalRef, phase === "entered", onClose);
|
|
@@ -908,12 +980,9 @@ function DauthProfileModal({
|
|
|
908
980
|
if (hasField("lastname")) fields.lastname = lastname;
|
|
909
981
|
if (hasField("nickname")) fields.nickname = nickname;
|
|
910
982
|
if (hasField("country")) fields.country = country;
|
|
911
|
-
if (hasField("tel_prefix"))
|
|
912
|
-
|
|
913
|
-
if (hasField("
|
|
914
|
-
fields.telSuffix = telSuffix;
|
|
915
|
-
if (hasField("birth_date") && birthDate)
|
|
916
|
-
fields.birthDate = birthDate;
|
|
983
|
+
if (hasField("tel_prefix")) fields.telPrefix = telPrefix;
|
|
984
|
+
if (hasField("tel_suffix")) fields.telSuffix = telSuffix;
|
|
985
|
+
if (hasField("birth_date") && birthDate) fields.birthDate = birthDate;
|
|
917
986
|
if ((domain.customFields ?? []).length > 0)
|
|
918
987
|
fields.customFields = customFieldValues;
|
|
919
988
|
const ok = await updateUser(fields);
|
|
@@ -966,9 +1035,7 @@ function DauthProfileModal({
|
|
|
966
1035
|
const handleRegisterPasskey = useCallback(async () => {
|
|
967
1036
|
setRegistering(true);
|
|
968
1037
|
setPasskeyStatus(null);
|
|
969
|
-
const cred = await registerPasskey(
|
|
970
|
-
passkeyName || void 0
|
|
971
|
-
);
|
|
1038
|
+
const cred = await registerPasskey(passkeyName || void 0);
|
|
972
1039
|
setRegistering(false);
|
|
973
1040
|
if (cred) {
|
|
974
1041
|
setCredentials((prev) => [...prev, cred]);
|
|
@@ -989,9 +1056,7 @@ function DauthProfileModal({
|
|
|
989
1056
|
async (credentialId) => {
|
|
990
1057
|
const ok = await deletePasskeyCredential(credentialId);
|
|
991
1058
|
if (ok) {
|
|
992
|
-
setCredentials(
|
|
993
|
-
(prev) => prev.filter((c) => c._id !== credentialId)
|
|
994
|
-
);
|
|
1059
|
+
setCredentials((prev) => prev.filter((c) => c._id !== credentialId));
|
|
995
1060
|
}
|
|
996
1061
|
},
|
|
997
1062
|
[deletePasskeyCredential]
|
|
@@ -1031,15 +1096,11 @@ function DauthProfileModal({
|
|
|
1031
1096
|
if (!t) return {};
|
|
1032
1097
|
const vars = {};
|
|
1033
1098
|
if (t.accent) vars["--dauth-accent"] = t.accent;
|
|
1034
|
-
if (t.accentHover)
|
|
1035
|
-
vars["--dauth-accent-hover"] = t.accentHover;
|
|
1099
|
+
if (t.accentHover) vars["--dauth-accent-hover"] = t.accentHover;
|
|
1036
1100
|
if (t.surface) vars["--dauth-surface"] = t.surface;
|
|
1037
|
-
if (t.surfaceHover)
|
|
1038
|
-
|
|
1039
|
-
if (t.
|
|
1040
|
-
vars["--dauth-text-primary"] = t.textPrimary;
|
|
1041
|
-
if (t.textSecondary)
|
|
1042
|
-
vars["--dauth-text-secondary"] = t.textSecondary;
|
|
1101
|
+
if (t.surfaceHover) vars["--dauth-surface-hover"] = t.surfaceHover;
|
|
1102
|
+
if (t.textPrimary) vars["--dauth-text-primary"] = t.textPrimary;
|
|
1103
|
+
if (t.textSecondary) vars["--dauth-text-secondary"] = t.textSecondary;
|
|
1043
1104
|
if (t.border) vars["--dauth-border"] = t.border;
|
|
1044
1105
|
return vars;
|
|
1045
1106
|
}, [domain.modalTheme]);
|
|
@@ -1206,14 +1267,7 @@ function DauthProfileModal({
|
|
|
1206
1267
|
),
|
|
1207
1268
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
1208
1269
|
/* @__PURE__ */ jsxs("div", { style: fieldGroup, children: [
|
|
1209
|
-
/* @__PURE__ */ jsx(
|
|
1210
|
-
"label",
|
|
1211
|
-
{
|
|
1212
|
-
htmlFor: "dauth-name",
|
|
1213
|
-
style: label,
|
|
1214
|
-
children: "Name *"
|
|
1215
|
-
}
|
|
1216
|
-
),
|
|
1270
|
+
/* @__PURE__ */ jsx("label", { htmlFor: "dauth-name", style: label, children: "Name *" }),
|
|
1217
1271
|
/* @__PURE__ */ jsx(
|
|
1218
1272
|
"input",
|
|
1219
1273
|
{
|
|
@@ -1230,17 +1284,10 @@ function DauthProfileModal({
|
|
|
1230
1284
|
)
|
|
1231
1285
|
] }),
|
|
1232
1286
|
hasField("lastname") && /* @__PURE__ */ jsxs("div", { style: fieldGroup, children: [
|
|
1233
|
-
/* @__PURE__ */ jsxs(
|
|
1234
|
-
"
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
style: label,
|
|
1238
|
-
children: [
|
|
1239
|
-
"Last name",
|
|
1240
|
-
isRequired("lastname") ? " *" : ""
|
|
1241
|
-
]
|
|
1242
|
-
}
|
|
1243
|
-
),
|
|
1287
|
+
/* @__PURE__ */ jsxs("label", { htmlFor: "dauth-lastname", style: label, children: [
|
|
1288
|
+
"Last name",
|
|
1289
|
+
isRequired("lastname") ? " *" : ""
|
|
1290
|
+
] }),
|
|
1244
1291
|
/* @__PURE__ */ jsx(
|
|
1245
1292
|
"input",
|
|
1246
1293
|
{
|
|
@@ -1257,17 +1304,10 @@ function DauthProfileModal({
|
|
|
1257
1304
|
)
|
|
1258
1305
|
] }),
|
|
1259
1306
|
hasField("nickname") && /* @__PURE__ */ jsxs("div", { style: fieldGroup, children: [
|
|
1260
|
-
/* @__PURE__ */ jsxs(
|
|
1261
|
-
"
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
style: label,
|
|
1265
|
-
children: [
|
|
1266
|
-
"Nickname",
|
|
1267
|
-
isRequired("nickname") ? " *" : ""
|
|
1268
|
-
]
|
|
1269
|
-
}
|
|
1270
|
-
),
|
|
1307
|
+
/* @__PURE__ */ jsxs("label", { htmlFor: "dauth-nickname", style: label, children: [
|
|
1308
|
+
"Nickname",
|
|
1309
|
+
isRequired("nickname") ? " *" : ""
|
|
1310
|
+
] }),
|
|
1271
1311
|
/* @__PURE__ */ jsx(
|
|
1272
1312
|
"input",
|
|
1273
1313
|
{
|
|
@@ -1284,17 +1324,10 @@ function DauthProfileModal({
|
|
|
1284
1324
|
)
|
|
1285
1325
|
] }),
|
|
1286
1326
|
hasField("country") && /* @__PURE__ */ jsxs("div", { style: fieldGroup, children: [
|
|
1287
|
-
/* @__PURE__ */ jsxs(
|
|
1288
|
-
"
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
style: label,
|
|
1292
|
-
children: [
|
|
1293
|
-
"Country",
|
|
1294
|
-
isRequired("country") ? " *" : ""
|
|
1295
|
-
]
|
|
1296
|
-
}
|
|
1297
|
-
),
|
|
1327
|
+
/* @__PURE__ */ jsxs("label", { htmlFor: "dauth-country", style: label, children: [
|
|
1328
|
+
"Country",
|
|
1329
|
+
isRequired("country") ? " *" : ""
|
|
1330
|
+
] }),
|
|
1298
1331
|
/* @__PURE__ */ jsx(
|
|
1299
1332
|
"input",
|
|
1300
1333
|
{
|
|
@@ -1365,17 +1398,10 @@ function DauthProfileModal({
|
|
|
1365
1398
|
)
|
|
1366
1399
|
] }),
|
|
1367
1400
|
hasField("birth_date") && /* @__PURE__ */ jsxs("div", { style: fieldGroup, children: [
|
|
1368
|
-
/* @__PURE__ */ jsxs(
|
|
1369
|
-
"
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
style: label,
|
|
1373
|
-
children: [
|
|
1374
|
-
"Birth date",
|
|
1375
|
-
isRequired("birth_date") ? " *" : ""
|
|
1376
|
-
]
|
|
1377
|
-
}
|
|
1378
|
-
),
|
|
1401
|
+
/* @__PURE__ */ jsxs("label", { htmlFor: "dauth-birthdate", style: label, children: [
|
|
1402
|
+
"Birth date",
|
|
1403
|
+
isRequired("birth_date") ? " *" : ""
|
|
1404
|
+
] }),
|
|
1379
1405
|
/* @__PURE__ */ jsx(
|
|
1380
1406
|
"input",
|
|
1381
1407
|
{
|
|
@@ -1392,44 +1418,28 @@ function DauthProfileModal({
|
|
|
1392
1418
|
] }),
|
|
1393
1419
|
(domain.customFields ?? []).length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1394
1420
|
/* @__PURE__ */ jsx("hr", { style: separator }),
|
|
1395
|
-
domain.customFields.map((cf) => /* @__PURE__ */ jsxs(
|
|
1396
|
-
"
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
onChange: (e) => setCustomFieldValues(
|
|
1418
|
-
(prev) => ({
|
|
1419
|
-
...prev,
|
|
1420
|
-
[cf.key]: e.target.value
|
|
1421
|
-
})
|
|
1422
|
-
),
|
|
1423
|
-
disabled: saving,
|
|
1424
|
-
style: input,
|
|
1425
|
-
onFocus: inputFocusHandler,
|
|
1426
|
-
onBlur: inputBlurHandler
|
|
1427
|
-
}
|
|
1428
|
-
)
|
|
1429
|
-
]
|
|
1430
|
-
},
|
|
1431
|
-
cf.key
|
|
1432
|
-
))
|
|
1421
|
+
domain.customFields.map((cf) => /* @__PURE__ */ jsxs("div", { style: fieldGroup, children: [
|
|
1422
|
+
/* @__PURE__ */ jsxs("label", { htmlFor: `dauth-cf-${cf.key}`, style: label, children: [
|
|
1423
|
+
cf.label,
|
|
1424
|
+
cf.required ? " *" : ""
|
|
1425
|
+
] }),
|
|
1426
|
+
/* @__PURE__ */ jsx(
|
|
1427
|
+
"input",
|
|
1428
|
+
{
|
|
1429
|
+
id: `dauth-cf-${cf.key}`,
|
|
1430
|
+
type: "text",
|
|
1431
|
+
value: customFieldValues[cf.key] ?? "",
|
|
1432
|
+
onChange: (e) => setCustomFieldValues((prev) => ({
|
|
1433
|
+
...prev,
|
|
1434
|
+
[cf.key]: e.target.value
|
|
1435
|
+
})),
|
|
1436
|
+
disabled: saving,
|
|
1437
|
+
style: input,
|
|
1438
|
+
onFocus: inputFocusHandler,
|
|
1439
|
+
onBlur: inputBlurHandler
|
|
1440
|
+
}
|
|
1441
|
+
)
|
|
1442
|
+
] }, cf.key))
|
|
1433
1443
|
] })
|
|
1434
1444
|
] }),
|
|
1435
1445
|
/* @__PURE__ */ jsx("hr", { style: separator }),
|
|
@@ -1489,14 +1499,7 @@ function DauthProfileModal({
|
|
|
1489
1499
|
),
|
|
1490
1500
|
showRegister && /* @__PURE__ */ jsxs("div", { style: registerPanel, children: [
|
|
1491
1501
|
/* @__PURE__ */ jsxs("div", { style: fieldGroup, children: [
|
|
1492
|
-
/* @__PURE__ */ jsx(
|
|
1493
|
-
"label",
|
|
1494
|
-
{
|
|
1495
|
-
htmlFor: "dauth-passkey-name",
|
|
1496
|
-
style: label,
|
|
1497
|
-
children: "Passkey name (optional)"
|
|
1498
|
-
}
|
|
1499
|
-
),
|
|
1502
|
+
/* @__PURE__ */ jsx("label", { htmlFor: "dauth-passkey-name", style: label, children: "Passkey name (optional)" }),
|
|
1500
1503
|
/* @__PURE__ */ jsx(
|
|
1501
1504
|
"input",
|
|
1502
1505
|
{
|
|
@@ -1572,89 +1575,82 @@ function DauthProfileModal({
|
|
|
1572
1575
|
},
|
|
1573
1576
|
children: /* @__PURE__ */ jsx(Spinner, {})
|
|
1574
1577
|
}
|
|
1575
|
-
) : credentials.length > 0 ? credentials.map((cred) => /* @__PURE__ */ jsxs(
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
"
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
"
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
children: /* @__PURE__ */ jsx(IconTrash, {})
|
|
1652
|
-
}
|
|
1653
|
-
)
|
|
1654
|
-
]
|
|
1655
|
-
},
|
|
1656
|
-
cred._id
|
|
1657
|
-
)) : /* @__PURE__ */ jsxs("div", { style: emptyState, children: [
|
|
1578
|
+
) : credentials.length > 0 ? credentials.map((cred) => /* @__PURE__ */ jsxs("div", { style: credentialRow, children: [
|
|
1579
|
+
/* @__PURE__ */ jsxs(
|
|
1580
|
+
"div",
|
|
1581
|
+
{
|
|
1582
|
+
style: {
|
|
1583
|
+
display: "flex",
|
|
1584
|
+
alignItems: "center",
|
|
1585
|
+
gap: 12,
|
|
1586
|
+
flex: 1,
|
|
1587
|
+
minWidth: 0
|
|
1588
|
+
},
|
|
1589
|
+
children: [
|
|
1590
|
+
/* @__PURE__ */ jsx(
|
|
1591
|
+
"span",
|
|
1592
|
+
{
|
|
1593
|
+
style: {
|
|
1594
|
+
color: "var(--dauth-accent, #6366f1)",
|
|
1595
|
+
flexShrink: 0
|
|
1596
|
+
},
|
|
1597
|
+
children: /* @__PURE__ */ jsx(IconFingerprint, {})
|
|
1598
|
+
}
|
|
1599
|
+
),
|
|
1600
|
+
/* @__PURE__ */ jsxs(
|
|
1601
|
+
"div",
|
|
1602
|
+
{
|
|
1603
|
+
style: {
|
|
1604
|
+
minWidth: 0,
|
|
1605
|
+
flex: 1
|
|
1606
|
+
},
|
|
1607
|
+
children: [
|
|
1608
|
+
/* @__PURE__ */ jsx(
|
|
1609
|
+
"div",
|
|
1610
|
+
{
|
|
1611
|
+
style: {
|
|
1612
|
+
fontSize: "var(--dauth-font-size-sm, 0.875rem)",
|
|
1613
|
+
fontWeight: 500,
|
|
1614
|
+
color: "var(--dauth-text-primary, #e4e4e7)",
|
|
1615
|
+
overflow: "hidden",
|
|
1616
|
+
textOverflow: "ellipsis",
|
|
1617
|
+
whiteSpace: "nowrap"
|
|
1618
|
+
},
|
|
1619
|
+
children: cred.name || "Passkey"
|
|
1620
|
+
}
|
|
1621
|
+
),
|
|
1622
|
+
/* @__PURE__ */ jsxs(
|
|
1623
|
+
"div",
|
|
1624
|
+
{
|
|
1625
|
+
style: {
|
|
1626
|
+
fontSize: "var(--dauth-font-size-xs, 0.75rem)",
|
|
1627
|
+
color: "var(--dauth-text-muted, #71717a)"
|
|
1628
|
+
},
|
|
1629
|
+
children: [
|
|
1630
|
+
cred.deviceType === "multiDevice" ? "Synced" : "Device-bound",
|
|
1631
|
+
cred.createdAt && ` \xB7 Created ${new Date(cred.createdAt).toLocaleDateString()}`
|
|
1632
|
+
]
|
|
1633
|
+
}
|
|
1634
|
+
)
|
|
1635
|
+
]
|
|
1636
|
+
}
|
|
1637
|
+
)
|
|
1638
|
+
]
|
|
1639
|
+
}
|
|
1640
|
+
),
|
|
1641
|
+
/* @__PURE__ */ jsx(
|
|
1642
|
+
"button",
|
|
1643
|
+
{
|
|
1644
|
+
type: "button",
|
|
1645
|
+
onClick: () => handleDeletePasskey(cred._id),
|
|
1646
|
+
style: trashBtn,
|
|
1647
|
+
onMouseEnter: (e) => e.currentTarget.style.color = "var(--dauth-error, #ef4444)",
|
|
1648
|
+
onMouseLeave: (e) => e.currentTarget.style.color = "var(--dauth-text-muted, #71717a)",
|
|
1649
|
+
"aria-label": `Delete passkey ${cred.name || ""}`,
|
|
1650
|
+
children: /* @__PURE__ */ jsx(IconTrash, {})
|
|
1651
|
+
}
|
|
1652
|
+
)
|
|
1653
|
+
] }, cred._id)) : /* @__PURE__ */ jsxs("div", { style: emptyState, children: [
|
|
1658
1654
|
/* @__PURE__ */ jsx(
|
|
1659
1655
|
"span",
|
|
1660
1656
|
{
|
|
@@ -2262,6 +2258,10 @@ var DauthProvider = (props) => {
|
|
|
2262
2258
|
(file) => uploadAvatarAction(ctx, file),
|
|
2263
2259
|
[ctx]
|
|
2264
2260
|
);
|
|
2261
|
+
const loginWithPasskey = useCallback2(
|
|
2262
|
+
() => loginWithPasskeyAction(ctx),
|
|
2263
|
+
[ctx]
|
|
2264
|
+
);
|
|
2265
2265
|
const memoProvider = useMemo2(
|
|
2266
2266
|
() => ({
|
|
2267
2267
|
...dauthState,
|
|
@@ -2272,7 +2272,8 @@ var DauthProvider = (props) => {
|
|
|
2272
2272
|
getPasskeyCredentials,
|
|
2273
2273
|
registerPasskey,
|
|
2274
2274
|
deletePasskeyCredential,
|
|
2275
|
-
uploadAvatar
|
|
2275
|
+
uploadAvatar,
|
|
2276
|
+
loginWithPasskey
|
|
2276
2277
|
}),
|
|
2277
2278
|
[
|
|
2278
2279
|
dauthState,
|
|
@@ -2283,7 +2284,8 @@ var DauthProvider = (props) => {
|
|
|
2283
2284
|
getPasskeyCredentials,
|
|
2284
2285
|
registerPasskey,
|
|
2285
2286
|
deletePasskeyCredential,
|
|
2286
|
-
uploadAvatar
|
|
2287
|
+
uploadAvatar,
|
|
2288
|
+
loginWithPasskey
|
|
2287
2289
|
]
|
|
2288
2290
|
);
|
|
2289
2291
|
return /* @__PURE__ */ jsx2(DauthContext.Provider, { value: memoProvider, children });
|