dauth-context-react 6.4.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 +4 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +297 -290
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +297 -290
- 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 +13 -0
- package/src/initialDauthState.ts +2 -0
- package/src/interfaces.ts +6 -6
- package/src/reducer/dauth.actions.ts +85 -28
- package/src/webauthn.ts +62 -32
package/dist/index.mjs
CHANGED
|
@@ -11,7 +11,8 @@ import {
|
|
|
11
11
|
// src/initialDauthState.ts
|
|
12
12
|
var initialDauthState = {
|
|
13
13
|
user: {
|
|
14
|
-
language: (typeof window !== "undefined" ? window.document.documentElement.getAttribute("lang") : null) || "es"
|
|
14
|
+
language: (typeof window !== "undefined" ? window.document.documentElement.getAttribute("lang") : null) || "es",
|
|
15
|
+
theme: "system"
|
|
15
16
|
},
|
|
16
17
|
domain: {},
|
|
17
18
|
isLoading: true,
|
|
@@ -25,7 +26,8 @@ var initialDauthState = {
|
|
|
25
26
|
getPasskeyCredentials: () => Promise.resolve([]),
|
|
26
27
|
registerPasskey: () => Promise.resolve(null),
|
|
27
28
|
deletePasskeyCredential: () => Promise.resolve(false),
|
|
28
|
-
uploadAvatar: () => Promise.resolve(false)
|
|
29
|
+
uploadAvatar: () => Promise.resolve(false),
|
|
30
|
+
loginWithPasskey: () => Promise.resolve(false)
|
|
29
31
|
};
|
|
30
32
|
var initialDauthState_default = initialDauthState;
|
|
31
33
|
|
|
@@ -133,45 +135,59 @@ async function deleteAccountAPI(basePath) {
|
|
|
133
135
|
return { response, data };
|
|
134
136
|
}
|
|
135
137
|
async function getPasskeyCredentialsAPI(basePath) {
|
|
136
|
-
const response = await fetch(
|
|
137
|
-
|
|
138
|
-
{
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
credentials: "include"
|
|
142
|
-
}
|
|
143
|
-
);
|
|
138
|
+
const response = await fetch(`${basePath}/passkey/credentials`, {
|
|
139
|
+
method: "GET",
|
|
140
|
+
headers: { "X-CSRF-Token": getCsrfToken() },
|
|
141
|
+
credentials: "include"
|
|
142
|
+
});
|
|
144
143
|
const data = await response.json();
|
|
145
144
|
return { response, data };
|
|
146
145
|
}
|
|
147
146
|
async function startPasskeyRegistrationAPI(basePath) {
|
|
148
|
-
const response = await fetch(
|
|
149
|
-
|
|
150
|
-
{
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
credentials: "include"
|
|
157
|
-
}
|
|
158
|
-
);
|
|
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
|
+
});
|
|
159
155
|
const data = await response.json();
|
|
160
156
|
return { response, data };
|
|
161
157
|
}
|
|
162
158
|
async function finishPasskeyRegistrationAPI(basePath, body) {
|
|
163
|
-
const response = await fetch(
|
|
164
|
-
|
|
165
|
-
{
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
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
|
+
});
|
|
175
191
|
const data = await response.json();
|
|
176
192
|
return { response, data };
|
|
177
193
|
}
|
|
@@ -223,17 +239,16 @@ function bufferToBase64url(buffer) {
|
|
|
223
239
|
async function createPasskeyCredential(options) {
|
|
224
240
|
const publicKey = {
|
|
225
241
|
...options,
|
|
242
|
+
rp: { ...options.rp, id: window.location.hostname },
|
|
226
243
|
challenge: base64urlToBuffer(options.challenge),
|
|
227
244
|
user: {
|
|
228
245
|
...options.user,
|
|
229
246
|
id: base64urlToBuffer(options.user.id)
|
|
230
247
|
},
|
|
231
|
-
excludeCredentials: (options.excludeCredentials ?? []).map(
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
})
|
|
236
|
-
)
|
|
248
|
+
excludeCredentials: (options.excludeCredentials ?? []).map((c) => ({
|
|
249
|
+
...c,
|
|
250
|
+
id: base64urlToBuffer(c.id)
|
|
251
|
+
}))
|
|
237
252
|
};
|
|
238
253
|
const credential = await navigator.credentials.create({
|
|
239
254
|
publicKey
|
|
@@ -247,20 +262,14 @@ async function createPasskeyCredential(options) {
|
|
|
247
262
|
rawId: bufferToBase64url(credential.rawId),
|
|
248
263
|
type: credential.type,
|
|
249
264
|
response: {
|
|
250
|
-
clientDataJSON: bufferToBase64url(
|
|
251
|
-
|
|
252
|
-
),
|
|
253
|
-
attestationObject: bufferToBase64url(
|
|
254
|
-
attestation.attestationObject
|
|
255
|
-
),
|
|
265
|
+
clientDataJSON: bufferToBase64url(attestation.clientDataJSON),
|
|
266
|
+
attestationObject: bufferToBase64url(attestation.attestationObject),
|
|
256
267
|
...attestation.getTransports ? { transports: attestation.getTransports() } : {},
|
|
257
268
|
...attestation.getPublicKeyAlgorithm ? {
|
|
258
269
|
publicKeyAlgorithm: attestation.getPublicKeyAlgorithm()
|
|
259
270
|
} : {},
|
|
260
271
|
...attestation.getPublicKey ? {
|
|
261
|
-
publicKey: bufferToBase64url(
|
|
262
|
-
attestation.getPublicKey()
|
|
263
|
-
)
|
|
272
|
+
publicKey: bufferToBase64url(attestation.getPublicKey())
|
|
264
273
|
} : {},
|
|
265
274
|
...attestation.getAuthenticatorData ? {
|
|
266
275
|
authenticatorData: bufferToBase64url(
|
|
@@ -272,6 +281,38 @@ async function createPasskeyCredential(options) {
|
|
|
272
281
|
authenticatorAttachment: credential.authenticatorAttachment ?? void 0
|
|
273
282
|
};
|
|
274
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
|
+
}
|
|
275
316
|
|
|
276
317
|
// src/reducer/dauth.actions.ts
|
|
277
318
|
async function exchangeCodeAction(ctx, code) {
|
|
@@ -418,19 +459,15 @@ async function registerPasskeyAction(ctx, name) {
|
|
|
418
459
|
onError(new Error("Failed to start passkey registration"));
|
|
419
460
|
return null;
|
|
420
461
|
}
|
|
421
|
-
const credential = await createPasskeyCredential(
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
{ credential, name }
|
|
427
|
-
);
|
|
462
|
+
const credential = await createPasskeyCredential(startResult.data);
|
|
463
|
+
const finishResult = await finishPasskeyRegistrationAPI(authProxyPath, {
|
|
464
|
+
credential,
|
|
465
|
+
name
|
|
466
|
+
});
|
|
428
467
|
if (finishResult.response.status === 200 || finishResult.response.status === 201) {
|
|
429
468
|
return finishResult.data.credential;
|
|
430
469
|
}
|
|
431
|
-
onError(
|
|
432
|
-
new Error("Failed to finish passkey registration")
|
|
433
|
-
);
|
|
470
|
+
onError(new Error("Failed to finish passkey registration"));
|
|
434
471
|
return null;
|
|
435
472
|
} catch (error) {
|
|
436
473
|
onError(
|
|
@@ -448,9 +485,7 @@ async function deletePasskeyCredentialAction(ctx, credentialId) {
|
|
|
448
485
|
);
|
|
449
486
|
return result.response.status === 200;
|
|
450
487
|
} catch (error) {
|
|
451
|
-
onError(
|
|
452
|
-
error instanceof Error ? error : new Error("Delete passkey error")
|
|
453
|
-
);
|
|
488
|
+
onError(error instanceof Error ? error : new Error("Delete passkey error"));
|
|
454
489
|
return false;
|
|
455
490
|
}
|
|
456
491
|
}
|
|
@@ -465,16 +500,69 @@ async function uploadAvatarAction(ctx, file) {
|
|
|
465
500
|
});
|
|
466
501
|
return true;
|
|
467
502
|
}
|
|
468
|
-
onError(
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
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
|
|
472
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
|
+
});
|
|
473
557
|
return false;
|
|
474
558
|
} catch (error) {
|
|
475
559
|
onError(
|
|
476
|
-
error instanceof Error ? error : new Error("
|
|
560
|
+
error instanceof Error ? error : new Error("Passkey authentication error")
|
|
477
561
|
);
|
|
562
|
+
dispatch({
|
|
563
|
+
type: SET_IS_LOADING,
|
|
564
|
+
payload: { isLoading: false }
|
|
565
|
+
});
|
|
478
566
|
return false;
|
|
479
567
|
}
|
|
480
568
|
}
|
|
@@ -498,13 +586,7 @@ function setDauthUrl(url) {
|
|
|
498
586
|
function checkIsLocalhost() {
|
|
499
587
|
if (typeof window === "undefined") return false;
|
|
500
588
|
const hostname = window.location.hostname;
|
|
501
|
-
return hostname === "localhost" || hostname === "[::1]" || /^127(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d\d?)){3}$/.test(
|
|
502
|
-
hostname
|
|
503
|
-
) || /^192\.168(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d\d?)){2}$/.test(
|
|
504
|
-
hostname
|
|
505
|
-
) || /^10(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d\d?)){3}$/.test(
|
|
506
|
-
hostname
|
|
507
|
-
);
|
|
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);
|
|
508
590
|
}
|
|
509
591
|
function getClientBasePath() {
|
|
510
592
|
if (_dauthUrl) return _dauthUrl;
|
|
@@ -703,10 +785,7 @@ function useModalAnimation(open) {
|
|
|
703
785
|
}
|
|
704
786
|
if (phase === "entered" || phase === "entering") {
|
|
705
787
|
setPhase("exiting");
|
|
706
|
-
const timer = setTimeout(
|
|
707
|
-
() => setPhase("exited"),
|
|
708
|
-
MOBILE_TRANSITION_MS
|
|
709
|
-
);
|
|
788
|
+
const timer = setTimeout(() => setPhase("exited"), MOBILE_TRANSITION_MS);
|
|
710
789
|
return () => clearTimeout(timer);
|
|
711
790
|
}
|
|
712
791
|
return void 0;
|
|
@@ -856,18 +935,12 @@ function DauthProfileModal({
|
|
|
856
935
|
}, [activeTab, showSecurity, getPasskeyCredentials]);
|
|
857
936
|
useEffect(() => {
|
|
858
937
|
if (status?.type !== "success") return;
|
|
859
|
-
const timer = setTimeout(
|
|
860
|
-
() => setStatus(null),
|
|
861
|
-
SUCCESS_TIMEOUT_MS
|
|
862
|
-
);
|
|
938
|
+
const timer = setTimeout(() => setStatus(null), SUCCESS_TIMEOUT_MS);
|
|
863
939
|
return () => clearTimeout(timer);
|
|
864
940
|
}, [status]);
|
|
865
941
|
useEffect(() => {
|
|
866
942
|
if (passkeyStatus?.type !== "success") return;
|
|
867
|
-
const timer = setTimeout(
|
|
868
|
-
() => setPasskeyStatus(null),
|
|
869
|
-
SUCCESS_TIMEOUT_MS
|
|
870
|
-
);
|
|
943
|
+
const timer = setTimeout(() => setPasskeyStatus(null), SUCCESS_TIMEOUT_MS);
|
|
871
944
|
return () => clearTimeout(timer);
|
|
872
945
|
}, [passkeyStatus]);
|
|
873
946
|
useFocusTrap(modalRef, phase === "entered", onClose);
|
|
@@ -907,12 +980,9 @@ function DauthProfileModal({
|
|
|
907
980
|
if (hasField("lastname")) fields.lastname = lastname;
|
|
908
981
|
if (hasField("nickname")) fields.nickname = nickname;
|
|
909
982
|
if (hasField("country")) fields.country = country;
|
|
910
|
-
if (hasField("tel_prefix"))
|
|
911
|
-
|
|
912
|
-
if (hasField("
|
|
913
|
-
fields.telSuffix = telSuffix;
|
|
914
|
-
if (hasField("birth_date") && birthDate)
|
|
915
|
-
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;
|
|
916
986
|
if ((domain.customFields ?? []).length > 0)
|
|
917
987
|
fields.customFields = customFieldValues;
|
|
918
988
|
const ok = await updateUser(fields);
|
|
@@ -965,9 +1035,7 @@ function DauthProfileModal({
|
|
|
965
1035
|
const handleRegisterPasskey = useCallback(async () => {
|
|
966
1036
|
setRegistering(true);
|
|
967
1037
|
setPasskeyStatus(null);
|
|
968
|
-
const cred = await registerPasskey(
|
|
969
|
-
passkeyName || void 0
|
|
970
|
-
);
|
|
1038
|
+
const cred = await registerPasskey(passkeyName || void 0);
|
|
971
1039
|
setRegistering(false);
|
|
972
1040
|
if (cred) {
|
|
973
1041
|
setCredentials((prev) => [...prev, cred]);
|
|
@@ -988,9 +1056,7 @@ function DauthProfileModal({
|
|
|
988
1056
|
async (credentialId) => {
|
|
989
1057
|
const ok = await deletePasskeyCredential(credentialId);
|
|
990
1058
|
if (ok) {
|
|
991
|
-
setCredentials(
|
|
992
|
-
(prev) => prev.filter((c) => c._id !== credentialId)
|
|
993
|
-
);
|
|
1059
|
+
setCredentials((prev) => prev.filter((c) => c._id !== credentialId));
|
|
994
1060
|
}
|
|
995
1061
|
},
|
|
996
1062
|
[deletePasskeyCredential]
|
|
@@ -1030,15 +1096,11 @@ function DauthProfileModal({
|
|
|
1030
1096
|
if (!t) return {};
|
|
1031
1097
|
const vars = {};
|
|
1032
1098
|
if (t.accent) vars["--dauth-accent"] = t.accent;
|
|
1033
|
-
if (t.accentHover)
|
|
1034
|
-
vars["--dauth-accent-hover"] = t.accentHover;
|
|
1099
|
+
if (t.accentHover) vars["--dauth-accent-hover"] = t.accentHover;
|
|
1035
1100
|
if (t.surface) vars["--dauth-surface"] = t.surface;
|
|
1036
|
-
if (t.surfaceHover)
|
|
1037
|
-
|
|
1038
|
-
if (t.
|
|
1039
|
-
vars["--dauth-text-primary"] = t.textPrimary;
|
|
1040
|
-
if (t.textSecondary)
|
|
1041
|
-
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;
|
|
1042
1104
|
if (t.border) vars["--dauth-border"] = t.border;
|
|
1043
1105
|
return vars;
|
|
1044
1106
|
}, [domain.modalTheme]);
|
|
@@ -1205,14 +1267,7 @@ function DauthProfileModal({
|
|
|
1205
1267
|
),
|
|
1206
1268
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
1207
1269
|
/* @__PURE__ */ jsxs("div", { style: fieldGroup, children: [
|
|
1208
|
-
/* @__PURE__ */ jsx(
|
|
1209
|
-
"label",
|
|
1210
|
-
{
|
|
1211
|
-
htmlFor: "dauth-name",
|
|
1212
|
-
style: label,
|
|
1213
|
-
children: "Name *"
|
|
1214
|
-
}
|
|
1215
|
-
),
|
|
1270
|
+
/* @__PURE__ */ jsx("label", { htmlFor: "dauth-name", style: label, children: "Name *" }),
|
|
1216
1271
|
/* @__PURE__ */ jsx(
|
|
1217
1272
|
"input",
|
|
1218
1273
|
{
|
|
@@ -1229,17 +1284,10 @@ function DauthProfileModal({
|
|
|
1229
1284
|
)
|
|
1230
1285
|
] }),
|
|
1231
1286
|
hasField("lastname") && /* @__PURE__ */ jsxs("div", { style: fieldGroup, children: [
|
|
1232
|
-
/* @__PURE__ */ jsxs(
|
|
1233
|
-
"
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
style: label,
|
|
1237
|
-
children: [
|
|
1238
|
-
"Last name",
|
|
1239
|
-
isRequired("lastname") ? " *" : ""
|
|
1240
|
-
]
|
|
1241
|
-
}
|
|
1242
|
-
),
|
|
1287
|
+
/* @__PURE__ */ jsxs("label", { htmlFor: "dauth-lastname", style: label, children: [
|
|
1288
|
+
"Last name",
|
|
1289
|
+
isRequired("lastname") ? " *" : ""
|
|
1290
|
+
] }),
|
|
1243
1291
|
/* @__PURE__ */ jsx(
|
|
1244
1292
|
"input",
|
|
1245
1293
|
{
|
|
@@ -1256,17 +1304,10 @@ function DauthProfileModal({
|
|
|
1256
1304
|
)
|
|
1257
1305
|
] }),
|
|
1258
1306
|
hasField("nickname") && /* @__PURE__ */ jsxs("div", { style: fieldGroup, children: [
|
|
1259
|
-
/* @__PURE__ */ jsxs(
|
|
1260
|
-
"
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
style: label,
|
|
1264
|
-
children: [
|
|
1265
|
-
"Nickname",
|
|
1266
|
-
isRequired("nickname") ? " *" : ""
|
|
1267
|
-
]
|
|
1268
|
-
}
|
|
1269
|
-
),
|
|
1307
|
+
/* @__PURE__ */ jsxs("label", { htmlFor: "dauth-nickname", style: label, children: [
|
|
1308
|
+
"Nickname",
|
|
1309
|
+
isRequired("nickname") ? " *" : ""
|
|
1310
|
+
] }),
|
|
1270
1311
|
/* @__PURE__ */ jsx(
|
|
1271
1312
|
"input",
|
|
1272
1313
|
{
|
|
@@ -1283,17 +1324,10 @@ function DauthProfileModal({
|
|
|
1283
1324
|
)
|
|
1284
1325
|
] }),
|
|
1285
1326
|
hasField("country") && /* @__PURE__ */ jsxs("div", { style: fieldGroup, children: [
|
|
1286
|
-
/* @__PURE__ */ jsxs(
|
|
1287
|
-
"
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
style: label,
|
|
1291
|
-
children: [
|
|
1292
|
-
"Country",
|
|
1293
|
-
isRequired("country") ? " *" : ""
|
|
1294
|
-
]
|
|
1295
|
-
}
|
|
1296
|
-
),
|
|
1327
|
+
/* @__PURE__ */ jsxs("label", { htmlFor: "dauth-country", style: label, children: [
|
|
1328
|
+
"Country",
|
|
1329
|
+
isRequired("country") ? " *" : ""
|
|
1330
|
+
] }),
|
|
1297
1331
|
/* @__PURE__ */ jsx(
|
|
1298
1332
|
"input",
|
|
1299
1333
|
{
|
|
@@ -1364,17 +1398,10 @@ function DauthProfileModal({
|
|
|
1364
1398
|
)
|
|
1365
1399
|
] }),
|
|
1366
1400
|
hasField("birth_date") && /* @__PURE__ */ jsxs("div", { style: fieldGroup, children: [
|
|
1367
|
-
/* @__PURE__ */ jsxs(
|
|
1368
|
-
"
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
style: label,
|
|
1372
|
-
children: [
|
|
1373
|
-
"Birth date",
|
|
1374
|
-
isRequired("birth_date") ? " *" : ""
|
|
1375
|
-
]
|
|
1376
|
-
}
|
|
1377
|
-
),
|
|
1401
|
+
/* @__PURE__ */ jsxs("label", { htmlFor: "dauth-birthdate", style: label, children: [
|
|
1402
|
+
"Birth date",
|
|
1403
|
+
isRequired("birth_date") ? " *" : ""
|
|
1404
|
+
] }),
|
|
1378
1405
|
/* @__PURE__ */ jsx(
|
|
1379
1406
|
"input",
|
|
1380
1407
|
{
|
|
@@ -1391,44 +1418,28 @@ function DauthProfileModal({
|
|
|
1391
1418
|
] }),
|
|
1392
1419
|
(domain.customFields ?? []).length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1393
1420
|
/* @__PURE__ */ jsx("hr", { style: separator }),
|
|
1394
|
-
domain.customFields.map((cf) => /* @__PURE__ */ jsxs(
|
|
1395
|
-
"
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
onChange: (e) => setCustomFieldValues(
|
|
1417
|
-
(prev) => ({
|
|
1418
|
-
...prev,
|
|
1419
|
-
[cf.key]: e.target.value
|
|
1420
|
-
})
|
|
1421
|
-
),
|
|
1422
|
-
disabled: saving,
|
|
1423
|
-
style: input,
|
|
1424
|
-
onFocus: inputFocusHandler,
|
|
1425
|
-
onBlur: inputBlurHandler
|
|
1426
|
-
}
|
|
1427
|
-
)
|
|
1428
|
-
]
|
|
1429
|
-
},
|
|
1430
|
-
cf.key
|
|
1431
|
-
))
|
|
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))
|
|
1432
1443
|
] })
|
|
1433
1444
|
] }),
|
|
1434
1445
|
/* @__PURE__ */ jsx("hr", { style: separator }),
|
|
@@ -1488,14 +1499,7 @@ function DauthProfileModal({
|
|
|
1488
1499
|
),
|
|
1489
1500
|
showRegister && /* @__PURE__ */ jsxs("div", { style: registerPanel, children: [
|
|
1490
1501
|
/* @__PURE__ */ jsxs("div", { style: fieldGroup, children: [
|
|
1491
|
-
/* @__PURE__ */ jsx(
|
|
1492
|
-
"label",
|
|
1493
|
-
{
|
|
1494
|
-
htmlFor: "dauth-passkey-name",
|
|
1495
|
-
style: label,
|
|
1496
|
-
children: "Passkey name (optional)"
|
|
1497
|
-
}
|
|
1498
|
-
),
|
|
1502
|
+
/* @__PURE__ */ jsx("label", { htmlFor: "dauth-passkey-name", style: label, children: "Passkey name (optional)" }),
|
|
1499
1503
|
/* @__PURE__ */ jsx(
|
|
1500
1504
|
"input",
|
|
1501
1505
|
{
|
|
@@ -1571,89 +1575,82 @@ function DauthProfileModal({
|
|
|
1571
1575
|
},
|
|
1572
1576
|
children: /* @__PURE__ */ jsx(Spinner, {})
|
|
1573
1577
|
}
|
|
1574
|
-
) : credentials.length > 0 ? credentials.map((cred) => /* @__PURE__ */ jsxs(
|
|
1575
|
-
|
|
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
|
-
children: /* @__PURE__ */ jsx(IconTrash, {})
|
|
1651
|
-
}
|
|
1652
|
-
)
|
|
1653
|
-
]
|
|
1654
|
-
},
|
|
1655
|
-
cred._id
|
|
1656
|
-
)) : /* @__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: [
|
|
1657
1654
|
/* @__PURE__ */ jsx(
|
|
1658
1655
|
"span",
|
|
1659
1656
|
{
|
|
@@ -2216,10 +2213,12 @@ var DauthProvider = (props) => {
|
|
|
2216
2213
|
telPrefix,
|
|
2217
2214
|
telSuffix,
|
|
2218
2215
|
language,
|
|
2216
|
+
theme,
|
|
2219
2217
|
avatar,
|
|
2220
2218
|
birthDate,
|
|
2221
2219
|
country,
|
|
2222
|
-
metadata
|
|
2220
|
+
metadata,
|
|
2221
|
+
customFields
|
|
2223
2222
|
} = fields;
|
|
2224
2223
|
const user = {
|
|
2225
2224
|
name,
|
|
@@ -2228,10 +2227,12 @@ var DauthProvider = (props) => {
|
|
|
2228
2227
|
telPrefix,
|
|
2229
2228
|
telSuffix,
|
|
2230
2229
|
language,
|
|
2230
|
+
theme,
|
|
2231
2231
|
avatar,
|
|
2232
2232
|
birthDate,
|
|
2233
2233
|
country,
|
|
2234
|
-
metadata
|
|
2234
|
+
metadata,
|
|
2235
|
+
customFields
|
|
2235
2236
|
};
|
|
2236
2237
|
return updateUserAction(ctx, user);
|
|
2237
2238
|
},
|
|
@@ -2257,6 +2258,10 @@ var DauthProvider = (props) => {
|
|
|
2257
2258
|
(file) => uploadAvatarAction(ctx, file),
|
|
2258
2259
|
[ctx]
|
|
2259
2260
|
);
|
|
2261
|
+
const loginWithPasskey = useCallback2(
|
|
2262
|
+
() => loginWithPasskeyAction(ctx),
|
|
2263
|
+
[ctx]
|
|
2264
|
+
);
|
|
2260
2265
|
const memoProvider = useMemo2(
|
|
2261
2266
|
() => ({
|
|
2262
2267
|
...dauthState,
|
|
@@ -2267,7 +2272,8 @@ var DauthProvider = (props) => {
|
|
|
2267
2272
|
getPasskeyCredentials,
|
|
2268
2273
|
registerPasskey,
|
|
2269
2274
|
deletePasskeyCredential,
|
|
2270
|
-
uploadAvatar
|
|
2275
|
+
uploadAvatar,
|
|
2276
|
+
loginWithPasskey
|
|
2271
2277
|
}),
|
|
2272
2278
|
[
|
|
2273
2279
|
dauthState,
|
|
@@ -2278,7 +2284,8 @@ var DauthProvider = (props) => {
|
|
|
2278
2284
|
getPasskeyCredentials,
|
|
2279
2285
|
registerPasskey,
|
|
2280
2286
|
deletePasskeyCredential,
|
|
2281
|
-
uploadAvatar
|
|
2287
|
+
uploadAvatar,
|
|
2288
|
+
loginWithPasskey
|
|
2282
2289
|
]
|
|
2283
2290
|
);
|
|
2284
2291
|
return /* @__PURE__ */ jsx2(DauthContext.Provider, { value: memoProvider, children });
|