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.js
CHANGED
|
@@ -30,7 +30,8 @@ var import_react2 = require("react");
|
|
|
30
30
|
// src/initialDauthState.ts
|
|
31
31
|
var initialDauthState = {
|
|
32
32
|
user: {
|
|
33
|
-
language: (typeof window !== "undefined" ? window.document.documentElement.getAttribute("lang") : null) || "es"
|
|
33
|
+
language: (typeof window !== "undefined" ? window.document.documentElement.getAttribute("lang") : null) || "es",
|
|
34
|
+
theme: "system"
|
|
34
35
|
},
|
|
35
36
|
domain: {},
|
|
36
37
|
isLoading: true,
|
|
@@ -44,7 +45,8 @@ var initialDauthState = {
|
|
|
44
45
|
getPasskeyCredentials: () => Promise.resolve([]),
|
|
45
46
|
registerPasskey: () => Promise.resolve(null),
|
|
46
47
|
deletePasskeyCredential: () => Promise.resolve(false),
|
|
47
|
-
uploadAvatar: () => Promise.resolve(false)
|
|
48
|
+
uploadAvatar: () => Promise.resolve(false),
|
|
49
|
+
loginWithPasskey: () => Promise.resolve(false)
|
|
48
50
|
};
|
|
49
51
|
var initialDauthState_default = initialDauthState;
|
|
50
52
|
|
|
@@ -152,45 +154,59 @@ async function deleteAccountAPI(basePath) {
|
|
|
152
154
|
return { response, data };
|
|
153
155
|
}
|
|
154
156
|
async function getPasskeyCredentialsAPI(basePath) {
|
|
155
|
-
const response = await fetch(
|
|
156
|
-
|
|
157
|
-
{
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
credentials: "include"
|
|
161
|
-
}
|
|
162
|
-
);
|
|
157
|
+
const response = await fetch(`${basePath}/passkey/credentials`, {
|
|
158
|
+
method: "GET",
|
|
159
|
+
headers: { "X-CSRF-Token": getCsrfToken() },
|
|
160
|
+
credentials: "include"
|
|
161
|
+
});
|
|
163
162
|
const data = await response.json();
|
|
164
163
|
return { response, data };
|
|
165
164
|
}
|
|
166
165
|
async function startPasskeyRegistrationAPI(basePath) {
|
|
167
|
-
const response = await fetch(
|
|
168
|
-
|
|
169
|
-
{
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
credentials: "include"
|
|
176
|
-
}
|
|
177
|
-
);
|
|
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
|
+
});
|
|
178
174
|
const data = await response.json();
|
|
179
175
|
return { response, data };
|
|
180
176
|
}
|
|
181
177
|
async function finishPasskeyRegistrationAPI(basePath, body) {
|
|
182
|
-
const response = await fetch(
|
|
183
|
-
|
|
184
|
-
{
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
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
|
+
});
|
|
194
210
|
const data = await response.json();
|
|
195
211
|
return { response, data };
|
|
196
212
|
}
|
|
@@ -242,17 +258,16 @@ function bufferToBase64url(buffer) {
|
|
|
242
258
|
async function createPasskeyCredential(options) {
|
|
243
259
|
const publicKey = {
|
|
244
260
|
...options,
|
|
261
|
+
rp: { ...options.rp, id: window.location.hostname },
|
|
245
262
|
challenge: base64urlToBuffer(options.challenge),
|
|
246
263
|
user: {
|
|
247
264
|
...options.user,
|
|
248
265
|
id: base64urlToBuffer(options.user.id)
|
|
249
266
|
},
|
|
250
|
-
excludeCredentials: (options.excludeCredentials ?? []).map(
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
})
|
|
255
|
-
)
|
|
267
|
+
excludeCredentials: (options.excludeCredentials ?? []).map((c) => ({
|
|
268
|
+
...c,
|
|
269
|
+
id: base64urlToBuffer(c.id)
|
|
270
|
+
}))
|
|
256
271
|
};
|
|
257
272
|
const credential = await navigator.credentials.create({
|
|
258
273
|
publicKey
|
|
@@ -266,20 +281,14 @@ async function createPasskeyCredential(options) {
|
|
|
266
281
|
rawId: bufferToBase64url(credential.rawId),
|
|
267
282
|
type: credential.type,
|
|
268
283
|
response: {
|
|
269
|
-
clientDataJSON: bufferToBase64url(
|
|
270
|
-
|
|
271
|
-
),
|
|
272
|
-
attestationObject: bufferToBase64url(
|
|
273
|
-
attestation.attestationObject
|
|
274
|
-
),
|
|
284
|
+
clientDataJSON: bufferToBase64url(attestation.clientDataJSON),
|
|
285
|
+
attestationObject: bufferToBase64url(attestation.attestationObject),
|
|
275
286
|
...attestation.getTransports ? { transports: attestation.getTransports() } : {},
|
|
276
287
|
...attestation.getPublicKeyAlgorithm ? {
|
|
277
288
|
publicKeyAlgorithm: attestation.getPublicKeyAlgorithm()
|
|
278
289
|
} : {},
|
|
279
290
|
...attestation.getPublicKey ? {
|
|
280
|
-
publicKey: bufferToBase64url(
|
|
281
|
-
attestation.getPublicKey()
|
|
282
|
-
)
|
|
291
|
+
publicKey: bufferToBase64url(attestation.getPublicKey())
|
|
283
292
|
} : {},
|
|
284
293
|
...attestation.getAuthenticatorData ? {
|
|
285
294
|
authenticatorData: bufferToBase64url(
|
|
@@ -291,6 +300,38 @@ async function createPasskeyCredential(options) {
|
|
|
291
300
|
authenticatorAttachment: credential.authenticatorAttachment ?? void 0
|
|
292
301
|
};
|
|
293
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
|
+
}
|
|
294
335
|
|
|
295
336
|
// src/reducer/dauth.actions.ts
|
|
296
337
|
async function exchangeCodeAction(ctx, code) {
|
|
@@ -437,19 +478,15 @@ async function registerPasskeyAction(ctx, name) {
|
|
|
437
478
|
onError(new Error("Failed to start passkey registration"));
|
|
438
479
|
return null;
|
|
439
480
|
}
|
|
440
|
-
const credential = await createPasskeyCredential(
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
{ credential, name }
|
|
446
|
-
);
|
|
481
|
+
const credential = await createPasskeyCredential(startResult.data);
|
|
482
|
+
const finishResult = await finishPasskeyRegistrationAPI(authProxyPath, {
|
|
483
|
+
credential,
|
|
484
|
+
name
|
|
485
|
+
});
|
|
447
486
|
if (finishResult.response.status === 200 || finishResult.response.status === 201) {
|
|
448
487
|
return finishResult.data.credential;
|
|
449
488
|
}
|
|
450
|
-
onError(
|
|
451
|
-
new Error("Failed to finish passkey registration")
|
|
452
|
-
);
|
|
489
|
+
onError(new Error("Failed to finish passkey registration"));
|
|
453
490
|
return null;
|
|
454
491
|
} catch (error) {
|
|
455
492
|
onError(
|
|
@@ -467,9 +504,7 @@ async function deletePasskeyCredentialAction(ctx, credentialId) {
|
|
|
467
504
|
);
|
|
468
505
|
return result.response.status === 200;
|
|
469
506
|
} catch (error) {
|
|
470
|
-
onError(
|
|
471
|
-
error instanceof Error ? error : new Error("Delete passkey error")
|
|
472
|
-
);
|
|
507
|
+
onError(error instanceof Error ? error : new Error("Delete passkey error"));
|
|
473
508
|
return false;
|
|
474
509
|
}
|
|
475
510
|
}
|
|
@@ -484,16 +519,69 @@ async function uploadAvatarAction(ctx, file) {
|
|
|
484
519
|
});
|
|
485
520
|
return true;
|
|
486
521
|
}
|
|
487
|
-
onError(
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
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
|
|
491
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
|
+
});
|
|
492
576
|
return false;
|
|
493
577
|
} catch (error) {
|
|
494
578
|
onError(
|
|
495
|
-
error instanceof Error ? error : new Error("
|
|
579
|
+
error instanceof Error ? error : new Error("Passkey authentication error")
|
|
496
580
|
);
|
|
581
|
+
dispatch({
|
|
582
|
+
type: SET_IS_LOADING,
|
|
583
|
+
payload: { isLoading: false }
|
|
584
|
+
});
|
|
497
585
|
return false;
|
|
498
586
|
}
|
|
499
587
|
}
|
|
@@ -517,13 +605,7 @@ function setDauthUrl(url) {
|
|
|
517
605
|
function checkIsLocalhost() {
|
|
518
606
|
if (typeof window === "undefined") return false;
|
|
519
607
|
const hostname = window.location.hostname;
|
|
520
|
-
return hostname === "localhost" || hostname === "[::1]" || /^127(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d\d?)){3}$/.test(
|
|
521
|
-
hostname
|
|
522
|
-
) || /^192\.168(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d\d?)){2}$/.test(
|
|
523
|
-
hostname
|
|
524
|
-
) || /^10(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d\d?)){3}$/.test(
|
|
525
|
-
hostname
|
|
526
|
-
);
|
|
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);
|
|
527
609
|
}
|
|
528
610
|
function getClientBasePath() {
|
|
529
611
|
if (_dauthUrl) return _dauthUrl;
|
|
@@ -716,10 +798,7 @@ function useModalAnimation(open) {
|
|
|
716
798
|
}
|
|
717
799
|
if (phase === "entered" || phase === "entering") {
|
|
718
800
|
setPhase("exiting");
|
|
719
|
-
const timer = setTimeout(
|
|
720
|
-
() => setPhase("exited"),
|
|
721
|
-
MOBILE_TRANSITION_MS
|
|
722
|
-
);
|
|
801
|
+
const timer = setTimeout(() => setPhase("exited"), MOBILE_TRANSITION_MS);
|
|
723
802
|
return () => clearTimeout(timer);
|
|
724
803
|
}
|
|
725
804
|
return void 0;
|
|
@@ -869,18 +948,12 @@ function DauthProfileModal({
|
|
|
869
948
|
}, [activeTab, showSecurity, getPasskeyCredentials]);
|
|
870
949
|
(0, import_react.useEffect)(() => {
|
|
871
950
|
if (status?.type !== "success") return;
|
|
872
|
-
const timer = setTimeout(
|
|
873
|
-
() => setStatus(null),
|
|
874
|
-
SUCCESS_TIMEOUT_MS
|
|
875
|
-
);
|
|
951
|
+
const timer = setTimeout(() => setStatus(null), SUCCESS_TIMEOUT_MS);
|
|
876
952
|
return () => clearTimeout(timer);
|
|
877
953
|
}, [status]);
|
|
878
954
|
(0, import_react.useEffect)(() => {
|
|
879
955
|
if (passkeyStatus?.type !== "success") return;
|
|
880
|
-
const timer = setTimeout(
|
|
881
|
-
() => setPasskeyStatus(null),
|
|
882
|
-
SUCCESS_TIMEOUT_MS
|
|
883
|
-
);
|
|
956
|
+
const timer = setTimeout(() => setPasskeyStatus(null), SUCCESS_TIMEOUT_MS);
|
|
884
957
|
return () => clearTimeout(timer);
|
|
885
958
|
}, [passkeyStatus]);
|
|
886
959
|
useFocusTrap(modalRef, phase === "entered", onClose);
|
|
@@ -920,12 +993,9 @@ function DauthProfileModal({
|
|
|
920
993
|
if (hasField("lastname")) fields.lastname = lastname;
|
|
921
994
|
if (hasField("nickname")) fields.nickname = nickname;
|
|
922
995
|
if (hasField("country")) fields.country = country;
|
|
923
|
-
if (hasField("tel_prefix"))
|
|
924
|
-
|
|
925
|
-
if (hasField("
|
|
926
|
-
fields.telSuffix = telSuffix;
|
|
927
|
-
if (hasField("birth_date") && birthDate)
|
|
928
|
-
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;
|
|
929
999
|
if ((domain.customFields ?? []).length > 0)
|
|
930
1000
|
fields.customFields = customFieldValues;
|
|
931
1001
|
const ok = await updateUser(fields);
|
|
@@ -978,9 +1048,7 @@ function DauthProfileModal({
|
|
|
978
1048
|
const handleRegisterPasskey = (0, import_react.useCallback)(async () => {
|
|
979
1049
|
setRegistering(true);
|
|
980
1050
|
setPasskeyStatus(null);
|
|
981
|
-
const cred = await registerPasskey(
|
|
982
|
-
passkeyName || void 0
|
|
983
|
-
);
|
|
1051
|
+
const cred = await registerPasskey(passkeyName || void 0);
|
|
984
1052
|
setRegistering(false);
|
|
985
1053
|
if (cred) {
|
|
986
1054
|
setCredentials((prev) => [...prev, cred]);
|
|
@@ -1001,9 +1069,7 @@ function DauthProfileModal({
|
|
|
1001
1069
|
async (credentialId) => {
|
|
1002
1070
|
const ok = await deletePasskeyCredential(credentialId);
|
|
1003
1071
|
if (ok) {
|
|
1004
|
-
setCredentials(
|
|
1005
|
-
(prev) => prev.filter((c) => c._id !== credentialId)
|
|
1006
|
-
);
|
|
1072
|
+
setCredentials((prev) => prev.filter((c) => c._id !== credentialId));
|
|
1007
1073
|
}
|
|
1008
1074
|
},
|
|
1009
1075
|
[deletePasskeyCredential]
|
|
@@ -1043,15 +1109,11 @@ function DauthProfileModal({
|
|
|
1043
1109
|
if (!t) return {};
|
|
1044
1110
|
const vars = {};
|
|
1045
1111
|
if (t.accent) vars["--dauth-accent"] = t.accent;
|
|
1046
|
-
if (t.accentHover)
|
|
1047
|
-
vars["--dauth-accent-hover"] = t.accentHover;
|
|
1112
|
+
if (t.accentHover) vars["--dauth-accent-hover"] = t.accentHover;
|
|
1048
1113
|
if (t.surface) vars["--dauth-surface"] = t.surface;
|
|
1049
|
-
if (t.surfaceHover)
|
|
1050
|
-
|
|
1051
|
-
if (t.
|
|
1052
|
-
vars["--dauth-text-primary"] = t.textPrimary;
|
|
1053
|
-
if (t.textSecondary)
|
|
1054
|
-
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;
|
|
1055
1117
|
if (t.border) vars["--dauth-border"] = t.border;
|
|
1056
1118
|
return vars;
|
|
1057
1119
|
}, [domain.modalTheme]);
|
|
@@ -1218,14 +1280,7 @@ function DauthProfileModal({
|
|
|
1218
1280
|
),
|
|
1219
1281
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
1220
1282
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: fieldGroup, children: [
|
|
1221
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1222
|
-
"label",
|
|
1223
|
-
{
|
|
1224
|
-
htmlFor: "dauth-name",
|
|
1225
|
-
style: label,
|
|
1226
|
-
children: "Name *"
|
|
1227
|
-
}
|
|
1228
|
-
),
|
|
1283
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { htmlFor: "dauth-name", style: label, children: "Name *" }),
|
|
1229
1284
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1230
1285
|
"input",
|
|
1231
1286
|
{
|
|
@@ -1242,17 +1297,10 @@ function DauthProfileModal({
|
|
|
1242
1297
|
)
|
|
1243
1298
|
] }),
|
|
1244
1299
|
hasField("lastname") && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: fieldGroup, children: [
|
|
1245
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1246
|
-
"
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
style: label,
|
|
1250
|
-
children: [
|
|
1251
|
-
"Last name",
|
|
1252
|
-
isRequired("lastname") ? " *" : ""
|
|
1253
|
-
]
|
|
1254
|
-
}
|
|
1255
|
-
),
|
|
1300
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { htmlFor: "dauth-lastname", style: label, children: [
|
|
1301
|
+
"Last name",
|
|
1302
|
+
isRequired("lastname") ? " *" : ""
|
|
1303
|
+
] }),
|
|
1256
1304
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1257
1305
|
"input",
|
|
1258
1306
|
{
|
|
@@ -1269,17 +1317,10 @@ function DauthProfileModal({
|
|
|
1269
1317
|
)
|
|
1270
1318
|
] }),
|
|
1271
1319
|
hasField("nickname") && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: fieldGroup, children: [
|
|
1272
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1273
|
-
"
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
style: label,
|
|
1277
|
-
children: [
|
|
1278
|
-
"Nickname",
|
|
1279
|
-
isRequired("nickname") ? " *" : ""
|
|
1280
|
-
]
|
|
1281
|
-
}
|
|
1282
|
-
),
|
|
1320
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { htmlFor: "dauth-nickname", style: label, children: [
|
|
1321
|
+
"Nickname",
|
|
1322
|
+
isRequired("nickname") ? " *" : ""
|
|
1323
|
+
] }),
|
|
1283
1324
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1284
1325
|
"input",
|
|
1285
1326
|
{
|
|
@@ -1296,17 +1337,10 @@ function DauthProfileModal({
|
|
|
1296
1337
|
)
|
|
1297
1338
|
] }),
|
|
1298
1339
|
hasField("country") && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: fieldGroup, children: [
|
|
1299
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1300
|
-
"
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
style: label,
|
|
1304
|
-
children: [
|
|
1305
|
-
"Country",
|
|
1306
|
-
isRequired("country") ? " *" : ""
|
|
1307
|
-
]
|
|
1308
|
-
}
|
|
1309
|
-
),
|
|
1340
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { htmlFor: "dauth-country", style: label, children: [
|
|
1341
|
+
"Country",
|
|
1342
|
+
isRequired("country") ? " *" : ""
|
|
1343
|
+
] }),
|
|
1310
1344
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1311
1345
|
"input",
|
|
1312
1346
|
{
|
|
@@ -1377,17 +1411,10 @@ function DauthProfileModal({
|
|
|
1377
1411
|
)
|
|
1378
1412
|
] }),
|
|
1379
1413
|
hasField("birth_date") && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: fieldGroup, children: [
|
|
1380
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1381
|
-
"
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
style: label,
|
|
1385
|
-
children: [
|
|
1386
|
-
"Birth date",
|
|
1387
|
-
isRequired("birth_date") ? " *" : ""
|
|
1388
|
-
]
|
|
1389
|
-
}
|
|
1390
|
-
),
|
|
1414
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { htmlFor: "dauth-birthdate", style: label, children: [
|
|
1415
|
+
"Birth date",
|
|
1416
|
+
isRequired("birth_date") ? " *" : ""
|
|
1417
|
+
] }),
|
|
1391
1418
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1392
1419
|
"input",
|
|
1393
1420
|
{
|
|
@@ -1404,44 +1431,28 @@ function DauthProfileModal({
|
|
|
1404
1431
|
] }),
|
|
1405
1432
|
(domain.customFields ?? []).length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
1406
1433
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("hr", { style: separator }),
|
|
1407
|
-
domain.customFields.map((cf) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1408
|
-
"
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
onChange: (e) => setCustomFieldValues(
|
|
1430
|
-
(prev) => ({
|
|
1431
|
-
...prev,
|
|
1432
|
-
[cf.key]: e.target.value
|
|
1433
|
-
})
|
|
1434
|
-
),
|
|
1435
|
-
disabled: saving,
|
|
1436
|
-
style: input,
|
|
1437
|
-
onFocus: inputFocusHandler,
|
|
1438
|
-
onBlur: inputBlurHandler
|
|
1439
|
-
}
|
|
1440
|
-
)
|
|
1441
|
-
]
|
|
1442
|
-
},
|
|
1443
|
-
cf.key
|
|
1444
|
-
))
|
|
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))
|
|
1445
1456
|
] })
|
|
1446
1457
|
] }),
|
|
1447
1458
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("hr", { style: separator }),
|
|
@@ -1501,14 +1512,7 @@ function DauthProfileModal({
|
|
|
1501
1512
|
),
|
|
1502
1513
|
showRegister && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: registerPanel, children: [
|
|
1503
1514
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: fieldGroup, children: [
|
|
1504
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1505
|
-
"label",
|
|
1506
|
-
{
|
|
1507
|
-
htmlFor: "dauth-passkey-name",
|
|
1508
|
-
style: label,
|
|
1509
|
-
children: "Passkey name (optional)"
|
|
1510
|
-
}
|
|
1511
|
-
),
|
|
1515
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { htmlFor: "dauth-passkey-name", style: label, children: "Passkey name (optional)" }),
|
|
1512
1516
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1513
1517
|
"input",
|
|
1514
1518
|
{
|
|
@@ -1584,89 +1588,82 @@ function DauthProfileModal({
|
|
|
1584
1588
|
},
|
|
1585
1589
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Spinner, {})
|
|
1586
1590
|
}
|
|
1587
|
-
) : credentials.length > 0 ? credentials.map((cred) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
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
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconTrash, {})
|
|
1664
|
-
}
|
|
1665
|
-
)
|
|
1666
|
-
]
|
|
1667
|
-
},
|
|
1668
|
-
cred._id
|
|
1669
|
-
)) : /* @__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: [
|
|
1670
1667
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1671
1668
|
"span",
|
|
1672
1669
|
{
|
|
@@ -2229,10 +2226,12 @@ var DauthProvider = (props) => {
|
|
|
2229
2226
|
telPrefix,
|
|
2230
2227
|
telSuffix,
|
|
2231
2228
|
language,
|
|
2229
|
+
theme,
|
|
2232
2230
|
avatar,
|
|
2233
2231
|
birthDate,
|
|
2234
2232
|
country,
|
|
2235
|
-
metadata
|
|
2233
|
+
metadata,
|
|
2234
|
+
customFields
|
|
2236
2235
|
} = fields;
|
|
2237
2236
|
const user = {
|
|
2238
2237
|
name,
|
|
@@ -2241,10 +2240,12 @@ var DauthProvider = (props) => {
|
|
|
2241
2240
|
telPrefix,
|
|
2242
2241
|
telSuffix,
|
|
2243
2242
|
language,
|
|
2243
|
+
theme,
|
|
2244
2244
|
avatar,
|
|
2245
2245
|
birthDate,
|
|
2246
2246
|
country,
|
|
2247
|
-
metadata
|
|
2247
|
+
metadata,
|
|
2248
|
+
customFields
|
|
2248
2249
|
};
|
|
2249
2250
|
return updateUserAction(ctx, user);
|
|
2250
2251
|
},
|
|
@@ -2270,6 +2271,10 @@ var DauthProvider = (props) => {
|
|
|
2270
2271
|
(file) => uploadAvatarAction(ctx, file),
|
|
2271
2272
|
[ctx]
|
|
2272
2273
|
);
|
|
2274
|
+
const loginWithPasskey = (0, import_react2.useCallback)(
|
|
2275
|
+
() => loginWithPasskeyAction(ctx),
|
|
2276
|
+
[ctx]
|
|
2277
|
+
);
|
|
2273
2278
|
const memoProvider = (0, import_react2.useMemo)(
|
|
2274
2279
|
() => ({
|
|
2275
2280
|
...dauthState,
|
|
@@ -2280,7 +2285,8 @@ var DauthProvider = (props) => {
|
|
|
2280
2285
|
getPasskeyCredentials,
|
|
2281
2286
|
registerPasskey,
|
|
2282
2287
|
deletePasskeyCredential,
|
|
2283
|
-
uploadAvatar
|
|
2288
|
+
uploadAvatar,
|
|
2289
|
+
loginWithPasskey
|
|
2284
2290
|
}),
|
|
2285
2291
|
[
|
|
2286
2292
|
dauthState,
|
|
@@ -2291,7 +2297,8 @@ var DauthProvider = (props) => {
|
|
|
2291
2297
|
getPasskeyCredentials,
|
|
2292
2298
|
registerPasskey,
|
|
2293
2299
|
deletePasskeyCredential,
|
|
2294
|
-
uploadAvatar
|
|
2300
|
+
uploadAvatar,
|
|
2301
|
+
loginWithPasskey
|
|
2295
2302
|
]
|
|
2296
2303
|
);
|
|
2297
2304
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(DauthContext.Provider, { value: memoProvider, children });
|