@sanvika/auth 2.7.0 → 2.8.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.
Files changed (2) hide show
  1. package/dist/index.js +224 -0
  2. package/package.json +6 -7
package/dist/index.js CHANGED
@@ -463,10 +463,234 @@ function SanvikaAccountButtonContent({
463
463
  function SanvikaAccountButton(props) {
464
464
  return /* @__PURE__ */ jsx2(SanvikaAccountButtonErrorBoundary, { children: /* @__PURE__ */ jsx2(SanvikaAccountButtonContent, { ...props }) });
465
465
  }
466
+
467
+ // SanvikaAdminLogin.jsx
468
+ import { useState as useState3, useEffect as useEffect3 } from "react";
469
+ import { useRouter } from "next/navigation";
470
+ import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
471
+ var AUTH_BASE_URL = "https://auth.sanvikaproduction.com";
472
+ var DEVICE_ID_KEY = "sanvika_admin_device_id";
473
+ function getDeviceId() {
474
+ var _a;
475
+ if (typeof window === "undefined") return "";
476
+ try {
477
+ let id = window.localStorage.getItem(DEVICE_ID_KEY);
478
+ if (!id) {
479
+ id = ((_a = crypto == null ? void 0 : crypto.randomUUID) == null ? void 0 : _a.call(crypto)) || `dev-${Date.now()}-${Math.random()}`;
480
+ window.localStorage.setItem(DEVICE_ID_KEY, id);
481
+ }
482
+ return id;
483
+ } catch {
484
+ return `dev-${Date.now()}`;
485
+ }
486
+ }
487
+ function friendlyError(code) {
488
+ switch (code) {
489
+ case "INVALID_MOBILE":
490
+ return "Mobile number is not valid.";
491
+ case "MISSING_DEVICE_ID":
492
+ return "Device could not be identified. Reload and retry.";
493
+ case "USER_NOT_FOUND":
494
+ return "No account found for this mobile.";
495
+ case "MISSING_PASSWORD":
496
+ return "Please enter your password.";
497
+ case "INVALID_PASSWORD":
498
+ return "Incorrect password.";
499
+ case "RATE_LIMIT_EXCEEDED":
500
+ return "Too many attempts. Please try again in 15 minutes.";
501
+ case "SERVER_ERROR":
502
+ return "Auth service error. Please try again.";
503
+ default:
504
+ return "Login failed. Please try again.";
505
+ }
506
+ }
507
+ function SanvikaAdminLogin({
508
+ serviceName = "Sanvika",
509
+ dashboardPath = "/dashboard/admin",
510
+ homePath = "/"
511
+ }) {
512
+ const router = useRouter();
513
+ const { isAuthenticated, loading, user, setAuth } = useSanvikaAuth();
514
+ const [mobile, setMobile] = useState3("");
515
+ const [password, setPassword] = useState3("");
516
+ const [error, setError] = useState3("");
517
+ const [submitting, setSubmitting] = useState3(false);
518
+ const [ready, setReady] = useState3(false);
519
+ useEffect3(() => {
520
+ if (loading) return;
521
+ if (isAuthenticated && (user == null ? void 0 : user.role) === "superadmin") {
522
+ router.replace(dashboardPath);
523
+ return;
524
+ }
525
+ setReady(true);
526
+ }, [loading, isAuthenticated, user, router, dashboardPath]);
527
+ async function handleLogin(e) {
528
+ var _a;
529
+ e.preventDefault();
530
+ setError("");
531
+ setSubmitting(true);
532
+ try {
533
+ const res = await fetch(`${AUTH_BASE_URL}/api/auth/login`, {
534
+ method: "POST",
535
+ headers: { "Content-Type": "application/json" },
536
+ body: JSON.stringify({
537
+ mobile,
538
+ password,
539
+ deviceId: getDeviceId(),
540
+ deviceName: "Browser"
541
+ })
542
+ });
543
+ const data = await res.json().catch(() => ({}));
544
+ if (!data.success) {
545
+ setError(friendlyError(data.error));
546
+ setPassword("");
547
+ return;
548
+ }
549
+ if (((_a = data.user) == null ? void 0 : _a.role) !== "superadmin") {
550
+ setError("This account does not have admin access.");
551
+ setPassword("");
552
+ return;
553
+ }
554
+ setAuth(data.accessToken, data.user);
555
+ router.replace(dashboardPath);
556
+ } catch {
557
+ setError("Could not reach the auth service. Please try again.");
558
+ } finally {
559
+ setSubmitting(false);
560
+ }
561
+ }
562
+ const S = {
563
+ page: {
564
+ minHeight: "100vh",
565
+ display: "flex",
566
+ alignItems: "center",
567
+ justifyContent: "center",
568
+ padding: "20px",
569
+ background: "linear-gradient(135deg,#0f172a 0%,#1e1b4b 100%)",
570
+ fontFamily: "system-ui,-apple-system,'Segoe UI',Roboto,sans-serif"
571
+ },
572
+ card: {
573
+ position: "relative",
574
+ width: "100%",
575
+ maxWidth: "380px",
576
+ background: "#1e293b",
577
+ borderRadius: "16px",
578
+ padding: "36px 32px",
579
+ boxShadow: "0 20px 50px rgba(0,0,0,.4)",
580
+ border: "1px solid #334155"
581
+ },
582
+ closeBtn: {
583
+ position: "absolute",
584
+ top: "14px",
585
+ right: "16px",
586
+ background: "none",
587
+ border: "none",
588
+ color: "#64748b",
589
+ fontSize: "20px",
590
+ cursor: "pointer",
591
+ lineHeight: 1
592
+ },
593
+ logo: { fontSize: "40px", textAlign: "center", marginBottom: "8px" },
594
+ title: {
595
+ margin: "0 0 4px",
596
+ textAlign: "center",
597
+ color: "#f1f5f9",
598
+ fontSize: "22px",
599
+ fontWeight: 700
600
+ },
601
+ subtitle: {
602
+ margin: "0 0 24px",
603
+ textAlign: "center",
604
+ color: "#94a3b8",
605
+ fontSize: "13px"
606
+ },
607
+ form: { display: "flex", flexDirection: "column", gap: "6px" },
608
+ label: { color: "#cbd5e1", fontSize: "13px", marginTop: "10px" },
609
+ input: {
610
+ padding: "11px 13px",
611
+ borderRadius: "9px",
612
+ border: "1px solid #475569",
613
+ background: "#0f172a",
614
+ color: "#f1f5f9",
615
+ fontSize: "15px",
616
+ outline: "none"
617
+ },
618
+ button: {
619
+ marginTop: "18px",
620
+ padding: "12px",
621
+ borderRadius: "9px",
622
+ border: "none",
623
+ background: submitting ? "#4338ca" : "#6366f1",
624
+ color: "#fff",
625
+ fontSize: "15px",
626
+ fontWeight: 600,
627
+ cursor: submitting ? "default" : "pointer"
628
+ },
629
+ error: {
630
+ marginTop: "14px",
631
+ textAlign: "center",
632
+ color: "#f87171",
633
+ fontSize: "13px"
634
+ }
635
+ };
636
+ if (loading || !ready) {
637
+ return /* @__PURE__ */ jsx3("div", { style: S.page, children: /* @__PURE__ */ jsx3("div", { style: S.card, children: /* @__PURE__ */ jsx3("p", { style: S.subtitle, children: "Loading\u2026" }) }) });
638
+ }
639
+ return /* @__PURE__ */ jsx3("div", { style: S.page, children: /* @__PURE__ */ jsxs2("div", { style: S.card, children: [
640
+ /* @__PURE__ */ jsx3("button", { style: S.closeBtn, onClick: () => router.push(homePath), "aria-label": "Close", children: "\u2715" }),
641
+ /* @__PURE__ */ jsx3("div", { style: S.logo, children: "\u{1F6E1}\uFE0F" }),
642
+ /* @__PURE__ */ jsxs2("h1", { style: S.title, children: [
643
+ serviceName,
644
+ " Admin"
645
+ ] }),
646
+ /* @__PURE__ */ jsx3("p", { style: S.subtitle, children: "SuperAdmin access \u2014 Sanvika Accounts SSO" }),
647
+ /* @__PURE__ */ jsxs2("form", { onSubmit: handleLogin, style: S.form, autoComplete: "off", children: [
648
+ /* @__PURE__ */ jsx3("label", { style: S.label, children: "Mobile Number" }),
649
+ /* @__PURE__ */ jsx3(
650
+ "input",
651
+ {
652
+ type: "tel",
653
+ value: mobile,
654
+ onChange: (e) => setMobile(e.target.value.replace(/\D/g, "").slice(0, 10)),
655
+ placeholder: "10-digit mobile",
656
+ style: S.input,
657
+ maxLength: 10,
658
+ required: true,
659
+ autoFocus: true,
660
+ autoComplete: "off"
661
+ }
662
+ ),
663
+ /* @__PURE__ */ jsx3("label", { style: S.label, children: "Password" }),
664
+ /* @__PURE__ */ jsx3(
665
+ "input",
666
+ {
667
+ type: "password",
668
+ value: password,
669
+ onChange: (e) => setPassword(e.target.value),
670
+ placeholder: "Password",
671
+ style: S.input,
672
+ required: true,
673
+ autoComplete: "new-password"
674
+ }
675
+ ),
676
+ /* @__PURE__ */ jsx3(
677
+ "button",
678
+ {
679
+ type: "submit",
680
+ style: S.button,
681
+ disabled: submitting || mobile.length !== 10 || !password,
682
+ children: submitting ? "Signing in\u2026" : "Sign in"
683
+ }
684
+ )
685
+ ] }),
686
+ error && /* @__PURE__ */ jsx3("p", { style: S.error, children: error })
687
+ ] }) });
688
+ }
466
689
  export {
467
690
  DEFAULT_AVATAR_SVG,
468
691
  STORAGE_KEYS,
469
692
  SanvikaAccountButton,
693
+ SanvikaAdminLogin,
470
694
  SanvikaAuthContext,
471
695
  SanvikaAuthProvider,
472
696
  useSanvikaAuth
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanvika/auth",
3
- "version": "2.7.0",
3
+ "version": "2.8.0",
4
4
  "description": "Sanvika Auth SDK — React components/hooks + server-side token verification and user proxy",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -12,10 +12,6 @@
12
12
  "files": [
13
13
  "dist"
14
14
  ],
15
- "scripts": {
16
- "build": "tsup",
17
- "prepublishOnly": "npm run build"
18
- },
19
15
  "publishConfig": {
20
16
  "access": "public"
21
17
  },
@@ -39,5 +35,8 @@
39
35
  "nextjs"
40
36
  ],
41
37
  "author": "sanvika",
42
- "license": "MIT"
43
- }
38
+ "license": "MIT",
39
+ "scripts": {
40
+ "build": "tsup"
41
+ }
42
+ }