@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.
- package/dist/index.components.d.ts +52 -1
- package/dist/index.components.js +165 -3
- package/dist/index.components.js.map +1 -1
- package/dist/index.components.mjs +164 -4
- package/dist/index.components.mjs.map +1 -1
- package/dist/index.d.ts +68 -1
- package/dist/index.js +202 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +182 -5
- package/dist/index.mjs.map +1 -1
- package/dist/index.next.d.ts +59 -1
- package/dist/index.next.js +180 -4
- package/dist/index.next.js.map +1 -1
- package/dist/index.next.mjs +179 -5
- package/dist/index.next.mjs.map +1 -1
- package/dist/index.next.server.d.ts +15 -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.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>;
|
|
@@ -438,6 +454,48 @@ interface PhoneInputProps {
|
|
|
438
454
|
}
|
|
439
455
|
declare const PhoneInput: React.FC<PhoneInputProps>;
|
|
440
456
|
|
|
457
|
+
interface AvatarUploaderProps {
|
|
458
|
+
onUploadComplete?: (avatarUrl: string) => void;
|
|
459
|
+
onError?: (error: Error) => void;
|
|
460
|
+
className?: string;
|
|
461
|
+
buttonClassName?: string;
|
|
462
|
+
dropzoneClassName?: string;
|
|
463
|
+
maxFileSize?: number;
|
|
464
|
+
accept?: string[];
|
|
465
|
+
upfilesConfig: {
|
|
466
|
+
baseUrl: string;
|
|
467
|
+
apiKey?: string;
|
|
468
|
+
apiKeyHeader?: 'authorization' | 'x-api-key' | 'x-up-api-key';
|
|
469
|
+
presignUrl?: string;
|
|
470
|
+
presignPath?: string;
|
|
471
|
+
folderPath?: string;
|
|
472
|
+
};
|
|
473
|
+
}
|
|
474
|
+
declare const AvatarUploader: React.FC<AvatarUploaderProps>;
|
|
475
|
+
|
|
476
|
+
interface AvatarManagerProps {
|
|
477
|
+
open: boolean;
|
|
478
|
+
onOpenChange: (open: boolean) => void;
|
|
479
|
+
onAvatarUpdated?: (avatarUrl: string) => void;
|
|
480
|
+
onError?: (error: Error) => void;
|
|
481
|
+
title?: string;
|
|
482
|
+
description?: string;
|
|
483
|
+
className?: string;
|
|
484
|
+
gridClassName?: string;
|
|
485
|
+
maxFileSize?: number;
|
|
486
|
+
mode?: 'full' | 'browse' | 'upload';
|
|
487
|
+
showDelete?: boolean;
|
|
488
|
+
upfilesConfig: {
|
|
489
|
+
baseUrl: string;
|
|
490
|
+
apiKey?: string;
|
|
491
|
+
apiKeyHeader?: 'authorization' | 'x-api-key' | 'x-up-api-key';
|
|
492
|
+
presignUrl?: string;
|
|
493
|
+
presignPath?: string;
|
|
494
|
+
folderPath?: string;
|
|
495
|
+
};
|
|
496
|
+
}
|
|
497
|
+
declare const AvatarManager: React.FC<AvatarManagerProps>;
|
|
498
|
+
|
|
441
499
|
interface UseNextAuthReturn {
|
|
442
500
|
user: User | null;
|
|
443
501
|
isAuthenticated: boolean;
|
|
@@ -458,4 +516,4 @@ interface UseNextAuthReturn {
|
|
|
458
516
|
}
|
|
459
517
|
declare const useNextAuth: (config: AuthConfig) => UseNextAuthReturn;
|
|
460
518
|
|
|
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 };
|
|
519
|
+
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
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
4
|
var axios = require('axios');
|
|
5
|
+
var upfiles = require('@thetechfossil/upfiles');
|
|
5
6
|
var React3 = require('react');
|
|
6
7
|
var jsxRuntime = require('react/jsx-runtime');
|
|
7
8
|
var PhoneInputWithCountry = require('react-phone-number-input');
|
|
@@ -120,11 +121,10 @@ var HttpClient = class {
|
|
|
120
121
|
}
|
|
121
122
|
}
|
|
122
123
|
};
|
|
123
|
-
|
|
124
|
-
// src/core/auth-service.ts
|
|
125
124
|
var AuthService = class {
|
|
126
125
|
constructor(config) {
|
|
127
126
|
this.token = null;
|
|
127
|
+
this.upfilesClient = null;
|
|
128
128
|
this.config = {
|
|
129
129
|
localStorageKey: "auth_token",
|
|
130
130
|
csrfEnabled: true,
|
|
@@ -132,6 +132,15 @@ var AuthService = class {
|
|
|
132
132
|
};
|
|
133
133
|
this.httpClient = new HttpClient(this.config.baseUrl);
|
|
134
134
|
this.loadTokenFromStorage();
|
|
135
|
+
if (this.config.upfilesConfig) {
|
|
136
|
+
this.upfilesClient = new upfiles.UpfilesClient({
|
|
137
|
+
baseUrl: this.config.upfilesConfig.baseUrl,
|
|
138
|
+
apiKey: this.config.upfilesConfig.apiKey,
|
|
139
|
+
apiKeyHeader: this.config.upfilesConfig.apiKeyHeader,
|
|
140
|
+
presignUrl: this.config.upfilesConfig.presignUrl,
|
|
141
|
+
presignPath: this.config.upfilesConfig.presignPath
|
|
142
|
+
});
|
|
143
|
+
}
|
|
135
144
|
if (typeof window !== "undefined") {
|
|
136
145
|
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
146
|
if (frontendBaseUrl) {
|
|
@@ -359,6 +368,28 @@ var AuthService = class {
|
|
|
359
368
|
}
|
|
360
369
|
return response;
|
|
361
370
|
}
|
|
371
|
+
async uploadAndUpdateAvatar(file) {
|
|
372
|
+
if (!this.token) {
|
|
373
|
+
throw new Error("Not authenticated");
|
|
374
|
+
}
|
|
375
|
+
if (!this.upfilesClient) {
|
|
376
|
+
throw new Error("Upfiles configuration is required. Please provide upfilesConfig in AuthConfig.");
|
|
377
|
+
}
|
|
378
|
+
try {
|
|
379
|
+
const folderPath = this.config.upfilesConfig?.folderPath || "avatars/";
|
|
380
|
+
const uploadResult = await this.upfilesClient.upload(file, {
|
|
381
|
+
folderPath,
|
|
382
|
+
fetchThumbnails: true
|
|
383
|
+
});
|
|
384
|
+
const response = await this.updateAvatar(uploadResult.publicUrl);
|
|
385
|
+
return response;
|
|
386
|
+
} catch (error) {
|
|
387
|
+
throw new Error(`Failed to upload avatar: ${error.message || "Unknown error"}`);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
getUpfilesClient() {
|
|
391
|
+
return this.upfilesClient;
|
|
392
|
+
}
|
|
362
393
|
async requestEmailChange(newEmail) {
|
|
363
394
|
if (!this.token) {
|
|
364
395
|
throw new Error("Not authenticated");
|
|
@@ -589,6 +620,18 @@ var useAuth = (config) => {
|
|
|
589
620
|
setLoading(false);
|
|
590
621
|
}
|
|
591
622
|
}, [authService]);
|
|
623
|
+
const uploadAndUpdateAvatar = React3.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]);
|
|
592
635
|
return {
|
|
593
636
|
user,
|
|
594
637
|
isAuthenticated,
|
|
@@ -601,7 +644,8 @@ var useAuth = (config) => {
|
|
|
601
644
|
updateProfile,
|
|
602
645
|
getProfile,
|
|
603
646
|
getAllUsers,
|
|
604
|
-
getUserById
|
|
647
|
+
getUserById,
|
|
648
|
+
uploadAndUpdateAvatar
|
|
605
649
|
};
|
|
606
650
|
};
|
|
607
651
|
var ThemeContext = React3.createContext({ theme: "light", mounted: false });
|
|
@@ -660,7 +704,8 @@ var AuthProvider = ({ children, config }) => {
|
|
|
660
704
|
const authConfig = {
|
|
661
705
|
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
706
|
localStorageKey: config?.localStorageKey || "auth_token",
|
|
663
|
-
csrfEnabled: config?.csrfEnabled !== void 0 ? config.csrfEnabled : true
|
|
707
|
+
csrfEnabled: config?.csrfEnabled !== void 0 ? config.csrfEnabled : true,
|
|
708
|
+
upfilesConfig: config?.upfilesConfig
|
|
664
709
|
};
|
|
665
710
|
const [authService] = React3.useState(() => new AuthService(authConfig));
|
|
666
711
|
const [user, setUser] = React3.useState(null);
|
|
@@ -810,6 +855,18 @@ var AuthProvider = ({ children, config }) => {
|
|
|
810
855
|
setLoading(false);
|
|
811
856
|
}
|
|
812
857
|
}, [authService]);
|
|
858
|
+
const uploadAndUpdateAvatar = React3.useCallback(async (file) => {
|
|
859
|
+
setLoading(true);
|
|
860
|
+
try {
|
|
861
|
+
const response = await authService.uploadAndUpdateAvatar(file);
|
|
862
|
+
if (response.success && response.user) {
|
|
863
|
+
setUser(response.user);
|
|
864
|
+
}
|
|
865
|
+
return response;
|
|
866
|
+
} finally {
|
|
867
|
+
setLoading(false);
|
|
868
|
+
}
|
|
869
|
+
}, [authService]);
|
|
813
870
|
const requestEmailChange = React3.useCallback(async (newEmail) => {
|
|
814
871
|
setLoading(true);
|
|
815
872
|
try {
|
|
@@ -907,6 +964,7 @@ var AuthProvider = ({ children, config }) => {
|
|
|
907
964
|
resetPassword,
|
|
908
965
|
changePassword,
|
|
909
966
|
updateAvatar,
|
|
967
|
+
uploadAndUpdateAvatar,
|
|
910
968
|
requestEmailChange,
|
|
911
969
|
verifyEmailChange,
|
|
912
970
|
generate2FA,
|
|
@@ -4667,6 +4725,122 @@ var UserProfile = ({
|
|
|
4667
4725
|
] })
|
|
4668
4726
|
] });
|
|
4669
4727
|
};
|
|
4728
|
+
var AvatarUploader = ({
|
|
4729
|
+
onUploadComplete,
|
|
4730
|
+
onError,
|
|
4731
|
+
className,
|
|
4732
|
+
buttonClassName,
|
|
4733
|
+
dropzoneClassName,
|
|
4734
|
+
maxFileSize = 5 * 1024 * 1024,
|
|
4735
|
+
// 5MB default
|
|
4736
|
+
accept = ["image/*"],
|
|
4737
|
+
upfilesConfig
|
|
4738
|
+
}) => {
|
|
4739
|
+
const { uploadAndUpdateAvatar } = useAuth2();
|
|
4740
|
+
const [uploading, setUploading] = React3.useState(false);
|
|
4741
|
+
const handleUploadComplete = async (files) => {
|
|
4742
|
+
if (files.length === 0)
|
|
4743
|
+
return;
|
|
4744
|
+
setUploading(true);
|
|
4745
|
+
try {
|
|
4746
|
+
const file = files[0];
|
|
4747
|
+
const response = await uploadAndUpdateAvatar(file.file);
|
|
4748
|
+
if (response.success && response.user?.avatar) {
|
|
4749
|
+
onUploadComplete?.(response.user.avatar);
|
|
4750
|
+
} else {
|
|
4751
|
+
throw new Error(response.message || "Failed to update avatar");
|
|
4752
|
+
}
|
|
4753
|
+
} catch (error) {
|
|
4754
|
+
const err = error instanceof Error ? error : new Error("Upload failed");
|
|
4755
|
+
onError?.(err);
|
|
4756
|
+
} finally {
|
|
4757
|
+
setUploading(false);
|
|
4758
|
+
}
|
|
4759
|
+
};
|
|
4760
|
+
const handleError = (error) => {
|
|
4761
|
+
onError?.(error);
|
|
4762
|
+
};
|
|
4763
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4764
|
+
upfiles.Uploader,
|
|
4765
|
+
{
|
|
4766
|
+
clientOptions: {
|
|
4767
|
+
baseUrl: upfilesConfig.baseUrl,
|
|
4768
|
+
apiKey: upfilesConfig.apiKey,
|
|
4769
|
+
apiKeyHeader: upfilesConfig.apiKeyHeader || "authorization",
|
|
4770
|
+
presignUrl: upfilesConfig.presignUrl,
|
|
4771
|
+
presignPath: upfilesConfig.presignPath
|
|
4772
|
+
},
|
|
4773
|
+
multiple: false,
|
|
4774
|
+
accept,
|
|
4775
|
+
maxFileSize,
|
|
4776
|
+
maxFiles: 1,
|
|
4777
|
+
onComplete: handleUploadComplete,
|
|
4778
|
+
onError: handleError,
|
|
4779
|
+
buttonClassName,
|
|
4780
|
+
dropzoneClassName,
|
|
4781
|
+
children: uploading ? "Uploading..." : "Upload Avatar"
|
|
4782
|
+
}
|
|
4783
|
+
) });
|
|
4784
|
+
};
|
|
4785
|
+
var AvatarManager = ({
|
|
4786
|
+
open,
|
|
4787
|
+
onOpenChange,
|
|
4788
|
+
onAvatarUpdated,
|
|
4789
|
+
onError,
|
|
4790
|
+
title = "Select Avatar",
|
|
4791
|
+
description = "Choose an existing image or upload a new one",
|
|
4792
|
+
className,
|
|
4793
|
+
gridClassName,
|
|
4794
|
+
maxFileSize = 5 * 1024 * 1024,
|
|
4795
|
+
// 5MB default
|
|
4796
|
+
mode = "full",
|
|
4797
|
+
showDelete = false,
|
|
4798
|
+
upfilesConfig
|
|
4799
|
+
}) => {
|
|
4800
|
+
const { updateProfile } = useAuth2();
|
|
4801
|
+
const [updating, setUpdating] = React3.useState(false);
|
|
4802
|
+
const handleSelect = async (image) => {
|
|
4803
|
+
setUpdating(true);
|
|
4804
|
+
try {
|
|
4805
|
+
const response = await updateProfile({ avatar: image.url });
|
|
4806
|
+
if (response.success && response.user?.avatar) {
|
|
4807
|
+
onAvatarUpdated?.(response.user.avatar);
|
|
4808
|
+
onOpenChange(false);
|
|
4809
|
+
} else {
|
|
4810
|
+
throw new Error(response.message || "Failed to update avatar");
|
|
4811
|
+
}
|
|
4812
|
+
} catch (error) {
|
|
4813
|
+
const err = error instanceof Error ? error : new Error("Failed to update avatar");
|
|
4814
|
+
onError?.(err);
|
|
4815
|
+
} finally {
|
|
4816
|
+
setUpdating(false);
|
|
4817
|
+
}
|
|
4818
|
+
};
|
|
4819
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4820
|
+
upfiles.ImageManager,
|
|
4821
|
+
{
|
|
4822
|
+
open,
|
|
4823
|
+
onOpenChange,
|
|
4824
|
+
clientOptions: {
|
|
4825
|
+
baseUrl: upfilesConfig.baseUrl,
|
|
4826
|
+
apiKey: upfilesConfig.apiKey,
|
|
4827
|
+
apiKeyHeader: upfilesConfig.apiKeyHeader || "authorization",
|
|
4828
|
+
presignUrl: upfilesConfig.presignUrl,
|
|
4829
|
+
presignPath: upfilesConfig.presignPath
|
|
4830
|
+
},
|
|
4831
|
+
folderPath: upfilesConfig.folderPath || "avatars/",
|
|
4832
|
+
title,
|
|
4833
|
+
description,
|
|
4834
|
+
className,
|
|
4835
|
+
gridClassName,
|
|
4836
|
+
onSelect: handleSelect,
|
|
4837
|
+
maxFileSize,
|
|
4838
|
+
mode,
|
|
4839
|
+
showDelete,
|
|
4840
|
+
fetchThumbnails: true
|
|
4841
|
+
}
|
|
4842
|
+
);
|
|
4843
|
+
};
|
|
4670
4844
|
var isServer = typeof window === "undefined";
|
|
4671
4845
|
var useNextAuth = (config) => {
|
|
4672
4846
|
const [authService] = React3.useState(() => {
|
|
@@ -4863,6 +5037,8 @@ exports.AuthFlow = AuthFlow;
|
|
|
4863
5037
|
exports.AuthProvider = AuthProvider;
|
|
4864
5038
|
exports.AuthService = AuthService;
|
|
4865
5039
|
exports.AuthThemeProvider = AuthThemeProvider;
|
|
5040
|
+
exports.AvatarManager = AvatarManager;
|
|
5041
|
+
exports.AvatarUploader = AvatarUploader;
|
|
4866
5042
|
exports.ChangePassword = ChangePassword;
|
|
4867
5043
|
exports.EmailVerificationPage = EmailVerificationPage;
|
|
4868
5044
|
exports.ForgotPassword = ForgotPassword;
|