@sanvika/auth 2.7.0 → 2.9.0
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.js +408 -23
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -17,10 +17,9 @@ var STORAGE_KEYS = {
|
|
|
17
17
|
};
|
|
18
18
|
var DEFAULT_AVATAR_SVG = `data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 40 40'%3E%3Ccircle cx='20' cy='20' r='20' fill='%23e5e7eb'/%3E%3Ccircle cx='20' cy='15' r='7' fill='%23adb5bd'/%3E%3Cellipse cx='20' cy='35' rx='12' ry='8' fill='%23adb5bd'/%3E%3C/svg%3E`;
|
|
19
19
|
|
|
20
|
-
//
|
|
21
|
-
|
|
22
|
-
var
|
|
23
|
-
var SanvikaAuthContext = createContext(null);
|
|
20
|
+
// authFlow.js
|
|
21
|
+
var DEFAULT_AUTH_URL = "https://auth.sanvikaproduction.com";
|
|
22
|
+
var DEVICE_ID_STORAGE_KEY = "sanvika_deviceId";
|
|
24
23
|
function randomDeviceId() {
|
|
25
24
|
try {
|
|
26
25
|
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
@@ -30,6 +29,121 @@ function randomDeviceId() {
|
|
|
30
29
|
}
|
|
31
30
|
return `device-${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;
|
|
32
31
|
}
|
|
32
|
+
function getOrCreateWebDeviceId() {
|
|
33
|
+
var _a, _b;
|
|
34
|
+
if (typeof window === "undefined") return randomDeviceId();
|
|
35
|
+
let deviceId = localStorage.getItem(DEVICE_ID_STORAGE_KEY);
|
|
36
|
+
if (!deviceId) {
|
|
37
|
+
const raw = `${navigator.userAgent}|${((_a = window.screen) == null ? void 0 : _a.width) ?? 0}x${((_b = window.screen) == null ? void 0 : _b.height) ?? 0}|${navigator.language}`;
|
|
38
|
+
let hash = 0;
|
|
39
|
+
for (let i = 0; i < raw.length; i++) {
|
|
40
|
+
hash = Math.imul(31, hash) + raw.charCodeAt(i) | 0;
|
|
41
|
+
}
|
|
42
|
+
deviceId = `d_${Math.abs(hash).toString(36)}_${Date.now().toString(36)}`;
|
|
43
|
+
localStorage.setItem(DEVICE_ID_STORAGE_KEY, deviceId);
|
|
44
|
+
}
|
|
45
|
+
return deviceId;
|
|
46
|
+
}
|
|
47
|
+
async function checkMobile({
|
|
48
|
+
authBaseUrl = DEFAULT_AUTH_URL,
|
|
49
|
+
mobile,
|
|
50
|
+
deviceId,
|
|
51
|
+
clientId,
|
|
52
|
+
callbackUrl
|
|
53
|
+
}) {
|
|
54
|
+
const res = await fetch(`${authBaseUrl}/api/auth/check-mobile`, {
|
|
55
|
+
method: "POST",
|
|
56
|
+
headers: { "Content-Type": "application/json" },
|
|
57
|
+
body: JSON.stringify({
|
|
58
|
+
mobile: String(mobile).trim(),
|
|
59
|
+
deviceId,
|
|
60
|
+
clientId,
|
|
61
|
+
...callbackUrl ? { callbackUrl } : {}
|
|
62
|
+
})
|
|
63
|
+
});
|
|
64
|
+
const data = await res.json();
|
|
65
|
+
if (!data.success) {
|
|
66
|
+
const err = new Error(data.message || data.error || "Check mobile failed");
|
|
67
|
+
err.code = data.error;
|
|
68
|
+
throw err;
|
|
69
|
+
}
|
|
70
|
+
return data;
|
|
71
|
+
}
|
|
72
|
+
async function postLogin({
|
|
73
|
+
authBaseUrl = DEFAULT_AUTH_URL,
|
|
74
|
+
mobile,
|
|
75
|
+
password,
|
|
76
|
+
deviceId,
|
|
77
|
+
userAgent,
|
|
78
|
+
clientId,
|
|
79
|
+
deviceName
|
|
80
|
+
}) {
|
|
81
|
+
const body = {
|
|
82
|
+
mobile: String(mobile).trim(),
|
|
83
|
+
deviceId,
|
|
84
|
+
clientId,
|
|
85
|
+
userAgent: userAgent || deviceName || "Sanvika App"
|
|
86
|
+
};
|
|
87
|
+
if (password) {
|
|
88
|
+
body.password = password;
|
|
89
|
+
}
|
|
90
|
+
const res = await fetch(`${authBaseUrl}/api/auth/login`, {
|
|
91
|
+
method: "POST",
|
|
92
|
+
headers: { "Content-Type": "application/json" },
|
|
93
|
+
body: JSON.stringify(body)
|
|
94
|
+
});
|
|
95
|
+
const data = await res.json();
|
|
96
|
+
if (!data.success) {
|
|
97
|
+
const err = new Error(data.error || data.message || "Login failed");
|
|
98
|
+
err.code = data.error;
|
|
99
|
+
throw err;
|
|
100
|
+
}
|
|
101
|
+
return data;
|
|
102
|
+
}
|
|
103
|
+
async function deviceAwareLogin({
|
|
104
|
+
authBaseUrl = DEFAULT_AUTH_URL,
|
|
105
|
+
mobile,
|
|
106
|
+
password,
|
|
107
|
+
deviceId,
|
|
108
|
+
userAgent,
|
|
109
|
+
deviceName,
|
|
110
|
+
clientId,
|
|
111
|
+
callbackUrl,
|
|
112
|
+
resolveDeviceId
|
|
113
|
+
}) {
|
|
114
|
+
const resolvedDeviceId = deviceId || (typeof resolveDeviceId === "function" ? await resolveDeviceId() : getOrCreateWebDeviceId());
|
|
115
|
+
const check = await checkMobile({
|
|
116
|
+
authBaseUrl,
|
|
117
|
+
mobile,
|
|
118
|
+
deviceId: resolvedDeviceId,
|
|
119
|
+
clientId,
|
|
120
|
+
callbackUrl
|
|
121
|
+
});
|
|
122
|
+
if (!check.exists) {
|
|
123
|
+
const err = new Error("Mobile number not registered.");
|
|
124
|
+
err.code = "USER_NOT_REGISTERED";
|
|
125
|
+
throw err;
|
|
126
|
+
}
|
|
127
|
+
if (!check.isKnownDevice && !password) {
|
|
128
|
+
const err = new Error("Password is required for this device.");
|
|
129
|
+
err.code = "MISSING_PASSWORD";
|
|
130
|
+
err.requiresPassword = true;
|
|
131
|
+
throw err;
|
|
132
|
+
}
|
|
133
|
+
return postLogin({
|
|
134
|
+
authBaseUrl,
|
|
135
|
+
mobile,
|
|
136
|
+
password: check.isKnownDevice ? void 0 : password,
|
|
137
|
+
deviceId: resolvedDeviceId,
|
|
138
|
+
userAgent,
|
|
139
|
+
deviceName,
|
|
140
|
+
clientId
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// SanvikaAuthProvider.jsx
|
|
145
|
+
import { jsx } from "react/jsx-runtime";
|
|
146
|
+
var SanvikaAuthContext = createContext(null);
|
|
33
147
|
function createDefaultWebPersistence() {
|
|
34
148
|
return {
|
|
35
149
|
getItem: async (key) => typeof localStorage !== "undefined" ? localStorage.getItem(key) : null,
|
|
@@ -50,6 +164,7 @@ function SanvikaAuthProvider({
|
|
|
50
164
|
clientId,
|
|
51
165
|
redirectUri,
|
|
52
166
|
dashboardPath,
|
|
167
|
+
authBaseUrl = DEFAULT_AUTH_URL,
|
|
53
168
|
persistence: persistenceProp
|
|
54
169
|
}) {
|
|
55
170
|
const persistence = useMemo(() => {
|
|
@@ -83,25 +198,62 @@ function SanvikaAuthProvider({
|
|
|
83
198
|
cancelled = true;
|
|
84
199
|
};
|
|
85
200
|
}, [persistence]);
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
201
|
+
const persistSession = useCallback(
|
|
202
|
+
async (token, userData) => {
|
|
203
|
+
await persistence.setItem(STORAGE_KEYS.ACCESS_TOKEN, token);
|
|
204
|
+
await persistence.setItem(STORAGE_KEYS.USER, JSON.stringify(userData));
|
|
205
|
+
setToken(token);
|
|
206
|
+
setUser(userData);
|
|
207
|
+
},
|
|
208
|
+
[persistence]
|
|
209
|
+
);
|
|
210
|
+
const checkMobile2 = useCallback(
|
|
211
|
+
async ({ mobile, deviceId }) => {
|
|
212
|
+
const resolvedDeviceId = deviceId || getOrCreateWebDeviceId();
|
|
213
|
+
return checkMobile({
|
|
214
|
+
authBaseUrl,
|
|
215
|
+
mobile,
|
|
216
|
+
deviceId: resolvedDeviceId,
|
|
217
|
+
clientId,
|
|
218
|
+
callbackUrl: redirectUri
|
|
219
|
+
});
|
|
220
|
+
},
|
|
221
|
+
[authBaseUrl, clientId, redirectUri]
|
|
222
|
+
);
|
|
223
|
+
const login = async ({
|
|
224
|
+
mobile,
|
|
225
|
+
password,
|
|
226
|
+
deviceId,
|
|
227
|
+
deviceName,
|
|
228
|
+
userAgent,
|
|
229
|
+
skipDeviceCheck = false
|
|
230
|
+
}) => {
|
|
231
|
+
const resolveDeviceId = async () => deviceId || getOrCreateWebDeviceId();
|
|
232
|
+
let data;
|
|
233
|
+
if (skipDeviceCheck) {
|
|
234
|
+
data = await postLogin({
|
|
235
|
+
authBaseUrl,
|
|
91
236
|
mobile,
|
|
92
237
|
password,
|
|
93
238
|
deviceId: deviceId || randomDeviceId(),
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
239
|
+
userAgent: userAgent || deviceName,
|
|
240
|
+
clientId,
|
|
241
|
+
deviceName
|
|
242
|
+
});
|
|
243
|
+
} else {
|
|
244
|
+
data = await deviceAwareLogin({
|
|
245
|
+
authBaseUrl,
|
|
246
|
+
mobile,
|
|
247
|
+
password,
|
|
248
|
+
deviceId,
|
|
249
|
+
userAgent: userAgent || (typeof navigator !== "undefined" ? navigator.userAgent : void 0),
|
|
250
|
+
deviceName,
|
|
251
|
+
clientId,
|
|
252
|
+
callbackUrl: redirectUri,
|
|
253
|
+
resolveDeviceId
|
|
254
|
+
});
|
|
100
255
|
}
|
|
101
|
-
await
|
|
102
|
-
await persistence.setItem(STORAGE_KEYS.USER, JSON.stringify(data.user));
|
|
103
|
-
setToken(data.accessToken);
|
|
104
|
-
setUser(data.user);
|
|
256
|
+
await persistSession(data.accessToken, data.user);
|
|
105
257
|
return data;
|
|
106
258
|
};
|
|
107
259
|
const setAuth = useCallback(
|
|
@@ -115,7 +267,7 @@ function SanvikaAuthProvider({
|
|
|
115
267
|
);
|
|
116
268
|
const logout = async () => {
|
|
117
269
|
try {
|
|
118
|
-
await fetch(`${
|
|
270
|
+
await fetch(`${authBaseUrl}/api/auth/logout`, {
|
|
119
271
|
method: "POST",
|
|
120
272
|
headers: {
|
|
121
273
|
"Content-Type": "application/json",
|
|
@@ -153,12 +305,14 @@ function SanvikaAuthProvider({
|
|
|
153
305
|
isAuthenticated: !!user,
|
|
154
306
|
isLoggedIn: !!user,
|
|
155
307
|
login,
|
|
308
|
+
checkMobile: checkMobile2,
|
|
156
309
|
logout,
|
|
157
310
|
setAuth,
|
|
158
311
|
authFetch,
|
|
159
312
|
clientId,
|
|
160
313
|
redirectUri,
|
|
161
|
-
dashboardPath
|
|
314
|
+
dashboardPath,
|
|
315
|
+
authBaseUrl
|
|
162
316
|
};
|
|
163
317
|
return /* @__PURE__ */ jsx(SanvikaAuthContext.Provider, { value, children });
|
|
164
318
|
}
|
|
@@ -196,7 +350,7 @@ styleInject("@keyframes snvk-shimmer {\n 0% {\n background-position: 200% 0;
|
|
|
196
350
|
|
|
197
351
|
// SanvikaAccountButton.jsx
|
|
198
352
|
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
199
|
-
var
|
|
353
|
+
var S_AUTH_URL = "https://auth.sanvikaproduction.com";
|
|
200
354
|
var SanvikaAccountButtonErrorBoundary = class extends Component {
|
|
201
355
|
constructor(props) {
|
|
202
356
|
super(props);
|
|
@@ -329,7 +483,7 @@ function SanvikaAccountButtonContent({
|
|
|
329
483
|
if (!isAuthenticated || loading) {
|
|
330
484
|
const { clientId } = auth;
|
|
331
485
|
const redirectUri = auth.redirectUri || (typeof window !== "undefined" && window.location ? window.location.origin + "/auth/callback" : "");
|
|
332
|
-
const authorizeUrl = clientId && redirectUri ? `${
|
|
486
|
+
const authorizeUrl = clientId && redirectUri ? `${S_AUTH_URL}/authorize?client_id=${encodeURIComponent(clientId)}&redirect_uri=${encodeURIComponent(redirectUri)}` : `${S_AUTH_URL}/authorize`;
|
|
333
487
|
return /* @__PURE__ */ jsxs(
|
|
334
488
|
"button",
|
|
335
489
|
{
|
|
@@ -463,11 +617,242 @@ function SanvikaAccountButtonContent({
|
|
|
463
617
|
function SanvikaAccountButton(props) {
|
|
464
618
|
return /* @__PURE__ */ jsx2(SanvikaAccountButtonErrorBoundary, { children: /* @__PURE__ */ jsx2(SanvikaAccountButtonContent, { ...props }) });
|
|
465
619
|
}
|
|
620
|
+
|
|
621
|
+
// SanvikaAdminLogin.jsx
|
|
622
|
+
import { useState as useState3, useEffect as useEffect3 } from "react";
|
|
623
|
+
import { useRouter } from "next/navigation";
|
|
624
|
+
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
625
|
+
var AUTH_BASE_URL = "https://auth.sanvikaproduction.com";
|
|
626
|
+
var DEVICE_ID_KEY = "sanvika_admin_device_id";
|
|
627
|
+
function getDeviceId() {
|
|
628
|
+
var _a;
|
|
629
|
+
if (typeof window === "undefined") return "";
|
|
630
|
+
try {
|
|
631
|
+
let id = window.localStorage.getItem(DEVICE_ID_KEY);
|
|
632
|
+
if (!id) {
|
|
633
|
+
id = ((_a = crypto == null ? void 0 : crypto.randomUUID) == null ? void 0 : _a.call(crypto)) || `dev-${Date.now()}-${Math.random()}`;
|
|
634
|
+
window.localStorage.setItem(DEVICE_ID_KEY, id);
|
|
635
|
+
}
|
|
636
|
+
return id;
|
|
637
|
+
} catch {
|
|
638
|
+
return `dev-${Date.now()}`;
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
function friendlyError(code) {
|
|
642
|
+
switch (code) {
|
|
643
|
+
case "INVALID_MOBILE":
|
|
644
|
+
return "Mobile number is not valid.";
|
|
645
|
+
case "MISSING_DEVICE_ID":
|
|
646
|
+
return "Device could not be identified. Reload and retry.";
|
|
647
|
+
case "USER_NOT_FOUND":
|
|
648
|
+
return "No account found for this mobile.";
|
|
649
|
+
case "MISSING_PASSWORD":
|
|
650
|
+
return "Please enter your password.";
|
|
651
|
+
case "INVALID_PASSWORD":
|
|
652
|
+
return "Incorrect password.";
|
|
653
|
+
case "RATE_LIMIT_EXCEEDED":
|
|
654
|
+
return "Too many attempts. Please try again in 15 minutes.";
|
|
655
|
+
case "SERVER_ERROR":
|
|
656
|
+
return "Auth service error. Please try again.";
|
|
657
|
+
default:
|
|
658
|
+
return "Login failed. Please try again.";
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
function SanvikaAdminLogin({
|
|
662
|
+
serviceName = "Sanvika",
|
|
663
|
+
dashboardPath = "/dashboard/admin",
|
|
664
|
+
homePath = "/"
|
|
665
|
+
}) {
|
|
666
|
+
const router = useRouter();
|
|
667
|
+
const { isAuthenticated, loading, user, setAuth } = useSanvikaAuth();
|
|
668
|
+
const [mobile, setMobile] = useState3("");
|
|
669
|
+
const [password, setPassword] = useState3("");
|
|
670
|
+
const [error, setError] = useState3("");
|
|
671
|
+
const [submitting, setSubmitting] = useState3(false);
|
|
672
|
+
const [ready, setReady] = useState3(false);
|
|
673
|
+
useEffect3(() => {
|
|
674
|
+
if (loading) return;
|
|
675
|
+
if (isAuthenticated && (user == null ? void 0 : user.role) === "superadmin") {
|
|
676
|
+
router.replace(dashboardPath);
|
|
677
|
+
return;
|
|
678
|
+
}
|
|
679
|
+
setReady(true);
|
|
680
|
+
}, [loading, isAuthenticated, user, router, dashboardPath]);
|
|
681
|
+
async function handleLogin(e) {
|
|
682
|
+
var _a;
|
|
683
|
+
e.preventDefault();
|
|
684
|
+
setError("");
|
|
685
|
+
setSubmitting(true);
|
|
686
|
+
try {
|
|
687
|
+
const res = await fetch(`${AUTH_BASE_URL}/api/auth/login`, {
|
|
688
|
+
method: "POST",
|
|
689
|
+
headers: { "Content-Type": "application/json" },
|
|
690
|
+
body: JSON.stringify({
|
|
691
|
+
mobile,
|
|
692
|
+
password,
|
|
693
|
+
deviceId: getDeviceId(),
|
|
694
|
+
deviceName: "Browser"
|
|
695
|
+
})
|
|
696
|
+
});
|
|
697
|
+
const data = await res.json().catch(() => ({}));
|
|
698
|
+
if (!data.success) {
|
|
699
|
+
setError(friendlyError(data.error));
|
|
700
|
+
setPassword("");
|
|
701
|
+
return;
|
|
702
|
+
}
|
|
703
|
+
if (((_a = data.user) == null ? void 0 : _a.role) !== "superadmin") {
|
|
704
|
+
setError("This account does not have admin access.");
|
|
705
|
+
setPassword("");
|
|
706
|
+
return;
|
|
707
|
+
}
|
|
708
|
+
setAuth(data.accessToken, data.user);
|
|
709
|
+
router.replace(dashboardPath);
|
|
710
|
+
} catch {
|
|
711
|
+
setError("Could not reach the auth service. Please try again.");
|
|
712
|
+
} finally {
|
|
713
|
+
setSubmitting(false);
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
const S = {
|
|
717
|
+
page: {
|
|
718
|
+
minHeight: "100vh",
|
|
719
|
+
display: "flex",
|
|
720
|
+
alignItems: "center",
|
|
721
|
+
justifyContent: "center",
|
|
722
|
+
padding: "20px",
|
|
723
|
+
background: "linear-gradient(135deg,#0f172a 0%,#1e1b4b 100%)",
|
|
724
|
+
fontFamily: "system-ui,-apple-system,'Segoe UI',Roboto,sans-serif"
|
|
725
|
+
},
|
|
726
|
+
card: {
|
|
727
|
+
position: "relative",
|
|
728
|
+
width: "100%",
|
|
729
|
+
maxWidth: "380px",
|
|
730
|
+
background: "#1e293b",
|
|
731
|
+
borderRadius: "16px",
|
|
732
|
+
padding: "36px 32px",
|
|
733
|
+
boxShadow: "0 20px 50px rgba(0,0,0,.4)",
|
|
734
|
+
border: "1px solid #334155"
|
|
735
|
+
},
|
|
736
|
+
closeBtn: {
|
|
737
|
+
position: "absolute",
|
|
738
|
+
top: "14px",
|
|
739
|
+
right: "16px",
|
|
740
|
+
background: "none",
|
|
741
|
+
border: "none",
|
|
742
|
+
color: "#64748b",
|
|
743
|
+
fontSize: "20px",
|
|
744
|
+
cursor: "pointer",
|
|
745
|
+
lineHeight: 1
|
|
746
|
+
},
|
|
747
|
+
logo: { fontSize: "40px", textAlign: "center", marginBottom: "8px" },
|
|
748
|
+
title: {
|
|
749
|
+
margin: "0 0 4px",
|
|
750
|
+
textAlign: "center",
|
|
751
|
+
color: "#f1f5f9",
|
|
752
|
+
fontSize: "22px",
|
|
753
|
+
fontWeight: 700
|
|
754
|
+
},
|
|
755
|
+
subtitle: {
|
|
756
|
+
margin: "0 0 24px",
|
|
757
|
+
textAlign: "center",
|
|
758
|
+
color: "#94a3b8",
|
|
759
|
+
fontSize: "13px"
|
|
760
|
+
},
|
|
761
|
+
form: { display: "flex", flexDirection: "column", gap: "6px" },
|
|
762
|
+
label: { color: "#cbd5e1", fontSize: "13px", marginTop: "10px" },
|
|
763
|
+
input: {
|
|
764
|
+
padding: "11px 13px",
|
|
765
|
+
borderRadius: "9px",
|
|
766
|
+
border: "1px solid #475569",
|
|
767
|
+
background: "#0f172a",
|
|
768
|
+
color: "#f1f5f9",
|
|
769
|
+
fontSize: "15px",
|
|
770
|
+
outline: "none"
|
|
771
|
+
},
|
|
772
|
+
button: {
|
|
773
|
+
marginTop: "18px",
|
|
774
|
+
padding: "12px",
|
|
775
|
+
borderRadius: "9px",
|
|
776
|
+
border: "none",
|
|
777
|
+
background: submitting ? "#4338ca" : "#6366f1",
|
|
778
|
+
color: "#fff",
|
|
779
|
+
fontSize: "15px",
|
|
780
|
+
fontWeight: 600,
|
|
781
|
+
cursor: submitting ? "default" : "pointer"
|
|
782
|
+
},
|
|
783
|
+
error: {
|
|
784
|
+
marginTop: "14px",
|
|
785
|
+
textAlign: "center",
|
|
786
|
+
color: "#f87171",
|
|
787
|
+
fontSize: "13px"
|
|
788
|
+
}
|
|
789
|
+
};
|
|
790
|
+
if (loading || !ready) {
|
|
791
|
+
return /* @__PURE__ */ jsx3("div", { style: S.page, children: /* @__PURE__ */ jsx3("div", { style: S.card, children: /* @__PURE__ */ jsx3("p", { style: S.subtitle, children: "Loading\u2026" }) }) });
|
|
792
|
+
}
|
|
793
|
+
return /* @__PURE__ */ jsx3("div", { style: S.page, children: /* @__PURE__ */ jsxs2("div", { style: S.card, children: [
|
|
794
|
+
/* @__PURE__ */ jsx3("button", { style: S.closeBtn, onClick: () => router.push(homePath), "aria-label": "Close", children: "\u2715" }),
|
|
795
|
+
/* @__PURE__ */ jsx3("div", { style: S.logo, children: "\u{1F6E1}\uFE0F" }),
|
|
796
|
+
/* @__PURE__ */ jsxs2("h1", { style: S.title, children: [
|
|
797
|
+
serviceName,
|
|
798
|
+
" Admin"
|
|
799
|
+
] }),
|
|
800
|
+
/* @__PURE__ */ jsx3("p", { style: S.subtitle, children: "SuperAdmin access \u2014 Sanvika Accounts SSO" }),
|
|
801
|
+
/* @__PURE__ */ jsxs2("form", { onSubmit: handleLogin, style: S.form, autoComplete: "off", children: [
|
|
802
|
+
/* @__PURE__ */ jsx3("label", { style: S.label, children: "Mobile Number" }),
|
|
803
|
+
/* @__PURE__ */ jsx3(
|
|
804
|
+
"input",
|
|
805
|
+
{
|
|
806
|
+
type: "tel",
|
|
807
|
+
value: mobile,
|
|
808
|
+
onChange: (e) => setMobile(e.target.value.replace(/\D/g, "").slice(0, 10)),
|
|
809
|
+
placeholder: "10-digit mobile",
|
|
810
|
+
style: S.input,
|
|
811
|
+
maxLength: 10,
|
|
812
|
+
required: true,
|
|
813
|
+
autoFocus: true,
|
|
814
|
+
autoComplete: "off"
|
|
815
|
+
}
|
|
816
|
+
),
|
|
817
|
+
/* @__PURE__ */ jsx3("label", { style: S.label, children: "Password" }),
|
|
818
|
+
/* @__PURE__ */ jsx3(
|
|
819
|
+
"input",
|
|
820
|
+
{
|
|
821
|
+
type: "password",
|
|
822
|
+
value: password,
|
|
823
|
+
onChange: (e) => setPassword(e.target.value),
|
|
824
|
+
placeholder: "Password",
|
|
825
|
+
style: S.input,
|
|
826
|
+
required: true,
|
|
827
|
+
autoComplete: "new-password"
|
|
828
|
+
}
|
|
829
|
+
),
|
|
830
|
+
/* @__PURE__ */ jsx3(
|
|
831
|
+
"button",
|
|
832
|
+
{
|
|
833
|
+
type: "submit",
|
|
834
|
+
style: S.button,
|
|
835
|
+
disabled: submitting || mobile.length !== 10 || !password,
|
|
836
|
+
children: submitting ? "Signing in\u2026" : "Sign in"
|
|
837
|
+
}
|
|
838
|
+
)
|
|
839
|
+
] }),
|
|
840
|
+
error && /* @__PURE__ */ jsx3("p", { style: S.error, children: error })
|
|
841
|
+
] }) });
|
|
842
|
+
}
|
|
466
843
|
export {
|
|
844
|
+
DEFAULT_AUTH_URL,
|
|
467
845
|
DEFAULT_AVATAR_SVG,
|
|
846
|
+
DEVICE_ID_STORAGE_KEY,
|
|
468
847
|
STORAGE_KEYS,
|
|
469
848
|
SanvikaAccountButton,
|
|
849
|
+
SanvikaAdminLogin,
|
|
470
850
|
SanvikaAuthContext,
|
|
471
851
|
SanvikaAuthProvider,
|
|
852
|
+
checkMobile,
|
|
853
|
+
deviceAwareLogin,
|
|
854
|
+
getOrCreateWebDeviceId,
|
|
855
|
+
postLogin,
|
|
856
|
+
randomDeviceId,
|
|
472
857
|
useSanvikaAuth
|
|
473
858
|
};
|