@thetechfossil/auth2 1.2.20 → 1.2.22
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/README.md +7 -0
- package/dist/index.components.d.mts +14 -1
- package/dist/index.components.d.ts +14 -1
- package/dist/index.components.js +529 -67
- package/dist/index.components.js.map +1 -1
- package/dist/index.components.mjs +529 -68
- package/dist/index.components.mjs.map +1 -1
- package/dist/index.d.mts +19 -2
- package/dist/index.d.ts +19 -2
- package/dist/index.js +530 -67
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +530 -68
- package/dist/index.mjs.map +1 -1
- package/dist/index.next.d.mts +17 -1
- package/dist/index.next.d.ts +17 -1
- package/dist/index.next.js +529 -67
- package/dist/index.next.js.map +1 -1
- package/dist/index.next.mjs +529 -68
- package/dist/index.next.mjs.map +1 -1
- package/dist/index.next.server.d.mts +3 -0
- package/dist/index.next.server.d.ts +3 -0
- package/dist/index.next.server.js +85 -8
- package/dist/index.next.server.js.map +1 -1
- package/dist/index.next.server.mjs +85 -8
- package/dist/index.next.server.mjs.map +1 -1
- package/dist/index.node.d.mts +3 -0
- package/dist/index.node.d.ts +3 -0
- package/dist/index.node.js +85 -8
- package/dist/index.node.js.map +1 -1
- package/dist/index.node.mjs +85 -8
- package/dist/index.node.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -13,16 +13,20 @@ var axios__default = /*#__PURE__*/_interopDefault(axios);
|
|
|
13
13
|
var React__default = /*#__PURE__*/_interopDefault(React);
|
|
14
14
|
|
|
15
15
|
var __defProp = Object.defineProperty;
|
|
16
|
-
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
17
|
-
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
18
|
-
}) : x)(function(x) {
|
|
19
|
-
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
20
|
-
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
21
|
-
});
|
|
22
16
|
var __export = (target, all) => {
|
|
23
17
|
for (var name in all)
|
|
24
18
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
25
19
|
};
|
|
20
|
+
var ERROR_MESSAGES = {
|
|
21
|
+
NETWORK_ERROR: "Unable to connect to the server. Please check your internet connection and try again.",
|
|
22
|
+
TIMEOUT: "The request took too long. Please try again.",
|
|
23
|
+
SERVER_ERROR: "Something went wrong on our end. Please try again later.",
|
|
24
|
+
UNAUTHORIZED: "Your session has expired. Please log in again.",
|
|
25
|
+
FORBIDDEN: "You do not have permission to perform this action.",
|
|
26
|
+
NOT_FOUND: "The requested resource was not found.",
|
|
27
|
+
RATE_LIMITED: "Too many requests. Please wait a moment and try again.",
|
|
28
|
+
UNKNOWN: "An unexpected error occurred. Please try again."
|
|
29
|
+
};
|
|
26
30
|
var HttpClient = class {
|
|
27
31
|
constructor(baseUrl, defaultHeaders = {}) {
|
|
28
32
|
this.csrfToken = null;
|
|
@@ -57,7 +61,7 @@ var HttpClient = class {
|
|
|
57
61
|
}
|
|
58
62
|
return config;
|
|
59
63
|
},
|
|
60
|
-
(error) => Promise.reject(error)
|
|
64
|
+
(error) => Promise.reject(this.createUserFriendlyError(error))
|
|
61
65
|
);
|
|
62
66
|
this.axiosInstance.interceptors.response.use(
|
|
63
67
|
(response) => response,
|
|
@@ -72,18 +76,71 @@ var HttpClient = class {
|
|
|
72
76
|
}
|
|
73
77
|
return this.axiosInstance(originalRequest);
|
|
74
78
|
} catch (refreshError) {
|
|
75
|
-
return Promise.reject(refreshError);
|
|
79
|
+
return Promise.reject(this.createUserFriendlyError(refreshError));
|
|
76
80
|
}
|
|
77
81
|
}
|
|
78
|
-
|
|
79
|
-
const customError = new Error(error.response.data.message);
|
|
80
|
-
customError.response = error.response;
|
|
81
|
-
return Promise.reject(customError);
|
|
82
|
-
}
|
|
83
|
-
return Promise.reject(error);
|
|
82
|
+
return Promise.reject(this.createUserFriendlyError(error));
|
|
84
83
|
}
|
|
85
84
|
);
|
|
86
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* Creates a user-friendly error message from an Axios error
|
|
88
|
+
*/
|
|
89
|
+
createUserFriendlyError(error) {
|
|
90
|
+
if (error instanceof Error && !error.isAxiosError) {
|
|
91
|
+
return error;
|
|
92
|
+
}
|
|
93
|
+
let message;
|
|
94
|
+
let statusCode;
|
|
95
|
+
if (axios__default.default.isAxiosError(error)) {
|
|
96
|
+
statusCode = error.response?.status;
|
|
97
|
+
const responseData = error.response?.data;
|
|
98
|
+
if (responseData?.message) {
|
|
99
|
+
message = responseData.message;
|
|
100
|
+
} else if (!error.response) {
|
|
101
|
+
if (error.code === "ECONNABORTED" || error.message.includes("timeout")) {
|
|
102
|
+
message = ERROR_MESSAGES.TIMEOUT;
|
|
103
|
+
} else if (error.code === "ERR_NETWORK" || error.message === "Network Error") {
|
|
104
|
+
message = ERROR_MESSAGES.NETWORK_ERROR;
|
|
105
|
+
} else {
|
|
106
|
+
message = ERROR_MESSAGES.NETWORK_ERROR;
|
|
107
|
+
}
|
|
108
|
+
} else {
|
|
109
|
+
switch (statusCode) {
|
|
110
|
+
case 400:
|
|
111
|
+
message = responseData?.message || "Invalid request. Please check your input.";
|
|
112
|
+
break;
|
|
113
|
+
case 401:
|
|
114
|
+
message = responseData?.message || ERROR_MESSAGES.UNAUTHORIZED;
|
|
115
|
+
break;
|
|
116
|
+
case 403:
|
|
117
|
+
message = responseData?.message || ERROR_MESSAGES.FORBIDDEN;
|
|
118
|
+
break;
|
|
119
|
+
case 404:
|
|
120
|
+
message = responseData?.message || ERROR_MESSAGES.NOT_FOUND;
|
|
121
|
+
break;
|
|
122
|
+
case 429:
|
|
123
|
+
message = ERROR_MESSAGES.RATE_LIMITED;
|
|
124
|
+
break;
|
|
125
|
+
case 500:
|
|
126
|
+
case 502:
|
|
127
|
+
case 503:
|
|
128
|
+
case 504:
|
|
129
|
+
message = ERROR_MESSAGES.SERVER_ERROR;
|
|
130
|
+
break;
|
|
131
|
+
default:
|
|
132
|
+
message = responseData?.message || ERROR_MESSAGES.UNKNOWN;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
} else {
|
|
136
|
+
message = error?.message || ERROR_MESSAGES.UNKNOWN;
|
|
137
|
+
}
|
|
138
|
+
const customError = new Error(message);
|
|
139
|
+
customError.response = error?.response;
|
|
140
|
+
customError.statusCode = statusCode;
|
|
141
|
+
customError.originalError = error;
|
|
142
|
+
return customError;
|
|
143
|
+
}
|
|
87
144
|
async get(endpoint, headers) {
|
|
88
145
|
const response = await this.axiosInstance.get(endpoint, { headers });
|
|
89
146
|
return response.data;
|
|
@@ -289,6 +346,7 @@ var AuthService = class {
|
|
|
289
346
|
if (token) {
|
|
290
347
|
this.token = token;
|
|
291
348
|
this.httpClient.setAuthToken(token);
|
|
349
|
+
this.setTokenCookie(token);
|
|
292
350
|
}
|
|
293
351
|
} catch (error) {
|
|
294
352
|
console.warn("Failed to load token from storage:", error);
|
|
@@ -299,15 +357,28 @@ var AuthService = class {
|
|
|
299
357
|
if (typeof window !== "undefined" && this.config.localStorageKey) {
|
|
300
358
|
try {
|
|
301
359
|
localStorage.setItem(this.config.localStorageKey, token);
|
|
360
|
+
this.setTokenCookie(token);
|
|
302
361
|
} catch (error) {
|
|
303
362
|
console.warn("Failed to save token to storage:", error);
|
|
304
363
|
}
|
|
305
364
|
}
|
|
306
365
|
}
|
|
366
|
+
setTokenCookie(token) {
|
|
367
|
+
if (typeof window !== "undefined") {
|
|
368
|
+
const maxAge = 7 * 24 * 60 * 60;
|
|
369
|
+
document.cookie = `auth_token=${token}; path=/; max-age=${maxAge}; SameSite=Lax`;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
removeTokenCookie() {
|
|
373
|
+
if (typeof window !== "undefined") {
|
|
374
|
+
document.cookie = "auth_token=; path=/; max-age=0; SameSite=Lax";
|
|
375
|
+
}
|
|
376
|
+
}
|
|
307
377
|
removeTokenFromStorage() {
|
|
308
378
|
if (typeof window !== "undefined" && this.config.localStorageKey) {
|
|
309
379
|
try {
|
|
310
380
|
localStorage.removeItem(this.config.localStorageKey);
|
|
381
|
+
this.removeTokenCookie();
|
|
311
382
|
} catch (error) {
|
|
312
383
|
console.warn("Failed to remove token from storage:", error);
|
|
313
384
|
}
|
|
@@ -1286,14 +1357,6 @@ function useThemeColors() {
|
|
|
1286
1357
|
const { theme } = useAuthTheme();
|
|
1287
1358
|
return theme === "dark" ? darkTheme : lightTheme;
|
|
1288
1359
|
}
|
|
1289
|
-
var PhoneInputWithCountry = null;
|
|
1290
|
-
try {
|
|
1291
|
-
const module = __require("react-phone-number-input");
|
|
1292
|
-
PhoneInputWithCountry = module.default || module;
|
|
1293
|
-
__require("react-phone-number-input/style.css");
|
|
1294
|
-
} catch (error) {
|
|
1295
|
-
console.warn("react-phone-number-input not available, using fallback");
|
|
1296
|
-
}
|
|
1297
1360
|
var CustomPhoneInput = React__default.default.forwardRef((props, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1298
1361
|
"input",
|
|
1299
1362
|
{
|
|
@@ -1314,6 +1377,8 @@ var PhoneInput = ({
|
|
|
1314
1377
|
}) => {
|
|
1315
1378
|
const colors = useThemeColors();
|
|
1316
1379
|
const [defaultCountry, setDefaultCountry] = React.useState("US");
|
|
1380
|
+
const [PhoneInputComponent, setPhoneInputComponent] = React.useState(null);
|
|
1381
|
+
const [isLoading, setIsLoading] = React.useState(true);
|
|
1317
1382
|
const styleContent = React.useMemo(() => `
|
|
1318
1383
|
.PhoneInput {
|
|
1319
1384
|
display: flex;
|
|
@@ -1426,6 +1491,29 @@ var PhoneInput = ({
|
|
|
1426
1491
|
opacity: 0.6;
|
|
1427
1492
|
}
|
|
1428
1493
|
`, [colors]);
|
|
1494
|
+
React.useEffect(() => {
|
|
1495
|
+
let mounted = true;
|
|
1496
|
+
const loadPhoneInput = async () => {
|
|
1497
|
+
try {
|
|
1498
|
+
const module = await import('react-phone-number-input');
|
|
1499
|
+
if (mounted) {
|
|
1500
|
+
setPhoneInputComponent(() => module.default);
|
|
1501
|
+
}
|
|
1502
|
+
} catch (error) {
|
|
1503
|
+
if (mounted) {
|
|
1504
|
+
setPhoneInputComponent(null);
|
|
1505
|
+
}
|
|
1506
|
+
} finally {
|
|
1507
|
+
if (mounted) {
|
|
1508
|
+
setIsLoading(false);
|
|
1509
|
+
}
|
|
1510
|
+
}
|
|
1511
|
+
};
|
|
1512
|
+
loadPhoneInput();
|
|
1513
|
+
return () => {
|
|
1514
|
+
mounted = false;
|
|
1515
|
+
};
|
|
1516
|
+
}, []);
|
|
1429
1517
|
React.useEffect(() => {
|
|
1430
1518
|
const detectCountry = async () => {
|
|
1431
1519
|
try {
|
|
@@ -1478,7 +1566,6 @@ var PhoneInput = ({
|
|
|
1478
1566
|
}
|
|
1479
1567
|
}
|
|
1480
1568
|
} catch (error) {
|
|
1481
|
-
console.log("Country detection failed, using default US");
|
|
1482
1569
|
}
|
|
1483
1570
|
};
|
|
1484
1571
|
detectCountry();
|
|
@@ -1486,7 +1573,31 @@ var PhoneInput = ({
|
|
|
1486
1573
|
const handleChange = React.useMemo(() => (val) => {
|
|
1487
1574
|
onChange(val || "");
|
|
1488
1575
|
}, [onChange]);
|
|
1489
|
-
if (
|
|
1576
|
+
if (isLoading) {
|
|
1577
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1578
|
+
"input",
|
|
1579
|
+
{
|
|
1580
|
+
id,
|
|
1581
|
+
type: "tel",
|
|
1582
|
+
value,
|
|
1583
|
+
onChange: (e) => onChange(e.target.value),
|
|
1584
|
+
disabled,
|
|
1585
|
+
required,
|
|
1586
|
+
placeholder,
|
|
1587
|
+
style: {
|
|
1588
|
+
width: "100%",
|
|
1589
|
+
padding: "12px 16px",
|
|
1590
|
+
border: `1px solid ${colors.borderSecondary}`,
|
|
1591
|
+
borderRadius: "8px",
|
|
1592
|
+
fontSize: "16px",
|
|
1593
|
+
backgroundColor: colors.bgSecondary,
|
|
1594
|
+
color: colors.textPrimary,
|
|
1595
|
+
...style
|
|
1596
|
+
}
|
|
1597
|
+
}
|
|
1598
|
+
);
|
|
1599
|
+
}
|
|
1600
|
+
if (!PhoneInputComponent) {
|
|
1490
1601
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1491
1602
|
"input",
|
|
1492
1603
|
{
|
|
@@ -1520,7 +1631,7 @@ var PhoneInput = ({
|
|
|
1520
1631
|
children: [
|
|
1521
1632
|
/* @__PURE__ */ jsxRuntime.jsx("style", { children: styleContent }),
|
|
1522
1633
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1523
|
-
|
|
1634
|
+
PhoneInputComponent,
|
|
1524
1635
|
{
|
|
1525
1636
|
id,
|
|
1526
1637
|
international: true,
|
|
@@ -2018,6 +2129,28 @@ var RegisterForm = ({
|
|
|
2018
2129
|
const [error, setError] = React.useState(null);
|
|
2019
2130
|
const [showPassword, setShowPassword] = React.useState(false);
|
|
2020
2131
|
const [showConfirmPassword, setShowConfirmPassword] = React.useState(false);
|
|
2132
|
+
const [invitationDetails, setInvitationDetails] = React.useState(null);
|
|
2133
|
+
const [isLoadingInvitation, setIsLoadingInvitation] = React.useState(false);
|
|
2134
|
+
const config = authConfig || {
|
|
2135
|
+
baseUrl: "http://localhost:7000"
|
|
2136
|
+
};
|
|
2137
|
+
React.useEffect(() => {
|
|
2138
|
+
if (invitationToken) {
|
|
2139
|
+
setIsLoadingInvitation(true);
|
|
2140
|
+
fetch(`${config.baseUrl}/api/v1/auth/verify-invitation/${invitationToken}`).then((res) => res.json()).then((data) => {
|
|
2141
|
+
setInvitationDetails(data);
|
|
2142
|
+
if (data.valid && data.email) {
|
|
2143
|
+
setEmail(data.email);
|
|
2144
|
+
}
|
|
2145
|
+
}).catch((err) => {
|
|
2146
|
+
console.error("Failed to verify invitation:", err);
|
|
2147
|
+
setError("Failed to verify invitation. Please try again.");
|
|
2148
|
+
}).finally(() => {
|
|
2149
|
+
setIsLoadingInvitation(false);
|
|
2150
|
+
});
|
|
2151
|
+
}
|
|
2152
|
+
}, [invitationToken, config.baseUrl]);
|
|
2153
|
+
const isEmailDisabled = isLoading || invitationDetails?.valid && !!invitationDetails?.email;
|
|
2021
2154
|
const getPasswordStrength = (pwd) => {
|
|
2022
2155
|
if (!pwd) return { strength: "weak", score: 0, label: "" };
|
|
2023
2156
|
let score = 0;
|
|
@@ -2031,9 +2164,6 @@ var RegisterForm = ({
|
|
|
2031
2164
|
return { strength: "strong", score, label: "Strong" };
|
|
2032
2165
|
};
|
|
2033
2166
|
getPasswordStrength(password);
|
|
2034
|
-
const config = authConfig || {
|
|
2035
|
-
baseUrl: "http://localhost:7000"
|
|
2036
|
-
};
|
|
2037
2167
|
const { register } = useAuth2(config);
|
|
2038
2168
|
const handleSubmit = async (e) => {
|
|
2039
2169
|
e.preventDefault();
|
|
@@ -2068,6 +2198,25 @@ var RegisterForm = ({
|
|
|
2068
2198
|
if (response.ok && data.success) {
|
|
2069
2199
|
if (typeof window !== "undefined" && data.token) {
|
|
2070
2200
|
localStorage.setItem("auth_token", data.token);
|
|
2201
|
+
if (data.invitation?.organizationId && data.invitation?.role) {
|
|
2202
|
+
localStorage.setItem("currentOrganizationId", data.invitation.organizationId);
|
|
2203
|
+
const backendUrl = typeof window !== "undefined" ? process.env.NEXT_PUBLIC_INVENTORY_API_URL || process.env.NEXT_PUBLIC_BIZFLOW_API_URL || "http://localhost:5002" : "http://localhost:5002";
|
|
2204
|
+
try {
|
|
2205
|
+
await fetch(`${backendUrl}/api/auth/sync-with-role`, {
|
|
2206
|
+
method: "POST",
|
|
2207
|
+
headers: {
|
|
2208
|
+
"Content-Type": "application/json",
|
|
2209
|
+
"Authorization": `Bearer ${data.token}`
|
|
2210
|
+
},
|
|
2211
|
+
body: JSON.stringify({
|
|
2212
|
+
organizationId: data.invitation.organizationId,
|
|
2213
|
+
roleName: data.invitation.role
|
|
2214
|
+
})
|
|
2215
|
+
});
|
|
2216
|
+
} catch (syncError) {
|
|
2217
|
+
console.error("Failed to sync user role with backend:", syncError);
|
|
2218
|
+
}
|
|
2219
|
+
}
|
|
2071
2220
|
}
|
|
2072
2221
|
onRegisterSuccess?.();
|
|
2073
2222
|
} else {
|
|
@@ -2175,7 +2324,7 @@ var RegisterForm = ({
|
|
|
2175
2324
|
value: email,
|
|
2176
2325
|
onChange: (e) => setEmail(e.target.value),
|
|
2177
2326
|
required: !phoneNumber,
|
|
2178
|
-
disabled:
|
|
2327
|
+
disabled: isEmailDisabled,
|
|
2179
2328
|
style: {
|
|
2180
2329
|
width: "100%",
|
|
2181
2330
|
padding: "12px 16px",
|
|
@@ -2183,9 +2332,11 @@ var RegisterForm = ({
|
|
|
2183
2332
|
borderRadius: "8px",
|
|
2184
2333
|
fontSize: "16px",
|
|
2185
2334
|
boxSizing: "border-box",
|
|
2186
|
-
color: colors.textPrimary,
|
|
2335
|
+
color: isEmailDisabled ? colors.textSecondary : colors.textPrimary,
|
|
2187
2336
|
transition: "all 0.2s ease",
|
|
2188
|
-
backgroundColor: colors.bgSecondary
|
|
2337
|
+
backgroundColor: isEmailDisabled ? colors.bgHover : colors.bgSecondary,
|
|
2338
|
+
cursor: isEmailDisabled ? "not-allowed" : "text",
|
|
2339
|
+
opacity: isEmailDisabled ? 0.7 : 1
|
|
2189
2340
|
},
|
|
2190
2341
|
placeholder: "Enter your email"
|
|
2191
2342
|
}
|
|
@@ -2888,7 +3039,7 @@ var EmailVerificationPage = ({
|
|
|
2888
3039
|
} })
|
|
2889
3040
|
] }) });
|
|
2890
3041
|
}
|
|
2891
|
-
return /* @__PURE__ */ jsxRuntime.
|
|
3042
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: {
|
|
2892
3043
|
maxWidth: "500px",
|
|
2893
3044
|
margin: "0 auto",
|
|
2894
3045
|
padding: "30px",
|
|
@@ -2897,44 +3048,86 @@ var EmailVerificationPage = ({
|
|
|
2897
3048
|
backgroundColor: "#ffffff",
|
|
2898
3049
|
textAlign: "center",
|
|
2899
3050
|
border: "1px solid #eaeaea"
|
|
2900
|
-
}, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: {
|
|
2901
|
-
padding: "20px"
|
|
2902
3051
|
}, children: [
|
|
2903
|
-
/* @__PURE__ */ jsxRuntime.
|
|
2904
|
-
|
|
2905
|
-
padding: "16px 20px",
|
|
2906
|
-
margin: "24px 0",
|
|
2907
|
-
borderRadius: "8px",
|
|
2908
|
-
fontSize: "15px",
|
|
2909
|
-
fontWeight: 500,
|
|
2910
|
-
backgroundColor: isSuccess ? "#d4edda" : "#f8d7da",
|
|
2911
|
-
color: isSuccess ? "#155724" : "#721c24",
|
|
2912
|
-
border: isSuccess ? "1px solid #c3e6cb" : "1px solid #f5c6cb"
|
|
2913
|
-
}, children: message }),
|
|
2914
|
-
isSuccess && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: {
|
|
2915
|
-
marginTop: "24px"
|
|
3052
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: {
|
|
3053
|
+
padding: "20px"
|
|
2916
3054
|
}, children: [
|
|
2917
|
-
/* @__PURE__ */ jsxRuntime.jsx("
|
|
2918
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2919
|
-
"
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
3055
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { style: { color: "black" }, children: isSuccess ? "\u2713 Email Verified!" : "\u2717 Verification Failed" }),
|
|
3056
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: {
|
|
3057
|
+
padding: "16px 20px",
|
|
3058
|
+
margin: "24px 0",
|
|
3059
|
+
borderRadius: "8px",
|
|
3060
|
+
fontSize: "15px",
|
|
3061
|
+
fontWeight: 500,
|
|
3062
|
+
backgroundColor: isSuccess ? "#d4edda" : "#f8d7da",
|
|
3063
|
+
color: isSuccess ? "#155724" : "#721c24",
|
|
3064
|
+
border: isSuccess ? "1px solid #c3e6cb" : "1px solid #f5c6cb"
|
|
3065
|
+
}, children: message }),
|
|
3066
|
+
isSuccess ? /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginTop: "24px" }, children: [
|
|
3067
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { style: { color: "#666", marginBottom: "16px" }, children: "Redirecting to login..." }),
|
|
3068
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: {
|
|
3069
|
+
border: "3px solid #d4edda",
|
|
3070
|
+
borderTop: "3px solid #28a745",
|
|
3071
|
+
borderRadius: "50%",
|
|
3072
|
+
width: "30px",
|
|
3073
|
+
height: "30px",
|
|
3074
|
+
animation: "spin 1s linear infinite",
|
|
3075
|
+
margin: "0 auto"
|
|
3076
|
+
} })
|
|
3077
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginTop: "24px" }, children: [
|
|
3078
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { style: { color: "#666", marginBottom: "16px" }, children: "The verification link may have expired or already been used." }),
|
|
3079
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3080
|
+
"button",
|
|
3081
|
+
{
|
|
3082
|
+
onClick: () => {
|
|
3083
|
+
const registerPath = process.env.NEXT_PUBLIC_AUTH_REDIRECT_TO_REGISTER || process.env.REACT_APP_AUTH_REDIRECT_TO_REGISTER || "/auth/register";
|
|
3084
|
+
window.location.href = registerPath;
|
|
3085
|
+
},
|
|
3086
|
+
style: {
|
|
3087
|
+
padding: "12px 24px",
|
|
3088
|
+
backgroundColor: "#007bff",
|
|
3089
|
+
color: "white",
|
|
3090
|
+
border: "none",
|
|
3091
|
+
borderRadius: "8px",
|
|
3092
|
+
fontSize: "16px",
|
|
3093
|
+
fontWeight: 600,
|
|
3094
|
+
cursor: "pointer",
|
|
3095
|
+
transition: "all 0.2s ease",
|
|
3096
|
+
marginRight: "12px"
|
|
3097
|
+
},
|
|
3098
|
+
children: "Register Again"
|
|
3099
|
+
}
|
|
3100
|
+
),
|
|
3101
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3102
|
+
"button",
|
|
3103
|
+
{
|
|
3104
|
+
onClick: () => {
|
|
3105
|
+
const loginPath = process.env.NEXT_PUBLIC_AUTH_REDIRECT_TO_LOGIN || process.env.REACT_APP_AUTH_REDIRECT_TO_LOGIN || "/auth/login";
|
|
3106
|
+
window.location.href = loginPath;
|
|
3107
|
+
},
|
|
3108
|
+
style: {
|
|
3109
|
+
padding: "12px 24px",
|
|
3110
|
+
backgroundColor: "#6c757d",
|
|
3111
|
+
color: "white",
|
|
3112
|
+
border: "none",
|
|
3113
|
+
borderRadius: "8px",
|
|
3114
|
+
fontSize: "16px",
|
|
3115
|
+
fontWeight: 600,
|
|
3116
|
+
cursor: "pointer",
|
|
3117
|
+
transition: "all 0.2s ease"
|
|
3118
|
+
},
|
|
3119
|
+
children: "Go to Login"
|
|
3120
|
+
}
|
|
3121
|
+
)
|
|
3122
|
+
] })
|
|
3123
|
+
] }),
|
|
3124
|
+
/* @__PURE__ */ jsxRuntime.jsx("style", { children: `
|
|
3125
|
+
@keyframes spin {
|
|
3126
|
+
0% { transform: rotate(0deg); }
|
|
3127
|
+
100% { transform: rotate(360deg); }
|
|
2934
3128
|
}
|
|
2935
|
-
)
|
|
2936
|
-
|
|
2937
|
-
] }) });
|
|
3129
|
+
` })
|
|
3130
|
+
] });
|
|
2938
3131
|
};
|
|
2939
3132
|
var ThemeWrapper = React.forwardRef(
|
|
2940
3133
|
({ children, className = "", style }, ref) => {
|
|
@@ -5145,6 +5338,274 @@ var UserProfile = ({
|
|
|
5145
5338
|
] })
|
|
5146
5339
|
] });
|
|
5147
5340
|
};
|
|
5341
|
+
var SuperAdminSignIn = ({ redirectUrl, appearance }) => {
|
|
5342
|
+
const { signIn, isSignedIn, loading: authLoading, user } = useAuth();
|
|
5343
|
+
const colors = useThemeColors();
|
|
5344
|
+
const [email, setEmail] = React.useState("");
|
|
5345
|
+
const [password, setPassword] = React.useState("");
|
|
5346
|
+
const [showPassword, setShowPassword] = React.useState(false);
|
|
5347
|
+
const [isLoading, setIsLoading] = React.useState(false);
|
|
5348
|
+
const [error, setError] = React.useState(null);
|
|
5349
|
+
const [success, setSuccess] = React.useState(null);
|
|
5350
|
+
React.useEffect(() => {
|
|
5351
|
+
if (isSignedIn && user) {
|
|
5352
|
+
const isSuperAdmin = user.role === "SUPER_ADMIN" || user.role === "SUPERADMIN";
|
|
5353
|
+
if (isSuperAdmin) {
|
|
5354
|
+
const redirect = redirectUrl || process.env.NEXT_PUBLIC_AUTH_REDIRECT_AFTER_LOGIN || process.env.REACT_APP_AUTH_REDIRECT_AFTER_LOGIN || "/dashboard";
|
|
5355
|
+
const baseUrl = process.env.NEXT_PUBLIC_FRONTEND_BASE_URL || process.env.REACT_APP_FRONTEND_BASE_URL || (typeof window !== "undefined" ? window.location.origin : "");
|
|
5356
|
+
window.location.href = `${baseUrl}${redirect}`;
|
|
5357
|
+
} else {
|
|
5358
|
+
setError("Access denied. Only Super Admin users can access this portal.");
|
|
5359
|
+
document.cookie = "auth_token=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT";
|
|
5360
|
+
document.cookie = "refresh_token=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT";
|
|
5361
|
+
}
|
|
5362
|
+
}
|
|
5363
|
+
}, [isSignedIn, user, redirectUrl]);
|
|
5364
|
+
const handleSubmit = async (e) => {
|
|
5365
|
+
e.preventDefault();
|
|
5366
|
+
setIsLoading(true);
|
|
5367
|
+
setError(null);
|
|
5368
|
+
setSuccess(null);
|
|
5369
|
+
try {
|
|
5370
|
+
const response = await signIn({ email, password });
|
|
5371
|
+
if (response.success) {
|
|
5372
|
+
const userRole = response.user?.role;
|
|
5373
|
+
const isSuperAdmin = userRole === "SUPER_ADMIN" || userRole === "SUPERADMIN";
|
|
5374
|
+
if (!isSuperAdmin) {
|
|
5375
|
+
document.cookie = "auth_token=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT";
|
|
5376
|
+
document.cookie = "refresh_token=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT";
|
|
5377
|
+
setError("Access denied. Only Super Admin users can access this portal.");
|
|
5378
|
+
return;
|
|
5379
|
+
}
|
|
5380
|
+
setSuccess("Login successful! Redirecting...");
|
|
5381
|
+
} else {
|
|
5382
|
+
setError(response.message || "Login failed. Please check your credentials.");
|
|
5383
|
+
}
|
|
5384
|
+
} catch (err) {
|
|
5385
|
+
setError(err instanceof Error ? err.message : "An error occurred during login.");
|
|
5386
|
+
} finally {
|
|
5387
|
+
setIsLoading(false);
|
|
5388
|
+
}
|
|
5389
|
+
};
|
|
5390
|
+
if (authLoading) {
|
|
5391
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { style: { textAlign: "center", padding: "40px" }, children: /* @__PURE__ */ jsxRuntime.jsx("div", { children: "Loading..." }) });
|
|
5392
|
+
}
|
|
5393
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5394
|
+
ThemeWrapper,
|
|
5395
|
+
{
|
|
5396
|
+
style: {
|
|
5397
|
+
maxWidth: "400px",
|
|
5398
|
+
margin: "0 auto",
|
|
5399
|
+
padding: "30px",
|
|
5400
|
+
borderRadius: "12px",
|
|
5401
|
+
boxShadow: "0 4px 20px rgba(0, 0, 0, 0.1)",
|
|
5402
|
+
backgroundColor: colors.bgPrimary,
|
|
5403
|
+
border: `1px solid ${colors.borderPrimary}`,
|
|
5404
|
+
...appearance?.elements?.card
|
|
5405
|
+
},
|
|
5406
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: handleSubmit, children: [
|
|
5407
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { textAlign: "center", marginBottom: "24px" }, children: [
|
|
5408
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: {
|
|
5409
|
+
width: "60px",
|
|
5410
|
+
height: "60px",
|
|
5411
|
+
margin: "0 auto 16px",
|
|
5412
|
+
backgroundColor: colors.buttonPrimary + "20",
|
|
5413
|
+
borderRadius: "12px",
|
|
5414
|
+
display: "flex",
|
|
5415
|
+
alignItems: "center",
|
|
5416
|
+
justifyContent: "center"
|
|
5417
|
+
}, children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "32", height: "32", viewBox: "0 0 24 24", fill: "none", stroke: colors.buttonPrimary, strokeWidth: "2", children: [
|
|
5418
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" }),
|
|
5419
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M9 12l2 2 4-4" })
|
|
5420
|
+
] }) }),
|
|
5421
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { style: {
|
|
5422
|
+
color: colors.textPrimary,
|
|
5423
|
+
fontSize: "24px",
|
|
5424
|
+
fontWeight: 600,
|
|
5425
|
+
margin: 0,
|
|
5426
|
+
...appearance?.elements?.headerTitle
|
|
5427
|
+
}, children: "Super Admin Portal" }),
|
|
5428
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { style: {
|
|
5429
|
+
color: colors.textSecondary,
|
|
5430
|
+
fontSize: "14px",
|
|
5431
|
+
marginTop: "8px"
|
|
5432
|
+
}, children: "Sign in with your administrator credentials" })
|
|
5433
|
+
] }),
|
|
5434
|
+
error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: {
|
|
5435
|
+
padding: "12px 16px",
|
|
5436
|
+
marginBottom: "20px",
|
|
5437
|
+
backgroundColor: colors.errorBg,
|
|
5438
|
+
color: colors.errorText,
|
|
5439
|
+
border: `1px solid ${colors.errorBorder}`,
|
|
5440
|
+
borderRadius: "8px",
|
|
5441
|
+
fontSize: "14px"
|
|
5442
|
+
}, children: error }),
|
|
5443
|
+
success && /* @__PURE__ */ jsxRuntime.jsx("div", { style: {
|
|
5444
|
+
padding: "12px 16px",
|
|
5445
|
+
marginBottom: "20px",
|
|
5446
|
+
backgroundColor: colors.successBg,
|
|
5447
|
+
color: colors.successText,
|
|
5448
|
+
border: `1px solid ${colors.successBorder}`,
|
|
5449
|
+
borderRadius: "8px",
|
|
5450
|
+
fontSize: "14px"
|
|
5451
|
+
}, children: success }),
|
|
5452
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginBottom: "20px" }, children: [
|
|
5453
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: "email", style: {
|
|
5454
|
+
display: "block",
|
|
5455
|
+
marginBottom: "8px",
|
|
5456
|
+
fontWeight: 500,
|
|
5457
|
+
color: colors.textSecondary,
|
|
5458
|
+
fontSize: "14px"
|
|
5459
|
+
}, children: "Email Address" }),
|
|
5460
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5461
|
+
"input",
|
|
5462
|
+
{
|
|
5463
|
+
id: "email",
|
|
5464
|
+
type: "email",
|
|
5465
|
+
value: email,
|
|
5466
|
+
onChange: (e) => setEmail(e.target.value),
|
|
5467
|
+
onFocus: (e) => {
|
|
5468
|
+
e.currentTarget.style.borderColor = colors.buttonPrimary;
|
|
5469
|
+
e.currentTarget.style.outline = `2px solid ${colors.buttonPrimary}40`;
|
|
5470
|
+
},
|
|
5471
|
+
onBlur: (e) => {
|
|
5472
|
+
e.currentTarget.style.borderColor = colors.borderSecondary;
|
|
5473
|
+
e.currentTarget.style.outline = "none";
|
|
5474
|
+
},
|
|
5475
|
+
required: true,
|
|
5476
|
+
disabled: isLoading,
|
|
5477
|
+
autoComplete: "email",
|
|
5478
|
+
style: {
|
|
5479
|
+
width: "100%",
|
|
5480
|
+
padding: "12px 16px",
|
|
5481
|
+
border: `1px solid ${colors.borderSecondary}`,
|
|
5482
|
+
borderRadius: "8px",
|
|
5483
|
+
fontSize: "16px",
|
|
5484
|
+
boxSizing: "border-box",
|
|
5485
|
+
backgroundColor: colors.bgSecondary,
|
|
5486
|
+
color: colors.textPrimary,
|
|
5487
|
+
transition: "all 0.2s ease",
|
|
5488
|
+
WebkitTextFillColor: colors.textPrimary,
|
|
5489
|
+
WebkitBoxShadow: `0 0 0 1000px ${colors.bgSecondary} inset`,
|
|
5490
|
+
...appearance?.elements?.formFieldInput
|
|
5491
|
+
},
|
|
5492
|
+
placeholder: "admin@example.com"
|
|
5493
|
+
}
|
|
5494
|
+
)
|
|
5495
|
+
] }),
|
|
5496
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginBottom: "24px", position: "relative" }, children: [
|
|
5497
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: "password", style: {
|
|
5498
|
+
display: "block",
|
|
5499
|
+
marginBottom: "8px",
|
|
5500
|
+
fontWeight: 500,
|
|
5501
|
+
color: colors.textSecondary,
|
|
5502
|
+
fontSize: "14px"
|
|
5503
|
+
}, children: "Password" }),
|
|
5504
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5505
|
+
"input",
|
|
5506
|
+
{
|
|
5507
|
+
id: "password",
|
|
5508
|
+
type: showPassword ? "text" : "password",
|
|
5509
|
+
value: password,
|
|
5510
|
+
onChange: (e) => setPassword(e.target.value),
|
|
5511
|
+
onFocus: (e) => {
|
|
5512
|
+
e.currentTarget.style.borderColor = colors.buttonPrimary;
|
|
5513
|
+
e.currentTarget.style.outline = `2px solid ${colors.buttonPrimary}40`;
|
|
5514
|
+
},
|
|
5515
|
+
onBlur: (e) => {
|
|
5516
|
+
e.currentTarget.style.borderColor = colors.borderSecondary;
|
|
5517
|
+
e.currentTarget.style.outline = "none";
|
|
5518
|
+
},
|
|
5519
|
+
required: true,
|
|
5520
|
+
disabled: isLoading,
|
|
5521
|
+
autoComplete: "current-password",
|
|
5522
|
+
style: {
|
|
5523
|
+
width: "100%",
|
|
5524
|
+
padding: "12px 16px",
|
|
5525
|
+
paddingRight: "60px",
|
|
5526
|
+
border: `1px solid ${colors.borderSecondary}`,
|
|
5527
|
+
borderRadius: "8px",
|
|
5528
|
+
fontSize: "16px",
|
|
5529
|
+
boxSizing: "border-box",
|
|
5530
|
+
backgroundColor: colors.bgSecondary,
|
|
5531
|
+
color: colors.textPrimary,
|
|
5532
|
+
transition: "all 0.2s ease",
|
|
5533
|
+
WebkitTextFillColor: colors.textPrimary,
|
|
5534
|
+
WebkitBoxShadow: `0 0 0 1000px ${colors.bgSecondary} inset`,
|
|
5535
|
+
...appearance?.elements?.formFieldInput
|
|
5536
|
+
},
|
|
5537
|
+
placeholder: "Enter your password"
|
|
5538
|
+
}
|
|
5539
|
+
),
|
|
5540
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5541
|
+
"button",
|
|
5542
|
+
{
|
|
5543
|
+
type: "button",
|
|
5544
|
+
onClick: () => setShowPassword(!showPassword),
|
|
5545
|
+
style: {
|
|
5546
|
+
position: "absolute",
|
|
5547
|
+
right: "12px",
|
|
5548
|
+
top: "38px",
|
|
5549
|
+
background: "none",
|
|
5550
|
+
border: "none",
|
|
5551
|
+
cursor: "pointer",
|
|
5552
|
+
color: colors.textTertiary,
|
|
5553
|
+
fontSize: "14px",
|
|
5554
|
+
padding: "4px 8px"
|
|
5555
|
+
},
|
|
5556
|
+
children: showPassword ? "Hide" : "Show"
|
|
5557
|
+
}
|
|
5558
|
+
)
|
|
5559
|
+
] }),
|
|
5560
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5561
|
+
"button",
|
|
5562
|
+
{
|
|
5563
|
+
type: "submit",
|
|
5564
|
+
disabled: isLoading || !email || !password,
|
|
5565
|
+
onMouseEnter: (e) => {
|
|
5566
|
+
if (!isLoading && email && password) {
|
|
5567
|
+
e.currentTarget.style.backgroundColor = colors.buttonPrimaryHover;
|
|
5568
|
+
}
|
|
5569
|
+
},
|
|
5570
|
+
onMouseLeave: (e) => {
|
|
5571
|
+
e.currentTarget.style.backgroundColor = colors.buttonPrimary;
|
|
5572
|
+
},
|
|
5573
|
+
style: {
|
|
5574
|
+
width: "100%",
|
|
5575
|
+
padding: "14px",
|
|
5576
|
+
backgroundColor: colors.buttonPrimary,
|
|
5577
|
+
color: "white",
|
|
5578
|
+
border: "none",
|
|
5579
|
+
borderRadius: "8px",
|
|
5580
|
+
fontSize: "16px",
|
|
5581
|
+
fontWeight: 600,
|
|
5582
|
+
cursor: isLoading || !email || !password ? "not-allowed" : "pointer",
|
|
5583
|
+
opacity: isLoading || !email || !password ? 0.6 : 1,
|
|
5584
|
+
transition: "all 0.2s ease",
|
|
5585
|
+
...appearance?.elements?.formButtonPrimary
|
|
5586
|
+
},
|
|
5587
|
+
children: isLoading ? "Signing in..." : "Sign In"
|
|
5588
|
+
}
|
|
5589
|
+
),
|
|
5590
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: {
|
|
5591
|
+
marginTop: "20px",
|
|
5592
|
+
padding: "12px",
|
|
5593
|
+
backgroundColor: colors.bgSecondary,
|
|
5594
|
+
borderRadius: "8px",
|
|
5595
|
+
textAlign: "center"
|
|
5596
|
+
}, children: /* @__PURE__ */ jsxRuntime.jsxs("p", { style: {
|
|
5597
|
+
color: colors.textTertiary,
|
|
5598
|
+
fontSize: "12px",
|
|
5599
|
+
margin: 0
|
|
5600
|
+
}, children: [
|
|
5601
|
+
"\u{1F512} This portal is restricted to Super Admin users only.",
|
|
5602
|
+
/* @__PURE__ */ jsxRuntime.jsx("br", {}),
|
|
5603
|
+
"Contact your system administrator if you need access."
|
|
5604
|
+
] }) })
|
|
5605
|
+
] })
|
|
5606
|
+
}
|
|
5607
|
+
);
|
|
5608
|
+
};
|
|
5148
5609
|
var AvatarManager = ({
|
|
5149
5610
|
open,
|
|
5150
5611
|
onOpenChange,
|
|
@@ -5248,6 +5709,7 @@ __export(react_exports, {
|
|
|
5248
5709
|
SignIn: () => SignIn,
|
|
5249
5710
|
SignOut: () => SignOut,
|
|
5250
5711
|
SignUp: () => SignUp,
|
|
5712
|
+
SuperAdminSignIn: () => SuperAdminSignIn,
|
|
5251
5713
|
UserButton: () => UserButton,
|
|
5252
5714
|
UserProfile: () => UserProfile,
|
|
5253
5715
|
VerifyEmail: () => VerifyEmail,
|
|
@@ -5512,6 +5974,7 @@ exports.SignIn = SignIn;
|
|
|
5512
5974
|
exports.SignOut = SignOut;
|
|
5513
5975
|
exports.SignUp = SignUp;
|
|
5514
5976
|
exports.SocketService = SocketService;
|
|
5977
|
+
exports.SuperAdminSignIn = SuperAdminSignIn;
|
|
5515
5978
|
exports.UserButton = UserButton;
|
|
5516
5979
|
exports.UserProfile = UserProfile;
|
|
5517
5980
|
exports.VerifyEmail = VerifyEmail;
|