@entropy-softworks/ui 2026.7.31

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 (590) hide show
  1. package/CHANGELOG.md +96 -0
  2. package/LICENSE +21 -0
  3. package/README.md +115 -0
  4. package/lib/components/auth/LockOverlay.d.ts +22 -0
  5. package/lib/components/auth/LockOverlay.d.ts.map +1 -0
  6. package/lib/components/auth/LockOverlay.jsx +82 -0
  7. package/lib/components/auth/LockOverlay.jsx.map +1 -0
  8. package/lib/components/auth/PasswordStrengthMeter.d.ts +12 -0
  9. package/lib/components/auth/PasswordStrengthMeter.d.ts.map +1 -0
  10. package/lib/components/auth/PasswordStrengthMeter.jsx +81 -0
  11. package/lib/components/auth/PasswordStrengthMeter.jsx.map +1 -0
  12. package/lib/components/auth/ProtectedRoute.d.ts +24 -0
  13. package/lib/components/auth/ProtectedRoute.d.ts.map +1 -0
  14. package/lib/components/auth/ProtectedRoute.jsx +56 -0
  15. package/lib/components/auth/ProtectedRoute.jsx.map +1 -0
  16. package/lib/components/auth/PwnedPasswordWarning.d.ts +13 -0
  17. package/lib/components/auth/PwnedPasswordWarning.d.ts.map +1 -0
  18. package/lib/components/auth/PwnedPasswordWarning.jsx +29 -0
  19. package/lib/components/auth/PwnedPasswordWarning.jsx.map +1 -0
  20. package/lib/components/auth/index.d.ts +5 -0
  21. package/lib/components/auth/index.d.ts.map +1 -0
  22. package/lib/components/auth/index.js +5 -0
  23. package/lib/components/auth/index.js.map +1 -0
  24. package/lib/components/bottom-nav.d.ts +25 -0
  25. package/lib/components/bottom-nav.d.ts.map +1 -0
  26. package/lib/components/bottom-nav.jsx +51 -0
  27. package/lib/components/bottom-nav.jsx.map +1 -0
  28. package/lib/components/button.d.ts +16 -0
  29. package/lib/components/button.d.ts.map +1 -0
  30. package/lib/components/button.jsx +73 -0
  31. package/lib/components/button.jsx.map +1 -0
  32. package/lib/components/card.d.ts +22 -0
  33. package/lib/components/card.d.ts.map +1 -0
  34. package/lib/components/card.jsx +36 -0
  35. package/lib/components/card.jsx.map +1 -0
  36. package/lib/components/checkbox.d.ts +12 -0
  37. package/lib/components/checkbox.d.ts.map +1 -0
  38. package/lib/components/checkbox.jsx +16 -0
  39. package/lib/components/checkbox.jsx.map +1 -0
  40. package/lib/components/connection-settings.d.ts +41 -0
  41. package/lib/components/connection-settings.d.ts.map +1 -0
  42. package/lib/components/connection-settings.jsx +354 -0
  43. package/lib/components/connection-settings.jsx.map +1 -0
  44. package/lib/components/context-menu.d.ts +52 -0
  45. package/lib/components/context-menu.d.ts.map +1 -0
  46. package/lib/components/context-menu.jsx +24 -0
  47. package/lib/components/context-menu.jsx.map +1 -0
  48. package/lib/components/data-table.d.ts +59 -0
  49. package/lib/components/data-table.d.ts.map +1 -0
  50. package/lib/components/data-table.jsx +101 -0
  51. package/lib/components/data-table.jsx.map +1 -0
  52. package/lib/components/dialog.d.ts +58 -0
  53. package/lib/components/dialog.d.ts.map +1 -0
  54. package/lib/components/dialog.jsx +197 -0
  55. package/lib/components/dialog.jsx.map +1 -0
  56. package/lib/components/dropdown-menu.d.ts +55 -0
  57. package/lib/components/dropdown-menu.d.ts.map +1 -0
  58. package/lib/components/dropdown-menu.jsx +38 -0
  59. package/lib/components/dropdown-menu.jsx.map +1 -0
  60. package/lib/components/entropy-boot-splash.d.ts +24 -0
  61. package/lib/components/entropy-boot-splash.d.ts.map +1 -0
  62. package/lib/components/entropy-boot-splash.jsx +83 -0
  63. package/lib/components/entropy-boot-splash.jsx.map +1 -0
  64. package/lib/components/entropy-mark-animated.d.ts +20 -0
  65. package/lib/components/entropy-mark-animated.d.ts.map +1 -0
  66. package/lib/components/entropy-mark-animated.jsx +148 -0
  67. package/lib/components/entropy-mark-animated.jsx.map +1 -0
  68. package/lib/components/entropy-mark-geometry.d.ts +8 -0
  69. package/lib/components/entropy-mark-geometry.d.ts.map +1 -0
  70. package/lib/components/entropy-mark-geometry.js +10 -0
  71. package/lib/components/entropy-mark-geometry.js.map +1 -0
  72. package/lib/components/entropy-mark-sequential.d.ts +12 -0
  73. package/lib/components/entropy-mark-sequential.d.ts.map +1 -0
  74. package/lib/components/entropy-mark-sequential.jsx +53 -0
  75. package/lib/components/entropy-mark-sequential.jsx.map +1 -0
  76. package/lib/components/entropy-mark.d.ts +29 -0
  77. package/lib/components/entropy-mark.d.ts.map +1 -0
  78. package/lib/components/entropy-mark.jsx +66 -0
  79. package/lib/components/entropy-mark.jsx.map +1 -0
  80. package/lib/components/error-boundary.d.ts +31 -0
  81. package/lib/components/error-boundary.d.ts.map +1 -0
  82. package/lib/components/error-boundary.jsx +40 -0
  83. package/lib/components/error-boundary.jsx.map +1 -0
  84. package/lib/components/index.d.ts +41 -0
  85. package/lib/components/index.d.ts.map +1 -0
  86. package/lib/components/index.js +43 -0
  87. package/lib/components/index.js.map +1 -0
  88. package/lib/components/input.d.ts +26 -0
  89. package/lib/components/input.d.ts.map +1 -0
  90. package/lib/components/input.jsx +95 -0
  91. package/lib/components/input.jsx.map +1 -0
  92. package/lib/components/item-icon.d.ts +32 -0
  93. package/lib/components/item-icon.d.ts.map +1 -0
  94. package/lib/components/item-icon.jsx +54 -0
  95. package/lib/components/item-icon.jsx.map +1 -0
  96. package/lib/components/label.d.ts +13 -0
  97. package/lib/components/label.d.ts.map +1 -0
  98. package/lib/components/label.jsx +9 -0
  99. package/lib/components/label.jsx.map +1 -0
  100. package/lib/components/legal-dialog.d.ts +18 -0
  101. package/lib/components/legal-dialog.d.ts.map +1 -0
  102. package/lib/components/legal-dialog.jsx +31 -0
  103. package/lib/components/legal-dialog.jsx.map +1 -0
  104. package/lib/components/license-gate.d.ts +17 -0
  105. package/lib/components/license-gate.d.ts.map +1 -0
  106. package/lib/components/license-gate.jsx +21 -0
  107. package/lib/components/license-gate.jsx.map +1 -0
  108. package/lib/components/logo.d.ts +15 -0
  109. package/lib/components/logo.d.ts.map +1 -0
  110. package/lib/components/logo.jsx +20 -0
  111. package/lib/components/logo.jsx.map +1 -0
  112. package/lib/components/onboarding-wizard.d.ts +89 -0
  113. package/lib/components/onboarding-wizard.d.ts.map +1 -0
  114. package/lib/components/onboarding-wizard.jsx +185 -0
  115. package/lib/components/onboarding-wizard.jsx.map +1 -0
  116. package/lib/components/pagination.d.ts +43 -0
  117. package/lib/components/pagination.d.ts.map +1 -0
  118. package/lib/components/pagination.jsx +72 -0
  119. package/lib/components/pagination.jsx.map +1 -0
  120. package/lib/components/password-generator.d.ts +15 -0
  121. package/lib/components/password-generator.d.ts.map +1 -0
  122. package/lib/components/password-generator.jsx +273 -0
  123. package/lib/components/password-generator.jsx.map +1 -0
  124. package/lib/components/pin-pad.d.ts +20 -0
  125. package/lib/components/pin-pad.d.ts.map +1 -0
  126. package/lib/components/pin-pad.jsx +93 -0
  127. package/lib/components/pin-pad.jsx.map +1 -0
  128. package/lib/components/popover.d.ts +27 -0
  129. package/lib/components/popover.d.ts.map +1 -0
  130. package/lib/components/popover.jsx +18 -0
  131. package/lib/components/popover.jsx.map +1 -0
  132. package/lib/components/profile/ProfileDialog.d.ts +25 -0
  133. package/lib/components/profile/ProfileDialog.d.ts.map +1 -0
  134. package/lib/components/profile/ProfileDialog.jsx +71 -0
  135. package/lib/components/profile/ProfileDialog.jsx.map +1 -0
  136. package/lib/components/profile/ProfileTab.d.ts +12 -0
  137. package/lib/components/profile/ProfileTab.d.ts.map +1 -0
  138. package/lib/components/profile/ProfileTab.jsx +112 -0
  139. package/lib/components/profile/ProfileTab.jsx.map +1 -0
  140. package/lib/components/profile/SecurityTab.d.ts +32 -0
  141. package/lib/components/profile/SecurityTab.d.ts.map +1 -0
  142. package/lib/components/profile/SecurityTab.jsx +145 -0
  143. package/lib/components/profile/SecurityTab.jsx.map +1 -0
  144. package/lib/components/profile/index.d.ts +4 -0
  145. package/lib/components/profile/index.d.ts.map +1 -0
  146. package/lib/components/profile/index.js +4 -0
  147. package/lib/components/profile/index.js.map +1 -0
  148. package/lib/components/segmented-toggle.d.ts +28 -0
  149. package/lib/components/segmented-toggle.d.ts.map +1 -0
  150. package/lib/components/segmented-toggle.jsx +64 -0
  151. package/lib/components/segmented-toggle.jsx.map +1 -0
  152. package/lib/components/separator.d.ts +13 -0
  153. package/lib/components/separator.d.ts.map +1 -0
  154. package/lib/components/separator.jsx +16 -0
  155. package/lib/components/separator.jsx.map +1 -0
  156. package/lib/components/server-settings.d.ts +27 -0
  157. package/lib/components/server-settings.d.ts.map +1 -0
  158. package/lib/components/server-settings.jsx +307 -0
  159. package/lib/components/server-settings.jsx.map +1 -0
  160. package/lib/components/settings/AccountSection.d.ts +26 -0
  161. package/lib/components/settings/AccountSection.d.ts.map +1 -0
  162. package/lib/components/settings/AccountSection.jsx +32 -0
  163. package/lib/components/settings/AccountSection.jsx.map +1 -0
  164. package/lib/components/settings/DangerZoneSection.d.ts +13 -0
  165. package/lib/components/settings/DangerZoneSection.d.ts.map +1 -0
  166. package/lib/components/settings/DangerZoneSection.jsx +16 -0
  167. package/lib/components/settings/DangerZoneSection.jsx.map +1 -0
  168. package/lib/components/settings/GeneralSection.d.ts +11 -0
  169. package/lib/components/settings/GeneralSection.d.ts.map +1 -0
  170. package/lib/components/settings/GeneralSection.jsx +12 -0
  171. package/lib/components/settings/GeneralSection.jsx.map +1 -0
  172. package/lib/components/settings/SupportSection.d.ts +11 -0
  173. package/lib/components/settings/SupportSection.d.ts.map +1 -0
  174. package/lib/components/settings/SupportSection.jsx +22 -0
  175. package/lib/components/settings/SupportSection.jsx.map +1 -0
  176. package/lib/components/settings/index.d.ts +5 -0
  177. package/lib/components/settings/index.d.ts.map +1 -0
  178. package/lib/components/settings/index.js +5 -0
  179. package/lib/components/settings/index.js.map +1 -0
  180. package/lib/components/settings-row.d.ts +28 -0
  181. package/lib/components/settings-row.d.ts.map +1 -0
  182. package/lib/components/settings-row.jsx +68 -0
  183. package/lib/components/settings-row.jsx.map +1 -0
  184. package/lib/components/skeleton.d.ts +8 -0
  185. package/lib/components/skeleton.d.ts.map +1 -0
  186. package/lib/components/skeleton.jsx +24 -0
  187. package/lib/components/skeleton.jsx.map +1 -0
  188. package/lib/components/social-connections.d.ts +15 -0
  189. package/lib/components/social-connections.d.ts.map +1 -0
  190. package/lib/components/social-connections.jsx +31 -0
  191. package/lib/components/social-connections.jsx.map +1 -0
  192. package/lib/components/stat-card.d.ts +29 -0
  193. package/lib/components/stat-card.d.ts.map +1 -0
  194. package/lib/components/stat-card.jsx +36 -0
  195. package/lib/components/stat-card.jsx.map +1 -0
  196. package/lib/components/tag-chip.d.ts +18 -0
  197. package/lib/components/tag-chip.d.ts.map +1 -0
  198. package/lib/components/tag-chip.jsx +54 -0
  199. package/lib/components/tag-chip.jsx.map +1 -0
  200. package/lib/components/tag-multi-select.d.ts +27 -0
  201. package/lib/components/tag-multi-select.d.ts.map +1 -0
  202. package/lib/components/tag-multi-select.jsx +65 -0
  203. package/lib/components/tag-multi-select.jsx.map +1 -0
  204. package/lib/components/text.d.ts +22 -0
  205. package/lib/components/text.d.ts.map +1 -0
  206. package/lib/components/text.jsx +43 -0
  207. package/lib/components/text.jsx.map +1 -0
  208. package/lib/components/toast/ToastPortal.d.ts +11 -0
  209. package/lib/components/toast/ToastPortal.d.ts.map +1 -0
  210. package/lib/components/toast/ToastPortal.jsx +15 -0
  211. package/lib/components/toast/ToastPortal.jsx.map +1 -0
  212. package/lib/components/toast/ToastPortal.web.d.ts +14 -0
  213. package/lib/components/toast/ToastPortal.web.d.ts.map +1 -0
  214. package/lib/components/toast/ToastPortal.web.jsx +39 -0
  215. package/lib/components/toast/ToastPortal.web.jsx.map +1 -0
  216. package/lib/components/toast/index.d.ts +3 -0
  217. package/lib/components/toast/index.d.ts.map +1 -0
  218. package/lib/components/toast/index.js +3 -0
  219. package/lib/components/toast/index.js.map +1 -0
  220. package/lib/components/toast/toast-config.d.ts +14 -0
  221. package/lib/components/toast/toast-config.d.ts.map +1 -0
  222. package/lib/components/toast/toast-config.jsx +24 -0
  223. package/lib/components/toast/toast-config.jsx.map +1 -0
  224. package/lib/components/tooltip.d.ts +30 -0
  225. package/lib/components/tooltip.d.ts.map +1 -0
  226. package/lib/components/tooltip.jsx +14 -0
  227. package/lib/components/tooltip.jsx.map +1 -0
  228. package/lib/components/totp-display.d.ts +23 -0
  229. package/lib/components/totp-display.d.ts.map +1 -0
  230. package/lib/components/totp-display.jsx +132 -0
  231. package/lib/components/totp-display.jsx.map +1 -0
  232. package/lib/components/user-avatar.d.ts +18 -0
  233. package/lib/components/user-avatar.d.ts.map +1 -0
  234. package/lib/components/user-avatar.jsx +25 -0
  235. package/lib/components/user-avatar.jsx.map +1 -0
  236. package/lib/context/AppConfigContext.d.ts +56 -0
  237. package/lib/context/AppConfigContext.d.ts.map +1 -0
  238. package/lib/context/AppConfigContext.jsx +14 -0
  239. package/lib/context/AppConfigContext.jsx.map +1 -0
  240. package/lib/context/NavigationContext.d.ts +42 -0
  241. package/lib/context/NavigationContext.d.ts.map +1 -0
  242. package/lib/context/NavigationContext.jsx +53 -0
  243. package/lib/context/NavigationContext.jsx.map +1 -0
  244. package/lib/context/NotificationContext.d.ts +32 -0
  245. package/lib/context/NotificationContext.d.ts.map +1 -0
  246. package/lib/context/NotificationContext.jsx +49 -0
  247. package/lib/context/NotificationContext.jsx.map +1 -0
  248. package/lib/context/ThemeContext.d.ts +12 -0
  249. package/lib/context/ThemeContext.d.ts.map +1 -0
  250. package/lib/context/ThemeContext.jsx +66 -0
  251. package/lib/context/ThemeContext.jsx.map +1 -0
  252. package/lib/context/index.d.ts +5 -0
  253. package/lib/context/index.d.ts.map +1 -0
  254. package/lib/context/index.js +5 -0
  255. package/lib/context/index.js.map +1 -0
  256. package/lib/flags.d.ts +9 -0
  257. package/lib/flags.d.ts.map +1 -0
  258. package/lib/flags.js +37 -0
  259. package/lib/flags.js.map +1 -0
  260. package/lib/forms/form-error.d.ts +12 -0
  261. package/lib/forms/form-error.d.ts.map +1 -0
  262. package/lib/forms/form-error.jsx +14 -0
  263. package/lib/forms/form-error.jsx.map +1 -0
  264. package/lib/forms/index.d.ts +3 -0
  265. package/lib/forms/index.d.ts.map +1 -0
  266. package/lib/forms/index.js +3 -0
  267. package/lib/forms/index.js.map +1 -0
  268. package/lib/forms/shake-field.d.ts +18 -0
  269. package/lib/forms/shake-field.d.ts.map +1 -0
  270. package/lib/forms/shake-field.jsx +30 -0
  271. package/lib/forms/shake-field.jsx.map +1 -0
  272. package/lib/hooks/index.d.ts +6 -0
  273. package/lib/hooks/index.d.ts.map +1 -0
  274. package/lib/hooks/index.js +6 -0
  275. package/lib/hooks/index.js.map +1 -0
  276. package/lib/hooks/useAuth.d.ts +109 -0
  277. package/lib/hooks/useAuth.d.ts.map +1 -0
  278. package/lib/hooks/useAuth.jsx +404 -0
  279. package/lib/hooks/useAuth.jsx.map +1 -0
  280. package/lib/hooks/useAutoLock.d.ts +22 -0
  281. package/lib/hooks/useAutoLock.d.ts.map +1 -0
  282. package/lib/hooks/useAutoLock.js +85 -0
  283. package/lib/hooks/useAutoLock.js.map +1 -0
  284. package/lib/hooks/useDebouncedValue.d.ts +19 -0
  285. package/lib/hooks/useDebouncedValue.d.ts.map +1 -0
  286. package/lib/hooks/useDebouncedValue.js +29 -0
  287. package/lib/hooks/useDebouncedValue.js.map +1 -0
  288. package/lib/hooks/useShakeAnimation.d.ts +17 -0
  289. package/lib/hooks/useShakeAnimation.d.ts.map +1 -0
  290. package/lib/hooks/useShakeAnimation.js +22 -0
  291. package/lib/hooks/useShakeAnimation.js.map +1 -0
  292. package/lib/hooks/useUploadBlobUrl.d.ts +13 -0
  293. package/lib/hooks/useUploadBlobUrl.d.ts.map +1 -0
  294. package/lib/hooks/useUploadBlobUrl.js +60 -0
  295. package/lib/hooks/useUploadBlobUrl.js.map +1 -0
  296. package/lib/index.d.ts +10 -0
  297. package/lib/index.d.ts.map +1 -0
  298. package/lib/index.js +47 -0
  299. package/lib/index.js.map +1 -0
  300. package/lib/screens/auth/AccountPickerScreen.d.ts +24 -0
  301. package/lib/screens/auth/AccountPickerScreen.d.ts.map +1 -0
  302. package/lib/screens/auth/AccountPickerScreen.jsx +47 -0
  303. package/lib/screens/auth/AccountPickerScreen.jsx.map +1 -0
  304. package/lib/screens/auth/AuthScreen.d.ts +59 -0
  305. package/lib/screens/auth/AuthScreen.d.ts.map +1 -0
  306. package/lib/screens/auth/AuthScreen.jsx +594 -0
  307. package/lib/screens/auth/AuthScreen.jsx.map +1 -0
  308. package/lib/screens/auth/ConsentScreen.d.ts +27 -0
  309. package/lib/screens/auth/ConsentScreen.d.ts.map +1 -0
  310. package/lib/screens/auth/ConsentScreen.jsx +55 -0
  311. package/lib/screens/auth/ConsentScreen.jsx.map +1 -0
  312. package/lib/screens/auth/ErrorScreen.d.ts +20 -0
  313. package/lib/screens/auth/ErrorScreen.d.ts.map +1 -0
  314. package/lib/screens/auth/ErrorScreen.jsx +43 -0
  315. package/lib/screens/auth/ErrorScreen.jsx.map +1 -0
  316. package/lib/screens/auth/ExpiredLinkScreen.d.ts +19 -0
  317. package/lib/screens/auth/ExpiredLinkScreen.d.ts.map +1 -0
  318. package/lib/screens/auth/ExpiredLinkScreen.jsx +38 -0
  319. package/lib/screens/auth/ExpiredLinkScreen.jsx.map +1 -0
  320. package/lib/screens/auth/ForgotPasswordScreen.d.ts +4 -0
  321. package/lib/screens/auth/ForgotPasswordScreen.d.ts.map +1 -0
  322. package/lib/screens/auth/ForgotPasswordScreen.jsx +123 -0
  323. package/lib/screens/auth/ForgotPasswordScreen.jsx.map +1 -0
  324. package/lib/screens/auth/ImportDataScreen.d.ts +17 -0
  325. package/lib/screens/auth/ImportDataScreen.d.ts.map +1 -0
  326. package/lib/screens/auth/ImportDataScreen.jsx +73 -0
  327. package/lib/screens/auth/ImportDataScreen.jsx.map +1 -0
  328. package/lib/screens/auth/LoginScreen.d.ts +38 -0
  329. package/lib/screens/auth/LoginScreen.d.ts.map +1 -0
  330. package/lib/screens/auth/LoginScreen.jsx +326 -0
  331. package/lib/screens/auth/LoginScreen.jsx.map +1 -0
  332. package/lib/screens/auth/MfaChallengeScreen.d.ts +4 -0
  333. package/lib/screens/auth/MfaChallengeScreen.d.ts.map +1 -0
  334. package/lib/screens/auth/MfaChallengeScreen.jsx +139 -0
  335. package/lib/screens/auth/MfaChallengeScreen.jsx.map +1 -0
  336. package/lib/screens/auth/MfaEnrollScreen.d.ts +12 -0
  337. package/lib/screens/auth/MfaEnrollScreen.d.ts.map +1 -0
  338. package/lib/screens/auth/MfaEnrollScreen.jsx +267 -0
  339. package/lib/screens/auth/MfaEnrollScreen.jsx.map +1 -0
  340. package/lib/screens/auth/PasskeyEnrollScreen.d.ts +18 -0
  341. package/lib/screens/auth/PasskeyEnrollScreen.d.ts.map +1 -0
  342. package/lib/screens/auth/PasskeyEnrollScreen.jsx +51 -0
  343. package/lib/screens/auth/PasskeyEnrollScreen.jsx.map +1 -0
  344. package/lib/screens/auth/PrivacyPolicyScreen.d.ts +19 -0
  345. package/lib/screens/auth/PrivacyPolicyScreen.d.ts.map +1 -0
  346. package/lib/screens/auth/PrivacyPolicyScreen.jsx +143 -0
  347. package/lib/screens/auth/PrivacyPolicyScreen.jsx.map +1 -0
  348. package/lib/screens/auth/RegisterScreen.d.ts +14 -0
  349. package/lib/screens/auth/RegisterScreen.d.ts.map +1 -0
  350. package/lib/screens/auth/RegisterScreen.jsx +296 -0
  351. package/lib/screens/auth/RegisterScreen.jsx.map +1 -0
  352. package/lib/screens/auth/ResetPasswordScreen.d.ts +12 -0
  353. package/lib/screens/auth/ResetPasswordScreen.d.ts.map +1 -0
  354. package/lib/screens/auth/ResetPasswordScreen.jsx +276 -0
  355. package/lib/screens/auth/ResetPasswordScreen.jsx.map +1 -0
  356. package/lib/screens/auth/ServerConfigScreen.d.ts +18 -0
  357. package/lib/screens/auth/ServerConfigScreen.d.ts.map +1 -0
  358. package/lib/screens/auth/ServerConfigScreen.jsx +259 -0
  359. package/lib/screens/auth/ServerConfigScreen.jsx.map +1 -0
  360. package/lib/screens/auth/TermsOfServiceScreen.d.ts +30 -0
  361. package/lib/screens/auth/TermsOfServiceScreen.d.ts.map +1 -0
  362. package/lib/screens/auth/TermsOfServiceScreen.jsx +130 -0
  363. package/lib/screens/auth/TermsOfServiceScreen.jsx.map +1 -0
  364. package/lib/screens/auth/VerifyEmailScreen.d.ts +4 -0
  365. package/lib/screens/auth/VerifyEmailScreen.d.ts.map +1 -0
  366. package/lib/screens/auth/VerifyEmailScreen.jsx +249 -0
  367. package/lib/screens/auth/VerifyEmailScreen.jsx.map +1 -0
  368. package/lib/screens/auth/WelcomeScreen.d.ts +17 -0
  369. package/lib/screens/auth/WelcomeScreen.d.ts.map +1 -0
  370. package/lib/screens/auth/WelcomeScreen.jsx +58 -0
  371. package/lib/screens/auth/WelcomeScreen.jsx.map +1 -0
  372. package/lib/screens/auth/index.d.ts +19 -0
  373. package/lib/screens/auth/index.d.ts.map +1 -0
  374. package/lib/screens/auth/index.js +19 -0
  375. package/lib/screens/auth/index.js.map +1 -0
  376. package/lib/screens/index.d.ts +2 -0
  377. package/lib/screens/index.d.ts.map +1 -0
  378. package/lib/screens/index.js +2 -0
  379. package/lib/screens/index.js.map +1 -0
  380. package/lib/services/api-config.d.ts +87 -0
  381. package/lib/services/api-config.d.ts.map +1 -0
  382. package/lib/services/api-config.js +202 -0
  383. package/lib/services/api-config.js.map +1 -0
  384. package/lib/services/auth.service.d.ts +140 -0
  385. package/lib/services/auth.service.d.ts.map +1 -0
  386. package/lib/services/auth.service.js +376 -0
  387. package/lib/services/auth.service.js.map +1 -0
  388. package/lib/services/favicon.d.ts +46 -0
  389. package/lib/services/favicon.d.ts.map +1 -0
  390. package/lib/services/favicon.js +84 -0
  391. package/lib/services/favicon.js.map +1 -0
  392. package/lib/services/hibp-cache.d.ts +23 -0
  393. package/lib/services/hibp-cache.d.ts.map +1 -0
  394. package/lib/services/hibp-cache.js +56 -0
  395. package/lib/services/hibp-cache.js.map +1 -0
  396. package/lib/services/hibp.d.ts +28 -0
  397. package/lib/services/hibp.d.ts.map +1 -0
  398. package/lib/services/hibp.js +92 -0
  399. package/lib/services/hibp.js.map +1 -0
  400. package/lib/services/index.d.ts +8 -0
  401. package/lib/services/index.d.ts.map +1 -0
  402. package/lib/services/index.js +7 -0
  403. package/lib/services/index.js.map +1 -0
  404. package/lib/services/passkey.d.ts +10 -0
  405. package/lib/services/passkey.d.ts.map +1 -0
  406. package/lib/services/passkey.js +192 -0
  407. package/lib/services/passkey.js.map +1 -0
  408. package/lib/utils/api-fetch.d.ts +11 -0
  409. package/lib/utils/api-fetch.d.ts.map +1 -0
  410. package/lib/utils/api-fetch.js +52 -0
  411. package/lib/utils/api-fetch.js.map +1 -0
  412. package/lib/utils/clipboard.d.ts +31 -0
  413. package/lib/utils/clipboard.d.ts.map +1 -0
  414. package/lib/utils/clipboard.js +66 -0
  415. package/lib/utils/clipboard.js.map +1 -0
  416. package/lib/utils/cn.d.ts +9 -0
  417. package/lib/utils/cn.d.ts.map +1 -0
  418. package/lib/utils/cn.js +12 -0
  419. package/lib/utils/cn.js.map +1 -0
  420. package/lib/utils/debounce.d.ts +13 -0
  421. package/lib/utils/debounce.d.ts.map +1 -0
  422. package/lib/utils/debounce.js +28 -0
  423. package/lib/utils/debounce.js.map +1 -0
  424. package/lib/utils/error.d.ts +9 -0
  425. package/lib/utils/error.d.ts.map +1 -0
  426. package/lib/utils/error.js +11 -0
  427. package/lib/utils/error.js.map +1 -0
  428. package/lib/utils/fetch.d.ts +17 -0
  429. package/lib/utils/fetch.d.ts.map +1 -0
  430. package/lib/utils/fetch.js +29 -0
  431. package/lib/utils/fetch.js.map +1 -0
  432. package/lib/utils/http-error.d.ts +41 -0
  433. package/lib/utils/http-error.d.ts.map +1 -0
  434. package/lib/utils/http-error.js +63 -0
  435. package/lib/utils/http-error.js.map +1 -0
  436. package/lib/utils/index.d.ts +11 -0
  437. package/lib/utils/index.d.ts.map +1 -0
  438. package/lib/utils/index.js +11 -0
  439. package/lib/utils/index.js.map +1 -0
  440. package/lib/utils/palette.d.ts +46 -0
  441. package/lib/utils/palette.d.ts.map +1 -0
  442. package/lib/utils/palette.js +75 -0
  443. package/lib/utils/palette.js.map +1 -0
  444. package/lib/utils/password.d.ts +20 -0
  445. package/lib/utils/password.d.ts.map +1 -0
  446. package/lib/utils/password.js +51 -0
  447. package/lib/utils/password.js.map +1 -0
  448. package/lib/utils/settings-storage.d.ts +3 -0
  449. package/lib/utils/settings-storage.d.ts.map +1 -0
  450. package/lib/utils/settings-storage.js +62 -0
  451. package/lib/utils/settings-storage.js.map +1 -0
  452. package/lib/utils/validation.d.ts +29 -0
  453. package/lib/utils/validation.d.ts.map +1 -0
  454. package/lib/utils/validation.js +58 -0
  455. package/lib/utils/validation.js.map +1 -0
  456. package/package.json +204 -0
  457. package/src/components/__tests__/data-table.test.ts +94 -0
  458. package/src/components/__tests__/pagination.test.ts +73 -0
  459. package/src/components/__tests__/stat-card.test.ts +21 -0
  460. package/src/components/auth/LockOverlay.tsx +122 -0
  461. package/src/components/auth/PasswordStrengthMeter.tsx +96 -0
  462. package/src/components/auth/ProtectedRoute.tsx +91 -0
  463. package/src/components/auth/PwnedPasswordWarning.tsx +54 -0
  464. package/src/components/auth/index.ts +10 -0
  465. package/src/components/bottom-nav.tsx +99 -0
  466. package/src/components/button.tsx +144 -0
  467. package/src/components/card.tsx +82 -0
  468. package/src/components/checkbox.tsx +48 -0
  469. package/src/components/connection-settings.tsx +583 -0
  470. package/src/components/context-menu.tsx +95 -0
  471. package/src/components/data-table.tsx +223 -0
  472. package/src/components/dialog.tsx +376 -0
  473. package/src/components/dropdown-menu.tsx +120 -0
  474. package/src/components/entropy-boot-splash.tsx +114 -0
  475. package/src/components/entropy-mark-animated.tsx +260 -0
  476. package/src/components/entropy-mark-geometry.ts +11 -0
  477. package/src/components/entropy-mark-sequential.tsx +132 -0
  478. package/src/components/entropy-mark.tsx +135 -0
  479. package/src/components/error-boundary.tsx +70 -0
  480. package/src/components/index.ts +156 -0
  481. package/src/components/input.tsx +246 -0
  482. package/src/components/item-icon.tsx +111 -0
  483. package/src/components/label.tsx +25 -0
  484. package/src/components/legal-dialog.tsx +47 -0
  485. package/src/components/license-gate.tsx +28 -0
  486. package/src/components/logo.tsx +34 -0
  487. package/src/components/onboarding-wizard.tsx +353 -0
  488. package/src/components/pagination.tsx +154 -0
  489. package/src/components/password-generator.tsx +393 -0
  490. package/src/components/pin-pad.tsx +156 -0
  491. package/src/components/popover.tsx +38 -0
  492. package/src/components/profile/ProfileDialog.tsx +129 -0
  493. package/src/components/profile/ProfileTab.tsx +151 -0
  494. package/src/components/profile/SecurityTab.tsx +229 -0
  495. package/src/components/profile/index.ts +3 -0
  496. package/src/components/segmented-toggle.tsx +119 -0
  497. package/src/components/separator.tsx +41 -0
  498. package/src/components/server-settings.tsx +442 -0
  499. package/src/components/settings/AccountSection.tsx +76 -0
  500. package/src/components/settings/DangerZoneSection.tsx +37 -0
  501. package/src/components/settings/GeneralSection.tsx +39 -0
  502. package/src/components/settings/SupportSection.tsx +53 -0
  503. package/src/components/settings/index.ts +4 -0
  504. package/src/components/settings-row.tsx +126 -0
  505. package/src/components/skeleton.tsx +48 -0
  506. package/src/components/social-connections.tsx +55 -0
  507. package/src/components/stat-card.tsx +64 -0
  508. package/src/components/tag-chip.tsx +78 -0
  509. package/src/components/tag-multi-select.tsx +136 -0
  510. package/src/components/text.tsx +77 -0
  511. package/src/components/toast/ToastPortal.tsx +16 -0
  512. package/src/components/toast/ToastPortal.web.tsx +47 -0
  513. package/src/components/toast/index.ts +2 -0
  514. package/src/components/toast/toast-config.tsx +31 -0
  515. package/src/components/tooltip.tsx +30 -0
  516. package/src/components/totp-display.tsx +207 -0
  517. package/src/components/user-avatar.tsx +46 -0
  518. package/src/context/AppConfigContext.tsx +76 -0
  519. package/src/context/NavigationContext.tsx +75 -0
  520. package/src/context/NotificationContext.tsx +69 -0
  521. package/src/context/ThemeContext.tsx +83 -0
  522. package/src/context/__tests__/NavigationContext.test.tsx +53 -0
  523. package/src/context/index.ts +24 -0
  524. package/src/flags.ts +44 -0
  525. package/src/forms/form-error.tsx +20 -0
  526. package/src/forms/index.ts +2 -0
  527. package/src/forms/shake-field.tsx +52 -0
  528. package/src/hooks/__tests__/useUploadBlobUrl.test.tsx +77 -0
  529. package/src/hooks/index.ts +18 -0
  530. package/src/hooks/useAuth.tsx +567 -0
  531. package/src/hooks/useAutoLock.ts +110 -0
  532. package/src/hooks/useDebouncedValue.ts +32 -0
  533. package/src/hooks/useShakeAnimation.ts +42 -0
  534. package/src/hooks/useUploadBlobUrl.ts +75 -0
  535. package/src/index.ts +48 -0
  536. package/src/screens/auth/AccountPickerScreen.tsx +103 -0
  537. package/src/screens/auth/AuthScreen.tsx +941 -0
  538. package/src/screens/auth/ConsentScreen.tsx +118 -0
  539. package/src/screens/auth/ErrorScreen.tsx +96 -0
  540. package/src/screens/auth/ExpiredLinkScreen.tsx +87 -0
  541. package/src/screens/auth/ForgotPasswordScreen.tsx +182 -0
  542. package/src/screens/auth/ImportDataScreen.tsx +112 -0
  543. package/src/screens/auth/LoginScreen.tsx +484 -0
  544. package/src/screens/auth/MfaChallengeScreen.tsx +216 -0
  545. package/src/screens/auth/MfaEnrollScreen.tsx +388 -0
  546. package/src/screens/auth/PasskeyEnrollScreen.tsx +96 -0
  547. package/src/screens/auth/PrivacyPolicyScreen.tsx +249 -0
  548. package/src/screens/auth/RegisterScreen.tsx +430 -0
  549. package/src/screens/auth/ResetPasswordScreen.tsx +377 -0
  550. package/src/screens/auth/ServerConfigScreen.tsx +388 -0
  551. package/src/screens/auth/TermsOfServiceScreen.tsx +236 -0
  552. package/src/screens/auth/VerifyEmailScreen.tsx +310 -0
  553. package/src/screens/auth/WelcomeScreen.tsx +78 -0
  554. package/src/screens/auth/index.ts +36 -0
  555. package/src/screens/index.ts +1 -0
  556. package/src/services/__tests__/api-config.test.ts +67 -0
  557. package/src/services/__tests__/favicon.test.ts +88 -0
  558. package/src/services/__tests__/hibp-cache.test.ts +37 -0
  559. package/src/services/__tests__/hibp.test.ts +39 -0
  560. package/src/services/api-config.ts +260 -0
  561. package/src/services/auth.service.ts +498 -0
  562. package/src/services/favicon.ts +102 -0
  563. package/src/services/hibp-cache.ts +71 -0
  564. package/src/services/hibp.ts +120 -0
  565. package/src/services/index.ts +52 -0
  566. package/src/services/passkey.ts +213 -0
  567. package/src/types/external.d.ts +24 -0
  568. package/src/utils/__tests__/clipboard.test.ts +59 -0
  569. package/src/utils/__tests__/cn.test.ts +24 -0
  570. package/src/utils/__tests__/debounce.test.ts +42 -0
  571. package/src/utils/__tests__/error.test.ts +18 -0
  572. package/src/utils/__tests__/http-error.test.ts +33 -0
  573. package/src/utils/__tests__/palette.test.ts +22 -0
  574. package/src/utils/__tests__/password.test.ts +55 -0
  575. package/src/utils/__tests__/settings-storage.test.ts +15 -0
  576. package/src/utils/__tests__/validation.test.ts +52 -0
  577. package/src/utils/api-fetch.ts +61 -0
  578. package/src/utils/clipboard.ts +69 -0
  579. package/src/utils/cn.ts +12 -0
  580. package/src/utils/debounce.ts +33 -0
  581. package/src/utils/error.ts +10 -0
  582. package/src/utils/fetch.ts +33 -0
  583. package/src/utils/http-error.ts +81 -0
  584. package/src/utils/index.ts +23 -0
  585. package/src/utils/palette.ts +105 -0
  586. package/src/utils/password.ts +64 -0
  587. package/src/utils/settings-storage.ts +68 -0
  588. package/src/utils/validation.ts +71 -0
  589. package/styles/globals.css +262 -0
  590. package/tailwind-preset.js +163 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,96 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). Released versions
6
+ are CalVer — `YYYY.M.D` of the publish date, with leading zeros dropped (npm's semver parser rejects
7
+ them), matching the `entropy-auth` crate. The `0.1.0` entry below predates the switch and was never
8
+ published to npm.
9
+
10
+ ## [Unreleased]
11
+
12
+ ## [2026.7.31] — 2026-07-31
13
+
14
+ First npm release. Contents unchanged from the `0.1.0` entry below, which was tagged but never
15
+ published.
16
+
17
+ ### Added
18
+
19
+ - **Admin-dashboard primitives**: `DataTable` (generic typed table with column defs, custom cell
20
+ renderers, fixed-`width`/`flex` sizing, alignment, row press, skeleton loading state, and empty
21
+ state; virtualised over react-native `FlatList` with an always-visible header row — works on RN
22
+ web and native), `Pagination` (prev/next controls, `X–Y of Z` summary, clamped page state,
23
+ accessible disabled controls, and an optional `DropdownMenu`-based page-size selector), and
24
+ `StatCard` (label + value + optional icon slot and trend/delta line, composed from `Card` +
25
+ `Text`). Exposes the pure helpers `getPaginationState`, `resolveColumnStyle`, `dataTableBodyMode`,
26
+ and `trendColorClass`.
27
+
28
+ ## [0.1.0] - 2026-05-26
29
+
30
+ ### Added
31
+
32
+ - Initial release.
33
+ - **UI primitives** (ported from vault mobile): `Button`, `IconButton`, `Card` family, `Checkbox`,
34
+ `ContextMenu` family, `Dialog` / `DialogContent` / `DialogFooter` / `DialogButton` /
35
+ `ConfirmDialog`, `DropdownMenu` family, `ErrorBoundary`, `Input` / `SearchInput` / `EmailInput` /
36
+ `PasswordInput` / `TextArea`, `FormLabel` / `FormLabelText`, `Popover` family, `Separator` /
37
+ `SeparatorWithText`, `Skeleton`, `Text` / `Heading` / `Label` / `MutedText` / `MonoText` /
38
+ `ErrorText`, `Tooltip` family.
39
+ - **Promoted shared widgets**: `BrandHeader`, `TagChip`, `BottomNav`, `ItemIcon`, `TotpDisplay`,
40
+ `UserAvatar`, `SocialConnections`, `ServerSettings`, `PasswordGenerator`, `TagMultiSelect`,
41
+ `SettingsRow` / `SettingsSection`, `AccountSection`, `GeneralSection`, `SupportSection`,
42
+ `DangerZoneSection`, `ProfileDialog` / `ProfileTab` / `SecurityTab`, `ToastPortal` (+ web
43
+ variant), `AuthScreen` / `StaggeredAuthScreen` / `FadeTransition` / `ScaleTransition`.
44
+ - **Auth helpers**: `LockOverlay`, `PasswordStrengthMeter` (+ `calculatePasswordStrength`),
45
+ `PwnedPasswordWarning`, `ProtectedRoute` / `withAuth` / `useProtectedContent`.
46
+ - **Auth screens** (sub-path `@entropy-softworks/ui/screens/auth`): `WelcomeScreen`, `LoginScreen`
47
+ (with optional passkey flow), `RegisterScreen`, `ForgotPasswordScreen`, `ResetPasswordScreen`,
48
+ `VerifyEmailScreen`, `MfaChallengeScreen`, `MfaEnrollScreen`, `ServerConfigScreen`,
49
+ `TermsOfServiceScreen`, `PrivacyPolicyScreen`, `ImportDataScreen`. All AppConfig-driven (logo /
50
+ appName / route map). Vault-specific bits (server-settings cog, password-demo animation,
51
+ social-auth, authenticator-app promo, Bitwarden import flow) exposed as optional render slots /
52
+ props.
53
+ - **Services**: `configureApi({ apiBaseUrl, storagePrefix, runtimeConfigKey })` runtime
54
+ configuration (state isolated on an `ApiConfigStore` for testability); `AuthService` with
55
+ login/register/logout/me/MFA/ email-verify/password-reset/forgot-password/delete-account methods;
56
+ `fetchHibpPolicy` + `getHibpPolicy`; `checkPasswordPwned` HIBP k-anonymity lookup; favicon helpers
57
+ (`buildFaviconUrl`, `customIconRef`, `customIconId`, `isCustomIconRef`, `resolveIcon`).
58
+ - **Transport**: `apiFetch` with cookie-based CSRF on web + Bearer tokens on native;
59
+ `fetchWithTimeout` helper using `AbortSignal.any`.
60
+ - **Context**: `AppConfigProvider`, `ThemeProvider` with `light` / `dark` / `system` preference
61
+ persistence, `NotificationProvider` exposing a `push()` toast helper, `NavigationProvider` +
62
+ `useNavigation` for pluggable routing (defaults to expo-router; consumers without it inject their
63
+ own stack-based adapter).
64
+ - **Hooks**: `useAuth` / `useRole` / `useRequireAuth` / `useSession` parameterised through
65
+ `AppConfig` and optional `onAfterLogin` / `onAfterRegister` / `onBeforeLogout` /
66
+ `onBeforeCheckAuth` / `loginWithPasskey` / `unlockWithPassword` callbacks; `useShakeAnimation`
67
+ invalid-input feedback; `useAutoLock` generic idle-lock hook; `useUploadBlobUrl` auth-aware blob
68
+ fetcher.
69
+ - **Forms**: `FormError` fixed-height error slot, `ShakeField` invalid-shake wrapper.
70
+ - **Utilities** (`@entropy-softworks/ui/utils`): `cn`, `getErrorMessage`, `extractErrorMessage`,
71
+ `debounce`, `copyToClipboard` / `clearClipboardNow` (auto-clear timer), `loadSetting` /
72
+ `saveSetting`, `generatePassword` (CSPRNG, rejection-sampled), `validateEmail` /
73
+ `validatePassword` / `validateUsername`, `darkPalette` / `lightPalette` / `usePalette` /
74
+ `getPalette`.
75
+
76
+ ### Security
77
+
78
+ - Web user records persist in memory only (not `sessionStorage`). XSS attacks cannot read the cached
79
+ email / display name; the HttpOnly session cookie remains the auth source of truth.
80
+ `isAuthenticated()` on web probes the non-HttpOnly `csrf_token` cookie set by the server alongside
81
+ the session cookie.
82
+ - `extractErrorMessage` caps detail arrays at 5 entries to bound the size of error toasts.
83
+ - `buildFaviconUrl` rejects inputs with non-http(s) explicit schemes before normalisation,
84
+ preventing scheme-confusion attacks against the favicon proxy.
85
+ - Password / email / username validators in `utils/validation` are UI-only previews. The application
86
+ server enforces the same rules authoritatively (see `entropy-auth`'s `password::policy` /
87
+ `Validation`).
88
+
89
+ ### Tests
90
+
91
+ - 82 unit tests across services, utilities, hooks, and contexts. Jest preset uses
92
+ `babel-preset-expo` with module mocks for `react-native` / `expo-secure-store` / `expo-crypto` /
93
+ `expo-clipboard` / `nativewind`.
94
+
95
+ [Unreleased]: https://gitlab.com/entropysoftworks/packages/entropy-ui/-/compare/v0.1.0...HEAD
96
+ [0.1.0]: https://gitlab.com/entropysoftworks/packages/entropy-ui/-/tags/v0.1.0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Entropy Softworks
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,115 @@
1
+ # entropy-ui
2
+
3
+ Shared React Native UI primitives, hooks, services, and auth screens for Entropy Softworks Expo
4
+ apps. Targets React 19 / React Native 0.83 / Expo SDK 55 with NativeWind v4.
5
+
6
+ Ships **both** forms via conditional exports: React Native / Metro consumers resolve the original
7
+ TypeScript source (`source` / `react-native` conditions) so NativeWind's `className` transform runs
8
+ at the consumer; other bundlers (web, Node) resolve the compiled `lib/` output (`default` condition)
9
+ with type declarations. JSX is preserved in the compiled output (`jsx: preserve`) so the `className`
10
+ transform still applies there too.
11
+
12
+ ### Runtime requirements
13
+
14
+ - **Node 20.3+** (web tooling). `utils/fetch` uses `AbortSignal.any`, which requires Node 20.3,
15
+ Safari 17.4, Chrome 116, Firefox 124, or newer. Older runtimes throw on import.
16
+ - **iOS 16+ / Android 9+ / Chromium 116+ / Safari 17.4+ / Firefox 124+** at runtime.
17
+
18
+ The package is **UI + auth screens + cross-cutting hooks/services** that are reusable across Entropy
19
+ Softworks consumer apps (vault, bootstrap, paperhands, pirates, …). App-specific branding (logo,
20
+ copy, route map) is parameterised through props and a config provider.
21
+
22
+ ## Installation
23
+
24
+ ```bash
25
+ npm install @entropy-softworks/ui
26
+ ```
27
+
28
+ Peer deps the consumer must provide (see `peerDependencies` in `package.json`): `react`,
29
+ `react-native`, `expo`, `expo-router`, `nativewind`, `react-hook-form`, `zod`,
30
+ `lucide-react-native`, the `@rn-primitives/*` family, `@tanstack/react-query`,
31
+ `class-variance-authority`, `clsx`, `tailwind-merge`, `react-native-toast-message`, plus the various
32
+ Expo modules referenced (`expo-image`, `expo-blur`, `expo-clipboard`, …).
33
+
34
+ ## Quick Start
35
+
36
+ ### Tailwind preset
37
+
38
+ ```js
39
+ // tailwind.config.js
40
+ module.exports = {
41
+ presets: [require("@entropy-softworks/ui/tailwind-preset")],
42
+ content: [
43
+ "./app/**/*.{js,jsx,ts,tsx}",
44
+ "./components/**/*.{js,jsx,ts,tsx}",
45
+ "./node_modules/@entropy-softworks/ui/**/*.{js,jsx,ts,tsx}",
46
+ ],
47
+ };
48
+ ```
49
+
50
+ ### Global CSS
51
+
52
+ ```css
53
+ /* styles/globals.css */
54
+ @import "@entropy-softworks/ui/styles/globals.css";
55
+ ```
56
+
57
+ ### Primitives
58
+
59
+ ```tsx
60
+ import { Button, Card, Input, Heading, MutedText } from "@entropy-softworks/ui";
61
+ ```
62
+
63
+ ### Auth screens
64
+
65
+ ```tsx
66
+ // app/(auth)/login.tsx
67
+ import { LoginScreen } from "@entropy-softworks/ui/screens/auth";
68
+ import { BootstrapLogo } from "@/components/BootstrapLogo";
69
+
70
+ export default function Login() {
71
+ return <LoginScreen Logo={BootstrapLogo} appName="Bootstrap" />;
72
+ }
73
+ ```
74
+
75
+ ## Exports
76
+
77
+ | Subpath | Contents |
78
+ | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
79
+ | `@entropy-softworks/ui` | UI primitives (Button, Card, Input, Text, Heading, MutedText, Checkbox, Dialog, …) |
80
+ | `@entropy-softworks/ui/screens/auth` | Welcome, Login, Register, MFA challenge/enroll, Verify-email, Forgot/Reset-password, Server-config, Terms, Privacy, Import-data |
81
+ | `@entropy-softworks/ui/hooks` | useAuth, useShakeAnimation, useAutoLock |
82
+ | `@entropy-softworks/ui/services` | auth.service, api-config, hibp |
83
+ | `@entropy-softworks/ui/context` | ThemeContext, NotificationContext, AppConfigContext |
84
+ | `@entropy-softworks/ui/forms` | form-error, shake-field |
85
+ | `@entropy-softworks/ui/utils` | cn, … |
86
+ | `@entropy-softworks/ui/tailwind-preset` | Tailwind preset (colors, typography, animations) |
87
+ | `@entropy-softworks/ui/styles/globals.css` | Global stylesheet (Tailwind directives + CSS vars + animations) |
88
+
89
+ ## Development
90
+
91
+ ```bash
92
+ git clone git@gitlab.com:entropysoftworks/packages/entropy-ui.git
93
+ cd entropy-ui
94
+ npm install
95
+ npm run type-check
96
+ npm run lint
97
+ npm test
98
+ npm run build # compile src -> lib (also runs automatically on publish)
99
+ ```
100
+
101
+ ## Publishing
102
+
103
+ Published to the public npm registry on a `vX.Y.Z` git tag (CI runs `npm publish`; `prepublishOnly`
104
+ builds `lib/` first). The tag must match `version` in `package.json`. Bump the version, tag, push.
105
+
106
+ See [CONTRIBUTING.md](./CONTRIBUTING.md) for the full workflow.
107
+
108
+ ## Versioning
109
+
110
+ Semantic Versioning. Breaking API changes bump the major; new components or screens bump the minor;
111
+ bug fixes bump the patch. See [CHANGELOG.md](./CHANGELOG.md).
112
+
113
+ ## License
114
+
115
+ MIT — see [LICENSE](./LICENSE).
@@ -0,0 +1,22 @@
1
+ import React from "react";
2
+ interface LockOverlayProps {
3
+ /**
4
+ * Validates the password and unlocks the session. Throw on bad
5
+ * password — the overlay catches and surfaces a generic error.
6
+ */
7
+ onUnlock: (password: string) => Promise<void> | void;
8
+ /** Fired when the user picks "Sign out". */
9
+ onSignOut: () => void;
10
+ /** Optional success-toast message. Defaults to `${appName} unlocked`. */
11
+ successMessage?: string;
12
+ }
13
+ /**
14
+ * Unlock form for session-locked flows (e.g. vault re-lock after idle).
15
+ * The typed password never leaves this component — it is captured into a
16
+ * local closure variable and wiped from React state before the async
17
+ * unlock work begins so the fiber tree no longer references the
18
+ * plaintext during PBKDF2 / WebCrypto derivation.
19
+ */
20
+ export declare function LockOverlay({ onUnlock, onSignOut, successMessage }: LockOverlayProps): React.JSX.Element;
21
+ export {};
22
+ //# sourceMappingURL=LockOverlay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LockOverlay.d.ts","sourceRoot":"","sources":["../../../src/components/auth/LockOverlay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAQxC,UAAU,gBAAgB;IACxB;;;OAGG;IACH,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACrD,4CAA4C;IAC5C,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,yEAAyE;IACzE,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,cAAc,EAAE,EAAE,gBAAgB,qBA8FpF"}
@@ -0,0 +1,82 @@
1
+ import React, { useState } from "react";
2
+ import { View } from "react-native";
3
+ import Toast from "react-native-toast-message";
4
+ import { Button } from "../../components/button";
5
+ import { PasswordInput } from "../../components/input";
6
+ import { MutedText, Text } from "../../components/text";
7
+ import { useAppConfig } from "../../context/AppConfigContext";
8
+ /**
9
+ * Unlock form for session-locked flows (e.g. vault re-lock after idle).
10
+ * The typed password never leaves this component — it is captured into a
11
+ * local closure variable and wiped from React state before the async
12
+ * unlock work begins so the fiber tree no longer references the
13
+ * plaintext during PBKDF2 / WebCrypto derivation.
14
+ */
15
+ export function LockOverlay({ onUnlock, onSignOut, successMessage }) {
16
+ const { appName, Logo } = useAppConfig();
17
+ const [password, setPassword] = useState("");
18
+ const [loading, setLoading] = useState(false);
19
+ const [error, setError] = useState("");
20
+ const handleUnlock = async () => {
21
+ const captured = password;
22
+ if (!captured.trim()) {
23
+ setError("Password is required");
24
+ return;
25
+ }
26
+ setPassword("");
27
+ setLoading(true);
28
+ setError("");
29
+ try {
30
+ await onUnlock(captured);
31
+ Toast.show({
32
+ type: "success",
33
+ text1: successMessage ?? `${appName} unlocked`,
34
+ visibilityTime: 1500,
35
+ });
36
+ }
37
+ catch (e) {
38
+ const msg = e instanceof Error ? e.message : String(e);
39
+ if (__DEV__) {
40
+ console.error("Unlock failed:", msg);
41
+ }
42
+ // Distinguish "wrong password" (the common case) from a real
43
+ // crypto/transport failure. The vault key-derivation pipeline
44
+ // surfaces wrong-password as a decrypt / authentication-tag
45
+ // mismatch from AES-GCM; anything else means the unlock path
46
+ // itself broke and the user can't recover by retyping.
47
+ const looksLikeWrongPassword = /decrypt|auth(entication)? tag|bad ?decrypt|invalid|unwrap/i.test(msg);
48
+ setError(looksLikeWrongPassword ? "Incorrect password. Please try again." : `Unlock failed: ${msg}`);
49
+ }
50
+ finally {
51
+ setLoading(false);
52
+ }
53
+ };
54
+ return (<View className="flex-1 items-center justify-center bg-background">
55
+ <View className="w-full max-w-[340px] items-center px-6">
56
+ <View className="mb-2 flex-row items-center justify-center">
57
+ <Logo width={56} height={56}/>
58
+ <Text className="font-sans-bold text-[28px] text-foreground dark:text-white">
59
+ {appName}
60
+ </Text>
61
+ </View>
62
+ <MutedText className="mb-8 text-center text-sm">
63
+ Enter your master password to unlock
64
+ </MutedText>
65
+ <View className="w-full gap-3">
66
+ <PasswordInput value={password} onChangeText={(text) => {
67
+ setPassword(text);
68
+ if (error) {
69
+ setError("");
70
+ }
71
+ }} placeholder="Master password" error={error} autoFocus returnKeyType="done" onSubmitEditing={handleUnlock} accessibilityLabel="Master password" testID="lock-password-input"/>
72
+ <Button className="w-full" onPress={handleUnlock} isLoading={loading} accessibilityLabel="Unlock" accessibilityRole="button" testID="lock-unlock-button">
73
+ Unlock
74
+ </Button>
75
+ <Button variant="ghost" className="w-full" onPress={onSignOut} accessibilityLabel="Sign out" accessibilityRole="button">
76
+ Sign out
77
+ </Button>
78
+ </View>
79
+ </View>
80
+ </View>);
81
+ }
82
+ //# sourceMappingURL=LockOverlay.jsx.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LockOverlay.jsx","sourceRoot":"","sources":["../../../src/components/auth/LockOverlay.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import React from "react";
2
+ interface PasswordStrengthMeterProps {
3
+ password: string;
4
+ }
5
+ export declare function calculatePasswordStrength(pass: string): {
6
+ strength: number;
7
+ color: string;
8
+ label: string;
9
+ };
10
+ declare const PasswordStrengthMeter: React.NamedExoticComponent<PasswordStrengthMeterProps>;
11
+ export default PasswordStrengthMeter;
12
+ //# sourceMappingURL=PasswordStrengthMeter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PasswordStrengthMeter.d.ts","sourceRoot":"","sources":["../../../src/components/auth/PasswordStrengthMeter.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,UAAU,0BAA0B;IAClC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM;;;;EAqDrD;AAED,QAAA,MAAM,qBAAqB,wDA8BzB,CAAC;AAEH,eAAe,qBAAqB,CAAC"}
@@ -0,0 +1,81 @@
1
+ import React from "react";
2
+ import { View } from "react-native";
3
+ import { MutedText } from "../../components/text";
4
+ export function calculatePasswordStrength(pass) {
5
+ let strength;
6
+ const hasLower = /[a-z]/.test(pass);
7
+ const hasUpper = /[A-Z]/.test(pass);
8
+ const hasNumber = /[0-9]/.test(pass);
9
+ const hasSpecial = /[^A-Za-z0-9]/.test(pass);
10
+ const complexityCount = [hasLower, hasUpper, hasNumber, hasSpecial].filter(Boolean).length;
11
+ if (complexityCount >= 4) {
12
+ strength = 60;
13
+ }
14
+ else if (complexityCount === 3) {
15
+ strength = 40;
16
+ }
17
+ else if (complexityCount === 2) {
18
+ strength = 20;
19
+ }
20
+ else {
21
+ strength = 10;
22
+ }
23
+ if (pass.length >= 16) {
24
+ strength += 40;
25
+ }
26
+ else if (pass.length >= 12) {
27
+ strength += 20;
28
+ }
29
+ else if (pass.length >= 8) {
30
+ strength += 10;
31
+ }
32
+ if (pass.length < 8) {
33
+ strength = Math.min(strength, 25);
34
+ }
35
+ else if (pass.length < 12) {
36
+ strength = Math.min(strength, 50);
37
+ }
38
+ else if (pass.length < 16) {
39
+ strength = Math.min(strength, 75);
40
+ }
41
+ let color;
42
+ let label;
43
+ if (strength <= 25) {
44
+ color = "#EF4444";
45
+ label = "Weak";
46
+ }
47
+ else if (strength <= 50) {
48
+ color = "#F59E0B";
49
+ label = "Moderate";
50
+ }
51
+ else if (strength <= 75) {
52
+ color = "#22C55E";
53
+ label = "Strong";
54
+ }
55
+ else {
56
+ color = "#10B981";
57
+ label = "Very Strong";
58
+ }
59
+ return { strength: Math.min(strength, 100), color, label };
60
+ }
61
+ const PasswordStrengthMeter = React.memo(function PasswordStrengthMeter({ password, }) {
62
+ if (!password) {
63
+ return null;
64
+ }
65
+ const { strength, color, label } = calculatePasswordStrength(password);
66
+ return (<View className="gap-2">
67
+ <View className="flex-row gap-1">
68
+ {[0, 1, 2, 3, 4].map((i) => {
69
+ const threshold = (i + 1) * 20;
70
+ const filled = strength >= threshold;
71
+ return (<View key={i} className="h-1 flex-1 rounded-full" style={{ backgroundColor: filled ? color : "#333333" }}/>);
72
+ })}
73
+ </View>
74
+ <View className="flex-row items-center justify-between">
75
+ <MutedText className="text-xs">{label}</MutedText>
76
+ <MutedText className="text-xs">{strength}%</MutedText>
77
+ </View>
78
+ </View>);
79
+ });
80
+ export default PasswordStrengthMeter;
81
+ //# sourceMappingURL=PasswordStrengthMeter.jsx.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PasswordStrengthMeter.jsx","sourceRoot":"","sources":["../../../src/components/auth/PasswordStrengthMeter.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import React from "react";
2
+ import { type Href } from "expo-router";
3
+ interface ProtectedRouteProps {
4
+ children: React.ReactNode;
5
+ requiredRole?: "Admin" | "User";
6
+ redirectTo?: Href;
7
+ fallback?: React.ReactNode;
8
+ }
9
+ export declare function ProtectedRoute({ children, requiredRole, redirectTo, fallback, }: ProtectedRouteProps): React.JSX.Element | null;
10
+ export declare function withAuth<P extends object>(Component: React.ComponentType<P>, options?: {
11
+ requiredRole?: "Admin" | "User";
12
+ redirectTo?: Href;
13
+ fallback?: React.ReactNode;
14
+ }): {
15
+ (props: P): React.JSX.Element;
16
+ displayName: string;
17
+ };
18
+ export declare function useProtectedContent(requiredRole?: "Admin" | "User"): {
19
+ canAccess: boolean;
20
+ isLoading: boolean;
21
+ user: import("../..").User | null;
22
+ };
23
+ export default ProtectedRoute;
24
+ //# sourceMappingURL=ProtectedRoute.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProtectedRoute.d.ts","sourceRoot":"","sources":["../../../src/components/auth/ProtectedRoute.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;AAEzC,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,aAAa,CAAC;AAMxC,UAAU,mBAAmB;IAC3B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,YAAY,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAChC,UAAU,CAAC,EAAE,IAAI,CAAC;IAClB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAED,wBAAgB,cAAc,CAAC,EAC7B,QAAQ,EACR,YAAY,EACZ,UAAU,EACV,QAAQ,GACT,EAAE,mBAAmB,4BAkCrB;AAED,wBAAgB,QAAQ,CAAC,CAAC,SAAS,MAAM,EACvC,SAAS,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,EACjC,OAAO,CAAC,EAAE;IACR,YAAY,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAChC,UAAU,CAAC,EAAE,IAAI,CAAC;IAClB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;YAE6D,CAAC;;EAahE;AAED,wBAAgB,mBAAmB,CAAC,YAAY,CAAC,EAAE,OAAO,GAAG,MAAM;;;;EASlE;AAED,eAAe,cAAc,CAAC"}
@@ -0,0 +1,56 @@
1
+ import React, { useEffect } from "react";
2
+ import { ActivityIndicator, View } from "react-native";
3
+ import { useNavigation } from "../../context/NavigationContext";
4
+ import { useColorScheme } from "nativewind";
5
+ import { useAuth, useRole } from "../../hooks/useAuth";
6
+ import { useAppConfig } from "../../context/AppConfigContext";
7
+ export function ProtectedRoute({ children, requiredRole, redirectTo, fallback, }) {
8
+ const { isAuthenticated, isLoading, user } = useAuth();
9
+ const router = useNavigation();
10
+ const { routes } = useAppConfig();
11
+ const hasRequiredRole = useRole(requiredRole || "User");
12
+ const { colorScheme } = useColorScheme();
13
+ const isDark = colorScheme === "dark";
14
+ useEffect(() => {
15
+ if (!isLoading) {
16
+ if (!isAuthenticated) {
17
+ router.replace((redirectTo ?? routes.login));
18
+ }
19
+ else if (requiredRole && !hasRequiredRole) {
20
+ router.replace(routes.home);
21
+ }
22
+ }
23
+ }, [isAuthenticated, isLoading, hasRequiredRole, requiredRole, user, router, redirectTo, routes]);
24
+ if (isLoading) {
25
+ if (fallback) {
26
+ return <>{fallback}</>;
27
+ }
28
+ return (<View className="flex-1 items-center justify-center bg-background">
29
+ <ActivityIndicator size="large" color={isDark ? "#FFFFFF" : "#000000"}/>
30
+ </View>);
31
+ }
32
+ if (!isAuthenticated || (requiredRole && !hasRequiredRole)) {
33
+ return null;
34
+ }
35
+ return <>{children}</>;
36
+ }
37
+ export function withAuth(Component, options) {
38
+ const ProtectedComponent = function ProtectedComponent(props) {
39
+ return (<ProtectedRoute requiredRole={options?.requiredRole} redirectTo={options?.redirectTo} fallback={options?.fallback}>
40
+ <Component {...props}/>
41
+ </ProtectedRoute>);
42
+ };
43
+ ProtectedComponent.displayName = `withAuth(${Component.displayName || Component.name || "Component"})`;
44
+ return ProtectedComponent;
45
+ }
46
+ export function useProtectedContent(requiredRole) {
47
+ const { isAuthenticated, isLoading, user } = useAuth();
48
+ const hasRole = useRole(requiredRole || "User");
49
+ return {
50
+ canAccess: isAuthenticated && (!requiredRole || hasRole),
51
+ isLoading,
52
+ user,
53
+ };
54
+ }
55
+ export default ProtectedRoute;
56
+ //# sourceMappingURL=ProtectedRoute.jsx.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProtectedRoute.jsx","sourceRoot":"","sources":["../../../src/components/auth/ProtectedRoute.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACzC,OAAO,EAAE,iBAAiB,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEvD,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAS9D,MAAM,UAAU,cAAc,CAAC,EAC7B,QAAQ,EACR,YAAY,EACZ,UAAU,EACV,QAAQ,GACY;IACpB,MAAM,EAAE,eAAe,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,OAAO,EAAE,CAAC;IACvD,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;IAC/B,MAAM,EAAE,MAAM,EAAE,GAAG,YAAY,EAAE,CAAC;IAClC,MAAM,eAAe,GAAG,OAAO,CAAC,YAAY,IAAI,MAAM,CAAC,CAAC;IACxD,MAAM,EAAE,WAAW,EAAE,GAAG,cAAc,EAAE,CAAC;IACzC,MAAM,MAAM,GAAG,WAAW,KAAK,MAAM,CAAC;IAEtC,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,IAAI,CAAC,eAAe,EAAE,CAAC;gBACrB,MAAM,CAAC,OAAO,CAAC,CAAC,UAAU,IAAI,MAAM,CAAC,KAAK,CAAS,CAAC,CAAC;YACvD,CAAC;iBAAM,IAAI,YAAY,IAAI,CAAC,eAAe,EAAE,CAAC;gBAC5C,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAC9B,CAAC;QACH,CAAC;IACH,CAAC,EAAE,CAAC,eAAe,EAAE,SAAS,EAAE,eAAe,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;IAElG,IAAI,SAAS,EAAE,CAAC;QACd,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC;QACzB,CAAC;QACD,OAAO,CACL,CAAC,IAAI,CAAC,SAAS,CAAC,kDAAkD,CAChE;QAAA,CAAC,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,EACxE;MAAA,EAAE,IAAI,CAAC,CACR,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,eAAe,IAAI,CAAC,YAAY,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC;QAC3D,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,QAAQ,CACtB,SAAiC,EACjC,OAIC;IAED,MAAM,kBAAkB,GAAG,SAAS,kBAAkB,CAAC,KAAQ;QAC7D,OAAO,CACL,CAAC,cAAc,CACb,YAAY,CAAC,CAAC,OAAO,EAAE,YAAY,CAAC,CACpC,UAAU,CAAC,CAAC,OAAO,EAAE,UAAU,CAAC,CAChC,QAAQ,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,CAE5B;QAAA,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC,EACvB;MAAA,EAAE,cAAc,CAAC,CAClB,CAAC;IACJ,CAAC,CAAC;IACF,kBAAkB,CAAC,WAAW,GAAG,YAAY,SAAS,CAAC,WAAW,IAAI,SAAS,CAAC,IAAI,IAAI,WAAW,GAAG,CAAC;IACvG,OAAO,kBAAkB,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,YAA+B;IACjE,MAAM,EAAE,eAAe,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,OAAO,EAAE,CAAC;IACvD,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,IAAI,MAAM,CAAC,CAAC;IAEhD,OAAO;QACL,SAAS,EAAE,eAAe,IAAI,CAAC,CAAC,YAAY,IAAI,OAAO,CAAC;QACxD,SAAS;QACT,IAAI;KACL,CAAC;AACJ,CAAC;AAED,eAAe,cAAc,CAAC"}
@@ -0,0 +1,13 @@
1
+ import React from "react";
2
+ interface PwnedPasswordInfo {
3
+ title: string;
4
+ message: string;
5
+ severity: "error" | "warning" | "info";
6
+ count: number;
7
+ }
8
+ interface PwnedPasswordWarningProps {
9
+ pwnedInfo: PwnedPasswordInfo | null;
10
+ }
11
+ export default function PwnedPasswordWarning({ pwnedInfo }: PwnedPasswordWarningProps): React.JSX.Element | null;
12
+ export {};
13
+ //# sourceMappingURL=PwnedPasswordWarning.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PwnedPasswordWarning.d.ts","sourceRoot":"","sources":["../../../src/components/auth/PwnedPasswordWarning.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAK1B,UAAU,iBAAiB;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IACvC,KAAK,EAAE,MAAM,CAAC;CACf;AAED,UAAU,yBAAyB;IACjC,SAAS,EAAE,iBAAiB,GAAG,IAAI,CAAC;CACrC;AAED,MAAM,CAAC,OAAO,UAAU,oBAAoB,CAAC,EAAE,SAAS,EAAE,EAAE,yBAAyB,4BAqCpF"}
@@ -0,0 +1,29 @@
1
+ import React from "react";
2
+ import { View } from "react-native";
3
+ import { Ionicons } from "@expo/vector-icons";
4
+ import { Text } from "../../components/text";
5
+ export default function PwnedPasswordWarning({ pwnedInfo }) {
6
+ if (!pwnedInfo) {
7
+ return null;
8
+ }
9
+ const iconName = pwnedInfo.severity === "error"
10
+ ? "warning"
11
+ : pwnedInfo.severity === "warning"
12
+ ? "alert-circle"
13
+ : "information-circle";
14
+ const iconColor = pwnedInfo.severity === "error"
15
+ ? "#EF4444"
16
+ : pwnedInfo.severity === "warning"
17
+ ? "#F59E0B"
18
+ : "#3B82F6";
19
+ const textClass = pwnedInfo.severity === "error"
20
+ ? "text-red-500 dark:text-red-400"
21
+ : pwnedInfo.severity === "warning"
22
+ ? "text-amber-500 dark:text-amber-400"
23
+ : "text-blue-500 dark:text-blue-400";
24
+ return (<View className="mt-1 flex-row items-start gap-1.5">
25
+ <Ionicons name={iconName} size={14} color={iconColor} style={{ marginTop: 2 }}/>
26
+ <Text className={`flex-1 text-xs ${textClass}`}>{pwnedInfo.message}</Text>
27
+ </View>);
28
+ }
29
+ //# sourceMappingURL=PwnedPasswordWarning.jsx.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PwnedPasswordWarning.jsx","sourceRoot":"","sources":["../../../src/components/auth/PwnedPasswordWarning.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAa7C,MAAM,CAAC,OAAO,UAAU,oBAAoB,CAAC,EAAE,SAAS,EAA6B;IACnF,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,QAAQ,GACZ,SAAS,CAAC,QAAQ,KAAK,OAAO;QAC5B,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,SAAS,CAAC,QAAQ,KAAK,SAAS;YAChC,CAAC,CAAC,cAAc;YAChB,CAAC,CAAC,oBAAoB,CAAC;IAE7B,MAAM,SAAS,GACb,SAAS,CAAC,QAAQ,KAAK,OAAO;QAC5B,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,SAAS,CAAC,QAAQ,KAAK,SAAS;YAChC,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,SAAS,CAAC;IAElB,MAAM,SAAS,GACb,SAAS,CAAC,QAAQ,KAAK,OAAO;QAC5B,CAAC,CAAC,gCAAgC;QAClC,CAAC,CAAC,SAAS,CAAC,QAAQ,KAAK,SAAS;YAChC,CAAC,CAAC,oCAAoC;YACtC,CAAC,CAAC,kCAAkC,CAAC;IAE3C,OAAO,CACL,CAAC,IAAI,CAAC,SAAS,CAAC,mCAAmC,CACjD;MAAA,CAAC,QAAQ,CACP,IAAI,CAAC,CAAC,QAA0C,CAAC,CACjD,IAAI,CAAC,CAAC,EAAE,CAAC,CACT,KAAK,CAAC,CAAC,SAAS,CAAC,CACjB,KAAK,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,EAE1B;MAAA,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,kBAAkB,SAAS,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,IAAI,CAC3E;IAAA,EAAE,IAAI,CAAC,CACR,CAAC;AACJ,CAAC"}
@@ -0,0 +1,5 @@
1
+ export { LockOverlay } from "./LockOverlay";
2
+ export { default as PasswordStrengthMeter, calculatePasswordStrength, } from "./PasswordStrengthMeter";
3
+ export { default as PwnedPasswordWarning } from "./PwnedPasswordWarning";
4
+ export { default as ProtectedRoute, withAuth, useProtectedContent } from "./ProtectedRoute";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/auth/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,EACL,OAAO,IAAI,qBAAqB,EAChC,yBAAyB,GAC1B,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAEzE,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,QAAQ,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,5 @@
1
+ export { LockOverlay } from "./LockOverlay";
2
+ export { default as PasswordStrengthMeter, calculatePasswordStrength, } from "./PasswordStrengthMeter";
3
+ export { default as PwnedPasswordWarning } from "./PwnedPasswordWarning";
4
+ export { default as ProtectedRoute, withAuth, useProtectedContent } from "./ProtectedRoute";
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/auth/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,EACL,OAAO,IAAI,qBAAqB,EAChC,yBAAyB,GAC1B,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAEzE,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,QAAQ,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC"}