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.js
CHANGED
|
@@ -45,7 +45,8 @@ var initialDauthState = {
|
|
|
45
45
|
getPasskeyCredentials: () => Promise.resolve([]),
|
|
46
46
|
registerPasskey: () => Promise.resolve(null),
|
|
47
47
|
deletePasskeyCredential: () => Promise.resolve(false),
|
|
48
|
-
uploadAvatar: () => Promise.resolve(false)
|
|
48
|
+
uploadAvatar: () => Promise.resolve(false),
|
|
49
|
+
loginWithPasskey: () => Promise.resolve(false)
|
|
49
50
|
};
|
|
50
51
|
var initialDauthState_default = initialDauthState;
|
|
51
52
|
|
|
@@ -153,45 +154,59 @@ async function deleteAccountAPI(basePath) {
|
|
|
153
154
|
return { response, data };
|
|
154
155
|
}
|
|
155
156
|
async function getPasskeyCredentialsAPI(basePath) {
|
|
156
|
-
const response = await fetch(
|
|
157
|
-
|
|
158
|
-
{
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
credentials: "include"
|
|
162
|
-
}
|
|
163
|
-
);
|
|
157
|
+
const response = await fetch(`${basePath}/passkey/credentials`, {
|
|
158
|
+
method: "GET",
|
|
159
|
+
headers: { "X-CSRF-Token": getCsrfToken() },
|
|
160
|
+
credentials: "include"
|
|
161
|
+
});
|
|
164
162
|
const data = await response.json();
|
|
165
163
|
return { response, data };
|
|
166
164
|
}
|
|
167
165
|
async function startPasskeyRegistrationAPI(basePath) {
|
|
168
|
-
const response = await fetch(
|
|
169
|
-
|
|
170
|
-
{
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
credentials: "include"
|
|
177
|
-
}
|
|
178
|
-
);
|
|
166
|
+
const response = await fetch(`${basePath}/passkey/register/start`, {
|
|
167
|
+
method: "POST",
|
|
168
|
+
headers: {
|
|
169
|
+
"Content-Type": "application/json",
|
|
170
|
+
"X-CSRF-Token": getCsrfToken()
|
|
171
|
+
},
|
|
172
|
+
credentials: "include"
|
|
173
|
+
});
|
|
179
174
|
const data = await response.json();
|
|
180
175
|
return { response, data };
|
|
181
176
|
}
|
|
182
177
|
async function finishPasskeyRegistrationAPI(basePath, body) {
|
|
183
|
-
const response = await fetch(
|
|
184
|
-
|
|
185
|
-
{
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
178
|
+
const response = await fetch(`${basePath}/passkey/register/finish`, {
|
|
179
|
+
method: "POST",
|
|
180
|
+
headers: {
|
|
181
|
+
"Content-Type": "application/json",
|
|
182
|
+
"X-CSRF-Token": getCsrfToken()
|
|
183
|
+
},
|
|
184
|
+
credentials: "include",
|
|
185
|
+
body: JSON.stringify(body)
|
|
186
|
+
});
|
|
187
|
+
const data = await response.json();
|
|
188
|
+
return { response, data };
|
|
189
|
+
}
|
|
190
|
+
async function startPasskeyAuthAPI(basePath) {
|
|
191
|
+
const response = await fetch(`${basePath}/passkey/auth-start`, {
|
|
192
|
+
method: "POST",
|
|
193
|
+
headers: {
|
|
194
|
+
"Content-Type": "application/json"
|
|
195
|
+
},
|
|
196
|
+
credentials: "include"
|
|
197
|
+
});
|
|
198
|
+
const data = await response.json();
|
|
199
|
+
return { response, data };
|
|
200
|
+
}
|
|
201
|
+
async function finishPasskeyAuthAPI(basePath, body) {
|
|
202
|
+
const response = await fetch(`${basePath}/passkey/auth-finish`, {
|
|
203
|
+
method: "POST",
|
|
204
|
+
headers: {
|
|
205
|
+
"Content-Type": "application/json"
|
|
206
|
+
},
|
|
207
|
+
credentials: "include",
|
|
208
|
+
body: JSON.stringify(body)
|
|
209
|
+
});
|
|
195
210
|
const data = await response.json();
|
|
196
211
|
return { response, data };
|
|
197
212
|
}
|
|
@@ -243,17 +258,16 @@ function bufferToBase64url(buffer) {
|
|
|
243
258
|
async function createPasskeyCredential(options) {
|
|
244
259
|
const publicKey = {
|
|
245
260
|
...options,
|
|
261
|
+
rp: { ...options.rp, id: window.location.hostname },
|
|
246
262
|
challenge: base64urlToBuffer(options.challenge),
|
|
247
263
|
user: {
|
|
248
264
|
...options.user,
|
|
249
265
|
id: base64urlToBuffer(options.user.id)
|
|
250
266
|
},
|
|
251
|
-
excludeCredentials: (options.excludeCredentials ?? []).map(
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
})
|
|
256
|
-
)
|
|
267
|
+
excludeCredentials: (options.excludeCredentials ?? []).map((c) => ({
|
|
268
|
+
...c,
|
|
269
|
+
id: base64urlToBuffer(c.id)
|
|
270
|
+
}))
|
|
257
271
|
};
|
|
258
272
|
const credential = await navigator.credentials.create({
|
|
259
273
|
publicKey
|
|
@@ -267,20 +281,14 @@ async function createPasskeyCredential(options) {
|
|
|
267
281
|
rawId: bufferToBase64url(credential.rawId),
|
|
268
282
|
type: credential.type,
|
|
269
283
|
response: {
|
|
270
|
-
clientDataJSON: bufferToBase64url(
|
|
271
|
-
|
|
272
|
-
),
|
|
273
|
-
attestationObject: bufferToBase64url(
|
|
274
|
-
attestation.attestationObject
|
|
275
|
-
),
|
|
284
|
+
clientDataJSON: bufferToBase64url(attestation.clientDataJSON),
|
|
285
|
+
attestationObject: bufferToBase64url(attestation.attestationObject),
|
|
276
286
|
...attestation.getTransports ? { transports: attestation.getTransports() } : {},
|
|
277
287
|
...attestation.getPublicKeyAlgorithm ? {
|
|
278
288
|
publicKeyAlgorithm: attestation.getPublicKeyAlgorithm()
|
|
279
289
|
} : {},
|
|
280
290
|
...attestation.getPublicKey ? {
|
|
281
|
-
publicKey: bufferToBase64url(
|
|
282
|
-
attestation.getPublicKey()
|
|
283
|
-
)
|
|
291
|
+
publicKey: bufferToBase64url(attestation.getPublicKey())
|
|
284
292
|
} : {},
|
|
285
293
|
...attestation.getAuthenticatorData ? {
|
|
286
294
|
authenticatorData: bufferToBase64url(
|
|
@@ -292,6 +300,38 @@ async function createPasskeyCredential(options) {
|
|
|
292
300
|
authenticatorAttachment: credential.authenticatorAttachment ?? void 0
|
|
293
301
|
};
|
|
294
302
|
}
|
|
303
|
+
async function getPasskeyCredential(options) {
|
|
304
|
+
const publicKey = {
|
|
305
|
+
challenge: base64urlToBuffer(options.challenge),
|
|
306
|
+
timeout: options.timeout,
|
|
307
|
+
rpId: window.location.hostname,
|
|
308
|
+
userVerification: options.userVerification || "preferred",
|
|
309
|
+
allowCredentials: (options.allowCredentials || []).map(
|
|
310
|
+
(c) => ({
|
|
311
|
+
...c,
|
|
312
|
+
id: base64urlToBuffer(c.id)
|
|
313
|
+
})
|
|
314
|
+
)
|
|
315
|
+
};
|
|
316
|
+
const credential = await navigator.credentials.get({
|
|
317
|
+
publicKey
|
|
318
|
+
});
|
|
319
|
+
if (!credential) throw new Error("No credential returned");
|
|
320
|
+
const assertion = credential.response;
|
|
321
|
+
return {
|
|
322
|
+
id: credential.id,
|
|
323
|
+
rawId: bufferToBase64url(credential.rawId),
|
|
324
|
+
type: credential.type,
|
|
325
|
+
response: {
|
|
326
|
+
clientDataJSON: bufferToBase64url(assertion.clientDataJSON),
|
|
327
|
+
authenticatorData: bufferToBase64url(assertion.authenticatorData),
|
|
328
|
+
signature: bufferToBase64url(assertion.signature),
|
|
329
|
+
userHandle: assertion.userHandle ? bufferToBase64url(assertion.userHandle) : null
|
|
330
|
+
},
|
|
331
|
+
clientExtensionResults: credential.getClientExtensionResults(),
|
|
332
|
+
authenticatorAttachment: credential.authenticatorAttachment
|
|
333
|
+
};
|
|
334
|
+
}
|
|
295
335
|
|
|
296
336
|
// src/reducer/dauth.actions.ts
|
|
297
337
|
async function exchangeCodeAction(ctx, code) {
|
|
@@ -438,19 +478,15 @@ async function registerPasskeyAction(ctx, name) {
|
|
|
438
478
|
onError(new Error("Failed to start passkey registration"));
|
|
439
479
|
return null;
|
|
440
480
|
}
|
|
441
|
-
const credential = await createPasskeyCredential(
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
{ credential, name }
|
|
447
|
-
);
|
|
481
|
+
const credential = await createPasskeyCredential(startResult.data);
|
|
482
|
+
const finishResult = await finishPasskeyRegistrationAPI(authProxyPath, {
|
|
483
|
+
credential,
|
|
484
|
+
name
|
|
485
|
+
});
|
|
448
486
|
if (finishResult.response.status === 200 || finishResult.response.status === 201) {
|
|
449
487
|
return finishResult.data.credential;
|
|
450
488
|
}
|
|
451
|
-
onError(
|
|
452
|
-
new Error("Failed to finish passkey registration")
|
|
453
|
-
);
|
|
489
|
+
onError(new Error("Failed to finish passkey registration"));
|
|
454
490
|
return null;
|
|
455
491
|
} catch (error) {
|
|
456
492
|
onError(
|
|
@@ -468,9 +504,7 @@ async function deletePasskeyCredentialAction(ctx, credentialId) {
|
|
|
468
504
|
);
|
|
469
505
|
return result.response.status === 200;
|
|
470
506
|
} catch (error) {
|
|
471
|
-
onError(
|
|
472
|
-
error instanceof Error ? error : new Error("Delete passkey error")
|
|
473
|
-
);
|
|
507
|
+
onError(error instanceof Error ? error : new Error("Delete passkey error"));
|
|
474
508
|
return false;
|
|
475
509
|
}
|
|
476
510
|
}
|
|
@@ -485,16 +519,69 @@ async function uploadAvatarAction(ctx, file) {
|
|
|
485
519
|
});
|
|
486
520
|
return true;
|
|
487
521
|
}
|
|
488
|
-
onError(
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
522
|
+
onError(new Error("Avatar upload error: " + result.data.message));
|
|
523
|
+
return false;
|
|
524
|
+
} catch (error) {
|
|
525
|
+
onError(error instanceof Error ? error : new Error("Avatar upload error"));
|
|
526
|
+
return false;
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
async function loginWithPasskeyAction(ctx) {
|
|
530
|
+
const { dispatch, authProxyPath, onError } = ctx;
|
|
531
|
+
dispatch({
|
|
532
|
+
type: SET_IS_LOADING,
|
|
533
|
+
payload: { isLoading: true }
|
|
534
|
+
});
|
|
535
|
+
try {
|
|
536
|
+
const startResult = await startPasskeyAuthAPI(authProxyPath);
|
|
537
|
+
if (startResult.data.status !== "success" || !startResult.data.options) {
|
|
538
|
+
dispatch({
|
|
539
|
+
type: SET_IS_LOADING,
|
|
540
|
+
payload: { isLoading: false }
|
|
541
|
+
});
|
|
542
|
+
return false;
|
|
543
|
+
}
|
|
544
|
+
const credential = await getPasskeyCredential(
|
|
545
|
+
startResult.data.options
|
|
492
546
|
);
|
|
547
|
+
const finishResult = await finishPasskeyAuthAPI(authProxyPath, {
|
|
548
|
+
credential,
|
|
549
|
+
sessionId: startResult.data.sessionId
|
|
550
|
+
});
|
|
551
|
+
if (finishResult.data.status === "login-success" && finishResult.data.redirect) {
|
|
552
|
+
const code = new URL(finishResult.data.redirect).searchParams.get("code");
|
|
553
|
+
if (code) {
|
|
554
|
+
const exchangeResult = await exchangeCodeAPI(authProxyPath, code);
|
|
555
|
+
if (exchangeResult.response.status === 200) {
|
|
556
|
+
dispatch({
|
|
557
|
+
type: LOGIN,
|
|
558
|
+
payload: {
|
|
559
|
+
user: exchangeResult.data.user,
|
|
560
|
+
domain: exchangeResult.data.domain,
|
|
561
|
+
isAuthenticated: true
|
|
562
|
+
}
|
|
563
|
+
});
|
|
564
|
+
dispatch({
|
|
565
|
+
type: SET_IS_LOADING,
|
|
566
|
+
payload: { isLoading: false }
|
|
567
|
+
});
|
|
568
|
+
return true;
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
dispatch({
|
|
573
|
+
type: SET_IS_LOADING,
|
|
574
|
+
payload: { isLoading: false }
|
|
575
|
+
});
|
|
493
576
|
return false;
|
|
494
577
|
} catch (error) {
|
|
495
578
|
onError(
|
|
496
|
-
error instanceof Error ? error : new Error("
|
|
579
|
+
error instanceof Error ? error : new Error("Passkey authentication error")
|
|
497
580
|
);
|
|
581
|
+
dispatch({
|
|
582
|
+
type: SET_IS_LOADING,
|
|
583
|
+
payload: { isLoading: false }
|
|
584
|
+
});
|
|
498
585
|
return false;
|
|
499
586
|
}
|
|
500
587
|
}
|
|
@@ -518,13 +605,7 @@ function setDauthUrl(url) {
|
|
|
518
605
|
function checkIsLocalhost() {
|
|
519
606
|
if (typeof window === "undefined") return false;
|
|
520
607
|
const hostname = window.location.hostname;
|
|
521
|
-
return hostname === "localhost" || hostname === "[::1]" || /^127(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d\d?)){3}$/.test(
|
|
522
|
-
hostname
|
|
523
|
-
) || /^192\.168(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d\d?)){2}$/.test(
|
|
524
|
-
hostname
|
|
525
|
-
) || /^10(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d\d?)){3}$/.test(
|
|
526
|
-
hostname
|
|
527
|
-
);
|
|
608
|
+
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);
|
|
528
609
|
}
|
|
529
610
|
function getClientBasePath() {
|
|
530
611
|
if (_dauthUrl) return _dauthUrl;
|
|
@@ -717,10 +798,7 @@ function useModalAnimation(open) {
|
|
|
717
798
|
}
|
|
718
799
|
if (phase === "entered" || phase === "entering") {
|
|
719
800
|
setPhase("exiting");
|
|
720
|
-
const timer = setTimeout(
|
|
721
|
-
() => setPhase("exited"),
|
|
722
|
-
MOBILE_TRANSITION_MS
|
|
723
|
-
);
|
|
801
|
+
const timer = setTimeout(() => setPhase("exited"), MOBILE_TRANSITION_MS);
|
|
724
802
|
return () => clearTimeout(timer);
|
|
725
803
|
}
|
|
726
804
|
return void 0;
|
|
@@ -870,18 +948,12 @@ function DauthProfileModal({
|
|
|
870
948
|
}, [activeTab, showSecurity, getPasskeyCredentials]);
|
|
871
949
|
(0, import_react.useEffect)(() => {
|
|
872
950
|
if (status?.type !== "success") return;
|
|
873
|
-
const timer = setTimeout(
|
|
874
|
-
() => setStatus(null),
|
|
875
|
-
SUCCESS_TIMEOUT_MS
|
|
876
|
-
);
|
|
951
|
+
const timer = setTimeout(() => setStatus(null), SUCCESS_TIMEOUT_MS);
|
|
877
952
|
return () => clearTimeout(timer);
|
|
878
953
|
}, [status]);
|
|
879
954
|
(0, import_react.useEffect)(() => {
|
|
880
955
|
if (passkeyStatus?.type !== "success") return;
|
|
881
|
-
const timer = setTimeout(
|
|
882
|
-
() => setPasskeyStatus(null),
|
|
883
|
-
SUCCESS_TIMEOUT_MS
|
|
884
|
-
);
|
|
956
|
+
const timer = setTimeout(() => setPasskeyStatus(null), SUCCESS_TIMEOUT_MS);
|
|
885
957
|
return () => clearTimeout(timer);
|
|
886
958
|
}, [passkeyStatus]);
|
|
887
959
|
useFocusTrap(modalRef, phase === "entered", onClose);
|
|
@@ -921,12 +993,9 @@ function DauthProfileModal({
|
|
|
921
993
|
if (hasField("lastname")) fields.lastname = lastname;
|
|
922
994
|
if (hasField("nickname")) fields.nickname = nickname;
|
|
923
995
|
if (hasField("country")) fields.country = country;
|
|
924
|
-
if (hasField("tel_prefix"))
|
|
925
|
-
|
|
926
|
-
if (hasField("
|
|
927
|
-
fields.telSuffix = telSuffix;
|
|
928
|
-
if (hasField("birth_date") && birthDate)
|
|
929
|
-
fields.birthDate = birthDate;
|
|
996
|
+
if (hasField("tel_prefix")) fields.telPrefix = telPrefix;
|
|
997
|
+
if (hasField("tel_suffix")) fields.telSuffix = telSuffix;
|
|
998
|
+
if (hasField("birth_date") && birthDate) fields.birthDate = birthDate;
|
|
930
999
|
if ((domain.customFields ?? []).length > 0)
|
|
931
1000
|
fields.customFields = customFieldValues;
|
|
932
1001
|
const ok = await updateUser(fields);
|
|
@@ -979,9 +1048,7 @@ function DauthProfileModal({
|
|
|
979
1048
|
const handleRegisterPasskey = (0, import_react.useCallback)(async () => {
|
|
980
1049
|
setRegistering(true);
|
|
981
1050
|
setPasskeyStatus(null);
|
|
982
|
-
const cred = await registerPasskey(
|
|
983
|
-
passkeyName || void 0
|
|
984
|
-
);
|
|
1051
|
+
const cred = await registerPasskey(passkeyName || void 0);
|
|
985
1052
|
setRegistering(false);
|
|
986
1053
|
if (cred) {
|
|
987
1054
|
setCredentials((prev) => [...prev, cred]);
|
|
@@ -1002,9 +1069,7 @@ function DauthProfileModal({
|
|
|
1002
1069
|
async (credentialId) => {
|
|
1003
1070
|
const ok = await deletePasskeyCredential(credentialId);
|
|
1004
1071
|
if (ok) {
|
|
1005
|
-
setCredentials(
|
|
1006
|
-
(prev) => prev.filter((c) => c._id !== credentialId)
|
|
1007
|
-
);
|
|
1072
|
+
setCredentials((prev) => prev.filter((c) => c._id !== credentialId));
|
|
1008
1073
|
}
|
|
1009
1074
|
},
|
|
1010
1075
|
[deletePasskeyCredential]
|
|
@@ -1044,15 +1109,11 @@ function DauthProfileModal({
|
|
|
1044
1109
|
if (!t) return {};
|
|
1045
1110
|
const vars = {};
|
|
1046
1111
|
if (t.accent) vars["--dauth-accent"] = t.accent;
|
|
1047
|
-
if (t.accentHover)
|
|
1048
|
-
vars["--dauth-accent-hover"] = t.accentHover;
|
|
1112
|
+
if (t.accentHover) vars["--dauth-accent-hover"] = t.accentHover;
|
|
1049
1113
|
if (t.surface) vars["--dauth-surface"] = t.surface;
|
|
1050
|
-
if (t.surfaceHover)
|
|
1051
|
-
|
|
1052
|
-
if (t.
|
|
1053
|
-
vars["--dauth-text-primary"] = t.textPrimary;
|
|
1054
|
-
if (t.textSecondary)
|
|
1055
|
-
vars["--dauth-text-secondary"] = t.textSecondary;
|
|
1114
|
+
if (t.surfaceHover) vars["--dauth-surface-hover"] = t.surfaceHover;
|
|
1115
|
+
if (t.textPrimary) vars["--dauth-text-primary"] = t.textPrimary;
|
|
1116
|
+
if (t.textSecondary) vars["--dauth-text-secondary"] = t.textSecondary;
|
|
1056
1117
|
if (t.border) vars["--dauth-border"] = t.border;
|
|
1057
1118
|
return vars;
|
|
1058
1119
|
}, [domain.modalTheme]);
|
|
@@ -1219,14 +1280,7 @@ function DauthProfileModal({
|
|
|
1219
1280
|
),
|
|
1220
1281
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
1221
1282
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: fieldGroup, children: [
|
|
1222
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1223
|
-
"label",
|
|
1224
|
-
{
|
|
1225
|
-
htmlFor: "dauth-name",
|
|
1226
|
-
style: label,
|
|
1227
|
-
children: "Name *"
|
|
1228
|
-
}
|
|
1229
|
-
),
|
|
1283
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { htmlFor: "dauth-name", style: label, children: "Name *" }),
|
|
1230
1284
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1231
1285
|
"input",
|
|
1232
1286
|
{
|
|
@@ -1243,17 +1297,10 @@ function DauthProfileModal({
|
|
|
1243
1297
|
)
|
|
1244
1298
|
] }),
|
|
1245
1299
|
hasField("lastname") && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: fieldGroup, children: [
|
|
1246
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1247
|
-
"
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
style: label,
|
|
1251
|
-
children: [
|
|
1252
|
-
"Last name",
|
|
1253
|
-
isRequired("lastname") ? " *" : ""
|
|
1254
|
-
]
|
|
1255
|
-
}
|
|
1256
|
-
),
|
|
1300
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { htmlFor: "dauth-lastname", style: label, children: [
|
|
1301
|
+
"Last name",
|
|
1302
|
+
isRequired("lastname") ? " *" : ""
|
|
1303
|
+
] }),
|
|
1257
1304
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1258
1305
|
"input",
|
|
1259
1306
|
{
|
|
@@ -1270,17 +1317,10 @@ function DauthProfileModal({
|
|
|
1270
1317
|
)
|
|
1271
1318
|
] }),
|
|
1272
1319
|
hasField("nickname") && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: fieldGroup, children: [
|
|
1273
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1274
|
-
"
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
style: label,
|
|
1278
|
-
children: [
|
|
1279
|
-
"Nickname",
|
|
1280
|
-
isRequired("nickname") ? " *" : ""
|
|
1281
|
-
]
|
|
1282
|
-
}
|
|
1283
|
-
),
|
|
1320
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { htmlFor: "dauth-nickname", style: label, children: [
|
|
1321
|
+
"Nickname",
|
|
1322
|
+
isRequired("nickname") ? " *" : ""
|
|
1323
|
+
] }),
|
|
1284
1324
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1285
1325
|
"input",
|
|
1286
1326
|
{
|
|
@@ -1297,17 +1337,10 @@ function DauthProfileModal({
|
|
|
1297
1337
|
)
|
|
1298
1338
|
] }),
|
|
1299
1339
|
hasField("country") && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: fieldGroup, children: [
|
|
1300
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1301
|
-
"
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
style: label,
|
|
1305
|
-
children: [
|
|
1306
|
-
"Country",
|
|
1307
|
-
isRequired("country") ? " *" : ""
|
|
1308
|
-
]
|
|
1309
|
-
}
|
|
1310
|
-
),
|
|
1340
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { htmlFor: "dauth-country", style: label, children: [
|
|
1341
|
+
"Country",
|
|
1342
|
+
isRequired("country") ? " *" : ""
|
|
1343
|
+
] }),
|
|
1311
1344
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1312
1345
|
"input",
|
|
1313
1346
|
{
|
|
@@ -1378,17 +1411,10 @@ function DauthProfileModal({
|
|
|
1378
1411
|
)
|
|
1379
1412
|
] }),
|
|
1380
1413
|
hasField("birth_date") && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: fieldGroup, children: [
|
|
1381
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1382
|
-
"
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
style: label,
|
|
1386
|
-
children: [
|
|
1387
|
-
"Birth date",
|
|
1388
|
-
isRequired("birth_date") ? " *" : ""
|
|
1389
|
-
]
|
|
1390
|
-
}
|
|
1391
|
-
),
|
|
1414
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { htmlFor: "dauth-birthdate", style: label, children: [
|
|
1415
|
+
"Birth date",
|
|
1416
|
+
isRequired("birth_date") ? " *" : ""
|
|
1417
|
+
] }),
|
|
1392
1418
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1393
1419
|
"input",
|
|
1394
1420
|
{
|
|
@@ -1405,44 +1431,28 @@ function DauthProfileModal({
|
|
|
1405
1431
|
] }),
|
|
1406
1432
|
(domain.customFields ?? []).length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
1407
1433
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("hr", { style: separator }),
|
|
1408
|
-
domain.customFields.map((cf) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1409
|
-
"
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
onChange: (e) => setCustomFieldValues(
|
|
1431
|
-
(prev) => ({
|
|
1432
|
-
...prev,
|
|
1433
|
-
[cf.key]: e.target.value
|
|
1434
|
-
})
|
|
1435
|
-
),
|
|
1436
|
-
disabled: saving,
|
|
1437
|
-
style: input,
|
|
1438
|
-
onFocus: inputFocusHandler,
|
|
1439
|
-
onBlur: inputBlurHandler
|
|
1440
|
-
}
|
|
1441
|
-
)
|
|
1442
|
-
]
|
|
1443
|
-
},
|
|
1444
|
-
cf.key
|
|
1445
|
-
))
|
|
1434
|
+
domain.customFields.map((cf) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: fieldGroup, children: [
|
|
1435
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { htmlFor: `dauth-cf-${cf.key}`, style: label, children: [
|
|
1436
|
+
cf.label,
|
|
1437
|
+
cf.required ? " *" : ""
|
|
1438
|
+
] }),
|
|
1439
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1440
|
+
"input",
|
|
1441
|
+
{
|
|
1442
|
+
id: `dauth-cf-${cf.key}`,
|
|
1443
|
+
type: "text",
|
|
1444
|
+
value: customFieldValues[cf.key] ?? "",
|
|
1445
|
+
onChange: (e) => setCustomFieldValues((prev) => ({
|
|
1446
|
+
...prev,
|
|
1447
|
+
[cf.key]: e.target.value
|
|
1448
|
+
})),
|
|
1449
|
+
disabled: saving,
|
|
1450
|
+
style: input,
|
|
1451
|
+
onFocus: inputFocusHandler,
|
|
1452
|
+
onBlur: inputBlurHandler
|
|
1453
|
+
}
|
|
1454
|
+
)
|
|
1455
|
+
] }, cf.key))
|
|
1446
1456
|
] })
|
|
1447
1457
|
] }),
|
|
1448
1458
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("hr", { style: separator }),
|
|
@@ -1502,14 +1512,7 @@ function DauthProfileModal({
|
|
|
1502
1512
|
),
|
|
1503
1513
|
showRegister && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: registerPanel, children: [
|
|
1504
1514
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: fieldGroup, children: [
|
|
1505
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1506
|
-
"label",
|
|
1507
|
-
{
|
|
1508
|
-
htmlFor: "dauth-passkey-name",
|
|
1509
|
-
style: label,
|
|
1510
|
-
children: "Passkey name (optional)"
|
|
1511
|
-
}
|
|
1512
|
-
),
|
|
1515
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { htmlFor: "dauth-passkey-name", style: label, children: "Passkey name (optional)" }),
|
|
1513
1516
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1514
1517
|
"input",
|
|
1515
1518
|
{
|
|
@@ -1585,89 +1588,82 @@ function DauthProfileModal({
|
|
|
1585
1588
|
},
|
|
1586
1589
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Spinner, {})
|
|
1587
1590
|
}
|
|
1588
|
-
) : credentials.length > 0 ? credentials.map((cred) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
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
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconTrash, {})
|
|
1665
|
-
}
|
|
1666
|
-
)
|
|
1667
|
-
]
|
|
1668
|
-
},
|
|
1669
|
-
cred._id
|
|
1670
|
-
)) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: emptyState, children: [
|
|
1591
|
+
) : credentials.length > 0 ? credentials.map((cred) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: credentialRow, children: [
|
|
1592
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1593
|
+
"div",
|
|
1594
|
+
{
|
|
1595
|
+
style: {
|
|
1596
|
+
display: "flex",
|
|
1597
|
+
alignItems: "center",
|
|
1598
|
+
gap: 12,
|
|
1599
|
+
flex: 1,
|
|
1600
|
+
minWidth: 0
|
|
1601
|
+
},
|
|
1602
|
+
children: [
|
|
1603
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1604
|
+
"span",
|
|
1605
|
+
{
|
|
1606
|
+
style: {
|
|
1607
|
+
color: "var(--dauth-accent, #6366f1)",
|
|
1608
|
+
flexShrink: 0
|
|
1609
|
+
},
|
|
1610
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconFingerprint, {})
|
|
1611
|
+
}
|
|
1612
|
+
),
|
|
1613
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1614
|
+
"div",
|
|
1615
|
+
{
|
|
1616
|
+
style: {
|
|
1617
|
+
minWidth: 0,
|
|
1618
|
+
flex: 1
|
|
1619
|
+
},
|
|
1620
|
+
children: [
|
|
1621
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1622
|
+
"div",
|
|
1623
|
+
{
|
|
1624
|
+
style: {
|
|
1625
|
+
fontSize: "var(--dauth-font-size-sm, 0.875rem)",
|
|
1626
|
+
fontWeight: 500,
|
|
1627
|
+
color: "var(--dauth-text-primary, #e4e4e7)",
|
|
1628
|
+
overflow: "hidden",
|
|
1629
|
+
textOverflow: "ellipsis",
|
|
1630
|
+
whiteSpace: "nowrap"
|
|
1631
|
+
},
|
|
1632
|
+
children: cred.name || "Passkey"
|
|
1633
|
+
}
|
|
1634
|
+
),
|
|
1635
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1636
|
+
"div",
|
|
1637
|
+
{
|
|
1638
|
+
style: {
|
|
1639
|
+
fontSize: "var(--dauth-font-size-xs, 0.75rem)",
|
|
1640
|
+
color: "var(--dauth-text-muted, #71717a)"
|
|
1641
|
+
},
|
|
1642
|
+
children: [
|
|
1643
|
+
cred.deviceType === "multiDevice" ? "Synced" : "Device-bound",
|
|
1644
|
+
cred.createdAt && ` \xB7 Created ${new Date(cred.createdAt).toLocaleDateString()}`
|
|
1645
|
+
]
|
|
1646
|
+
}
|
|
1647
|
+
)
|
|
1648
|
+
]
|
|
1649
|
+
}
|
|
1650
|
+
)
|
|
1651
|
+
]
|
|
1652
|
+
}
|
|
1653
|
+
),
|
|
1654
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1655
|
+
"button",
|
|
1656
|
+
{
|
|
1657
|
+
type: "button",
|
|
1658
|
+
onClick: () => handleDeletePasskey(cred._id),
|
|
1659
|
+
style: trashBtn,
|
|
1660
|
+
onMouseEnter: (e) => e.currentTarget.style.color = "var(--dauth-error, #ef4444)",
|
|
1661
|
+
onMouseLeave: (e) => e.currentTarget.style.color = "var(--dauth-text-muted, #71717a)",
|
|
1662
|
+
"aria-label": `Delete passkey ${cred.name || ""}`,
|
|
1663
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconTrash, {})
|
|
1664
|
+
}
|
|
1665
|
+
)
|
|
1666
|
+
] }, cred._id)) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: emptyState, children: [
|
|
1671
1667
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1672
1668
|
"span",
|
|
1673
1669
|
{
|
|
@@ -2275,6 +2271,10 @@ var DauthProvider = (props) => {
|
|
|
2275
2271
|
(file) => uploadAvatarAction(ctx, file),
|
|
2276
2272
|
[ctx]
|
|
2277
2273
|
);
|
|
2274
|
+
const loginWithPasskey = (0, import_react2.useCallback)(
|
|
2275
|
+
() => loginWithPasskeyAction(ctx),
|
|
2276
|
+
[ctx]
|
|
2277
|
+
);
|
|
2278
2278
|
const memoProvider = (0, import_react2.useMemo)(
|
|
2279
2279
|
() => ({
|
|
2280
2280
|
...dauthState,
|
|
@@ -2285,7 +2285,8 @@ var DauthProvider = (props) => {
|
|
|
2285
2285
|
getPasskeyCredentials,
|
|
2286
2286
|
registerPasskey,
|
|
2287
2287
|
deletePasskeyCredential,
|
|
2288
|
-
uploadAvatar
|
|
2288
|
+
uploadAvatar,
|
|
2289
|
+
loginWithPasskey
|
|
2289
2290
|
}),
|
|
2290
2291
|
[
|
|
2291
2292
|
dauthState,
|
|
@@ -2296,7 +2297,8 @@ var DauthProvider = (props) => {
|
|
|
2296
2297
|
getPasskeyCredentials,
|
|
2297
2298
|
registerPasskey,
|
|
2298
2299
|
deletePasskeyCredential,
|
|
2299
|
-
uploadAvatar
|
|
2300
|
+
uploadAvatar,
|
|
2301
|
+
loginWithPasskey
|
|
2300
2302
|
]
|
|
2301
2303
|
);
|
|
2302
2304
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(DauthContext.Provider, { value: memoProvider, children });
|