@mesob/auth-react 0.5.2 → 0.5.4

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 (138) hide show
  1. package/dist/{chunk-4CUQIZ2Q.js → chunk-4LHFPVAY.js} +2 -2
  2. package/dist/{chunk-YQLGGIE4.js → chunk-57L345IN.js} +4 -4
  3. package/dist/{chunk-RZFCA4YG.js → chunk-5B6GREDA.js} +2 -2
  4. package/dist/{chunk-UOQGT574.js → chunk-5XCUGCW7.js} +4 -4
  5. package/dist/{chunk-KWL6FBP7.js → chunk-6AV6I5B4.js} +3 -3
  6. package/dist/{chunk-LQX2365R.js → chunk-7VWWIN6Q.js} +3 -3
  7. package/dist/{chunk-2XIZ27DU.js → chunk-A5ON3RKH.js} +3 -3
  8. package/dist/chunk-A5ON3RKH.js.map +1 -0
  9. package/dist/{chunk-DJWX4ENN.js → chunk-BM3YKYGC.js} +2 -2
  10. package/dist/{chunk-WBRGSWKX.js → chunk-BX75EFF3.js} +4 -4
  11. package/dist/{chunk-JNVJWNJT.js → chunk-DCWKYK3D.js} +4 -4
  12. package/dist/{chunk-QJOBPOTR.js → chunk-DRM44QBR.js} +3 -3
  13. package/dist/{chunk-WFHQTVY6.js → chunk-EIJFTUTM.js} +3 -3
  14. package/dist/{chunk-22WQJ3NP.js → chunk-FCPN2FD7.js} +5 -5
  15. package/dist/{chunk-PFUTYTDB.js → chunk-FLGP4ROM.js} +5 -5
  16. package/dist/{chunk-PCBJBXEK.js → chunk-FU4K62DS.js} +2 -2
  17. package/dist/{chunk-WTAKMSWN.js → chunk-G4VPR4UC.js} +2 -2
  18. package/dist/{chunk-R6ME7P5U.js → chunk-GGBS64Z5.js} +4 -4
  19. package/dist/{chunk-VVFBMIIB.js → chunk-GQFTH5DQ.js} +12 -7
  20. package/dist/chunk-GQFTH5DQ.js.map +1 -0
  21. package/dist/{chunk-UN6YBSRS.js → chunk-H2W42KYL.js} +2 -2
  22. package/dist/{chunk-XUV6CYTY.js → chunk-HBQK5PAH.js} +2 -2
  23. package/dist/{chunk-XL2DCDFZ.js → chunk-IBRB7ABJ.js} +2 -2
  24. package/dist/{chunk-K2523VB5.js → chunk-IFFWIROT.js} +2 -2
  25. package/dist/{chunk-QHHVGLHT.js → chunk-IK7V3PT3.js} +2 -2
  26. package/dist/{chunk-RPKO5EQ5.js → chunk-JKUKCVY7.js} +5 -5
  27. package/dist/{chunk-BIP5XEDV.js → chunk-K6ACPILA.js} +4 -4
  28. package/dist/{chunk-55WFD2Y2.js → chunk-PUOQX6DR.js} +4 -4
  29. package/dist/{chunk-OPSVSBOB.js → chunk-SA6HTWCL.js} +2 -2
  30. package/dist/{chunk-SBSAOWP5.js → chunk-SX6WAVQS.js} +5 -5
  31. package/dist/{chunk-J4Q7RYYY.js → chunk-TAJQ7O3U.js} +2 -2
  32. package/dist/{chunk-NLK2J4UG.js → chunk-TPG4RW7H.js} +2 -2
  33. package/dist/{chunk-24E7XFGP.js → chunk-USVJBAWJ.js} +2 -2
  34. package/dist/{chunk-CDX5V66G.js → chunk-VMAGFUOK.js} +3 -3
  35. package/dist/{chunk-NUCDZRXS.js → chunk-VS5FEGMX.js} +2 -2
  36. package/dist/{chunk-LJIZEECR.js → chunk-VWYJI2FU.js} +4 -4
  37. package/dist/{chunk-TEARMXTQ.js → chunk-W2HMARW4.js} +4 -4
  38. package/dist/{chunk-RRLFPSSM.js → chunk-W7UHDTBI.js} +33 -2
  39. package/dist/chunk-W7UHDTBI.js.map +1 -0
  40. package/dist/{chunk-ZGDN6MQA.js → chunk-XLPPZKU2.js} +4 -4
  41. package/dist/{chunk-C34HWZA5.js → chunk-XO5LLEGV.js} +2 -2
  42. package/dist/{chunk-ZMJUIRZ6.js → chunk-XZAYLXLS.js} +2 -2
  43. package/dist/{chunk-S772WZD7.js → chunk-YCVDEX5U.js} +3 -3
  44. package/dist/{chunk-GXWBGB6G.js → chunk-YQU3KG74.js} +4 -4
  45. package/dist/{chunk-6L4K26KM.js → chunk-YVHMCTLM.js} +2 -2
  46. package/dist/{chunk-HVAYVDIM.js → chunk-Z4FXOZEJ.js} +3 -3
  47. package/dist/{chunk-XGE6G3EK.js → chunk-ZOKBN5H4.js} +2 -2
  48. package/dist/components/auth/countdown.js +3 -3
  49. package/dist/components/auth/forgot-password.js +4 -4
  50. package/dist/components/auth/reset-password-form.js +4 -4
  51. package/dist/components/auth/set-password.js +4 -4
  52. package/dist/components/auth/sign-in.js +4 -4
  53. package/dist/components/auth/sign-up.js +4 -4
  54. package/dist/components/auth/verification-form.js +4 -4
  55. package/dist/components/auth/verify-email.js +6 -6
  56. package/dist/components/auth/verify-phone.js +6 -6
  57. package/dist/components/authorization/deny.js +2 -2
  58. package/dist/components/authorization/grant.js +2 -2
  59. package/dist/components/iam/domains-page.js +6 -6
  60. package/dist/components/iam/iam-guard.js +3 -3
  61. package/dist/components/iam/permission-selector.js +2 -2
  62. package/dist/components/iam/permissions-page.js +4 -4
  63. package/dist/components/iam/permissions.js +2 -2
  64. package/dist/components/iam/role-detail-layout.js +2 -2
  65. package/dist/components/iam/role-detail-page.js +4 -4
  66. package/dist/components/iam/role-permissions-page.js +5 -5
  67. package/dist/components/iam/roles-page.js +6 -6
  68. package/dist/components/iam/roles.js +2 -2
  69. package/dist/components/iam/sessions-page.js +6 -6
  70. package/dist/components/iam/sessions.js +2 -2
  71. package/dist/components/iam/tenants-page.js +6 -6
  72. package/dist/components/iam/tenants.js +2 -2
  73. package/dist/components/iam/users-page.js +7 -7
  74. package/dist/components/iam/users.js +2 -2
  75. package/dist/components/profile/account.js +2 -2
  76. package/dist/components/profile/change-email-form.js +8 -8
  77. package/dist/components/profile/change-password-form.js +2 -2
  78. package/dist/components/profile/change-phone-form.js +8 -8
  79. package/dist/components/profile/otp-verification-modal.js +5 -5
  80. package/dist/components/profile/profile-layout.js +3 -3
  81. package/dist/components/profile/request-change-email-form.js +2 -2
  82. package/dist/components/profile/request-change-phone-form.js +2 -2
  83. package/dist/components/profile/security.js +13 -13
  84. package/dist/components/profile/verify-change-email-form.js +6 -6
  85. package/dist/components/profile/verify-change-phone-form.js +6 -6
  86. package/dist/index.js +44 -44
  87. package/dist/pages/auth/layout.js +1 -1
  88. package/dist/pages/iam/tenants/tenant-selector.js +3 -3
  89. package/dist/pages/iam/users/user-selector.js +4 -4
  90. package/dist/pages/profile/account.js +1 -1
  91. package/dist/pages/profile/security.js +1 -1
  92. package/dist/types.d.ts +5 -2
  93. package/dist/utils/handle-error.d.ts +3 -1
  94. package/package.json +3 -3
  95. package/dist/chunk-2XIZ27DU.js.map +0 -1
  96. package/dist/chunk-RRLFPSSM.js.map +0 -1
  97. package/dist/chunk-VVFBMIIB.js.map +0 -1
  98. /package/dist/{chunk-4CUQIZ2Q.js.map → chunk-4LHFPVAY.js.map} +0 -0
  99. /package/dist/{chunk-YQLGGIE4.js.map → chunk-57L345IN.js.map} +0 -0
  100. /package/dist/{chunk-RZFCA4YG.js.map → chunk-5B6GREDA.js.map} +0 -0
  101. /package/dist/{chunk-UOQGT574.js.map → chunk-5XCUGCW7.js.map} +0 -0
  102. /package/dist/{chunk-KWL6FBP7.js.map → chunk-6AV6I5B4.js.map} +0 -0
  103. /package/dist/{chunk-LQX2365R.js.map → chunk-7VWWIN6Q.js.map} +0 -0
  104. /package/dist/{chunk-DJWX4ENN.js.map → chunk-BM3YKYGC.js.map} +0 -0
  105. /package/dist/{chunk-WBRGSWKX.js.map → chunk-BX75EFF3.js.map} +0 -0
  106. /package/dist/{chunk-JNVJWNJT.js.map → chunk-DCWKYK3D.js.map} +0 -0
  107. /package/dist/{chunk-QJOBPOTR.js.map → chunk-DRM44QBR.js.map} +0 -0
  108. /package/dist/{chunk-WFHQTVY6.js.map → chunk-EIJFTUTM.js.map} +0 -0
  109. /package/dist/{chunk-22WQJ3NP.js.map → chunk-FCPN2FD7.js.map} +0 -0
  110. /package/dist/{chunk-PFUTYTDB.js.map → chunk-FLGP4ROM.js.map} +0 -0
  111. /package/dist/{chunk-PCBJBXEK.js.map → chunk-FU4K62DS.js.map} +0 -0
  112. /package/dist/{chunk-WTAKMSWN.js.map → chunk-G4VPR4UC.js.map} +0 -0
  113. /package/dist/{chunk-R6ME7P5U.js.map → chunk-GGBS64Z5.js.map} +0 -0
  114. /package/dist/{chunk-UN6YBSRS.js.map → chunk-H2W42KYL.js.map} +0 -0
  115. /package/dist/{chunk-XUV6CYTY.js.map → chunk-HBQK5PAH.js.map} +0 -0
  116. /package/dist/{chunk-XL2DCDFZ.js.map → chunk-IBRB7ABJ.js.map} +0 -0
  117. /package/dist/{chunk-K2523VB5.js.map → chunk-IFFWIROT.js.map} +0 -0
  118. /package/dist/{chunk-QHHVGLHT.js.map → chunk-IK7V3PT3.js.map} +0 -0
  119. /package/dist/{chunk-RPKO5EQ5.js.map → chunk-JKUKCVY7.js.map} +0 -0
  120. /package/dist/{chunk-BIP5XEDV.js.map → chunk-K6ACPILA.js.map} +0 -0
  121. /package/dist/{chunk-55WFD2Y2.js.map → chunk-PUOQX6DR.js.map} +0 -0
  122. /package/dist/{chunk-OPSVSBOB.js.map → chunk-SA6HTWCL.js.map} +0 -0
  123. /package/dist/{chunk-SBSAOWP5.js.map → chunk-SX6WAVQS.js.map} +0 -0
  124. /package/dist/{chunk-J4Q7RYYY.js.map → chunk-TAJQ7O3U.js.map} +0 -0
  125. /package/dist/{chunk-NLK2J4UG.js.map → chunk-TPG4RW7H.js.map} +0 -0
  126. /package/dist/{chunk-24E7XFGP.js.map → chunk-USVJBAWJ.js.map} +0 -0
  127. /package/dist/{chunk-CDX5V66G.js.map → chunk-VMAGFUOK.js.map} +0 -0
  128. /package/dist/{chunk-NUCDZRXS.js.map → chunk-VS5FEGMX.js.map} +0 -0
  129. /package/dist/{chunk-LJIZEECR.js.map → chunk-VWYJI2FU.js.map} +0 -0
  130. /package/dist/{chunk-TEARMXTQ.js.map → chunk-W2HMARW4.js.map} +0 -0
  131. /package/dist/{chunk-ZGDN6MQA.js.map → chunk-XLPPZKU2.js.map} +0 -0
  132. /package/dist/{chunk-C34HWZA5.js.map → chunk-XO5LLEGV.js.map} +0 -0
  133. /package/dist/{chunk-ZMJUIRZ6.js.map → chunk-XZAYLXLS.js.map} +0 -0
  134. /package/dist/{chunk-S772WZD7.js.map → chunk-YCVDEX5U.js.map} +0 -0
  135. /package/dist/{chunk-GXWBGB6G.js.map → chunk-YQU3KG74.js.map} +0 -0
  136. /package/dist/{chunk-6L4K26KM.js.map → chunk-YVHMCTLM.js.map} +0 -0
  137. /package/dist/{chunk-HVAYVDIM.js.map → chunk-Z4FXOZEJ.js.map} +0 -0
  138. /package/dist/{chunk-XGE6G3EK.js.map → chunk-ZOKBN5H4.js.map} +0 -0
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import {
3
3
  Security
4
- } from "./chunk-SBSAOWP5.js";
4
+ } from "./chunk-SX6WAVQS.js";
5
5
  import {
6
6
  AuthFormSkeleton
7
7
  } from "./chunk-5M7I7WNH.js";
@@ -11,53 +11,53 @@ import {
11
11
  import {
12
12
  getSafeRedirectFromSearch
13
13
  } from "./chunk-G2XRGSQE.js";
14
- import "./chunk-55WFD2Y2.js";
15
- import "./chunk-KWL6FBP7.js";
16
- import "./chunk-NUCDZRXS.js";
17
- import "./chunk-WBRGSWKX.js";
18
- import "./chunk-HVAYVDIM.js";
19
- import "./chunk-XGE6G3EK.js";
14
+ import "./chunk-PUOQX6DR.js";
15
+ import "./chunk-6AV6I5B4.js";
16
+ import "./chunk-VS5FEGMX.js";
17
+ import "./chunk-BX75EFF3.js";
18
+ import "./chunk-Z4FXOZEJ.js";
19
+ import "./chunk-ZOKBN5H4.js";
20
20
  import {
21
21
  ProfileLayout,
22
22
  ProfileSidebar
23
- } from "./chunk-LQX2365R.js";
24
- import "./chunk-WTAKMSWN.js";
25
- import "./chunk-4CUQIZ2Q.js";
23
+ } from "./chunk-7VWWIN6Q.js";
24
+ import "./chunk-G4VPR4UC.js";
25
+ import "./chunk-4LHFPVAY.js";
26
26
  import {
27
27
  Roles
28
- } from "./chunk-ZMJUIRZ6.js";
28
+ } from "./chunk-XZAYLXLS.js";
29
29
  import {
30
30
  SessionsPage
31
- } from "./chunk-YQLGGIE4.js";
31
+ } from "./chunk-57L345IN.js";
32
32
  import {
33
33
  Sessions
34
- } from "./chunk-C34HWZA5.js";
34
+ } from "./chunk-XO5LLEGV.js";
35
35
  import {
36
36
  TenantsPage
37
- } from "./chunk-GXWBGB6G.js";
37
+ } from "./chunk-YQU3KG74.js";
38
38
  import {
39
39
  str as str2
40
40
  } from "./chunk-EWXK56WQ.js";
41
41
  import {
42
42
  Tenants
43
- } from "./chunk-UN6YBSRS.js";
43
+ } from "./chunk-H2W42KYL.js";
44
44
  import {
45
45
  UsersPage
46
- } from "./chunk-RPKO5EQ5.js";
47
- import "./chunk-24E7XFGP.js";
46
+ } from "./chunk-JKUKCVY7.js";
47
+ import "./chunk-USVJBAWJ.js";
48
48
  import {
49
49
  Users
50
- } from "./chunk-J4Q7RYYY.js";
50
+ } from "./chunk-TAJQ7O3U.js";
51
51
  import {
52
52
  Account
53
- } from "./chunk-XL2DCDFZ.js";
53
+ } from "./chunk-IBRB7ABJ.js";
54
54
  import "./chunk-C5ZW7FD2.js";
55
55
  import {
56
56
  PermissionsPage
57
- } from "./chunk-CDX5V66G.js";
57
+ } from "./chunk-VMAGFUOK.js";
58
58
  import {
59
59
  Permissions
60
- } from "./chunk-NLK2J4UG.js";
60
+ } from "./chunk-TPG4RW7H.js";
61
61
  import {
62
62
  DataTable
63
63
  } from "./chunk-TFVBER3Y.js";
@@ -66,85 +66,85 @@ import {
66
66
  } from "./chunk-RT5C7IAE.js";
67
67
  import {
68
68
  RoleDetailLayout
69
- } from "./chunk-OPSVSBOB.js";
69
+ } from "./chunk-SA6HTWCL.js";
70
70
  import {
71
71
  RoleDetailPage
72
- } from "./chunk-S772WZD7.js";
72
+ } from "./chunk-YCVDEX5U.js";
73
73
  import {
74
74
  RolePermissionsPage
75
- } from "./chunk-LJIZEECR.js";
75
+ } from "./chunk-VWYJI2FU.js";
76
76
  import {
77
77
  PermissionSelector
78
- } from "./chunk-6L4K26KM.js";
78
+ } from "./chunk-YVHMCTLM.js";
79
79
  import {
80
80
  RoleCard,
81
81
  RolesList,
82
82
  RolesPage
83
- } from "./chunk-R6ME7P5U.js";
83
+ } from "./chunk-GGBS64Z5.js";
84
84
  import {
85
85
  str
86
86
  } from "./chunk-OW75JENQ.js";
87
87
  import {
88
88
  SignUp
89
- } from "./chunk-JNVJWNJT.js";
89
+ } from "./chunk-DCWKYK3D.js";
90
90
  import {
91
91
  VerifyEmail
92
- } from "./chunk-PFUTYTDB.js";
92
+ } from "./chunk-FLGP4ROM.js";
93
93
  import {
94
94
  VerifyPhone
95
- } from "./chunk-22WQJ3NP.js";
95
+ } from "./chunk-FCPN2FD7.js";
96
96
  import {
97
97
  VerificationForm
98
- } from "./chunk-WFHQTVY6.js";
98
+ } from "./chunk-EIJFTUTM.js";
99
99
  import {
100
100
  Deny
101
- } from "./chunk-RZFCA4YG.js";
101
+ } from "./chunk-5B6GREDA.js";
102
102
  import {
103
103
  AuthErrorBoundary,
104
104
  ErrorBoundary
105
105
  } from "./chunk-7KXTL6NT.js";
106
106
  import {
107
107
  DomainsPage
108
- } from "./chunk-BIP5XEDV.js";
108
+ } from "./chunk-K6ACPILA.js";
109
109
  import {
110
110
  authApi$
111
- } from "./chunk-QJOBPOTR.js";
112
- import "./chunk-QHHVGLHT.js";
111
+ } from "./chunk-DRM44QBR.js";
112
+ import "./chunk-IK7V3PT3.js";
113
113
  import {
114
114
  defaultEntityQueryOptions
115
115
  } from "./chunk-NPW7D2HZ.js";
116
116
  import {
117
117
  IAMGuard
118
- } from "./chunk-DJWX4ENN.js";
118
+ } from "./chunk-BM3YKYGC.js";
119
119
  import {
120
120
  Grant
121
- } from "./chunk-PCBJBXEK.js";
121
+ } from "./chunk-FU4K62DS.js";
122
122
  import {
123
123
  AuthCard
124
124
  } from "./chunk-G2AW2H36.js";
125
- import "./chunk-K2523VB5.js";
125
+ import "./chunk-IFFWIROT.js";
126
126
  import {
127
127
  ForgotPassword
128
- } from "./chunk-ZGDN6MQA.js";
128
+ } from "./chunk-XLPPZKU2.js";
129
129
  import {
130
130
  ResetPasswordForm
131
- } from "./chunk-TEARMXTQ.js";
131
+ } from "./chunk-W2HMARW4.js";
132
132
  import {
133
133
  SetPassword
134
- } from "./chunk-UOQGT574.js";
134
+ } from "./chunk-5XCUGCW7.js";
135
135
  import {
136
136
  SignIn
137
- } from "./chunk-VVFBMIIB.js";
137
+ } from "./chunk-GQFTH5DQ.js";
138
138
  import {
139
139
  normalizePhone
140
140
  } from "./chunk-V2W3WPCZ.js";
141
141
  import {
142
142
  handleError
143
- } from "./chunk-RRLFPSSM.js";
143
+ } from "./chunk-W7UHDTBI.js";
144
144
  import "./chunk-DPH2PHK3.js";
145
145
  import {
146
146
  useTranslator
147
- } from "./chunk-XUV6CYTY.js";
147
+ } from "./chunk-HBQK5PAH.js";
148
148
  import {
149
149
  MesobAuthProvider,
150
150
  getSessionCookieName,
@@ -153,7 +153,7 @@ import {
153
153
  useConfig,
154
154
  useHasAuthCookie,
155
155
  useSession
156
- } from "./chunk-2XIZ27DU.js";
156
+ } from "./chunk-A5ON3RKH.js";
157
157
 
158
158
  // src/hooks/use-session-cookie-name.ts
159
159
  function useSessionCookieName() {
@@ -5,7 +5,7 @@ import {
5
5
  import {
6
6
  useConfig,
7
7
  useSession
8
- } from "../../chunk-2XIZ27DU.js";
8
+ } from "../../chunk-A5ON3RKH.js";
9
9
 
10
10
  // src/pages/auth/layout.tsx
11
11
  import { AuthCard } from "@mesob/auth-react/components/auth/auth-card";
@@ -4,12 +4,12 @@ import {
4
4
  } from "../../../chunk-EWXK56WQ.js";
5
5
  import {
6
6
  authApi$
7
- } from "../../../chunk-QJOBPOTR.js";
8
- import "../../../chunk-QHHVGLHT.js";
7
+ } from "../../../chunk-DRM44QBR.js";
8
+ import "../../../chunk-IK7V3PT3.js";
9
9
  import {
10
10
  defaultEntityQueryOptions
11
11
  } from "../../../chunk-NPW7D2HZ.js";
12
- import "../../../chunk-2XIZ27DU.js";
12
+ import "../../../chunk-A5ON3RKH.js";
13
13
 
14
14
  // src/pages/iam/tenants/_components/tenant-selector.tsx
15
15
  import {
@@ -1,16 +1,16 @@
1
1
  "use client";
2
2
  import {
3
3
  UserCard
4
- } from "../../../chunk-24E7XFGP.js";
4
+ } from "../../../chunk-USVJBAWJ.js";
5
5
  import "../../../chunk-OW75JENQ.js";
6
6
  import {
7
7
  authApi$
8
- } from "../../../chunk-QJOBPOTR.js";
9
- import "../../../chunk-QHHVGLHT.js";
8
+ } from "../../../chunk-DRM44QBR.js";
9
+ import "../../../chunk-IK7V3PT3.js";
10
10
  import {
11
11
  defaultEntityQueryOptions
12
12
  } from "../../../chunk-NPW7D2HZ.js";
13
- import "../../../chunk-2XIZ27DU.js";
13
+ import "../../../chunk-A5ON3RKH.js";
14
14
 
15
15
  // src/pages/iam/users/_components/user-selector.tsx
16
16
  import {
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import {
3
3
  useConfig
4
- } from "../../chunk-2XIZ27DU.js";
4
+ } from "../../chunk-A5ON3RKH.js";
5
5
 
6
6
  // src/pages/profile/account.tsx
7
7
  import { Account } from "@mesob/auth-react/components/profile/account";
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import {
3
3
  useConfig
4
- } from "../../chunk-2XIZ27DU.js";
4
+ } from "../../chunk-A5ON3RKH.js";
5
5
 
6
6
  // src/pages/profile/security.tsx
7
7
  import { Security } from "@mesob/auth-react/components/profile/security";
package/dist/types.d.ts CHANGED
@@ -41,7 +41,10 @@ export type AuthClientConfig = {
41
41
  permissions?: PermissionTree;
42
42
  navigation?: NavigationConfig;
43
43
  messages?: Record<string, unknown>;
44
+ /** @deprecated use `prefix` */
44
45
  cookiePrefix?: string;
46
+ /** Must match API `prefix` (session cookie + KV namespace). */
47
+ prefix?: string;
45
48
  phoneRegex?: RegExp | string;
46
49
  /** Default userType filter for users list (e.g. 'employee'). Omit or 'all' to show all. */
47
50
  defaultUserType?: string;
@@ -61,7 +64,7 @@ type DefaultAuthClientConfig = {
61
64
  readonly navigation: {
62
65
  readonly locale: 'en';
63
66
  };
64
- readonly cookiePrefix: 'msb';
67
+ readonly prefix: 'msb';
65
68
  readonly phoneRegex: RegExp;
66
69
  };
67
70
  export declare const defaultAuthClientConfig: DefaultAuthClientConfig;
@@ -94,7 +97,7 @@ export type AuthResponse = {
94
97
  sessionToken?: string;
95
98
  sessionExpiresAt?: string;
96
99
  };
97
- export type AuthErrorCode = 'USER_NOT_FOUND' | 'INVALID_PASSWORD' | 'USER_EXISTS' | 'VERIFICATION_EXPIRED' | 'VERIFICATION_MISMATCH' | 'VERIFICATION_NOT_FOUND' | 'TOO_MANY_ATTEMPTS' | 'REQUIRES_VERIFICATION' | 'UNAUTHORIZED' | 'ACCESS_DENIED' | 'HAS_NO_PASSWORD' | 'PASSWORD_ALREADY_SET';
100
+ export type AuthErrorCode = 'USER_NOT_FOUND' | 'INVALID_PASSWORD' | 'USER_EXISTS' | 'VERIFICATION_EXPIRED' | 'VERIFICATION_MISMATCH' | 'VERIFICATION_NOT_FOUND' | 'TOO_MANY_ATTEMPTS' | 'REQUIRES_VERIFICATION' | 'UNAUTHORIZED' | 'ACCESS_DENIED' | 'HAS_NO_PASSWORD' | 'PASSWORD_ALREADY_SET' | 'RATE_LIMITED';
98
101
  export type AuthError = {
99
102
  message: string;
100
103
  code?: AuthErrorCode;
@@ -1,10 +1,12 @@
1
+ import type { AuthError } from '../types';
1
2
  export type AuthErrorContent = {
2
3
  title: string;
3
4
  description: string;
4
5
  };
5
6
  type TranslatorFunction = (key: string, params?: Record<string, string | number>) => string;
7
+ declare function normalizeOpenapiErrorBody(err: unknown): AuthError | null;
8
+ export { normalizeOpenapiErrorBody };
6
9
  export type HandleErrorOptions = {
7
10
  signIn?: boolean;
8
11
  };
9
12
  export declare const handleError: (err: unknown, setError: (error: AuthErrorContent | null) => void, t: TranslatorFunction, options?: HandleErrorOptions) => void;
10
- export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mesob/auth-react",
3
- "version": "0.5.2",
3
+ "version": "0.5.4",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",
@@ -132,8 +132,8 @@
132
132
  ],
133
133
  "dependencies": {
134
134
  "@hookform/resolvers": "^5.2.2",
135
- "@mesob/common": "^0.5.2",
136
- "@mesob/ui": "^0.5.2",
135
+ "@mesob/common": "^0.5.4",
136
+ "@mesob/ui": "^0.5.4",
137
137
  "@tabler/icons-react": "^3.35.0",
138
138
  "deepmerge-ts": "^7.1.5",
139
139
  "nuqs": "^2.8.1",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/utils/cookie.ts","../src/provider.tsx","../src/lib/translations.ts","../src/types.ts","../src/utils/custom-fetch.ts"],"sourcesContent":["import type { AuthClientConfig } from '../types';\n\nconst isProduction =\n typeof process !== 'undefined' && process.env.NODE_ENV === 'production';\n\nexport const getSessionCookieName = (config: AuthClientConfig): string => {\n const prefix = config.cookiePrefix || '';\n const baseName = 'session_token';\n if (prefix) {\n return `${prefix}_${baseName}`;\n }\n return isProduction ? '__Host-session_token' : baseName;\n};\n","'use client';\n\nimport { QueryClient, QueryClientProvider } from '@tanstack/react-query';\nimport { deepmerge } from 'deepmerge-ts';\nimport createFetchClient from 'openapi-fetch';\nimport createClient from 'openapi-react-query';\nimport type { ReactNode } from 'react';\nimport { createContext, useContext, useMemo, useState } from 'react';\nimport type { paths } from './data/openapi';\nimport { createTranslator } from './lib/translations';\nimport {\n type AuthClientConfig,\n type AuthResponse,\n defaultAuthClientConfig,\n type Session,\n type User,\n} from './types';\nimport { getSessionCookieName } from './utils/cookie';\nimport { createCustomFetch } from './utils/custom-fetch';\n\n// biome-ignore lint/suspicious/noExplicitAny: OpenAPI hooks type\ntype OpenApiHooks = any;\n\n// --- Utility: Check if running on server ---\nfunction isServer(): boolean {\n return typeof document === 'undefined';\n}\n\n/**\n * @deprecated Cookie is httpOnly and cannot be read client-side.\n * Use `useSession().isAuthenticated` instead.\n * This function always returns false on client.\n */\nexport function hasAuthCookie(_cookieName: string): boolean {\n // Cookie is httpOnly, can't check client-side\n // Always return false - use useSession() for auth status\n return false;\n}\n\n// --- Types ---\nexport type AuthStatus = 'loading' | 'authenticated' | 'unauthenticated';\n\ntype AuthState = {\n user: User | null;\n session: Session | null;\n status: AuthStatus;\n error: Error | null;\n};\n\ntype SessionContextValue = AuthState & {\n isLoading: boolean;\n isAuthenticated: boolean;\n refresh: () => Promise<void>;\n signOut: () => Promise<void>;\n};\n\ntype ApiContextValue = {\n hooks: OpenApiHooks;\n setAuth: (auth: AuthResponse) => void;\n clearAuth: () => void;\n refresh: () => Promise<void>;\n};\n\ntype ConfigContextValue = {\n config: AuthClientConfig;\n cookieName: string;\n t: (key: string, params?: Record<string, string | number>) => string;\n};\n\nconst SessionContext = createContext<SessionContextValue | null>(null);\nconst ApiContext = createContext<ApiContextValue | null>(null);\nconst ConfigContext = createContext<ConfigContextValue | null>(null);\n\nconst queryClient = new QueryClient({\n defaultOptions: {\n queries: {\n refetchOnWindowFocus: false,\n },\n },\n});\n\n// --- Hooks ---\n\n/**\n * Get session state including user, session, and auth status.\n * - `status`: 'loading' | 'authenticated' | 'unauthenticated'\n * - `isLoading`: true while fetching session\n * - `isAuthenticated`: true if user and session exist\n */\nexport function useSession(): SessionContextValue {\n const context = useContext(SessionContext);\n if (!context) {\n throw new Error('useSession must be used within MesobAuthProvider');\n }\n return context;\n}\n\nexport function useApi(): ApiContextValue {\n const context = useContext(ApiContext);\n if (!context) {\n throw new Error('useApi must be used within MesobAuthProvider');\n }\n return context;\n}\n\nexport function useConfig(): ConfigContextValue {\n const context = useContext(ConfigContext);\n if (!context) {\n throw new Error('useConfig must be used within MesobAuthProvider');\n }\n return context;\n}\n\n/**\n * @deprecated Cookie is httpOnly, can't be checked client-side.\n * Use `useSession().isAuthenticated` instead.\n */\nexport function useHasAuthCookie(): boolean {\n const { status } = useSession();\n return status === 'authenticated' || status === 'loading';\n}\n\n// --- Provider ---\n\ntype MesobAuthProviderProps = {\n config: AuthClientConfig;\n children: ReactNode;\n};\n\nexport function MesobAuthProvider({\n config,\n children,\n}: MesobAuthProviderProps) {\n const mergedConfig = useMemo(\n () =>\n deepmerge(\n { ...defaultAuthClientConfig } as Partial<AuthClientConfig>,\n config,\n ) as AuthClientConfig,\n [config],\n );\n\n const api = useMemo(\n () =>\n createFetchClient<paths>({\n baseUrl: mergedConfig.baseURL,\n fetch: createCustomFetch(mergedConfig),\n }),\n [mergedConfig],\n );\n\n const hooks = useMemo(() => createClient(api), [api]);\n const cookieName = useMemo(\n () => getSessionCookieName(mergedConfig),\n [mergedConfig],\n );\n\n return (\n <QueryClientProvider client={queryClient}>\n <AuthStateProvider\n config={mergedConfig}\n hooks={hooks}\n cookieName={cookieName}\n >\n {children}\n </AuthStateProvider>\n </QueryClientProvider>\n );\n}\n\ntype AuthStateProviderProps = {\n config: AuthClientConfig;\n hooks: OpenApiHooks;\n cookieName: string;\n children: ReactNode;\n};\n\nfunction AuthStateProvider({\n config,\n hooks,\n cookieName,\n children,\n}: AuthStateProviderProps) {\n // Manual override for sign-out / sign-in\n const [override, setOverride] = useState<AuthState | null>(null);\n\n // Always fetch session - cookie is httpOnly, can't check client-side\n // Server will read the cookie and return user/session if valid\n const {\n data: sessionData,\n isLoading,\n isFetched,\n error: sessionError,\n refetch,\n } = hooks.useQuery(\n 'get',\n '/session',\n {},\n {\n enabled: !(override || isServer()),\n refetchOnMount: false,\n refetchOnWindowFocus: false,\n refetchOnReconnect: false,\n retry: false,\n gcTime: 0,\n staleTime: 0,\n },\n );\n\n // Derive state directly - no useEffect\n const user = override?.user ?? sessionData?.user ?? null;\n const session = override?.session ?? sessionData?.session ?? null;\n const error = override?.error ?? (sessionError as Error | null);\n\n // Check error status code\n const errorStatus = (() => {\n if (!sessionError) {\n return null;\n }\n const err = sessionError as { status?: number };\n return err.status ?? null;\n })();\n\n // Check if error is a network/connection error\n const isNetworkError = (() => {\n if (!sessionError) {\n return false;\n }\n const error = sessionError as Error & { cause?: unknown; data?: unknown };\n const errorMessage =\n error.message || String(error) || JSON.stringify(error);\n // Network errors: TypeError, DOMException, or fetch failures\n if (\n error instanceof TypeError ||\n error instanceof DOMException ||\n error.name === 'TypeError' ||\n errorMessage.includes('Failed to fetch') ||\n errorMessage.includes('ERR_CONNECTION_REFUSED') ||\n errorMessage.includes('NetworkError') ||\n errorMessage.includes('Network request failed') ||\n errorMessage.includes('fetch failed')\n ) {\n return true;\n }\n // Check error cause\n if (error.cause) {\n const causeStr = String(error.cause);\n if (\n causeStr.includes('Failed to fetch') ||\n causeStr.includes('ERR_CONNECTION_REFUSED') ||\n causeStr.includes('NetworkError')\n ) {\n return true;\n }\n }\n return false;\n })();\n\n // Compute status\n // biome-ignore lint: Status determination requires multiple checks\n const status: AuthStatus = (() => {\n if (override) {\n return override.status;\n }\n if (isServer()) {\n return 'loading';\n }\n if (user && session) {\n return 'authenticated';\n }\n // Check for network errors or auth errors first - allow auth page to show\n if (isNetworkError || errorStatus === 401) {\n return 'unauthenticated';\n }\n // If we have an error but it's not a network error, still check loading state\n if (sessionError && !isNetworkError && errorStatus !== 401) {\n if (errorStatus && errorStatus >= 500) {\n return 'authenticated';\n }\n // Other errors mean unauthenticated\n if (isFetched) {\n return 'unauthenticated';\n }\n }\n if (isLoading || !isFetched) {\n return 'loading';\n }\n if (isFetched && !user && !session) {\n return 'unauthenticated';\n }\n return 'unauthenticated';\n })();\n\n const signOutMutation = hooks.useMutation('post', '/sign-out');\n const t = createTranslator(config.messages || {});\n\n const setAuth = (auth: AuthResponse) => {\n setOverride({\n user: auth.user,\n session: auth.session,\n status: 'authenticated',\n error: null,\n });\n };\n\n const clearAuth = () => {\n setOverride({\n user: null,\n session: null,\n status: 'unauthenticated',\n error: null,\n });\n };\n\n const refresh = async () => {\n setOverride(null);\n await refetch();\n };\n\n const signOut = async () => {\n await signOutMutation.mutateAsync({});\n clearAuth();\n\n const redirectUrl = config.navigation?.defaultRedirectUrl || '/';\n\n if (config.navigation?.onNavigate) {\n config.navigation.onNavigate(redirectUrl);\n } else if (typeof window !== 'undefined') {\n window.location.href = redirectUrl;\n }\n };\n\n return (\n <ConfigContext.Provider value={{ config, cookieName, t }}>\n <ApiContext.Provider value={{ hooks, setAuth, clearAuth, refresh }}>\n <SessionContext.Provider\n value={{\n user,\n session,\n status,\n error,\n isLoading: status === 'loading',\n isAuthenticated: status === 'authenticated',\n refresh,\n signOut,\n }}\n >\n {children}\n </SessionContext.Provider>\n </ApiContext.Provider>\n </ConfigContext.Provider>\n );\n}\n","type Messages = Record<string, unknown>;\n\nexport function createTranslator(messages: Messages, namespace?: string) {\n return (key: string, params?: Record<string, string | number>): string => {\n const fullKey = namespace ? `${namespace}.${key}` : key;\n const keys = fullKey.split('.');\n\n let value: unknown = messages;\n for (const k of keys) {\n if (value && typeof value === 'object' && value !== null) {\n value = (value as Record<string, unknown>)[k];\n } else {\n return fullKey;\n }\n }\n\n if (typeof value !== 'string') {\n return fullKey;\n }\n\n // Simple parameter replacement\n if (params) {\n return value.replace(/\\{(\\w+)\\}/g, (_, param) =>\n String(params[param] ?? `{${param}}`),\n );\n }\n\n return value;\n };\n}\n","import type { PermissionTree } from '@mesob/common';\n\nexport type UIConfig = {\n logo: React.ReactNode;\n name: React.ReactNode;\n logoImage?: string;\n};\n\nexport type FeaturesConfig = {\n enableSignup?: boolean;\n enablePasswordReset?: boolean;\n enableEmailSignup?: boolean;\n enablePhoneSignup?: boolean;\n enableEmailSignIn?: boolean;\n enablePhoneSignIn?: boolean;\n allowedSignupEmailDomains?: string[];\n enableSocialSignup?: boolean;\n socialProviders?: string[];\n};\n\nexport type TenantConfig = {\n enabled: boolean;\n tenantId: string;\n};\n\nexport type NavigationConfig = {\n locale?: string;\n defaultRedirectUrl?: string;\n onNavigate?: (path: string) => void;\n linkComponent?: React.ComponentType<\n React.ComponentProps<'a'> & { href: string }\n >;\n links?: {\n signIn?: string;\n signUp?: string;\n forgotPassword?: string;\n setPassword?: string;\n };\n};\n\nexport type AuthClientConfig = {\n baseURL: string;\n ui: UIConfig;\n features?: FeaturesConfig;\n tenant?: TenantConfig;\n permissions?: PermissionTree;\n navigation?: NavigationConfig;\n messages?: Record<string, unknown>;\n cookiePrefix?: string;\n phoneRegex?: RegExp | string;\n /** Default userType filter for users list (e.g. 'employee'). Omit or 'all' to show all. */\n defaultUserType?: string;\n};\n\ntype DefaultAuthClientConfig = {\n readonly features: {\n readonly enableSignup: true;\n readonly enablePasswordReset: true;\n readonly enableEmailSignup: true;\n readonly enablePhoneSignup: true;\n readonly enableEmailSignIn: true;\n readonly enablePhoneSignIn: true;\n readonly allowedSignupEmailDomains: [];\n readonly enableSocialSignup: false;\n readonly socialProviders: [];\n };\n readonly navigation: {\n readonly locale: 'en';\n };\n readonly cookiePrefix: 'msb';\n readonly phoneRegex: RegExp;\n};\n\nexport const defaultAuthClientConfig: DefaultAuthClientConfig = {\n features: {\n enableSignup: true,\n enablePasswordReset: true,\n enableEmailSignup: true,\n enablePhoneSignup: true,\n enableEmailSignIn: true,\n enablePhoneSignIn: true,\n allowedSignupEmailDomains: [],\n enableSocialSignup: false,\n socialProviders: [],\n },\n navigation: {\n locale: 'en',\n },\n cookiePrefix: 'msb',\n phoneRegex: /^(\\+2519|\\+2517|2519|2517|09|07)\\d{8}$/,\n} as const;\n\nexport type User = {\n id: string;\n tenantId: string;\n fullName: string;\n email: string | null;\n phone: string | null;\n handle?: string;\n image: string | null;\n emailVerified: boolean;\n phoneVerified: boolean;\n lastSignInAt?: string | null;\n /** Role IDs */\n roles?: string[] | null;\n roleCodes?: string[] | null;\n permissions?: string[] | null;\n};\n\nexport type Session = {\n id?: string;\n expiresAt: string;\n createdAt?: string;\n userAgent?: string | null;\n ip?: string | null;\n};\n\nexport type AuthResponse = {\n user: User;\n session: Session;\n sessionToken?: string;\n sessionExpiresAt?: string;\n};\n\nexport type AuthErrorCode =\n | 'USER_NOT_FOUND'\n | 'INVALID_PASSWORD'\n | 'USER_EXISTS'\n | 'VERIFICATION_EXPIRED'\n | 'VERIFICATION_MISMATCH'\n | 'VERIFICATION_NOT_FOUND'\n | 'TOO_MANY_ATTEMPTS'\n | 'REQUIRES_VERIFICATION'\n | 'UNAUTHORIZED'\n | 'ACCESS_DENIED'\n | 'HAS_NO_PASSWORD'\n | 'PASSWORD_ALREADY_SET';\n\nexport type AuthError = {\n message: string;\n code?: AuthErrorCode;\n status?: number;\n details?: Record<string, unknown>;\n};\n","import type { AuthClientConfig } from '../types';\n\nexport const createCustomFetch = (_config: AuthClientConfig) => {\n return (input: RequestInfo | URL, init?: RequestInit): Promise<Response> => {\n if (input instanceof Request) {\n return fetch(input, { ...init, credentials: 'include' });\n }\n return fetch(input, { ...init, credentials: 'include' });\n };\n};\n"],"mappings":"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","names":["error"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/constants/auth.error.codes.ts","../src/utils/handle-error.ts"],"sourcesContent":["export const AUTH_ERROR_MAPPING: Record<\n string,\n { title: string; description: string }\n> = {\n USER_NOT_FOUND: {\n title: 'Account Not Found',\n description:\n 'We could not find an account with that identifier. Please check your spelling or sign up.',\n },\n INVALID_PASSWORD: {\n title: 'Invalid Password',\n description: 'The password you entered is incorrect. Please try again.',\n },\n USER_EXISTS: {\n title: 'Account Already Exists',\n description:\n 'An account with this identifier already exists. Please sign in instead.',\n },\n VERIFICATION_EXPIRED: {\n title: 'Verification Expired',\n description:\n 'The verification code or link has expired. Please request a new one.',\n },\n VERIFICATION_MISMATCH: {\n title: 'Invalid Code',\n description:\n 'The verification code you entered is invalid. Please double-check and try again.',\n },\n VERIFICATION_NOT_FOUND: {\n title: 'Verification Not Found',\n description:\n 'We could not find a pending verification request. Please restart the process.',\n },\n TOO_MANY_ATTEMPTS: {\n title: 'Too Many Attempts',\n description:\n 'You have made too many requests recently. Please wait a moment before trying again.',\n },\n REQUIRES_VERIFICATION: {\n title: 'Verification Required',\n description:\n 'You need to verify your account before you can continue. Please check your email or phone.',\n },\n UNAUTHORIZED: {\n title: 'Unauthorized',\n description:\n 'You are not authorized to perform this action. Please sign in again.',\n },\n ACCESS_DENIED: {\n title: 'Access Denied',\n description:\n 'You do not have permission to access this resource. Please contact support if you believe this is an error.',\n },\n HAS_NO_PASSWORD: {\n title: 'No Password Set',\n description:\n 'Your account does not have a password yet. Continue to set a password before signing in.',\n },\n PASSWORD_ALREADY_SET: {\n title: 'Password Already Set',\n description:\n 'This account already has a password. Use the normal sign-in form instead.',\n },\n};\n\nexport const validCodes = Object.keys(AUTH_ERROR_MAPPING);\n","import { AUTH_ERROR_MAPPING, validCodes } from '../constants/auth.error.codes';\nimport type { AuthError } from '../types';\n\nexport type AuthErrorContent = {\n title: string;\n description: string;\n};\n\ntype TranslatorFunction = (\n key: string,\n params?: Record<string, string | number>,\n) => string;\n\n// Type guard to check if error is an AuthError\nfunction isAuthError(err: unknown): err is AuthError {\n return (\n typeof err === 'object' &&\n err !== null &&\n 'message' in err &&\n typeof (err as { message: unknown }).message === 'string'\n );\n}\n\nfunction extractErrorCode(err: AuthError): string {\n if (err.code && validCodes.includes(err.code)) {\n return err.code;\n }\n if (err.message) {\n const messageUpper = err.message.toUpperCase().trim();\n if (validCodes.includes(messageUpper)) {\n return messageUpper;\n }\n }\n return '';\n}\n\nconst GENERIC_ERROR = 'An error occurred while processing your request';\n\nfunction sanitizeErrorMessage(message: string): string {\n const lowerMessage = message.toLowerCase();\n const isUnsafe =\n lowerMessage.includes('failed query') ||\n lowerMessage.includes('select') ||\n lowerMessage.includes('insert') ||\n lowerMessage.includes('update') ||\n lowerMessage.includes('delete') ||\n lowerMessage.includes('from') ||\n lowerMessage.includes('where') ||\n lowerMessage.includes('limit') ||\n lowerMessage.includes('params:') ||\n lowerMessage.includes('query') ||\n message.includes('\"iam\".') ||\n message.includes('\"tenants\"') ||\n message.includes('\"users\"') ||\n message.includes('\"sessions\"') ||\n message.includes('\"accounts\"') ||\n lowerMessage.includes('relation') ||\n lowerMessage.includes('column') ||\n lowerMessage.includes('syntax error') ||\n lowerMessage.includes('database') ||\n lowerMessage.includes('postgres') ||\n lowerMessage.includes('sql') ||\n lowerMessage.includes(' at ') ||\n lowerMessage.includes('exception') ||\n /\\bstack\\b/.test(lowerMessage) ||\n /\\.(ts|js|mjs|cjs):\\d+/.test(message);\n\n return isUnsafe ? GENERIC_ERROR : message;\n}\n\n// On sign-in, only these codes get a specific message; all others → generic (no enumeration)\nconst SIGNIN_SAFE_CODES = ['TOO_MANY_ATTEMPTS'];\n\nfunction handleAuthError(\n err: AuthError,\n setError: (error: AuthErrorContent | null) => void,\n t: TranslatorFunction,\n options?: { signIn?: boolean },\n) {\n const errorCode = extractErrorCode(err);\n const isCredentialFailure =\n options?.signIn && !(errorCode && SIGNIN_SAFE_CODES.includes(errorCode));\n\n if (isCredentialFailure) {\n setError({\n title: t('errors.error'),\n description: t('errors.invalidCredentials'),\n });\n return;\n }\n\n if (errorCode && AUTH_ERROR_MAPPING[errorCode]) {\n const mapping = AUTH_ERROR_MAPPING[errorCode];\n setError({\n title: mapping.title,\n description: mapping.description,\n });\n return;\n }\n\n const sanitizedMessage = sanitizeErrorMessage(\n err.message || t('errors.fallback'),\n );\n setError({\n title: t('errors.fallback'),\n description: sanitizedMessage,\n });\n}\n\nfunction handleGenericError(\n err: unknown,\n setError: (error: AuthErrorContent | null) => void,\n t: TranslatorFunction,\n options?: { signIn?: boolean },\n) {\n if (options?.signIn) {\n setError({\n title: t('errors.error'),\n description: t('errors.invalidCredentials'),\n });\n return;\n }\n const rawMessage = err instanceof Error ? err.message : t('errors.fallback');\n const sanitizedMessage = sanitizeErrorMessage(rawMessage);\n setError({\n title: 'Error',\n description: sanitizedMessage,\n });\n}\n\nexport type HandleErrorOptions = { signIn?: boolean };\n\nexport const handleError = (\n err: unknown,\n setError: (error: AuthErrorContent | null) => void,\n t: TranslatorFunction,\n options?: HandleErrorOptions,\n) => {\n if (isAuthError(err)) {\n handleAuthError(err, setError, t, options);\n } else {\n handleGenericError(err, setError, t, options);\n }\n};\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/auth/sign-in.tsx"],"sourcesContent":["'use client';\n\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport {\n Alert,\n AlertDescription,\n AlertTitle,\n Button,\n Form,\n FormControl,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n Input,\n useFormField,\n} from '@mesob/ui/components';\nimport { useMesob } from '@mesob/ui/providers';\nimport { IconAlertCircle, IconEye, IconEyeOff } from '@tabler/icons-react';\nimport type { ChangeEvent, ComponentProps } from 'react';\nimport { useEffect, useState } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { toast } from 'sonner';\nimport { z } from 'zod';\nimport { useTranslator } from '../../hooks/use-translator';\nimport { useApi, useConfig } from '../../provider';\nimport type { AuthErrorContent } from '../../utils/handle-error';\nimport { handleError } from '../../utils/handle-error';\nimport { normalizePhone } from '../../utils/normalize-phone';\nimport { AuthLayout } from './auth-layout';\n\nconst isPhone = (s: string) => /^\\+?[0-9()[\\]\\s-]{6,}$/.test(s);\n\ntype PasswordInputProps = {\n field: ComponentProps<'input'> & {\n value: string;\n onChange: (e: ChangeEvent<HTMLInputElement>) => void;\n onBlur: () => void;\n };\n show: boolean;\n onToggle: () => void;\n};\n\nfunction PasswordInput({ field, show, onToggle }: PasswordInputProps) {\n const { formItemId, error } = useFormField();\n return (\n <div className=\"relative\">\n <Input\n {...field}\n id={formItemId}\n type={show ? 'text' : 'password'}\n autoComplete=\"current-password\"\n aria-invalid={!!error}\n className=\"pr-10\"\n />\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"absolute right-0 top-0 h-full px-3 text-muted-foreground hover:text-foreground\"\n onClick={onToggle}\n aria-label={show ? 'Hide password' : 'Show password'}\n >\n {show ? (\n <IconEyeOff className=\"h-4 w-4\" />\n ) : (\n <IconEye className=\"h-4 w-4\" />\n )}\n </Button>\n </div>\n );\n}\n\ntype SignInProps = {\n redirectUrl?: string;\n};\n\ntype SignInValidationOptions = {\n phoneRegex: RegExp;\n allowEmailSignIn: boolean;\n allowPhoneSignIn: boolean;\n};\n\nconst signInSchema = (\n t: (key: string) => string,\n options: SignInValidationOptions,\n) =>\n z.object({\n username: z\n .string()\n .trim()\n .min(1, { message: t('errors.requiredField') })\n .superRefine((value, ctx) => {\n const emailInput = z.email().safeParse(value).success;\n const phoneInput = options.phoneRegex.test(value);\n if (!(emailInput || phoneInput)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: t('errors.invalidEmailOrPhone'),\n });\n return;\n }\n if (emailInput && !options.allowEmailSignIn) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: 'Email sign in is disabled',\n });\n return;\n }\n if (phoneInput && !options.allowPhoneSignIn) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: 'Phone sign in is disabled',\n });\n }\n }),\n password: z\n .union([\n z.literal(''),\n z\n .string()\n .min(8, t('errors.passwordLength'))\n .max(128, t('errors.longPasswordError')),\n ])\n .optional(),\n });\n\ntype SignInFormValues = z.infer<ReturnType<typeof signInSchema>>;\n\n// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: multi-step form with two form contexts\nexport const SignIn = ({ redirectUrl }: SignInProps = {}) => {\n const { hooks, setAuth } = useApi();\n const { config } = useConfig();\n const mesob = useMesob();\n const t = useTranslator('Auth.signIn');\n const Link = mesob?.navigation?.Link;\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<AuthErrorContent | null>(null);\n const [showPasswordField, setShowPasswordField] = useState(false);\n const [showPassword, setShowPassword] = useState(false);\n const [username, setUsername] = useState('');\n const [isChecking, setIsChecking] = useState(false);\n\n const checkUserMutation = hooks.useMutation('post', '/check-account');\n const signInMutation = hooks.useMutation('post', '/sign-in');\n\n const phoneRegex =\n typeof config.phoneRegex === 'string'\n ? new RegExp(config.phoneRegex)\n : config.phoneRegex || /^(\\+2519|\\+2517|2519|2517|09|07)\\d{8}$/;\n const allowEmailSignIn = config.features?.enableEmailSignIn !== false;\n const allowPhoneSignIn = config.features?.enablePhoneSignIn !== false;\n const enableSignup = config.features?.enableSignup !== false;\n const allowEmailSignup = config.features?.enableEmailSignup !== false;\n const allowPhoneSignup = config.features?.enablePhoneSignup !== false;\n const hasSignInIdentifierChannel = allowEmailSignIn || allowPhoneSignIn;\n\n const defaultRedirect =\n redirectUrl || config.navigation?.defaultRedirectUrl || '/';\n const forgotPasswordLink =\n config.navigation?.links?.forgotPassword || '/auth/forgot-password';\n const signUpLink = config.navigation?.links?.signUp || '/auth/sign-up';\n const setPasswordLink =\n config.navigation?.links?.setPassword || '/auth/set-password';\n const onNavigate =\n config.navigation?.onNavigate ||\n ((path: string) => {\n if (typeof window !== 'undefined') {\n window.location.href = path;\n }\n });\n const logoImage = config.ui.logoImage;\n\n const form = useForm<SignInFormValues>({\n resolver: zodResolver(\n signInSchema(t, {\n phoneRegex,\n allowEmailSignIn,\n allowPhoneSignIn,\n }),\n ),\n defaultValues: { username: '', password: '' },\n mode: 'onSubmit',\n reValidateMode: 'onSubmit',\n });\n\n useEffect(() => {\n if (error) {\n toast.error(error.title || 'Error', {\n description: error.description,\n });\n }\n }, [error]);\n\n // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: auth branching is intentional\n const handleCheckAccount = async (usernameValue: string) => {\n if (!hasSignInIdentifierChannel) {\n form.setError('username', {\n message: 'Sign in is unavailable for email and phone',\n });\n return;\n }\n setIsChecking(true);\n try {\n const normalizedUsername = phoneRegex.test(usernameValue)\n ? normalizePhone(usernameValue)\n : usernameValue;\n const emailInput = z.email().safeParse(normalizedUsername).success;\n if (emailInput) {\n if (!allowEmailSignIn) {\n form.setError('username', { message: 'Email sign in is disabled' });\n return;\n }\n } else if (!allowPhoneSignIn) {\n form.setError('username', { message: 'Phone sign in is disabled' });\n return;\n }\n\n const result = await checkUserMutation.mutateAsync({\n body: {\n username: normalizedUsername,\n },\n });\n\n if (result.exists) {\n if (result.requiresPasswordSetup) {\n const redirectParam = defaultRedirect\n ? `&redirect=${encodeURIComponent(defaultRedirect)}`\n : '';\n onNavigate(\n `${setPasswordLink}?identifier=${encodeURIComponent(normalizedUsername)}${redirectParam}`,\n );\n return;\n }\n\n if (\n !result.verified &&\n result.needsVerification &&\n result.verificationId\n ) {\n const redirectParam = defaultRedirect\n ? `&redirect=${encodeURIComponent(defaultRedirect)}`\n : '';\n const verifyPath = isPhone(normalizedUsername)\n ? `/auth/verify-phone?context=sign-in&verificationId=${result.verificationId}&identifier=${encodeURIComponent(normalizedUsername)}${redirectParam}`\n : `/auth/verify-email?verificationId=${result.verificationId}&email=${encodeURIComponent(normalizedUsername)}${redirectParam}`;\n onNavigate(verifyPath);\n return;\n }\n\n setUsername(normalizedUsername);\n form.setValue('username', normalizedUsername);\n setShowPasswordField(true);\n } else {\n if (!enableSignup) {\n form.setError('username', { message: 'Sign up is disabled' });\n return;\n }\n const email = isPhone(normalizedUsername) ? '' : normalizedUsername;\n if (email) {\n if (!allowEmailSignup) {\n form.setError('username', { message: 'Email sign up is disabled' });\n return;\n }\n } else if (!allowPhoneSignup) {\n form.setError('username', { message: 'Phone sign up is disabled' });\n return;\n }\n const redirectParam = defaultRedirect\n ? `&redirect=${encodeURIComponent(defaultRedirect)}`\n : '';\n if (email) {\n onNavigate(\n `${signUpLink}?email=${encodeURIComponent(email)}${redirectParam}`,\n );\n } else {\n onNavigate(\n `${signUpLink}?phone=${encodeURIComponent(normalizedUsername)}${redirectParam}`,\n );\n }\n }\n } catch {\n form.setError('username', { message: t('errors.checkAccountFailed') });\n } finally {\n setIsChecking(false);\n }\n };\n\n const onSubmit = async (values: SignInFormValues) => {\n if (showPasswordField) {\n const pwd = values.password;\n if (!pwd || pwd.length < 8) {\n form.setError('password', { message: t('errors.passwordLength') });\n return;\n }\n await handlePasswordSubmit({ password: pwd });\n } else {\n await handleCheckAccount(values.username);\n }\n };\n\n // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: auth branching is intentional\n const handlePasswordSubmit = async (values: { password: string }) => {\n setIsLoading(true);\n setError(null);\n\n try {\n const res = await signInMutation.mutateAsync({\n body: {\n identifier: username,\n password: values.password,\n },\n });\n\n if ('verificationId' in res && res.verificationId) {\n const redirectParam = defaultRedirect\n ? `&redirect=${encodeURIComponent(defaultRedirect)}`\n : '';\n const verifyPath = isPhone(username)\n ? `/auth/verify-phone?context=sign-in&verificationId=${res.verificationId}&identifier=${encodeURIComponent(username)}${redirectParam}`\n : `/auth/verify-email?verificationId=${res.verificationId}${redirectParam}`;\n onNavigate(verifyPath);\n return;\n }\n\n if ('user' in res && 'session' in res) {\n setAuth(res);\n }\n onNavigate(defaultRedirect);\n } catch (err) {\n const authError = err as { code?: string; message?: string };\n const errorCode = authError.code || authError.message;\n if (errorCode === 'HAS_NO_PASSWORD') {\n const redirectParam = defaultRedirect\n ? `&redirect=${encodeURIComponent(defaultRedirect)}`\n : '';\n onNavigate(\n `${setPasswordLink}?identifier=${encodeURIComponent(username)}${redirectParam}`,\n );\n return;\n }\n handleError(err, setError, t, { signIn: true });\n } finally {\n setIsLoading(false);\n }\n };\n\n const handleBack = () => {\n setShowPasswordField(false);\n setUsername('');\n form.setValue('password', '');\n };\n\n const isSubmitting =\n isLoading ||\n checkUserMutation.isPending ||\n signInMutation.isPending ||\n isChecking;\n\n let submitLabel = t('form.continue');\n if (isSubmitting) {\n submitLabel = showPasswordField ? t('form.submitting') : t('form.checking');\n } else if (showPasswordField) {\n submitLabel = t('form.submit');\n }\n\n let accountLabel = t('form.accountLabel');\n if (allowEmailSignIn && !allowPhoneSignIn) {\n accountLabel = 'Email';\n } else if (!allowEmailSignIn && allowPhoneSignIn) {\n accountLabel = 'Phone';\n }\n\n let errorContent: AuthErrorContent | null = null;\n if (error) {\n if (typeof error === 'string') {\n errorContent = { title: 'Error', description: error };\n } else {\n errorContent = error;\n }\n }\n\n const formContent = (\n <Form {...form}>\n <form\n id=\"sign-in-form\"\n autoComplete=\"on\"\n onSubmit={form.handleSubmit(onSubmit)}\n className=\"space-y-4\"\n >\n {showPasswordField ? (\n <>\n <FormItem>\n <FormLabel className=\"flex justify-between items-center\">\n {accountLabel}\n <Button\n type=\"button\"\n variant=\"link\"\n size=\"sm\"\n className=\"p-0 m-0 h-auto\"\n onClick={handleBack}\n >\n {t('changeAccount')}\n </Button>\n </FormLabel>\n <Input\n id=\"sign-in-username\"\n type=\"text\"\n value={username}\n autoComplete=\"username\"\n disabled\n />\n </FormItem>\n <FormField\n control={form.control}\n name=\"password\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>{t('form.passwordLabel')}</FormLabel>\n <PasswordInput\n field={{ ...field, value: field.value ?? '' }}\n show={showPassword}\n onToggle={() => setShowPassword(!showPassword)}\n />\n <FormMessage />\n </FormItem>\n )}\n />\n </>\n ) : (\n <FormField\n control={form.control}\n name=\"username\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>{accountLabel}</FormLabel>\n <FormControl>\n <Input\n {...field}\n type={\n allowEmailSignIn && !allowPhoneSignIn ? 'email' : 'text'\n }\n autoComplete={\n allowEmailSignIn && !allowPhoneSignIn\n ? 'email'\n : 'username'\n }\n />\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n )}\n <Button\n type=\"submit\"\n className=\"w-full\"\n disabled={isSubmitting}\n loading={isSubmitting}\n >\n {submitLabel}\n </Button>\n </form>\n </Form>\n );\n\n return (\n <div className=\"space-y-4\">\n <AuthLayout\n title={config.ui.name}\n description={t('description')}\n logoImage={logoImage}\n footer={\n showPasswordField ? (\n <div className=\"flex items-center justify-center w-full\">\n {Link ? (\n <Link\n href={forgotPasswordLink}\n className=\"text-primary inline-block hover:underline\"\n >\n {t('footer.forgotPassword')}\n </Link>\n ) : (\n <a\n href={forgotPasswordLink}\n onClick={(e) => {\n e.preventDefault();\n onNavigate(forgotPasswordLink);\n }}\n className=\"text-primary inline-block hover:underline\"\n >\n {t('footer.forgotPassword')}\n </a>\n )}\n </div>\n ) : undefined\n }\n >\n {formContent}\n {errorContent && (\n <Alert variant=\"destructive\" className=\"mt-4\">\n <IconAlertCircle className=\"h-4 w-4\" />\n <AlertTitle>{errorContent.title}</AlertTitle>\n <AlertDescription>{errorContent.description}</AlertDescription>\n </Alert>\n )}\n </AuthLayout>\n </div>\n );\n};\n"],"mappings":"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","names":[]}