dauth-context-react 6.2.0 → 6.4.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 +11 -3
- package/dist/index.d.ts +11 -3
- package/dist/index.js +235 -19
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +235 -19
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/DauthProfileModal.tsx +215 -26
- package/src/api/dauth.api.ts +17 -0
- package/src/api/interfaces/dauth.api.responses.ts +9 -0
- package/src/index.tsx +9 -0
- package/src/initialDauthState.ts +1 -0
- package/src/interfaces.ts +11 -2
- package/src/reducer/dauth.actions.ts +31 -0
package/dist/index.mjs
CHANGED
|
@@ -24,7 +24,8 @@ var initialDauthState = {
|
|
|
24
24
|
deleteAccount: () => Promise.resolve(false),
|
|
25
25
|
getPasskeyCredentials: () => Promise.resolve([]),
|
|
26
26
|
registerPasskey: () => Promise.resolve(null),
|
|
27
|
-
deletePasskeyCredential: () => Promise.resolve(false)
|
|
27
|
+
deletePasskeyCredential: () => Promise.resolve(false),
|
|
28
|
+
uploadAvatar: () => Promise.resolve(false)
|
|
28
29
|
};
|
|
29
30
|
var initialDauthState_default = initialDauthState;
|
|
30
31
|
|
|
@@ -186,6 +187,18 @@ async function deletePasskeyCredentialAPI(basePath, credentialId) {
|
|
|
186
187
|
const data = await response.json();
|
|
187
188
|
return { response, data };
|
|
188
189
|
}
|
|
190
|
+
async function uploadAvatarAPI(basePath, file) {
|
|
191
|
+
const formData = new FormData();
|
|
192
|
+
formData.append("avatar", file);
|
|
193
|
+
const response = await fetch(`${basePath}/avatar`, {
|
|
194
|
+
method: "POST",
|
|
195
|
+
headers: { "X-CSRF-Token": getCsrfToken() },
|
|
196
|
+
credentials: "include",
|
|
197
|
+
body: formData
|
|
198
|
+
});
|
|
199
|
+
const data = await response.json();
|
|
200
|
+
return { response, data };
|
|
201
|
+
}
|
|
189
202
|
|
|
190
203
|
// src/webauthn.ts
|
|
191
204
|
function base64urlToBuffer(base64url) {
|
|
@@ -441,6 +454,30 @@ async function deletePasskeyCredentialAction(ctx, credentialId) {
|
|
|
441
454
|
return false;
|
|
442
455
|
}
|
|
443
456
|
}
|
|
457
|
+
async function uploadAvatarAction(ctx, file) {
|
|
458
|
+
const { dispatch, authProxyPath, onError } = ctx;
|
|
459
|
+
try {
|
|
460
|
+
const result = await uploadAvatarAPI(authProxyPath, file);
|
|
461
|
+
if (result.response.status === 200) {
|
|
462
|
+
dispatch({
|
|
463
|
+
type: UPDATE_USER,
|
|
464
|
+
payload: result.data.user
|
|
465
|
+
});
|
|
466
|
+
return true;
|
|
467
|
+
}
|
|
468
|
+
onError(
|
|
469
|
+
new Error(
|
|
470
|
+
"Avatar upload error: " + result.data.message
|
|
471
|
+
)
|
|
472
|
+
);
|
|
473
|
+
return false;
|
|
474
|
+
} catch (error) {
|
|
475
|
+
onError(
|
|
476
|
+
error instanceof Error ? error : new Error("Avatar upload error")
|
|
477
|
+
);
|
|
478
|
+
return false;
|
|
479
|
+
}
|
|
480
|
+
}
|
|
444
481
|
var resetUser = (dispatch) => {
|
|
445
482
|
return dispatch({
|
|
446
483
|
type: LOGIN,
|
|
@@ -750,7 +787,8 @@ function DauthProfileModal({
|
|
|
750
787
|
logout,
|
|
751
788
|
getPasskeyCredentials,
|
|
752
789
|
registerPasskey,
|
|
753
|
-
deletePasskeyCredential
|
|
790
|
+
deletePasskeyCredential,
|
|
791
|
+
uploadAvatar
|
|
754
792
|
} = useDauth();
|
|
755
793
|
const isDesktop = useMediaQuery("(min-width: 641px)");
|
|
756
794
|
const phase = useModalAnimation(open);
|
|
@@ -762,6 +800,10 @@ function DauthProfileModal({
|
|
|
762
800
|
const [lastname, setLastname] = useState("");
|
|
763
801
|
const [nickname, setNickname] = useState("");
|
|
764
802
|
const [country, setCountry] = useState("");
|
|
803
|
+
const [telPrefix, setTelPrefix] = useState("");
|
|
804
|
+
const [telSuffix, setTelSuffix] = useState("");
|
|
805
|
+
const [birthDate, setBirthDate] = useState("");
|
|
806
|
+
const [customFieldValues, setCustomFieldValues] = useState({});
|
|
765
807
|
const [populated, setPopulated] = useState(false);
|
|
766
808
|
const [saving, setSaving] = useState(false);
|
|
767
809
|
const [status, setStatus] = useState(null);
|
|
@@ -781,6 +823,16 @@ function DauthProfileModal({
|
|
|
781
823
|
setLastname(user.lastname || "");
|
|
782
824
|
setNickname(user.nickname || "");
|
|
783
825
|
setCountry(user.country || "");
|
|
826
|
+
setTelPrefix(user.telPrefix || "");
|
|
827
|
+
setTelSuffix(user.telSuffix || "");
|
|
828
|
+
setBirthDate(
|
|
829
|
+
user.birthDate ? new Date(user.birthDate).toISOString().split("T")[0] : ""
|
|
830
|
+
);
|
|
831
|
+
const cf = {};
|
|
832
|
+
for (const f of domain.customFields ?? []) {
|
|
833
|
+
cf[f.key] = user.customFields?.[f.key] ?? "";
|
|
834
|
+
}
|
|
835
|
+
setCustomFieldValues(cf);
|
|
784
836
|
setPopulated(true);
|
|
785
837
|
}
|
|
786
838
|
if (!open) {
|
|
@@ -830,8 +882,23 @@ function DauthProfileModal({
|
|
|
830
882
|
);
|
|
831
883
|
const hasChanges = useMemo(() => {
|
|
832
884
|
if (!user?._id) return false;
|
|
833
|
-
|
|
834
|
-
|
|
885
|
+
const origBirthDate = user.birthDate ? new Date(user.birthDate).toISOString().split("T")[0] : "";
|
|
886
|
+
const cfChanged = (domain.customFields ?? []).some(
|
|
887
|
+
(f) => (customFieldValues[f.key] ?? "") !== (user.customFields?.[f.key] ?? "")
|
|
888
|
+
);
|
|
889
|
+
return name !== (user.name || "") || lastname !== (user.lastname || "") || nickname !== (user.nickname || "") || country !== (user.country || "") || telPrefix !== (user.telPrefix || "") || telSuffix !== (user.telSuffix || "") || birthDate !== origBirthDate || cfChanged;
|
|
890
|
+
}, [
|
|
891
|
+
name,
|
|
892
|
+
lastname,
|
|
893
|
+
nickname,
|
|
894
|
+
country,
|
|
895
|
+
telPrefix,
|
|
896
|
+
telSuffix,
|
|
897
|
+
birthDate,
|
|
898
|
+
customFieldValues,
|
|
899
|
+
user,
|
|
900
|
+
domain.customFields
|
|
901
|
+
]);
|
|
835
902
|
const canSave = name.trim().length > 0 && hasChanges && !saving;
|
|
836
903
|
const handleSave = useCallback(async () => {
|
|
837
904
|
setSaving(true);
|
|
@@ -840,6 +907,14 @@ function DauthProfileModal({
|
|
|
840
907
|
if (hasField("lastname")) fields.lastname = lastname;
|
|
841
908
|
if (hasField("nickname")) fields.nickname = nickname;
|
|
842
909
|
if (hasField("country")) fields.country = country;
|
|
910
|
+
if (hasField("tel_prefix"))
|
|
911
|
+
fields.telPrefix = telPrefix;
|
|
912
|
+
if (hasField("tel_suffix"))
|
|
913
|
+
fields.telSuffix = telSuffix;
|
|
914
|
+
if (hasField("birth_date") && birthDate)
|
|
915
|
+
fields.birthDate = birthDate;
|
|
916
|
+
if ((domain.customFields ?? []).length > 0)
|
|
917
|
+
fields.customFields = customFieldValues;
|
|
843
918
|
const ok = await updateUser(fields);
|
|
844
919
|
setSaving(false);
|
|
845
920
|
if (ok) {
|
|
@@ -853,7 +928,19 @@ function DauthProfileModal({
|
|
|
853
928
|
message: "Something went wrong. Please try again."
|
|
854
929
|
});
|
|
855
930
|
}
|
|
856
|
-
}, [
|
|
931
|
+
}, [
|
|
932
|
+
name,
|
|
933
|
+
lastname,
|
|
934
|
+
nickname,
|
|
935
|
+
country,
|
|
936
|
+
telPrefix,
|
|
937
|
+
telSuffix,
|
|
938
|
+
birthDate,
|
|
939
|
+
customFieldValues,
|
|
940
|
+
hasField,
|
|
941
|
+
updateUser,
|
|
942
|
+
domain.customFields
|
|
943
|
+
]);
|
|
857
944
|
const handleDelete = useCallback(async () => {
|
|
858
945
|
setDeleting(true);
|
|
859
946
|
const ok = await deleteAccount();
|
|
@@ -909,19 +996,21 @@ function DauthProfileModal({
|
|
|
909
996
|
[deletePasskeyCredential]
|
|
910
997
|
);
|
|
911
998
|
const handleAvatarClick = useCallback(() => {
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
}
|
|
915
|
-
}, [onAvatarUpload]);
|
|
999
|
+
avatarInputRef.current?.click();
|
|
1000
|
+
}, []);
|
|
916
1001
|
const handleAvatarChange = useCallback(
|
|
917
1002
|
async (e) => {
|
|
918
1003
|
const file = e.target.files?.[0];
|
|
919
|
-
if (!file
|
|
1004
|
+
if (!file) return;
|
|
920
1005
|
setUploadingAvatar(true);
|
|
921
1006
|
try {
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
1007
|
+
if (onAvatarUpload) {
|
|
1008
|
+
const url = await onAvatarUpload(file);
|
|
1009
|
+
if (url) {
|
|
1010
|
+
await updateUser({ avatar: url });
|
|
1011
|
+
}
|
|
1012
|
+
} else {
|
|
1013
|
+
await uploadAvatar(file);
|
|
925
1014
|
}
|
|
926
1015
|
} catch {
|
|
927
1016
|
}
|
|
@@ -930,7 +1019,7 @@ function DauthProfileModal({
|
|
|
930
1019
|
avatarInputRef.current.value = "";
|
|
931
1020
|
}
|
|
932
1021
|
},
|
|
933
|
-
[onAvatarUpload, updateUser]
|
|
1022
|
+
[onAvatarUpload, updateUser, uploadAvatar]
|
|
934
1023
|
);
|
|
935
1024
|
const handleSignOut = useCallback(() => {
|
|
936
1025
|
logout();
|
|
@@ -1072,7 +1161,7 @@ function DauthProfileModal({
|
|
|
1072
1161
|
{
|
|
1073
1162
|
style: {
|
|
1074
1163
|
...avatarCircle,
|
|
1075
|
-
cursor:
|
|
1164
|
+
cursor: "pointer",
|
|
1076
1165
|
position: "relative"
|
|
1077
1166
|
},
|
|
1078
1167
|
onClick: handleAvatarClick,
|
|
@@ -1089,12 +1178,12 @@ function DauthProfileModal({
|
|
|
1089
1178
|
}
|
|
1090
1179
|
}
|
|
1091
1180
|
) : avatarInitial,
|
|
1092
|
-
|
|
1181
|
+
!uploadingAvatar && /* @__PURE__ */ jsx("div", { style: avatarOverlay, children: /* @__PURE__ */ jsx(IconCamera, {}) })
|
|
1093
1182
|
]
|
|
1094
1183
|
}
|
|
1095
1184
|
),
|
|
1096
1185
|
/* @__PURE__ */ jsx("div", { style: emailText, children: user.email }),
|
|
1097
|
-
|
|
1186
|
+
/* @__PURE__ */ jsx(
|
|
1098
1187
|
"input",
|
|
1099
1188
|
{
|
|
1100
1189
|
ref: avatarInputRef,
|
|
@@ -1219,6 +1308,127 @@ function DauthProfileModal({
|
|
|
1219
1308
|
onBlur: inputBlurHandler
|
|
1220
1309
|
}
|
|
1221
1310
|
)
|
|
1311
|
+
] }),
|
|
1312
|
+
(hasField("tel_prefix") || hasField("tel_suffix")) && /* @__PURE__ */ jsxs("div", { style: fieldGroup, children: [
|
|
1313
|
+
/* @__PURE__ */ jsxs("div", { style: label, children: [
|
|
1314
|
+
"Phone",
|
|
1315
|
+
isRequired("tel_prefix") || isRequired("tel_suffix") ? " *" : ""
|
|
1316
|
+
] }),
|
|
1317
|
+
/* @__PURE__ */ jsxs(
|
|
1318
|
+
"div",
|
|
1319
|
+
{
|
|
1320
|
+
style: {
|
|
1321
|
+
display: "flex",
|
|
1322
|
+
gap: 8
|
|
1323
|
+
},
|
|
1324
|
+
children: [
|
|
1325
|
+
hasField("tel_prefix") && /* @__PURE__ */ jsx(
|
|
1326
|
+
"input",
|
|
1327
|
+
{
|
|
1328
|
+
id: "dauth-tel-prefix",
|
|
1329
|
+
type: "text",
|
|
1330
|
+
value: telPrefix,
|
|
1331
|
+
onChange: (e) => setTelPrefix(e.target.value),
|
|
1332
|
+
placeholder: "+34",
|
|
1333
|
+
disabled: saving,
|
|
1334
|
+
style: {
|
|
1335
|
+
...input,
|
|
1336
|
+
width: 80,
|
|
1337
|
+
flexShrink: 0
|
|
1338
|
+
},
|
|
1339
|
+
onFocus: inputFocusHandler,
|
|
1340
|
+
onBlur: inputBlurHandler,
|
|
1341
|
+
"aria-label": "Phone prefix"
|
|
1342
|
+
}
|
|
1343
|
+
),
|
|
1344
|
+
hasField("tel_suffix") && /* @__PURE__ */ jsx(
|
|
1345
|
+
"input",
|
|
1346
|
+
{
|
|
1347
|
+
id: "dauth-tel-suffix",
|
|
1348
|
+
type: "tel",
|
|
1349
|
+
value: telSuffix,
|
|
1350
|
+
onChange: (e) => setTelSuffix(e.target.value),
|
|
1351
|
+
placeholder: "612 345 678",
|
|
1352
|
+
disabled: saving,
|
|
1353
|
+
style: {
|
|
1354
|
+
...input,
|
|
1355
|
+
flex: 1
|
|
1356
|
+
},
|
|
1357
|
+
onFocus: inputFocusHandler,
|
|
1358
|
+
onBlur: inputBlurHandler,
|
|
1359
|
+
"aria-label": "Phone number"
|
|
1360
|
+
}
|
|
1361
|
+
)
|
|
1362
|
+
]
|
|
1363
|
+
}
|
|
1364
|
+
)
|
|
1365
|
+
] }),
|
|
1366
|
+
hasField("birth_date") && /* @__PURE__ */ jsxs("div", { style: fieldGroup, children: [
|
|
1367
|
+
/* @__PURE__ */ jsxs(
|
|
1368
|
+
"label",
|
|
1369
|
+
{
|
|
1370
|
+
htmlFor: "dauth-birthdate",
|
|
1371
|
+
style: label,
|
|
1372
|
+
children: [
|
|
1373
|
+
"Birth date",
|
|
1374
|
+
isRequired("birth_date") ? " *" : ""
|
|
1375
|
+
]
|
|
1376
|
+
}
|
|
1377
|
+
),
|
|
1378
|
+
/* @__PURE__ */ jsx(
|
|
1379
|
+
"input",
|
|
1380
|
+
{
|
|
1381
|
+
id: "dauth-birthdate",
|
|
1382
|
+
type: "date",
|
|
1383
|
+
value: birthDate,
|
|
1384
|
+
onChange: (e) => setBirthDate(e.target.value),
|
|
1385
|
+
disabled: saving,
|
|
1386
|
+
style: input,
|
|
1387
|
+
onFocus: inputFocusHandler,
|
|
1388
|
+
onBlur: inputBlurHandler
|
|
1389
|
+
}
|
|
1390
|
+
)
|
|
1391
|
+
] }),
|
|
1392
|
+
(domain.customFields ?? []).length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1393
|
+
/* @__PURE__ */ jsx("hr", { style: separator }),
|
|
1394
|
+
domain.customFields.map((cf) => /* @__PURE__ */ jsxs(
|
|
1395
|
+
"div",
|
|
1396
|
+
{
|
|
1397
|
+
style: fieldGroup,
|
|
1398
|
+
children: [
|
|
1399
|
+
/* @__PURE__ */ jsxs(
|
|
1400
|
+
"label",
|
|
1401
|
+
{
|
|
1402
|
+
htmlFor: `dauth-cf-${cf.key}`,
|
|
1403
|
+
style: label,
|
|
1404
|
+
children: [
|
|
1405
|
+
cf.label,
|
|
1406
|
+
cf.required ? " *" : ""
|
|
1407
|
+
]
|
|
1408
|
+
}
|
|
1409
|
+
),
|
|
1410
|
+
/* @__PURE__ */ jsx(
|
|
1411
|
+
"input",
|
|
1412
|
+
{
|
|
1413
|
+
id: `dauth-cf-${cf.key}`,
|
|
1414
|
+
type: "text",
|
|
1415
|
+
value: customFieldValues[cf.key] ?? "",
|
|
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
|
+
))
|
|
1222
1432
|
] })
|
|
1223
1433
|
] }),
|
|
1224
1434
|
/* @__PURE__ */ jsx("hr", { style: separator }),
|
|
@@ -2043,6 +2253,10 @@ var DauthProvider = (props) => {
|
|
|
2043
2253
|
(credentialId) => deletePasskeyCredentialAction(ctx, credentialId),
|
|
2044
2254
|
[ctx]
|
|
2045
2255
|
);
|
|
2256
|
+
const uploadAvatar = useCallback2(
|
|
2257
|
+
(file) => uploadAvatarAction(ctx, file),
|
|
2258
|
+
[ctx]
|
|
2259
|
+
);
|
|
2046
2260
|
const memoProvider = useMemo2(
|
|
2047
2261
|
() => ({
|
|
2048
2262
|
...dauthState,
|
|
@@ -2052,7 +2266,8 @@ var DauthProvider = (props) => {
|
|
|
2052
2266
|
deleteAccount,
|
|
2053
2267
|
getPasskeyCredentials,
|
|
2054
2268
|
registerPasskey,
|
|
2055
|
-
deletePasskeyCredential
|
|
2269
|
+
deletePasskeyCredential,
|
|
2270
|
+
uploadAvatar
|
|
2056
2271
|
}),
|
|
2057
2272
|
[
|
|
2058
2273
|
dauthState,
|
|
@@ -2062,7 +2277,8 @@ var DauthProvider = (props) => {
|
|
|
2062
2277
|
deleteAccount,
|
|
2063
2278
|
getPasskeyCredentials,
|
|
2064
2279
|
registerPasskey,
|
|
2065
|
-
deletePasskeyCredential
|
|
2280
|
+
deletePasskeyCredential,
|
|
2281
|
+
uploadAvatar
|
|
2066
2282
|
]
|
|
2067
2283
|
);
|
|
2068
2284
|
return /* @__PURE__ */ jsx2(DauthContext.Provider, { value: memoProvider, children });
|