dauth-context-react 6.3.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 CHANGED
@@ -79,13 +79,14 @@ interface IDauthState {
79
79
  getPasskeyCredentials: () => Promise<IPasskeyCredential[]>;
80
80
  registerPasskey: (name?: string) => Promise<IPasskeyCredential | null>;
81
81
  deletePasskeyCredential: (credentialId: string) => Promise<boolean>;
82
+ uploadAvatar: (file: File) => Promise<boolean>;
82
83
  }
83
84
  interface DauthProfileModalProps {
84
85
  open: boolean;
85
86
  onClose: () => void;
86
- /** Optional: provide a function to handle avatar upload.
87
+ /** Optional override for avatar upload.
87
88
  * Receives a File, should return the URL string.
88
- * If not provided, the avatar edit button is hidden. */
89
+ * If not provided, uses the built-in upload via the auth proxy. */
89
90
  onAvatarUpload?: (file: File) => Promise<string>;
90
91
  }
91
92
  interface IDauthProviderProps {
package/dist/index.d.ts CHANGED
@@ -79,13 +79,14 @@ interface IDauthState {
79
79
  getPasskeyCredentials: () => Promise<IPasskeyCredential[]>;
80
80
  registerPasskey: (name?: string) => Promise<IPasskeyCredential | null>;
81
81
  deletePasskeyCredential: (credentialId: string) => Promise<boolean>;
82
+ uploadAvatar: (file: File) => Promise<boolean>;
82
83
  }
83
84
  interface DauthProfileModalProps {
84
85
  open: boolean;
85
86
  onClose: () => void;
86
- /** Optional: provide a function to handle avatar upload.
87
+ /** Optional override for avatar upload.
87
88
  * Receives a File, should return the URL string.
88
- * If not provided, the avatar edit button is hidden. */
89
+ * If not provided, uses the built-in upload via the auth proxy. */
89
90
  onAvatarUpload?: (file: File) => Promise<string>;
90
91
  }
91
92
  interface IDauthProviderProps {
package/dist/index.js CHANGED
@@ -43,7 +43,8 @@ var initialDauthState = {
43
43
  deleteAccount: () => Promise.resolve(false),
44
44
  getPasskeyCredentials: () => Promise.resolve([]),
45
45
  registerPasskey: () => Promise.resolve(null),
46
- deletePasskeyCredential: () => Promise.resolve(false)
46
+ deletePasskeyCredential: () => Promise.resolve(false),
47
+ uploadAvatar: () => Promise.resolve(false)
47
48
  };
48
49
  var initialDauthState_default = initialDauthState;
49
50
 
@@ -205,6 +206,18 @@ async function deletePasskeyCredentialAPI(basePath, credentialId) {
205
206
  const data = await response.json();
206
207
  return { response, data };
207
208
  }
209
+ async function uploadAvatarAPI(basePath, file) {
210
+ const formData = new FormData();
211
+ formData.append("avatar", file);
212
+ const response = await fetch(`${basePath}/avatar`, {
213
+ method: "POST",
214
+ headers: { "X-CSRF-Token": getCsrfToken() },
215
+ credentials: "include",
216
+ body: formData
217
+ });
218
+ const data = await response.json();
219
+ return { response, data };
220
+ }
208
221
 
209
222
  // src/webauthn.ts
210
223
  function base64urlToBuffer(base64url) {
@@ -460,6 +473,30 @@ async function deletePasskeyCredentialAction(ctx, credentialId) {
460
473
  return false;
461
474
  }
462
475
  }
476
+ async function uploadAvatarAction(ctx, file) {
477
+ const { dispatch, authProxyPath, onError } = ctx;
478
+ try {
479
+ const result = await uploadAvatarAPI(authProxyPath, file);
480
+ if (result.response.status === 200) {
481
+ dispatch({
482
+ type: UPDATE_USER,
483
+ payload: result.data.user
484
+ });
485
+ return true;
486
+ }
487
+ onError(
488
+ new Error(
489
+ "Avatar upload error: " + result.data.message
490
+ )
491
+ );
492
+ return false;
493
+ } catch (error) {
494
+ onError(
495
+ error instanceof Error ? error : new Error("Avatar upload error")
496
+ );
497
+ return false;
498
+ }
499
+ }
463
500
  var resetUser = (dispatch) => {
464
501
  return dispatch({
465
502
  type: LOGIN,
@@ -763,7 +800,8 @@ function DauthProfileModal({
763
800
  logout,
764
801
  getPasskeyCredentials,
765
802
  registerPasskey,
766
- deletePasskeyCredential
803
+ deletePasskeyCredential,
804
+ uploadAvatar
767
805
  } = useDauth();
768
806
  const isDesktop = useMediaQuery("(min-width: 641px)");
769
807
  const phase = useModalAnimation(open);
@@ -971,19 +1009,21 @@ function DauthProfileModal({
971
1009
  [deletePasskeyCredential]
972
1010
  );
973
1011
  const handleAvatarClick = (0, import_react.useCallback)(() => {
974
- if (onAvatarUpload) {
975
- avatarInputRef.current?.click();
976
- }
977
- }, [onAvatarUpload]);
1012
+ avatarInputRef.current?.click();
1013
+ }, []);
978
1014
  const handleAvatarChange = (0, import_react.useCallback)(
979
1015
  async (e) => {
980
1016
  const file = e.target.files?.[0];
981
- if (!file || !onAvatarUpload) return;
1017
+ if (!file) return;
982
1018
  setUploadingAvatar(true);
983
1019
  try {
984
- const url = await onAvatarUpload(file);
985
- if (url) {
986
- await updateUser({ avatar: url });
1020
+ if (onAvatarUpload) {
1021
+ const url = await onAvatarUpload(file);
1022
+ if (url) {
1023
+ await updateUser({ avatar: url });
1024
+ }
1025
+ } else {
1026
+ await uploadAvatar(file);
987
1027
  }
988
1028
  } catch {
989
1029
  }
@@ -992,7 +1032,7 @@ function DauthProfileModal({
992
1032
  avatarInputRef.current.value = "";
993
1033
  }
994
1034
  },
995
- [onAvatarUpload, updateUser]
1035
+ [onAvatarUpload, updateUser, uploadAvatar]
996
1036
  );
997
1037
  const handleSignOut = (0, import_react.useCallback)(() => {
998
1038
  logout();
@@ -1134,7 +1174,7 @@ function DauthProfileModal({
1134
1174
  {
1135
1175
  style: {
1136
1176
  ...avatarCircle,
1137
- cursor: onAvatarUpload ? "pointer" : "default",
1177
+ cursor: "pointer",
1138
1178
  position: "relative"
1139
1179
  },
1140
1180
  onClick: handleAvatarClick,
@@ -1151,12 +1191,12 @@ function DauthProfileModal({
1151
1191
  }
1152
1192
  }
1153
1193
  ) : avatarInitial,
1154
- onAvatarUpload && !uploadingAvatar && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: avatarOverlay, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconCamera, {}) })
1194
+ !uploadingAvatar && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: avatarOverlay, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IconCamera, {}) })
1155
1195
  ]
1156
1196
  }
1157
1197
  ),
1158
1198
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: emailText, children: user.email }),
1159
- onAvatarUpload && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1199
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1160
1200
  "input",
1161
1201
  {
1162
1202
  ref: avatarInputRef,
@@ -2226,6 +2266,10 @@ var DauthProvider = (props) => {
2226
2266
  (credentialId) => deletePasskeyCredentialAction(ctx, credentialId),
2227
2267
  [ctx]
2228
2268
  );
2269
+ const uploadAvatar = (0, import_react2.useCallback)(
2270
+ (file) => uploadAvatarAction(ctx, file),
2271
+ [ctx]
2272
+ );
2229
2273
  const memoProvider = (0, import_react2.useMemo)(
2230
2274
  () => ({
2231
2275
  ...dauthState,
@@ -2235,7 +2279,8 @@ var DauthProvider = (props) => {
2235
2279
  deleteAccount,
2236
2280
  getPasskeyCredentials,
2237
2281
  registerPasskey,
2238
- deletePasskeyCredential
2282
+ deletePasskeyCredential,
2283
+ uploadAvatar
2239
2284
  }),
2240
2285
  [
2241
2286
  dauthState,
@@ -2245,7 +2290,8 @@ var DauthProvider = (props) => {
2245
2290
  deleteAccount,
2246
2291
  getPasskeyCredentials,
2247
2292
  registerPasskey,
2248
- deletePasskeyCredential
2293
+ deletePasskeyCredential,
2294
+ uploadAvatar
2249
2295
  ]
2250
2296
  );
2251
2297
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(DauthContext.Provider, { value: memoProvider, children });