@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
|
@@ -24,6 +24,15 @@ interface AuthConfig {
|
|
|
24
24
|
localStorageKey?: string;
|
|
25
25
|
token?: string;
|
|
26
26
|
csrfEnabled?: boolean;
|
|
27
|
+
upfilesConfig?: UpfilesConfig;
|
|
28
|
+
}
|
|
29
|
+
interface UpfilesConfig {
|
|
30
|
+
baseUrl: string;
|
|
31
|
+
apiKey?: string;
|
|
32
|
+
apiKeyHeader?: 'authorization' | 'x-api-key' | 'x-up-api-key';
|
|
33
|
+
presignUrl?: string;
|
|
34
|
+
presignPath?: string;
|
|
35
|
+
folderPath?: string;
|
|
27
36
|
}
|
|
28
37
|
|
|
29
38
|
interface RegisterFormProps {
|
|
@@ -168,6 +177,15 @@ interface UserProfileProps {
|
|
|
168
177
|
showAvatar?: boolean;
|
|
169
178
|
showEmailChange?: boolean;
|
|
170
179
|
showPasswordChange?: boolean;
|
|
180
|
+
upfilesConfig?: {
|
|
181
|
+
baseUrl: string;
|
|
182
|
+
apiKey?: string;
|
|
183
|
+
apiKeyHeader?: 'authorization' | 'x-api-key' | 'x-up-api-key';
|
|
184
|
+
presignUrl?: string;
|
|
185
|
+
presignPath?: string;
|
|
186
|
+
folderPath?: string;
|
|
187
|
+
projectId?: string;
|
|
188
|
+
};
|
|
171
189
|
}
|
|
172
190
|
declare const UserProfile: React.FC<UserProfileProps>;
|
|
173
191
|
|
|
@@ -182,4 +200,48 @@ interface PhoneInputProps {
|
|
|
182
200
|
}
|
|
183
201
|
declare const PhoneInput: React.FC<PhoneInputProps>;
|
|
184
202
|
|
|
185
|
-
|
|
203
|
+
interface AvatarUploaderProps {
|
|
204
|
+
onUploadComplete?: (avatarUrl: string) => void;
|
|
205
|
+
onError?: (error: Error) => void;
|
|
206
|
+
className?: string;
|
|
207
|
+
buttonClassName?: string;
|
|
208
|
+
dropzoneClassName?: string;
|
|
209
|
+
maxFileSize?: number;
|
|
210
|
+
accept?: string[];
|
|
211
|
+
upfilesConfig: {
|
|
212
|
+
baseUrl: string;
|
|
213
|
+
apiKey?: string;
|
|
214
|
+
apiKeyHeader?: 'authorization' | 'x-api-key' | 'x-up-api-key';
|
|
215
|
+
presignUrl?: string;
|
|
216
|
+
presignPath?: string;
|
|
217
|
+
folderPath?: string;
|
|
218
|
+
projectId?: string;
|
|
219
|
+
};
|
|
220
|
+
buttonText?: string;
|
|
221
|
+
}
|
|
222
|
+
declare const AvatarUploader: React.FC<AvatarUploaderProps>;
|
|
223
|
+
|
|
224
|
+
interface AvatarManagerProps {
|
|
225
|
+
open: boolean;
|
|
226
|
+
onOpenChange: (open: boolean) => void;
|
|
227
|
+
onAvatarUpdated?: (avatarUrl: string) => void;
|
|
228
|
+
onError?: (error: Error) => void;
|
|
229
|
+
title?: string;
|
|
230
|
+
description?: string;
|
|
231
|
+
className?: string;
|
|
232
|
+
gridClassName?: string;
|
|
233
|
+
maxFileSize?: number;
|
|
234
|
+
mode?: 'full' | 'browse' | 'upload';
|
|
235
|
+
showDelete?: boolean;
|
|
236
|
+
upfilesConfig: {
|
|
237
|
+
baseUrl: string;
|
|
238
|
+
apiKey?: string;
|
|
239
|
+
apiKeyHeader?: 'authorization' | 'x-api-key' | 'x-up-api-key';
|
|
240
|
+
presignUrl?: string;
|
|
241
|
+
presignPath?: string;
|
|
242
|
+
folderPath?: string;
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
declare const AvatarManager: React.FC<AvatarManagerProps>;
|
|
246
|
+
|
|
247
|
+
export { AuthFlow, AvatarManager, AvatarManagerProps, AvatarUploader, AvatarUploaderProps, ChangePassword, EmailVerificationPage, ForgotPassword, LoginForm, OtpForm, PhoneInput, ProtectedRoute, PublicRoute, RegisterForm, RegisterFormProps, ResetPassword, SignIn, SignOut, SignUp, UserButton, UserProfile, VerifyEmail };
|
package/dist/index.components.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
"use client";
|
|
2
1
|
'use strict';
|
|
3
2
|
|
|
4
3
|
var React2 = require('react');
|
|
5
4
|
var axios = require('axios');
|
|
5
|
+
var upfiles = require('@thetechfossil/upfiles');
|
|
6
6
|
var jsxRuntime = require('react/jsx-runtime');
|
|
7
7
|
var PhoneInputWithCountry = require('react-phone-number-input');
|
|
8
8
|
require('react-phone-number-input/style.css');
|
|
@@ -119,11 +119,10 @@ var HttpClient = class {
|
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
121
|
};
|
|
122
|
-
|
|
123
|
-
// src/core/auth-service.ts
|
|
124
122
|
var AuthService = class {
|
|
125
123
|
constructor(config) {
|
|
126
124
|
this.token = null;
|
|
125
|
+
this.upfilesClient = null;
|
|
127
126
|
this.config = {
|
|
128
127
|
localStorageKey: "auth_token",
|
|
129
128
|
csrfEnabled: true,
|
|
@@ -131,6 +130,15 @@ var AuthService = class {
|
|
|
131
130
|
};
|
|
132
131
|
this.httpClient = new HttpClient(this.config.baseUrl);
|
|
133
132
|
this.loadTokenFromStorage();
|
|
133
|
+
if (this.config.upfilesConfig) {
|
|
134
|
+
this.upfilesClient = new upfiles.UpfilesClient({
|
|
135
|
+
baseUrl: this.config.upfilesConfig.baseUrl,
|
|
136
|
+
apiKey: this.config.upfilesConfig.apiKey,
|
|
137
|
+
apiKeyHeader: this.config.upfilesConfig.apiKeyHeader,
|
|
138
|
+
presignUrl: this.config.upfilesConfig.presignUrl,
|
|
139
|
+
presignPath: this.config.upfilesConfig.presignPath
|
|
140
|
+
});
|
|
141
|
+
}
|
|
134
142
|
if (typeof window !== "undefined") {
|
|
135
143
|
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;
|
|
136
144
|
if (frontendBaseUrl) {
|
|
@@ -358,6 +366,28 @@ var AuthService = class {
|
|
|
358
366
|
}
|
|
359
367
|
return response;
|
|
360
368
|
}
|
|
369
|
+
async uploadAndUpdateAvatar(file) {
|
|
370
|
+
if (!this.token) {
|
|
371
|
+
throw new Error("Not authenticated");
|
|
372
|
+
}
|
|
373
|
+
if (!this.upfilesClient) {
|
|
374
|
+
throw new Error("Upfiles configuration is required. Please provide upfilesConfig in AuthConfig.");
|
|
375
|
+
}
|
|
376
|
+
try {
|
|
377
|
+
const folderPath = this.config.upfilesConfig?.folderPath || "avatars/";
|
|
378
|
+
const uploadResult = await this.upfilesClient.upload(file, {
|
|
379
|
+
folderPath,
|
|
380
|
+
fetchThumbnails: true
|
|
381
|
+
});
|
|
382
|
+
const response = await this.updateAvatar(uploadResult.publicUrl);
|
|
383
|
+
return response;
|
|
384
|
+
} catch (error) {
|
|
385
|
+
throw new Error(`Failed to upload avatar: ${error.message || "Unknown error"}`);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
getUpfilesClient() {
|
|
389
|
+
return this.upfilesClient;
|
|
390
|
+
}
|
|
361
391
|
async requestEmailChange(newEmail) {
|
|
362
392
|
if (!this.token) {
|
|
363
393
|
throw new Error("Not authenticated");
|
|
@@ -590,6 +620,18 @@ var useAuth = (config) => {
|
|
|
590
620
|
setLoading(false);
|
|
591
621
|
}
|
|
592
622
|
}, [authService]);
|
|
623
|
+
const uploadAndUpdateAvatar = React2.useCallback(async (file) => {
|
|
624
|
+
setLoading(true);
|
|
625
|
+
try {
|
|
626
|
+
const response = await authService.uploadAndUpdateAvatar(file);
|
|
627
|
+
if (response.success && response.user) {
|
|
628
|
+
setUser(response.user);
|
|
629
|
+
}
|
|
630
|
+
return response;
|
|
631
|
+
} finally {
|
|
632
|
+
setLoading(false);
|
|
633
|
+
}
|
|
634
|
+
}, [authService]);
|
|
593
635
|
return {
|
|
594
636
|
user,
|
|
595
637
|
isAuthenticated,
|
|
@@ -602,7 +644,8 @@ var useAuth = (config) => {
|
|
|
602
644
|
updateProfile,
|
|
603
645
|
getProfile,
|
|
604
646
|
getAllUsers,
|
|
605
|
-
getUserById
|
|
647
|
+
getUserById,
|
|
648
|
+
uploadAndUpdateAvatar
|
|
606
649
|
};
|
|
607
650
|
};
|
|
608
651
|
var ThemeContext = React2.createContext({ theme: "light", mounted: false });
|
|
@@ -4069,15 +4112,85 @@ var ChangePassword = ({ onSuccess, appearance }) => {
|
|
|
4069
4112
|
)
|
|
4070
4113
|
] }) });
|
|
4071
4114
|
};
|
|
4115
|
+
var AvatarUploader = ({
|
|
4116
|
+
onUploadComplete,
|
|
4117
|
+
onError,
|
|
4118
|
+
className,
|
|
4119
|
+
buttonClassName,
|
|
4120
|
+
maxFileSize = 5 * 1024 * 1024,
|
|
4121
|
+
// 5MB default
|
|
4122
|
+
upfilesConfig,
|
|
4123
|
+
buttonText = "Upload Avatar"
|
|
4124
|
+
}) => {
|
|
4125
|
+
const { uploadAndUpdateAvatar } = useAuth2();
|
|
4126
|
+
const [open, setOpen] = React2.useState(false);
|
|
4127
|
+
const [uploading, setUploading] = React2.useState(false);
|
|
4128
|
+
const handleSelect = async (image) => {
|
|
4129
|
+
setUploading(true);
|
|
4130
|
+
try {
|
|
4131
|
+
const response = await fetch(image.url);
|
|
4132
|
+
const blob = await response.blob();
|
|
4133
|
+
const file = new File([blob], image.originalName, { type: image.contentType });
|
|
4134
|
+
const result = await uploadAndUpdateAvatar(file);
|
|
4135
|
+
if (result.success && result.user?.avatar) {
|
|
4136
|
+
onUploadComplete?.(result.user.avatar);
|
|
4137
|
+
setOpen(false);
|
|
4138
|
+
} else {
|
|
4139
|
+
throw new Error(result.message || "Failed to update avatar");
|
|
4140
|
+
}
|
|
4141
|
+
} catch (error) {
|
|
4142
|
+
const err = error instanceof Error ? error : new Error("Upload failed");
|
|
4143
|
+
onError?.(err);
|
|
4144
|
+
} finally {
|
|
4145
|
+
setUploading(false);
|
|
4146
|
+
}
|
|
4147
|
+
};
|
|
4148
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, children: [
|
|
4149
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4150
|
+
"button",
|
|
4151
|
+
{
|
|
4152
|
+
type: "button",
|
|
4153
|
+
onClick: () => setOpen(true),
|
|
4154
|
+
disabled: uploading,
|
|
4155
|
+
className: buttonClassName || "px-4 py-2 text-sm rounded border bg-blue-600 text-white hover:bg-blue-700 disabled:opacity-50",
|
|
4156
|
+
children: uploading ? "Uploading..." : buttonText
|
|
4157
|
+
}
|
|
4158
|
+
),
|
|
4159
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4160
|
+
upfiles.ImageManager,
|
|
4161
|
+
{
|
|
4162
|
+
open,
|
|
4163
|
+
onOpenChange: setOpen,
|
|
4164
|
+
clientOptions: {
|
|
4165
|
+
baseUrl: upfilesConfig.baseUrl,
|
|
4166
|
+
apiKey: upfilesConfig.apiKey,
|
|
4167
|
+
apiKeyHeader: upfilesConfig.apiKeyHeader || "authorization",
|
|
4168
|
+
presignUrl: upfilesConfig.presignUrl,
|
|
4169
|
+
presignPath: upfilesConfig.presignPath
|
|
4170
|
+
},
|
|
4171
|
+
projectId: upfilesConfig.projectId,
|
|
4172
|
+
folderPath: upfilesConfig.folderPath || "avatars/",
|
|
4173
|
+
title: "Select Avatar",
|
|
4174
|
+
description: "Upload a new avatar or select from existing images.",
|
|
4175
|
+
mode: "full",
|
|
4176
|
+
maxFileSize,
|
|
4177
|
+
maxFiles: 1,
|
|
4178
|
+
autoRecordToDb: true,
|
|
4179
|
+
fetchThumbnails: true,
|
|
4180
|
+
onSelect: handleSelect
|
|
4181
|
+
}
|
|
4182
|
+
)
|
|
4183
|
+
] });
|
|
4184
|
+
};
|
|
4072
4185
|
var UserProfile = ({
|
|
4073
4186
|
showAvatar = true,
|
|
4074
4187
|
showEmailChange = true,
|
|
4075
|
-
showPasswordChange = true
|
|
4188
|
+
showPasswordChange = true,
|
|
4189
|
+
upfilesConfig
|
|
4076
4190
|
}) => {
|
|
4077
4191
|
const { user, updateProfile, requestEmailChange } = useAuth2();
|
|
4078
4192
|
const colors = useThemeColors();
|
|
4079
4193
|
const [name, setName] = React2.useState(user?.name || "");
|
|
4080
|
-
const [avatar, setAvatar] = React2.useState(user?.avatar || "");
|
|
4081
4194
|
const [phoneNumber, setPhoneNumber] = React2.useState(user?.phoneNumber || "");
|
|
4082
4195
|
const [newEmail, setNewEmail] = React2.useState("");
|
|
4083
4196
|
const [isLoading, setIsLoading] = React2.useState(false);
|
|
@@ -4093,9 +4206,6 @@ var UserProfile = ({
|
|
|
4093
4206
|
if (name !== user?.name) {
|
|
4094
4207
|
updates.name = name;
|
|
4095
4208
|
}
|
|
4096
|
-
if (showAvatar && avatar !== user?.avatar) {
|
|
4097
|
-
updates.avatar = avatar;
|
|
4098
|
-
}
|
|
4099
4209
|
if (phoneNumber !== user?.phoneNumber) {
|
|
4100
4210
|
updates.phoneNumber = phoneNumber;
|
|
4101
4211
|
}
|
|
@@ -4116,6 +4226,12 @@ var UserProfile = ({
|
|
|
4116
4226
|
setIsLoading(false);
|
|
4117
4227
|
}
|
|
4118
4228
|
};
|
|
4229
|
+
const handleAvatarUploadComplete = (avatarUrl) => {
|
|
4230
|
+
setSuccess("Avatar updated successfully!");
|
|
4231
|
+
};
|
|
4232
|
+
const handleAvatarUploadError = (error2) => {
|
|
4233
|
+
setError(error2.message || "Failed to upload avatar");
|
|
4234
|
+
};
|
|
4119
4235
|
const handleRequestEmailChange = async (e) => {
|
|
4120
4236
|
e.preventDefault();
|
|
4121
4237
|
setIsLoading(true);
|
|
@@ -4218,34 +4334,36 @@ var UserProfile = ({
|
|
|
4218
4334
|
}
|
|
4219
4335
|
)
|
|
4220
4336
|
] }),
|
|
4221
|
-
showAvatar && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginBottom: "20px" }, children: [
|
|
4222
|
-
/* @__PURE__ */ jsxRuntime.jsx("label", {
|
|
4337
|
+
showAvatar && upfilesConfig && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginBottom: "20px" }, children: [
|
|
4338
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { style: {
|
|
4223
4339
|
display: "block",
|
|
4224
4340
|
marginBottom: "8px",
|
|
4225
4341
|
fontWeight: 500,
|
|
4226
4342
|
color: colors.textSecondary,
|
|
4227
4343
|
fontSize: "14px"
|
|
4228
|
-
}, children: "Avatar
|
|
4229
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4230
|
-
"
|
|
4344
|
+
}, children: "Avatar" }),
|
|
4345
|
+
user?.avatar && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { marginBottom: "12px" }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4346
|
+
"img",
|
|
4231
4347
|
{
|
|
4232
|
-
|
|
4233
|
-
|
|
4234
|
-
value: avatar,
|
|
4235
|
-
onChange: (e) => setAvatar(e.target.value),
|
|
4236
|
-
disabled: isLoading,
|
|
4348
|
+
src: user.avatar,
|
|
4349
|
+
alt: "Current avatar",
|
|
4237
4350
|
style: {
|
|
4238
|
-
width: "
|
|
4239
|
-
|
|
4240
|
-
|
|
4241
|
-
|
|
4242
|
-
|
|
4243
|
-
|
|
4244
|
-
|
|
4245
|
-
|
|
4246
|
-
|
|
4247
|
-
|
|
4248
|
-
|
|
4351
|
+
width: "80px",
|
|
4352
|
+
height: "80px",
|
|
4353
|
+
borderRadius: "50%",
|
|
4354
|
+
objectFit: "cover",
|
|
4355
|
+
border: `2px solid ${colors.borderSecondary}`
|
|
4356
|
+
}
|
|
4357
|
+
}
|
|
4358
|
+
) }),
|
|
4359
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4360
|
+
AvatarUploader,
|
|
4361
|
+
{
|
|
4362
|
+
upfilesConfig,
|
|
4363
|
+
onUploadComplete: handleAvatarUploadComplete,
|
|
4364
|
+
onError: handleAvatarUploadError,
|
|
4365
|
+
maxFileSize: 5 * 1024 * 1024,
|
|
4366
|
+
accept: ["image/*"]
|
|
4249
4367
|
}
|
|
4250
4368
|
)
|
|
4251
4369
|
] }),
|
|
@@ -4357,8 +4475,69 @@ var UserProfile = ({
|
|
|
4357
4475
|
] })
|
|
4358
4476
|
] });
|
|
4359
4477
|
};
|
|
4478
|
+
var AvatarManager = ({
|
|
4479
|
+
open,
|
|
4480
|
+
onOpenChange,
|
|
4481
|
+
onAvatarUpdated,
|
|
4482
|
+
onError,
|
|
4483
|
+
title = "Select Avatar",
|
|
4484
|
+
description = "Choose an existing image or upload a new one",
|
|
4485
|
+
className,
|
|
4486
|
+
gridClassName,
|
|
4487
|
+
maxFileSize = 5 * 1024 * 1024,
|
|
4488
|
+
// 5MB default
|
|
4489
|
+
mode = "full",
|
|
4490
|
+
showDelete = false,
|
|
4491
|
+
upfilesConfig
|
|
4492
|
+
}) => {
|
|
4493
|
+
const { updateProfile } = useAuth2();
|
|
4494
|
+
const [updating, setUpdating] = React2.useState(false);
|
|
4495
|
+
const handleSelect = async (image) => {
|
|
4496
|
+
setUpdating(true);
|
|
4497
|
+
try {
|
|
4498
|
+
const response = await updateProfile({ avatar: image.url });
|
|
4499
|
+
if (response.success && response.user?.avatar) {
|
|
4500
|
+
onAvatarUpdated?.(response.user.avatar);
|
|
4501
|
+
onOpenChange(false);
|
|
4502
|
+
} else {
|
|
4503
|
+
throw new Error(response.message || "Failed to update avatar");
|
|
4504
|
+
}
|
|
4505
|
+
} catch (error) {
|
|
4506
|
+
const err = error instanceof Error ? error : new Error("Failed to update avatar");
|
|
4507
|
+
onError?.(err);
|
|
4508
|
+
} finally {
|
|
4509
|
+
setUpdating(false);
|
|
4510
|
+
}
|
|
4511
|
+
};
|
|
4512
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4513
|
+
upfiles.ImageManager,
|
|
4514
|
+
{
|
|
4515
|
+
open,
|
|
4516
|
+
onOpenChange,
|
|
4517
|
+
clientOptions: {
|
|
4518
|
+
baseUrl: upfilesConfig.baseUrl,
|
|
4519
|
+
apiKey: upfilesConfig.apiKey,
|
|
4520
|
+
apiKeyHeader: upfilesConfig.apiKeyHeader || "authorization",
|
|
4521
|
+
presignUrl: upfilesConfig.presignUrl,
|
|
4522
|
+
presignPath: upfilesConfig.presignPath
|
|
4523
|
+
},
|
|
4524
|
+
folderPath: upfilesConfig.folderPath || "avatars/",
|
|
4525
|
+
title,
|
|
4526
|
+
description,
|
|
4527
|
+
className,
|
|
4528
|
+
gridClassName,
|
|
4529
|
+
onSelect: handleSelect,
|
|
4530
|
+
maxFileSize,
|
|
4531
|
+
mode,
|
|
4532
|
+
showDelete,
|
|
4533
|
+
fetchThumbnails: true
|
|
4534
|
+
}
|
|
4535
|
+
);
|
|
4536
|
+
};
|
|
4360
4537
|
|
|
4361
4538
|
exports.AuthFlow = AuthFlow;
|
|
4539
|
+
exports.AvatarManager = AvatarManager;
|
|
4540
|
+
exports.AvatarUploader = AvatarUploader;
|
|
4362
4541
|
exports.ChangePassword = ChangePassword;
|
|
4363
4542
|
exports.EmailVerificationPage = EmailVerificationPage;
|
|
4364
4543
|
exports.ForgotPassword = ForgotPassword;
|