@thetechfossil/auth2 1.2.6 → 1.2.7

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.
@@ -1,5 +1,6 @@
1
1
  "use client";
2
2
  import axios from 'axios';
3
+ import { UpfilesClient, Uploader, ImageManager } from '@thetechfossil/upfiles';
3
4
  import React3, { createContext, forwardRef, useState, useCallback, useEffect, useContext, useMemo, useRef } from 'react';
4
5
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
5
6
  import PhoneInputWithCountry from 'react-phone-number-input';
@@ -112,11 +113,10 @@ var HttpClient = class {
112
113
  }
113
114
  }
114
115
  };
115
-
116
- // src/core/auth-service.ts
117
116
  var AuthService = class {
118
117
  constructor(config) {
119
118
  this.token = null;
119
+ this.upfilesClient = null;
120
120
  this.config = {
121
121
  localStorageKey: "auth_token",
122
122
  csrfEnabled: true,
@@ -124,6 +124,15 @@ var AuthService = class {
124
124
  };
125
125
  this.httpClient = new HttpClient(this.config.baseUrl);
126
126
  this.loadTokenFromStorage();
127
+ if (this.config.upfilesConfig) {
128
+ this.upfilesClient = new UpfilesClient({
129
+ baseUrl: this.config.upfilesConfig.baseUrl,
130
+ apiKey: this.config.upfilesConfig.apiKey,
131
+ apiKeyHeader: this.config.upfilesConfig.apiKeyHeader,
132
+ presignUrl: this.config.upfilesConfig.presignUrl,
133
+ presignPath: this.config.upfilesConfig.presignPath
134
+ });
135
+ }
127
136
  if (typeof window !== "undefined") {
128
137
  const frontendBaseUrl = process.env.NEXT_PUBLIC_FRONTEND_BASE_URL || process.env.REACT_APP_FRONTEND_BASE_URL || process.env.NEXT_PUBLIC_APP_URL || window.location.origin;
129
138
  if (frontendBaseUrl) {
@@ -351,6 +360,28 @@ var AuthService = class {
351
360
  }
352
361
  return response;
353
362
  }
363
+ async uploadAndUpdateAvatar(file) {
364
+ if (!this.token) {
365
+ throw new Error("Not authenticated");
366
+ }
367
+ if (!this.upfilesClient) {
368
+ throw new Error("Upfiles configuration is required. Please provide upfilesConfig in AuthConfig.");
369
+ }
370
+ try {
371
+ const folderPath = this.config.upfilesConfig?.folderPath || "avatars/";
372
+ const uploadResult = await this.upfilesClient.upload(file, {
373
+ folderPath,
374
+ fetchThumbnails: true
375
+ });
376
+ const response = await this.updateAvatar(uploadResult.publicUrl);
377
+ return response;
378
+ } catch (error) {
379
+ throw new Error(`Failed to upload avatar: ${error.message || "Unknown error"}`);
380
+ }
381
+ }
382
+ getUpfilesClient() {
383
+ return this.upfilesClient;
384
+ }
354
385
  async requestEmailChange(newEmail) {
355
386
  if (!this.token) {
356
387
  throw new Error("Not authenticated");
@@ -581,6 +612,18 @@ var useAuth = (config) => {
581
612
  setLoading(false);
582
613
  }
583
614
  }, [authService]);
615
+ const uploadAndUpdateAvatar = useCallback(async (file) => {
616
+ setLoading(true);
617
+ try {
618
+ const response = await authService.uploadAndUpdateAvatar(file);
619
+ if (response.success && response.user) {
620
+ setUser(response.user);
621
+ }
622
+ return response;
623
+ } finally {
624
+ setLoading(false);
625
+ }
626
+ }, [authService]);
584
627
  return {
585
628
  user,
586
629
  isAuthenticated,
@@ -593,7 +636,8 @@ var useAuth = (config) => {
593
636
  updateProfile,
594
637
  getProfile,
595
638
  getAllUsers,
596
- getUserById
639
+ getUserById,
640
+ uploadAndUpdateAvatar
597
641
  };
598
642
  };
599
643
  var ThemeContext = createContext({ theme: "light", mounted: false });
@@ -652,7 +696,8 @@ var AuthProvider = ({ children, config }) => {
652
696
  const authConfig = {
653
697
  baseUrl: config?.baseUrl || (typeof window !== "undefined" ? process.env.NEXT_PUBLIC_AUTH_API_URL || process.env.REACT_APP_AUTH_API_URL || "http://localhost:7000" : "http://localhost:7000"),
654
698
  localStorageKey: config?.localStorageKey || "auth_token",
655
- csrfEnabled: config?.csrfEnabled !== void 0 ? config.csrfEnabled : true
699
+ csrfEnabled: config?.csrfEnabled !== void 0 ? config.csrfEnabled : true,
700
+ upfilesConfig: config?.upfilesConfig
656
701
  };
657
702
  const [authService] = useState(() => new AuthService(authConfig));
658
703
  const [user, setUser] = useState(null);
@@ -802,6 +847,18 @@ var AuthProvider = ({ children, config }) => {
802
847
  setLoading(false);
803
848
  }
804
849
  }, [authService]);
850
+ const uploadAndUpdateAvatar = useCallback(async (file) => {
851
+ setLoading(true);
852
+ try {
853
+ const response = await authService.uploadAndUpdateAvatar(file);
854
+ if (response.success && response.user) {
855
+ setUser(response.user);
856
+ }
857
+ return response;
858
+ } finally {
859
+ setLoading(false);
860
+ }
861
+ }, [authService]);
805
862
  const requestEmailChange = useCallback(async (newEmail) => {
806
863
  setLoading(true);
807
864
  try {
@@ -899,6 +956,7 @@ var AuthProvider = ({ children, config }) => {
899
956
  resetPassword,
900
957
  changePassword,
901
958
  updateAvatar,
959
+ uploadAndUpdateAvatar,
902
960
  requestEmailChange,
903
961
  verifyEmailChange,
904
962
  generate2FA,
@@ -4659,6 +4717,122 @@ var UserProfile = ({
4659
4717
  ] })
4660
4718
  ] });
4661
4719
  };
4720
+ var AvatarUploader = ({
4721
+ onUploadComplete,
4722
+ onError,
4723
+ className,
4724
+ buttonClassName,
4725
+ dropzoneClassName,
4726
+ maxFileSize = 5 * 1024 * 1024,
4727
+ // 5MB default
4728
+ accept = ["image/*"],
4729
+ upfilesConfig
4730
+ }) => {
4731
+ const { uploadAndUpdateAvatar } = useAuth2();
4732
+ const [uploading, setUploading] = useState(false);
4733
+ const handleUploadComplete = async (files) => {
4734
+ if (files.length === 0)
4735
+ return;
4736
+ setUploading(true);
4737
+ try {
4738
+ const file = files[0];
4739
+ const response = await uploadAndUpdateAvatar(file.file);
4740
+ if (response.success && response.user?.avatar) {
4741
+ onUploadComplete?.(response.user.avatar);
4742
+ } else {
4743
+ throw new Error(response.message || "Failed to update avatar");
4744
+ }
4745
+ } catch (error) {
4746
+ const err = error instanceof Error ? error : new Error("Upload failed");
4747
+ onError?.(err);
4748
+ } finally {
4749
+ setUploading(false);
4750
+ }
4751
+ };
4752
+ const handleError = (error) => {
4753
+ onError?.(error);
4754
+ };
4755
+ return /* @__PURE__ */ jsx("div", { className, children: /* @__PURE__ */ jsx(
4756
+ Uploader,
4757
+ {
4758
+ clientOptions: {
4759
+ baseUrl: upfilesConfig.baseUrl,
4760
+ apiKey: upfilesConfig.apiKey,
4761
+ apiKeyHeader: upfilesConfig.apiKeyHeader || "authorization",
4762
+ presignUrl: upfilesConfig.presignUrl,
4763
+ presignPath: upfilesConfig.presignPath
4764
+ },
4765
+ multiple: false,
4766
+ accept,
4767
+ maxFileSize,
4768
+ maxFiles: 1,
4769
+ onComplete: handleUploadComplete,
4770
+ onError: handleError,
4771
+ buttonClassName,
4772
+ dropzoneClassName,
4773
+ children: uploading ? "Uploading..." : "Upload Avatar"
4774
+ }
4775
+ ) });
4776
+ };
4777
+ var AvatarManager = ({
4778
+ open,
4779
+ onOpenChange,
4780
+ onAvatarUpdated,
4781
+ onError,
4782
+ title = "Select Avatar",
4783
+ description = "Choose an existing image or upload a new one",
4784
+ className,
4785
+ gridClassName,
4786
+ maxFileSize = 5 * 1024 * 1024,
4787
+ // 5MB default
4788
+ mode = "full",
4789
+ showDelete = false,
4790
+ upfilesConfig
4791
+ }) => {
4792
+ const { updateProfile } = useAuth2();
4793
+ const [updating, setUpdating] = useState(false);
4794
+ const handleSelect = async (image) => {
4795
+ setUpdating(true);
4796
+ try {
4797
+ const response = await updateProfile({ avatar: image.url });
4798
+ if (response.success && response.user?.avatar) {
4799
+ onAvatarUpdated?.(response.user.avatar);
4800
+ onOpenChange(false);
4801
+ } else {
4802
+ throw new Error(response.message || "Failed to update avatar");
4803
+ }
4804
+ } catch (error) {
4805
+ const err = error instanceof Error ? error : new Error("Failed to update avatar");
4806
+ onError?.(err);
4807
+ } finally {
4808
+ setUpdating(false);
4809
+ }
4810
+ };
4811
+ return /* @__PURE__ */ jsx(
4812
+ ImageManager,
4813
+ {
4814
+ open,
4815
+ onOpenChange,
4816
+ clientOptions: {
4817
+ baseUrl: upfilesConfig.baseUrl,
4818
+ apiKey: upfilesConfig.apiKey,
4819
+ apiKeyHeader: upfilesConfig.apiKeyHeader || "authorization",
4820
+ presignUrl: upfilesConfig.presignUrl,
4821
+ presignPath: upfilesConfig.presignPath
4822
+ },
4823
+ folderPath: upfilesConfig.folderPath || "avatars/",
4824
+ title,
4825
+ description,
4826
+ className,
4827
+ gridClassName,
4828
+ onSelect: handleSelect,
4829
+ maxFileSize,
4830
+ mode,
4831
+ showDelete,
4832
+ fetchThumbnails: true
4833
+ }
4834
+ );
4835
+ };
4662
4836
  var isServer = typeof window === "undefined";
4663
4837
  var useNextAuth = (config) => {
4664
4838
  const [authService] = useState(() => {
@@ -4851,6 +5025,6 @@ var useNextAuth = (config) => {
4851
5025
  };
4852
5026
  };
4853
5027
 
4854
- export { AuthFlow, AuthProvider, AuthService, AuthThemeProvider, ChangePassword, EmailVerificationPage, ForgotPassword, HttpClient, LoginForm, OtpForm, PhoneInput, ProtectedRoute, PublicRoute, RegisterForm, ResetPassword, SignIn, SignOut, SignUp, UserButton, UserProfile, VerifyEmail, useAuth2 as useAuth, useAuth as useAuthLegacy, useAuthTheme, useNextAuth };
5028
+ export { AuthFlow, AuthProvider, AuthService, AuthThemeProvider, AvatarManager, AvatarUploader, ChangePassword, EmailVerificationPage, ForgotPassword, HttpClient, LoginForm, OtpForm, PhoneInput, ProtectedRoute, PublicRoute, RegisterForm, ResetPassword, SignIn, SignOut, SignUp, UserButton, UserProfile, VerifyEmail, useAuth2 as useAuth, useAuth as useAuthLegacy, useAuthTheme, useNextAuth };
4855
5029
  //# sourceMappingURL=out.js.map
4856
5030
  //# sourceMappingURL=index.next.mjs.map