@thetechfossil/auth2 1.2.6 → 1.2.8
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.components.d.ts +63 -1
- package/dist/index.components.js +209 -30
- package/dist/index.components.js.map +1 -1
- package/dist/index.components.mjs +208 -31
- package/dist/index.components.mjs.map +1 -1
- package/dist/index.d.ts +79 -1
- package/dist/index.js +246 -31
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +226 -32
- package/dist/index.mjs.map +1 -1
- package/dist/index.next.d.ts +70 -1
- package/dist/index.next.js +224 -31
- package/dist/index.next.js.map +1 -1
- package/dist/index.next.mjs +223 -32
- package/dist/index.next.mjs.map +1 -1
- package/dist/index.next.server.js +33 -2
- package/dist/index.next.server.js.map +1 -1
- package/dist/index.next.server.mjs +33 -2
- package/dist/index.next.server.mjs.map +1 -1
- package/dist/index.node.d.ts +16 -1
- package/dist/index.node.js +33 -2
- package/dist/index.node.js.map +1 -1
- package/dist/index.node.mjs +33 -2
- package/dist/index.node.mjs.map +1 -1
- package/package.json +6 -1
- package/dist/index.next.server.d.ts +0 -258
package/dist/index.next.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { UpfilesClient } from '@thetechfossil/upfiles';
|
|
1
2
|
import React, { ReactNode } from 'react';
|
|
2
3
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
3
4
|
|
|
@@ -64,6 +65,15 @@ interface AuthConfig {
|
|
|
64
65
|
localStorageKey?: string;
|
|
65
66
|
token?: string;
|
|
66
67
|
csrfEnabled?: boolean;
|
|
68
|
+
upfilesConfig?: UpfilesConfig;
|
|
69
|
+
}
|
|
70
|
+
interface UpfilesConfig {
|
|
71
|
+
baseUrl: string;
|
|
72
|
+
apiKey?: string;
|
|
73
|
+
apiKeyHeader?: 'authorization' | 'x-api-key' | 'x-up-api-key';
|
|
74
|
+
presignUrl?: string;
|
|
75
|
+
presignPath?: string;
|
|
76
|
+
folderPath?: string;
|
|
67
77
|
}
|
|
68
78
|
interface Session {
|
|
69
79
|
id: string;
|
|
@@ -109,6 +119,7 @@ interface UseAuthReturn {
|
|
|
109
119
|
refreshCsrfToken: () => Promise<void>;
|
|
110
120
|
changePassword: (oldPassword: string, newPassword: string) => Promise<AuthResponse>;
|
|
111
121
|
updateAvatar: (avatar: string) => Promise<AuthResponse>;
|
|
122
|
+
uploadAndUpdateAvatar: (file: File) => Promise<AuthResponse>;
|
|
112
123
|
requestEmailChange: (newEmail: string) => Promise<AuthResponse>;
|
|
113
124
|
verifyEmailChange: (token: string) => Promise<AuthResponse>;
|
|
114
125
|
generate2FA: () => Promise<MFASetup>;
|
|
@@ -127,6 +138,7 @@ declare class AuthService {
|
|
|
127
138
|
private httpClient;
|
|
128
139
|
private config;
|
|
129
140
|
private token;
|
|
141
|
+
private upfilesClient;
|
|
130
142
|
constructor(config: AuthConfig);
|
|
131
143
|
private loadTokenFromStorage;
|
|
132
144
|
private saveTokenToStorage;
|
|
@@ -152,6 +164,8 @@ declare class AuthService {
|
|
|
152
164
|
resetPassword(token: string, password: string): Promise<AuthResponse>;
|
|
153
165
|
changePassword(oldPassword: string, newPassword: string): Promise<AuthResponse>;
|
|
154
166
|
updateAvatar(avatar: string): Promise<AuthResponse>;
|
|
167
|
+
uploadAndUpdateAvatar(file: File): Promise<AuthResponse>;
|
|
168
|
+
getUpfilesClient(): UpfilesClient | null;
|
|
155
169
|
requestEmailChange(newEmail: string): Promise<AuthResponse>;
|
|
156
170
|
verifyEmailChange(token: string): Promise<AuthResponse>;
|
|
157
171
|
generate2FA(): Promise<{
|
|
@@ -213,6 +227,7 @@ interface UseAuthReturnBase {
|
|
|
213
227
|
getProfile: () => Promise<User>;
|
|
214
228
|
getAllUsers: () => Promise<User[]>;
|
|
215
229
|
getUserById: (id: string) => Promise<User>;
|
|
230
|
+
uploadAndUpdateAvatar: (file: File) => Promise<AuthResponse>;
|
|
216
231
|
}
|
|
217
232
|
declare const useAuth$1: (config: AuthConfig) => UseAuthReturnBase;
|
|
218
233
|
|
|
@@ -235,6 +250,7 @@ interface AuthContextValue {
|
|
|
235
250
|
resetPassword: (token: string, password: string) => Promise<AuthResponse>;
|
|
236
251
|
changePassword: (oldPassword: string, newPassword: string) => Promise<AuthResponse>;
|
|
237
252
|
updateAvatar: (avatar: string) => Promise<AuthResponse>;
|
|
253
|
+
uploadAndUpdateAvatar: (file: File) => Promise<AuthResponse>;
|
|
238
254
|
requestEmailChange: (newEmail: string) => Promise<AuthResponse>;
|
|
239
255
|
verifyEmailChange: (token: string) => Promise<AuthResponse>;
|
|
240
256
|
generate2FA: () => Promise<any>;
|
|
@@ -424,6 +440,15 @@ interface UserProfileProps {
|
|
|
424
440
|
showAvatar?: boolean;
|
|
425
441
|
showEmailChange?: boolean;
|
|
426
442
|
showPasswordChange?: boolean;
|
|
443
|
+
upfilesConfig?: {
|
|
444
|
+
baseUrl: string;
|
|
445
|
+
apiKey?: string;
|
|
446
|
+
apiKeyHeader?: 'authorization' | 'x-api-key' | 'x-up-api-key';
|
|
447
|
+
presignUrl?: string;
|
|
448
|
+
presignPath?: string;
|
|
449
|
+
folderPath?: string;
|
|
450
|
+
projectId?: string;
|
|
451
|
+
};
|
|
427
452
|
}
|
|
428
453
|
declare const UserProfile: React.FC<UserProfileProps>;
|
|
429
454
|
|
|
@@ -438,6 +463,50 @@ interface PhoneInputProps {
|
|
|
438
463
|
}
|
|
439
464
|
declare const PhoneInput: React.FC<PhoneInputProps>;
|
|
440
465
|
|
|
466
|
+
interface AvatarUploaderProps {
|
|
467
|
+
onUploadComplete?: (avatarUrl: string) => void;
|
|
468
|
+
onError?: (error: Error) => void;
|
|
469
|
+
className?: string;
|
|
470
|
+
buttonClassName?: string;
|
|
471
|
+
dropzoneClassName?: string;
|
|
472
|
+
maxFileSize?: number;
|
|
473
|
+
accept?: string[];
|
|
474
|
+
upfilesConfig: {
|
|
475
|
+
baseUrl: string;
|
|
476
|
+
apiKey?: string;
|
|
477
|
+
apiKeyHeader?: 'authorization' | 'x-api-key' | 'x-up-api-key';
|
|
478
|
+
presignUrl?: string;
|
|
479
|
+
presignPath?: string;
|
|
480
|
+
folderPath?: string;
|
|
481
|
+
projectId?: string;
|
|
482
|
+
};
|
|
483
|
+
buttonText?: string;
|
|
484
|
+
}
|
|
485
|
+
declare const AvatarUploader: React.FC<AvatarUploaderProps>;
|
|
486
|
+
|
|
487
|
+
interface AvatarManagerProps {
|
|
488
|
+
open: boolean;
|
|
489
|
+
onOpenChange: (open: boolean) => void;
|
|
490
|
+
onAvatarUpdated?: (avatarUrl: string) => void;
|
|
491
|
+
onError?: (error: Error) => void;
|
|
492
|
+
title?: string;
|
|
493
|
+
description?: string;
|
|
494
|
+
className?: string;
|
|
495
|
+
gridClassName?: string;
|
|
496
|
+
maxFileSize?: number;
|
|
497
|
+
mode?: 'full' | 'browse' | 'upload';
|
|
498
|
+
showDelete?: boolean;
|
|
499
|
+
upfilesConfig: {
|
|
500
|
+
baseUrl: string;
|
|
501
|
+
apiKey?: string;
|
|
502
|
+
apiKeyHeader?: 'authorization' | 'x-api-key' | 'x-up-api-key';
|
|
503
|
+
presignUrl?: string;
|
|
504
|
+
presignPath?: string;
|
|
505
|
+
folderPath?: string;
|
|
506
|
+
};
|
|
507
|
+
}
|
|
508
|
+
declare const AvatarManager: React.FC<AvatarManagerProps>;
|
|
509
|
+
|
|
441
510
|
interface UseNextAuthReturn {
|
|
442
511
|
user: User | null;
|
|
443
512
|
isAuthenticated: boolean;
|
|
@@ -458,4 +527,4 @@ interface UseNextAuthReturn {
|
|
|
458
527
|
}
|
|
459
528
|
declare const useNextAuth: (config: AuthConfig) => UseNextAuthReturn;
|
|
460
529
|
|
|
461
|
-
export { AuditLog, AuthConfig, AuthFlow, AuthProvider, AuthResponse, AuthService, AuthThemeProvider, ChangePassword, CsrfTokenResponse, EmailVerificationPage, ForgotPassword, HttpClient, LinkedAccount, LoginData, LoginForm, MFASetup, OAuthConfig, OAuthProvider, OtpForm, PhoneInput, ProtectedRoute, PublicRoute, RegisterData, RegisterForm, RegisterFormProps, ResetPassword, Session, SignIn, SignOut, SignUp, UpdateUserData, UseAuthReturn, User, UserButton, UserProfile, VerifyData, VerifyEmail, useAuth, useAuth$1 as useAuthLegacy, useAuthTheme, useNextAuth };
|
|
530
|
+
export { AuditLog, AuthConfig, AuthFlow, AuthProvider, AuthResponse, AuthService, AuthThemeProvider, AvatarManager, AvatarManagerProps, AvatarUploader, AvatarUploaderProps, ChangePassword, CsrfTokenResponse, EmailVerificationPage, ForgotPassword, HttpClient, LinkedAccount, LoginData, LoginForm, MFASetup, OAuthConfig, OAuthProvider, OtpForm, PhoneInput, ProtectedRoute, PublicRoute, RegisterData, RegisterForm, RegisterFormProps, ResetPassword, Session, SignIn, SignOut, SignUp, UpdateUserData, UpfilesConfig, UseAuthReturn, User, UserButton, UserProfile, VerifyData, VerifyEmail, useAuth, useAuth$1 as useAuthLegacy, useAuthTheme, useNextAuth };
|
package/dist/index.next.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
"use client";
|
|
2
1
|
'use strict';
|
|
3
2
|
|
|
4
3
|
var axios = require('axios');
|
|
4
|
+
var upfiles = require('@thetechfossil/upfiles');
|
|
5
5
|
var React3 = require('react');
|
|
6
6
|
var jsxRuntime = require('react/jsx-runtime');
|
|
7
7
|
var PhoneInputWithCountry = require('react-phone-number-input');
|
|
@@ -120,11 +120,10 @@ var HttpClient = class {
|
|
|
120
120
|
}
|
|
121
121
|
}
|
|
122
122
|
};
|
|
123
|
-
|
|
124
|
-
// src/core/auth-service.ts
|
|
125
123
|
var AuthService = class {
|
|
126
124
|
constructor(config) {
|
|
127
125
|
this.token = null;
|
|
126
|
+
this.upfilesClient = null;
|
|
128
127
|
this.config = {
|
|
129
128
|
localStorageKey: "auth_token",
|
|
130
129
|
csrfEnabled: true,
|
|
@@ -132,6 +131,15 @@ var AuthService = class {
|
|
|
132
131
|
};
|
|
133
132
|
this.httpClient = new HttpClient(this.config.baseUrl);
|
|
134
133
|
this.loadTokenFromStorage();
|
|
134
|
+
if (this.config.upfilesConfig) {
|
|
135
|
+
this.upfilesClient = new upfiles.UpfilesClient({
|
|
136
|
+
baseUrl: this.config.upfilesConfig.baseUrl,
|
|
137
|
+
apiKey: this.config.upfilesConfig.apiKey,
|
|
138
|
+
apiKeyHeader: this.config.upfilesConfig.apiKeyHeader,
|
|
139
|
+
presignUrl: this.config.upfilesConfig.presignUrl,
|
|
140
|
+
presignPath: this.config.upfilesConfig.presignPath
|
|
141
|
+
});
|
|
142
|
+
}
|
|
135
143
|
if (typeof window !== "undefined") {
|
|
136
144
|
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;
|
|
137
145
|
if (frontendBaseUrl) {
|
|
@@ -359,6 +367,28 @@ var AuthService = class {
|
|
|
359
367
|
}
|
|
360
368
|
return response;
|
|
361
369
|
}
|
|
370
|
+
async uploadAndUpdateAvatar(file) {
|
|
371
|
+
if (!this.token) {
|
|
372
|
+
throw new Error("Not authenticated");
|
|
373
|
+
}
|
|
374
|
+
if (!this.upfilesClient) {
|
|
375
|
+
throw new Error("Upfiles configuration is required. Please provide upfilesConfig in AuthConfig.");
|
|
376
|
+
}
|
|
377
|
+
try {
|
|
378
|
+
const folderPath = this.config.upfilesConfig?.folderPath || "avatars/";
|
|
379
|
+
const uploadResult = await this.upfilesClient.upload(file, {
|
|
380
|
+
folderPath,
|
|
381
|
+
fetchThumbnails: true
|
|
382
|
+
});
|
|
383
|
+
const response = await this.updateAvatar(uploadResult.publicUrl);
|
|
384
|
+
return response;
|
|
385
|
+
} catch (error) {
|
|
386
|
+
throw new Error(`Failed to upload avatar: ${error.message || "Unknown error"}`);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
getUpfilesClient() {
|
|
390
|
+
return this.upfilesClient;
|
|
391
|
+
}
|
|
362
392
|
async requestEmailChange(newEmail) {
|
|
363
393
|
if (!this.token) {
|
|
364
394
|
throw new Error("Not authenticated");
|
|
@@ -589,6 +619,18 @@ var useAuth = (config) => {
|
|
|
589
619
|
setLoading(false);
|
|
590
620
|
}
|
|
591
621
|
}, [authService]);
|
|
622
|
+
const uploadAndUpdateAvatar = React3.useCallback(async (file) => {
|
|
623
|
+
setLoading(true);
|
|
624
|
+
try {
|
|
625
|
+
const response = await authService.uploadAndUpdateAvatar(file);
|
|
626
|
+
if (response.success && response.user) {
|
|
627
|
+
setUser(response.user);
|
|
628
|
+
}
|
|
629
|
+
return response;
|
|
630
|
+
} finally {
|
|
631
|
+
setLoading(false);
|
|
632
|
+
}
|
|
633
|
+
}, [authService]);
|
|
592
634
|
return {
|
|
593
635
|
user,
|
|
594
636
|
isAuthenticated,
|
|
@@ -601,7 +643,8 @@ var useAuth = (config) => {
|
|
|
601
643
|
updateProfile,
|
|
602
644
|
getProfile,
|
|
603
645
|
getAllUsers,
|
|
604
|
-
getUserById
|
|
646
|
+
getUserById,
|
|
647
|
+
uploadAndUpdateAvatar
|
|
605
648
|
};
|
|
606
649
|
};
|
|
607
650
|
var ThemeContext = React3.createContext({ theme: "light", mounted: false });
|
|
@@ -660,7 +703,8 @@ var AuthProvider = ({ children, config }) => {
|
|
|
660
703
|
const authConfig = {
|
|
661
704
|
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"),
|
|
662
705
|
localStorageKey: config?.localStorageKey || "auth_token",
|
|
663
|
-
csrfEnabled: config?.csrfEnabled !== void 0 ? config.csrfEnabled : true
|
|
706
|
+
csrfEnabled: config?.csrfEnabled !== void 0 ? config.csrfEnabled : true,
|
|
707
|
+
upfilesConfig: config?.upfilesConfig
|
|
664
708
|
};
|
|
665
709
|
const [authService] = React3.useState(() => new AuthService(authConfig));
|
|
666
710
|
const [user, setUser] = React3.useState(null);
|
|
@@ -810,6 +854,18 @@ var AuthProvider = ({ children, config }) => {
|
|
|
810
854
|
setLoading(false);
|
|
811
855
|
}
|
|
812
856
|
}, [authService]);
|
|
857
|
+
const uploadAndUpdateAvatar = React3.useCallback(async (file) => {
|
|
858
|
+
setLoading(true);
|
|
859
|
+
try {
|
|
860
|
+
const response = await authService.uploadAndUpdateAvatar(file);
|
|
861
|
+
if (response.success && response.user) {
|
|
862
|
+
setUser(response.user);
|
|
863
|
+
}
|
|
864
|
+
return response;
|
|
865
|
+
} finally {
|
|
866
|
+
setLoading(false);
|
|
867
|
+
}
|
|
868
|
+
}, [authService]);
|
|
813
869
|
const requestEmailChange = React3.useCallback(async (newEmail) => {
|
|
814
870
|
setLoading(true);
|
|
815
871
|
try {
|
|
@@ -907,6 +963,7 @@ var AuthProvider = ({ children, config }) => {
|
|
|
907
963
|
resetPassword,
|
|
908
964
|
changePassword,
|
|
909
965
|
updateAvatar,
|
|
966
|
+
uploadAndUpdateAvatar,
|
|
910
967
|
requestEmailChange,
|
|
911
968
|
verifyEmailChange,
|
|
912
969
|
generate2FA,
|
|
@@ -4379,15 +4436,85 @@ var ChangePassword = ({ onSuccess, appearance }) => {
|
|
|
4379
4436
|
)
|
|
4380
4437
|
] }) });
|
|
4381
4438
|
};
|
|
4439
|
+
var AvatarUploader = ({
|
|
4440
|
+
onUploadComplete,
|
|
4441
|
+
onError,
|
|
4442
|
+
className,
|
|
4443
|
+
buttonClassName,
|
|
4444
|
+
maxFileSize = 5 * 1024 * 1024,
|
|
4445
|
+
// 5MB default
|
|
4446
|
+
upfilesConfig,
|
|
4447
|
+
buttonText = "Upload Avatar"
|
|
4448
|
+
}) => {
|
|
4449
|
+
const { uploadAndUpdateAvatar } = useAuth2();
|
|
4450
|
+
const [open, setOpen] = React3.useState(false);
|
|
4451
|
+
const [uploading, setUploading] = React3.useState(false);
|
|
4452
|
+
const handleSelect = async (image) => {
|
|
4453
|
+
setUploading(true);
|
|
4454
|
+
try {
|
|
4455
|
+
const response = await fetch(image.url);
|
|
4456
|
+
const blob = await response.blob();
|
|
4457
|
+
const file = new File([blob], image.originalName, { type: image.contentType });
|
|
4458
|
+
const result = await uploadAndUpdateAvatar(file);
|
|
4459
|
+
if (result.success && result.user?.avatar) {
|
|
4460
|
+
onUploadComplete?.(result.user.avatar);
|
|
4461
|
+
setOpen(false);
|
|
4462
|
+
} else {
|
|
4463
|
+
throw new Error(result.message || "Failed to update avatar");
|
|
4464
|
+
}
|
|
4465
|
+
} catch (error) {
|
|
4466
|
+
const err = error instanceof Error ? error : new Error("Upload failed");
|
|
4467
|
+
onError?.(err);
|
|
4468
|
+
} finally {
|
|
4469
|
+
setUploading(false);
|
|
4470
|
+
}
|
|
4471
|
+
};
|
|
4472
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, children: [
|
|
4473
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4474
|
+
"button",
|
|
4475
|
+
{
|
|
4476
|
+
type: "button",
|
|
4477
|
+
onClick: () => setOpen(true),
|
|
4478
|
+
disabled: uploading,
|
|
4479
|
+
className: buttonClassName || "px-4 py-2 text-sm rounded border bg-blue-600 text-white hover:bg-blue-700 disabled:opacity-50",
|
|
4480
|
+
children: uploading ? "Uploading..." : buttonText
|
|
4481
|
+
}
|
|
4482
|
+
),
|
|
4483
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4484
|
+
upfiles.ImageManager,
|
|
4485
|
+
{
|
|
4486
|
+
open,
|
|
4487
|
+
onOpenChange: setOpen,
|
|
4488
|
+
clientOptions: {
|
|
4489
|
+
baseUrl: upfilesConfig.baseUrl,
|
|
4490
|
+
apiKey: upfilesConfig.apiKey,
|
|
4491
|
+
apiKeyHeader: upfilesConfig.apiKeyHeader || "authorization",
|
|
4492
|
+
presignUrl: upfilesConfig.presignUrl,
|
|
4493
|
+
presignPath: upfilesConfig.presignPath
|
|
4494
|
+
},
|
|
4495
|
+
projectId: upfilesConfig.projectId,
|
|
4496
|
+
folderPath: upfilesConfig.folderPath || "avatars/",
|
|
4497
|
+
title: "Select Avatar",
|
|
4498
|
+
description: "Upload a new avatar or select from existing images.",
|
|
4499
|
+
mode: "full",
|
|
4500
|
+
maxFileSize,
|
|
4501
|
+
maxFiles: 1,
|
|
4502
|
+
autoRecordToDb: true,
|
|
4503
|
+
fetchThumbnails: true,
|
|
4504
|
+
onSelect: handleSelect
|
|
4505
|
+
}
|
|
4506
|
+
)
|
|
4507
|
+
] });
|
|
4508
|
+
};
|
|
4382
4509
|
var UserProfile = ({
|
|
4383
4510
|
showAvatar = true,
|
|
4384
4511
|
showEmailChange = true,
|
|
4385
|
-
showPasswordChange = true
|
|
4512
|
+
showPasswordChange = true,
|
|
4513
|
+
upfilesConfig
|
|
4386
4514
|
}) => {
|
|
4387
4515
|
const { user, updateProfile, requestEmailChange } = useAuth2();
|
|
4388
4516
|
const colors = useThemeColors();
|
|
4389
4517
|
const [name, setName] = React3.useState(user?.name || "");
|
|
4390
|
-
const [avatar, setAvatar] = React3.useState(user?.avatar || "");
|
|
4391
4518
|
const [phoneNumber, setPhoneNumber] = React3.useState(user?.phoneNumber || "");
|
|
4392
4519
|
const [newEmail, setNewEmail] = React3.useState("");
|
|
4393
4520
|
const [isLoading, setIsLoading] = React3.useState(false);
|
|
@@ -4403,9 +4530,6 @@ var UserProfile = ({
|
|
|
4403
4530
|
if (name !== user?.name) {
|
|
4404
4531
|
updates.name = name;
|
|
4405
4532
|
}
|
|
4406
|
-
if (showAvatar && avatar !== user?.avatar) {
|
|
4407
|
-
updates.avatar = avatar;
|
|
4408
|
-
}
|
|
4409
4533
|
if (phoneNumber !== user?.phoneNumber) {
|
|
4410
4534
|
updates.phoneNumber = phoneNumber;
|
|
4411
4535
|
}
|
|
@@ -4426,6 +4550,12 @@ var UserProfile = ({
|
|
|
4426
4550
|
setIsLoading(false);
|
|
4427
4551
|
}
|
|
4428
4552
|
};
|
|
4553
|
+
const handleAvatarUploadComplete = (avatarUrl) => {
|
|
4554
|
+
setSuccess("Avatar updated successfully!");
|
|
4555
|
+
};
|
|
4556
|
+
const handleAvatarUploadError = (error2) => {
|
|
4557
|
+
setError(error2.message || "Failed to upload avatar");
|
|
4558
|
+
};
|
|
4429
4559
|
const handleRequestEmailChange = async (e) => {
|
|
4430
4560
|
e.preventDefault();
|
|
4431
4561
|
setIsLoading(true);
|
|
@@ -4528,34 +4658,36 @@ var UserProfile = ({
|
|
|
4528
4658
|
}
|
|
4529
4659
|
)
|
|
4530
4660
|
] }),
|
|
4531
|
-
showAvatar && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginBottom: "20px" }, children: [
|
|
4532
|
-
/* @__PURE__ */ jsxRuntime.jsx("label", {
|
|
4661
|
+
showAvatar && upfilesConfig && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginBottom: "20px" }, children: [
|
|
4662
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { style: {
|
|
4533
4663
|
display: "block",
|
|
4534
4664
|
marginBottom: "8px",
|
|
4535
4665
|
fontWeight: 500,
|
|
4536
4666
|
color: colors.textSecondary,
|
|
4537
4667
|
fontSize: "14px"
|
|
4538
|
-
}, children: "Avatar
|
|
4539
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4540
|
-
"
|
|
4668
|
+
}, children: "Avatar" }),
|
|
4669
|
+
user?.avatar && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { marginBottom: "12px" }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4670
|
+
"img",
|
|
4541
4671
|
{
|
|
4542
|
-
|
|
4543
|
-
|
|
4544
|
-
value: avatar,
|
|
4545
|
-
onChange: (e) => setAvatar(e.target.value),
|
|
4546
|
-
disabled: isLoading,
|
|
4672
|
+
src: user.avatar,
|
|
4673
|
+
alt: "Current avatar",
|
|
4547
4674
|
style: {
|
|
4548
|
-
width: "
|
|
4549
|
-
|
|
4550
|
-
|
|
4551
|
-
|
|
4552
|
-
|
|
4553
|
-
|
|
4554
|
-
|
|
4555
|
-
|
|
4556
|
-
|
|
4557
|
-
|
|
4558
|
-
|
|
4675
|
+
width: "80px",
|
|
4676
|
+
height: "80px",
|
|
4677
|
+
borderRadius: "50%",
|
|
4678
|
+
objectFit: "cover",
|
|
4679
|
+
border: `2px solid ${colors.borderSecondary}`
|
|
4680
|
+
}
|
|
4681
|
+
}
|
|
4682
|
+
) }),
|
|
4683
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4684
|
+
AvatarUploader,
|
|
4685
|
+
{
|
|
4686
|
+
upfilesConfig,
|
|
4687
|
+
onUploadComplete: handleAvatarUploadComplete,
|
|
4688
|
+
onError: handleAvatarUploadError,
|
|
4689
|
+
maxFileSize: 5 * 1024 * 1024,
|
|
4690
|
+
accept: ["image/*"]
|
|
4559
4691
|
}
|
|
4560
4692
|
)
|
|
4561
4693
|
] }),
|
|
@@ -4667,6 +4799,65 @@ var UserProfile = ({
|
|
|
4667
4799
|
] })
|
|
4668
4800
|
] });
|
|
4669
4801
|
};
|
|
4802
|
+
var AvatarManager = ({
|
|
4803
|
+
open,
|
|
4804
|
+
onOpenChange,
|
|
4805
|
+
onAvatarUpdated,
|
|
4806
|
+
onError,
|
|
4807
|
+
title = "Select Avatar",
|
|
4808
|
+
description = "Choose an existing image or upload a new one",
|
|
4809
|
+
className,
|
|
4810
|
+
gridClassName,
|
|
4811
|
+
maxFileSize = 5 * 1024 * 1024,
|
|
4812
|
+
// 5MB default
|
|
4813
|
+
mode = "full",
|
|
4814
|
+
showDelete = false,
|
|
4815
|
+
upfilesConfig
|
|
4816
|
+
}) => {
|
|
4817
|
+
const { updateProfile } = useAuth2();
|
|
4818
|
+
const [updating, setUpdating] = React3.useState(false);
|
|
4819
|
+
const handleSelect = async (image) => {
|
|
4820
|
+
setUpdating(true);
|
|
4821
|
+
try {
|
|
4822
|
+
const response = await updateProfile({ avatar: image.url });
|
|
4823
|
+
if (response.success && response.user?.avatar) {
|
|
4824
|
+
onAvatarUpdated?.(response.user.avatar);
|
|
4825
|
+
onOpenChange(false);
|
|
4826
|
+
} else {
|
|
4827
|
+
throw new Error(response.message || "Failed to update avatar");
|
|
4828
|
+
}
|
|
4829
|
+
} catch (error) {
|
|
4830
|
+
const err = error instanceof Error ? error : new Error("Failed to update avatar");
|
|
4831
|
+
onError?.(err);
|
|
4832
|
+
} finally {
|
|
4833
|
+
setUpdating(false);
|
|
4834
|
+
}
|
|
4835
|
+
};
|
|
4836
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4837
|
+
upfiles.ImageManager,
|
|
4838
|
+
{
|
|
4839
|
+
open,
|
|
4840
|
+
onOpenChange,
|
|
4841
|
+
clientOptions: {
|
|
4842
|
+
baseUrl: upfilesConfig.baseUrl,
|
|
4843
|
+
apiKey: upfilesConfig.apiKey,
|
|
4844
|
+
apiKeyHeader: upfilesConfig.apiKeyHeader || "authorization",
|
|
4845
|
+
presignUrl: upfilesConfig.presignUrl,
|
|
4846
|
+
presignPath: upfilesConfig.presignPath
|
|
4847
|
+
},
|
|
4848
|
+
folderPath: upfilesConfig.folderPath || "avatars/",
|
|
4849
|
+
title,
|
|
4850
|
+
description,
|
|
4851
|
+
className,
|
|
4852
|
+
gridClassName,
|
|
4853
|
+
onSelect: handleSelect,
|
|
4854
|
+
maxFileSize,
|
|
4855
|
+
mode,
|
|
4856
|
+
showDelete,
|
|
4857
|
+
fetchThumbnails: true
|
|
4858
|
+
}
|
|
4859
|
+
);
|
|
4860
|
+
};
|
|
4670
4861
|
var isServer = typeof window === "undefined";
|
|
4671
4862
|
var useNextAuth = (config) => {
|
|
4672
4863
|
const [authService] = React3.useState(() => {
|
|
@@ -4863,6 +5054,8 @@ exports.AuthFlow = AuthFlow;
|
|
|
4863
5054
|
exports.AuthProvider = AuthProvider;
|
|
4864
5055
|
exports.AuthService = AuthService;
|
|
4865
5056
|
exports.AuthThemeProvider = AuthThemeProvider;
|
|
5057
|
+
exports.AvatarManager = AvatarManager;
|
|
5058
|
+
exports.AvatarUploader = AvatarUploader;
|
|
4866
5059
|
exports.ChangePassword = ChangePassword;
|
|
4867
5060
|
exports.EmailVerificationPage = EmailVerificationPage;
|
|
4868
5061
|
exports.ForgotPassword = ForgotPassword;
|