@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
@@ -0,0 +1,118 @@
1
+ import React from "react";
2
+ import { ScrollView, View } from "react-native";
3
+ import { SafeAreaView } from "react-native-safe-area-context";
4
+ import { StatusBar } from "expo-status-bar";
5
+ import { useColorScheme } from "nativewind";
6
+ import { MutedText, Text } from "../../components/text";
7
+ import { Button } from "../../components/button";
8
+ import {
9
+ Card,
10
+ CardContent,
11
+ CardDescription,
12
+ CardFooter,
13
+ CardHeader,
14
+ CardTitle,
15
+ } from "../../components/card";
16
+
17
+ /** One requested scope, with an optional human-readable description. */
18
+ export interface ConsentScope {
19
+ scope: string;
20
+ description?: string;
21
+ }
22
+
23
+ export interface ConsentScreenProps {
24
+ /** The relying party's display name (heading). */
25
+ clientName: string;
26
+ /** The scopes the client is requesting. */
27
+ scopes: ConsentScope[];
28
+ /** Approve — the app records the grant and resumes the authorize request. */
29
+ onAllow: () => void;
30
+ /** Decline — the app bounces the client with `access_denied`. */
31
+ onDeny: () => void;
32
+ isLoading?: boolean;
33
+ error?: string;
34
+ }
35
+
36
+ /**
37
+ * OIDC consent prompt (OIDC Core §3.1.2.4). Presentational + prop-driven: the
38
+ * host app fetches the request detail, records the decision, and navigates —
39
+ * this screen only renders the scopes and the allow/deny choice, so it stays
40
+ * transport-agnostic and reusable across apps.
41
+ */
42
+ export function ConsentScreen({
43
+ clientName,
44
+ scopes,
45
+ onAllow,
46
+ onDeny,
47
+ isLoading,
48
+ error,
49
+ }: ConsentScreenProps) {
50
+ const { colorScheme } = useColorScheme();
51
+ const isDark = colorScheme === "dark";
52
+
53
+ return (
54
+ <SafeAreaView className="flex-1 bg-background">
55
+ <StatusBar style={isDark ? "light" : "dark"} />
56
+ <ScrollView
57
+ className="flex-1"
58
+ contentContainerClassName="flex-1 items-center justify-center p-6"
59
+ keyboardShouldPersistTaps="handled"
60
+ >
61
+ <Card className="w-full max-w-[400px]">
62
+ <CardHeader>
63
+ <CardTitle>Authorize {clientName}</CardTitle>
64
+ <CardDescription>
65
+ {clientName} wants access to your account. Review what it can do.
66
+ </CardDescription>
67
+ </CardHeader>
68
+
69
+ <CardContent className="gap-3">
70
+ {scopes.length === 0 ? (
71
+ <MutedText className="text-sm">
72
+ Basic sign-in (no additional access requested).
73
+ </MutedText>
74
+ ) : (
75
+ scopes.map((s) => (
76
+ <View key={s.scope} className="flex-row gap-2">
77
+ <Text className="text-sm text-foreground">•</Text>
78
+ <View className="flex-1">
79
+ <Text className="text-sm text-foreground">{s.scope}</Text>
80
+ {s.description ? (
81
+ <MutedText className="text-xs">{s.description}</MutedText>
82
+ ) : null}
83
+ </View>
84
+ </View>
85
+ ))
86
+ )}
87
+ {error ? (
88
+ <Text className="text-sm text-destructive">{error}</Text>
89
+ ) : null}
90
+ </CardContent>
91
+
92
+ <CardFooter className="flex-col gap-3 border-t-0">
93
+ <Button
94
+ className="w-full"
95
+ onPress={onAllow}
96
+ isLoading={isLoading}
97
+ accessibilityLabel={`Allow ${clientName}`}
98
+ accessibilityRole="button"
99
+ >
100
+ Allow
101
+ </Button>
102
+ <Button
103
+ className="w-full"
104
+ variant="outline"
105
+ onPress={onDeny}
106
+ accessibilityLabel="Deny access"
107
+ accessibilityRole="button"
108
+ >
109
+ Deny
110
+ </Button>
111
+ </CardFooter>
112
+ </Card>
113
+ </ScrollView>
114
+ </SafeAreaView>
115
+ );
116
+ }
117
+
118
+ export default ConsentScreen;
@@ -0,0 +1,96 @@
1
+ import React from "react";
2
+ import { ScrollView } from "react-native";
3
+ import { SafeAreaView } from "react-native-safe-area-context";
4
+ import { StatusBar } from "expo-status-bar";
5
+ import { useColorScheme } from "nativewind";
6
+ import { MutedText } from "../../components/text";
7
+ import { Button } from "../../components/button";
8
+ import {
9
+ Card,
10
+ CardContent,
11
+ CardDescription,
12
+ CardFooter,
13
+ CardHeader,
14
+ CardTitle,
15
+ } from "../../components/card";
16
+
17
+ export interface ErrorScreenProps {
18
+ /** Machine error code (e.g. `unknown_client`), shown for support/debugging. */
19
+ code?: string;
20
+ title?: string;
21
+ message?: string;
22
+ /** Optional retry action. */
23
+ onRetry?: () => void;
24
+ /** Optional "back to safety" action (e.g. home / sign-in). */
25
+ onHome?: () => void;
26
+ homeLabel?: string;
27
+ }
28
+
29
+ /**
30
+ * Polished terminal error screen for the auth surfaces (a failed authorize, an
31
+ * unexpected server error, …). Presentational; the host app maps codes to
32
+ * copy and wires the actions.
33
+ */
34
+ export function ErrorScreen({
35
+ code,
36
+ title = "Something went wrong",
37
+ message = "We couldn't complete that request. Please try again.",
38
+ onRetry,
39
+ onHome,
40
+ homeLabel = "Back to sign in",
41
+ }: ErrorScreenProps) {
42
+ const { colorScheme } = useColorScheme();
43
+ const isDark = colorScheme === "dark";
44
+
45
+ return (
46
+ <SafeAreaView className="flex-1 bg-background">
47
+ <StatusBar style={isDark ? "light" : "dark"} />
48
+ <ScrollView
49
+ className="flex-1"
50
+ contentContainerClassName="flex-1 items-center justify-center p-6"
51
+ keyboardShouldPersistTaps="handled"
52
+ >
53
+ <Card className="w-full max-w-[380px]">
54
+ <CardHeader>
55
+ <CardTitle>{title}</CardTitle>
56
+ <CardDescription>{message}</CardDescription>
57
+ </CardHeader>
58
+
59
+ {code ? (
60
+ <CardContent>
61
+ <MutedText className="font-mono text-xs">code: {code}</MutedText>
62
+ </CardContent>
63
+ ) : null}
64
+
65
+ {onRetry || onHome ? (
66
+ <CardFooter className="flex-col gap-3 border-t-0">
67
+ {onRetry ? (
68
+ <Button
69
+ className="w-full"
70
+ onPress={onRetry}
71
+ accessibilityLabel="Try again"
72
+ accessibilityRole="button"
73
+ >
74
+ Try again
75
+ </Button>
76
+ ) : null}
77
+ {onHome ? (
78
+ <Button
79
+ className="w-full"
80
+ variant="outline"
81
+ onPress={onHome}
82
+ accessibilityLabel={homeLabel}
83
+ accessibilityRole="button"
84
+ >
85
+ {homeLabel}
86
+ </Button>
87
+ ) : null}
88
+ </CardFooter>
89
+ ) : null}
90
+ </Card>
91
+ </ScrollView>
92
+ </SafeAreaView>
93
+ );
94
+ }
95
+
96
+ export default ErrorScreen;
@@ -0,0 +1,87 @@
1
+ import React from "react";
2
+ import { ScrollView } from "react-native";
3
+ import { SafeAreaView } from "react-native-safe-area-context";
4
+ import { StatusBar } from "expo-status-bar";
5
+ import { useColorScheme } from "nativewind";
6
+ import { Button } from "../../components/button";
7
+ import {
8
+ Card,
9
+ CardDescription,
10
+ CardFooter,
11
+ CardHeader,
12
+ CardTitle,
13
+ } from "../../components/card";
14
+
15
+ export interface ExpiredLinkScreenProps {
16
+ title?: string;
17
+ message?: string;
18
+ /** Request a fresh link (e.g. resend verification / reset). */
19
+ onRequestNew?: () => void;
20
+ requestLabel?: string;
21
+ /** Return to sign in. */
22
+ onHome?: () => void;
23
+ homeLabel?: string;
24
+ }
25
+
26
+ /**
27
+ * Shown when a one-time link (email verification, password reset, magic link)
28
+ * has expired or was already used. Presentational; the host app wires the
29
+ * "request a new link" + "back to sign in" actions.
30
+ */
31
+ export function ExpiredLinkScreen({
32
+ title = "This link has expired",
33
+ message = "For your security, this link is no longer valid. Request a new one to continue.",
34
+ onRequestNew,
35
+ requestLabel = "Send a new link",
36
+ onHome,
37
+ homeLabel = "Back to sign in",
38
+ }: ExpiredLinkScreenProps) {
39
+ const { colorScheme } = useColorScheme();
40
+ const isDark = colorScheme === "dark";
41
+
42
+ return (
43
+ <SafeAreaView className="flex-1 bg-background">
44
+ <StatusBar style={isDark ? "light" : "dark"} />
45
+ <ScrollView
46
+ className="flex-1"
47
+ contentContainerClassName="flex-1 items-center justify-center p-6"
48
+ keyboardShouldPersistTaps="handled"
49
+ >
50
+ <Card className="w-full max-w-[380px]">
51
+ <CardHeader>
52
+ <CardTitle>{title}</CardTitle>
53
+ <CardDescription>{message}</CardDescription>
54
+ </CardHeader>
55
+
56
+ {onRequestNew || onHome ? (
57
+ <CardFooter className="flex-col gap-3 border-t-0">
58
+ {onRequestNew ? (
59
+ <Button
60
+ className="w-full"
61
+ onPress={onRequestNew}
62
+ accessibilityLabel={requestLabel}
63
+ accessibilityRole="button"
64
+ >
65
+ {requestLabel}
66
+ </Button>
67
+ ) : null}
68
+ {onHome ? (
69
+ <Button
70
+ className="w-full"
71
+ variant="outline"
72
+ onPress={onHome}
73
+ accessibilityLabel={homeLabel}
74
+ accessibilityRole="button"
75
+ >
76
+ {homeLabel}
77
+ </Button>
78
+ ) : null}
79
+ </CardFooter>
80
+ ) : null}
81
+ </Card>
82
+ </ScrollView>
83
+ </SafeAreaView>
84
+ );
85
+ }
86
+
87
+ export default ExpiredLinkScreen;
@@ -0,0 +1,182 @@
1
+ import React, { useState } from "react";
2
+ import { ScrollView, View } from "react-native";
3
+ import { SafeAreaView } from "react-native-safe-area-context";
4
+ import { type Href } from "expo-router";
5
+ import { useNavigation } from "../../context/NavigationContext";
6
+ import { StatusBar } from "expo-status-bar";
7
+ import { Ionicons } from "@expo/vector-icons";
8
+ import { useColorScheme } from "nativewind";
9
+ import * as Haptics from "expo-haptics";
10
+ import { MutedText, Text } from "../../components/text";
11
+ import { Button, IconButton } from "../../components/button";
12
+ import {
13
+ Card,
14
+ CardContent,
15
+ CardDescription,
16
+ CardFooter,
17
+ CardHeader,
18
+ CardTitle,
19
+ } from "../../components/card";
20
+ import { EmailInput } from "../../components/input";
21
+ import AuthService from "../../services/auth.service";
22
+ import { validateEmail } from "../../utils/validation";
23
+ import { useAppConfig } from "../../context/AppConfigContext";
24
+
25
+ export function ForgotPasswordScreen() {
26
+ const [email, setEmail] = useState("");
27
+ const [error, setError] = useState("");
28
+ const [isLoading, setIsLoading] = useState(false);
29
+ const [sent, setSent] = useState(false);
30
+
31
+ const { colorScheme } = useColorScheme();
32
+ const isDark = colorScheme === "dark";
33
+ const router = useNavigation();
34
+ const { routes } = useAppConfig();
35
+
36
+ const handleSubmit = async () => {
37
+ // Re-entry guard against double-submit (button + form-submit
38
+ // keypress) firing before React flushes `setIsLoading(true)`
39
+ // and disables the button.
40
+ if (isLoading) {
41
+ return;
42
+ }
43
+ if (!email) {
44
+ setError("Email is required");
45
+ return;
46
+ }
47
+ if (!validateEmail(email)) {
48
+ setError("Please enter a valid email address");
49
+ return;
50
+ }
51
+
52
+ setIsLoading(true);
53
+ try {
54
+ await AuthService.forgotPassword(email);
55
+ } catch (e: unknown) {
56
+ // Deliberately swallow — the server is supposed to respond
57
+ // identically for known and unknown emails, but a 5xx (or a
58
+ // rate-limit, network blip, etc.) would otherwise let the UI
59
+ // branch on "did this email exist or not?". Surface the same
60
+ // confirmation regardless; the server retries on its own
61
+ // schedule and ops can read the failure from the server logs.
62
+ if (__DEV__) {
63
+ console.warn("[forgot-password] request failed; showing generic confirmation:", e);
64
+ }
65
+ }
66
+ await Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success);
67
+ setSent(true);
68
+ setIsLoading(false);
69
+ };
70
+
71
+ return (
72
+ <SafeAreaView className="flex-1 bg-background">
73
+ <StatusBar style={isDark ? "light" : "dark"} />
74
+ <ScrollView
75
+ className="flex-1"
76
+ contentContainerClassName="flex-1 items-center justify-center p-6"
77
+ keyboardShouldPersistTaps="handled"
78
+ >
79
+ <View className="mt-4 self-start absolute top-4 left-6">
80
+ <IconButton
81
+ variant="ghost"
82
+ onPress={() => router.back()}
83
+ accessibilityLabel="Go back"
84
+ accessibilityRole="button"
85
+ >
86
+ <Ionicons name="arrow-back" size={24} color={isDark ? "#FFFFFF" : "#000000"} />
87
+ </IconButton>
88
+ </View>
89
+
90
+ <Card className="w-full max-w-[360px]">
91
+ <CardHeader>
92
+ <CardTitle>{sent ? "Check your email" : "Forgot password?"}</CardTitle>
93
+ <CardDescription>
94
+ {sent
95
+ ? `If an account exists for ${email}, you will receive a password reset code.`
96
+ : "Enter your email to reset your password"}
97
+ </CardDescription>
98
+ </CardHeader>
99
+
100
+ {!sent ? (
101
+ <>
102
+ <CardContent className="gap-4">
103
+ <EmailInput
104
+ label="Email"
105
+ value={email}
106
+ onChangeText={(text) => {
107
+ setEmail(text);
108
+ if (error) {
109
+ setError("");
110
+ }
111
+ }}
112
+ error={error}
113
+ autoFocus
114
+ returnKeyType="done"
115
+ onSubmitEditing={handleSubmit}
116
+ accessibilityLabel="Email address"
117
+ />
118
+ </CardContent>
119
+
120
+ <CardFooter className="flex-col gap-3 border-t-0">
121
+ <Button
122
+ className="w-full"
123
+ onPress={handleSubmit}
124
+ isLoading={isLoading}
125
+ accessibilityLabel="Reset your password"
126
+ accessibilityRole="button"
127
+ >
128
+ Reset your password
129
+ </Button>
130
+
131
+ <MutedText className="text-center text-sm">
132
+ Remember your password?{" "}
133
+ <Text
134
+ className="text-sm text-foreground underline"
135
+ onPress={() => router.push(routes.login)}
136
+ accessibilityRole="link"
137
+ accessibilityLabel="Sign in"
138
+ >
139
+ Sign In
140
+ </Text>
141
+ </MutedText>
142
+ </CardFooter>
143
+ </>
144
+ ) : (
145
+ <CardFooter className="flex-col gap-3 border-t-0">
146
+ <Button
147
+ className="w-full"
148
+ onPress={() =>
149
+ router.push({
150
+ pathname: routes.resetPassword,
151
+ params: { email },
152
+ } as Href)
153
+ }
154
+ accessibilityLabel="Enter reset code"
155
+ accessibilityRole="button"
156
+ >
157
+ Enter reset code
158
+ </Button>
159
+
160
+ <MutedText className="text-center text-sm">
161
+ Didn't receive the code?{" "}
162
+ <Text
163
+ className="text-sm text-foreground underline"
164
+ onPress={() => {
165
+ setSent(false);
166
+ setError("");
167
+ }}
168
+ accessibilityRole="button"
169
+ accessibilityLabel="Resend reset email"
170
+ >
171
+ Resend
172
+ </Text>
173
+ </MutedText>
174
+ </CardFooter>
175
+ )}
176
+ </Card>
177
+ </ScrollView>
178
+ </SafeAreaView>
179
+ );
180
+ }
181
+
182
+ export default ForgotPasswordScreen;
@@ -0,0 +1,112 @@
1
+ import React from "react";
2
+ import { ScrollView, View } from "react-native";
3
+ import { SafeAreaView } from "react-native-safe-area-context";
4
+ import { useNavigation } from "../../context/NavigationContext";
5
+ import { StatusBar } from "expo-status-bar";
6
+ import { Ionicons } from "@expo/vector-icons";
7
+ import { useColorScheme } from "nativewind";
8
+ import Toast from "react-native-toast-message";
9
+ import { MutedText } from "../../components/text";
10
+ import { Button } from "../../components/button";
11
+ import {
12
+ Card,
13
+ CardContent,
14
+ CardDescription,
15
+ CardFooter,
16
+ CardHeader,
17
+ CardTitle,
18
+ } from "../../components/card";
19
+ import AuthService from "../../services/auth.service";
20
+ import { useAuth } from "../../hooks/useAuth";
21
+ import { useAppConfig } from "../../context/AppConfigContext";
22
+ import { getErrorMessage } from "../../utils/error";
23
+
24
+ export interface ImportDataScreenProps {
25
+ /**
26
+ * Optional custom import flow. When provided, the screen renders this
27
+ * instead of the default skip-only UI — call `onComplete` after a
28
+ * successful import and the screen advances onboarding + navigates to
29
+ * home. Vault wires its `parseBitwardenExport` + `VaultFacade` + key
30
+ * manager unlock flow through this slot.
31
+ */
32
+ renderImport?: (props: { onComplete: () => void; onSkip: () => void }) => React.ReactNode;
33
+ }
34
+
35
+ export function ImportDataScreen({ renderImport }: ImportDataScreenProps = {}) {
36
+ const router = useNavigation();
37
+ const { refreshUser } = useAuth();
38
+ const { appName, routes } = useAppConfig();
39
+ const { colorScheme } = useColorScheme();
40
+ const isDark = colorScheme === "dark";
41
+
42
+ const completeAndNavigate = async () => {
43
+ try {
44
+ await AuthService.completeOnboarding();
45
+ await refreshUser();
46
+ router.replace(routes.home);
47
+ } catch (e: unknown) {
48
+ Toast.show({
49
+ type: "error",
50
+ text1: getErrorMessage(e, "Failed to complete onboarding"),
51
+ visibilityTime: 3000,
52
+ });
53
+ }
54
+ };
55
+
56
+ if (renderImport) {
57
+ return (
58
+ <SafeAreaView className="flex-1 bg-background">
59
+ <StatusBar style={isDark ? "light" : "dark"} />
60
+ {renderImport({ onComplete: completeAndNavigate, onSkip: completeAndNavigate })}
61
+ </SafeAreaView>
62
+ );
63
+ }
64
+
65
+ return (
66
+ <SafeAreaView className="flex-1 bg-background">
67
+ <StatusBar style={isDark ? "light" : "dark"} />
68
+ <ScrollView
69
+ className="flex-1"
70
+ contentContainerClassName="flex-1 items-center justify-center p-6"
71
+ keyboardShouldPersistTaps="handled"
72
+ >
73
+ <Card className="w-full max-w-[420px]">
74
+ <CardHeader className="items-center">
75
+ <View className="mb-3 h-16 w-16 items-center justify-center rounded-full bg-secondary dark:bg-neutral-800">
76
+ <Ionicons
77
+ name="checkmark-done-outline"
78
+ size={32}
79
+ color={isDark ? "#FFFFFF" : "#000000"}
80
+ />
81
+ </View>
82
+ <CardTitle className="text-center">You&apos;re all set</CardTitle>
83
+ <CardDescription className="text-center">
84
+ Your {appName} account is ready. Continue to start using it.
85
+ </CardDescription>
86
+ </CardHeader>
87
+
88
+ <CardContent>
89
+ <MutedText className="text-center text-sm">
90
+ Nothing to migrate here — apps that need a data-import step wire a custom
91
+ `renderImport` slot.
92
+ </MutedText>
93
+ </CardContent>
94
+
95
+ <CardFooter className="border-t-0">
96
+ <Button
97
+ className="w-full"
98
+ onPress={completeAndNavigate}
99
+ accessibilityLabel={`Continue to ${appName}`}
100
+ accessibilityRole="button"
101
+ testID="import-continue"
102
+ >
103
+ Continue to {appName}
104
+ </Button>
105
+ </CardFooter>
106
+ </Card>
107
+ </ScrollView>
108
+ </SafeAreaView>
109
+ );
110
+ }
111
+
112
+ export default ImportDataScreen;