@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.
- package/CHANGELOG.md +96 -0
- package/LICENSE +21 -0
- package/README.md +115 -0
- package/lib/components/auth/LockOverlay.d.ts +22 -0
- package/lib/components/auth/LockOverlay.d.ts.map +1 -0
- package/lib/components/auth/LockOverlay.jsx +82 -0
- package/lib/components/auth/LockOverlay.jsx.map +1 -0
- package/lib/components/auth/PasswordStrengthMeter.d.ts +12 -0
- package/lib/components/auth/PasswordStrengthMeter.d.ts.map +1 -0
- package/lib/components/auth/PasswordStrengthMeter.jsx +81 -0
- package/lib/components/auth/PasswordStrengthMeter.jsx.map +1 -0
- package/lib/components/auth/ProtectedRoute.d.ts +24 -0
- package/lib/components/auth/ProtectedRoute.d.ts.map +1 -0
- package/lib/components/auth/ProtectedRoute.jsx +56 -0
- package/lib/components/auth/ProtectedRoute.jsx.map +1 -0
- package/lib/components/auth/PwnedPasswordWarning.d.ts +13 -0
- package/lib/components/auth/PwnedPasswordWarning.d.ts.map +1 -0
- package/lib/components/auth/PwnedPasswordWarning.jsx +29 -0
- package/lib/components/auth/PwnedPasswordWarning.jsx.map +1 -0
- package/lib/components/auth/index.d.ts +5 -0
- package/lib/components/auth/index.d.ts.map +1 -0
- package/lib/components/auth/index.js +5 -0
- package/lib/components/auth/index.js.map +1 -0
- package/lib/components/bottom-nav.d.ts +25 -0
- package/lib/components/bottom-nav.d.ts.map +1 -0
- package/lib/components/bottom-nav.jsx +51 -0
- package/lib/components/bottom-nav.jsx.map +1 -0
- package/lib/components/button.d.ts +16 -0
- package/lib/components/button.d.ts.map +1 -0
- package/lib/components/button.jsx +73 -0
- package/lib/components/button.jsx.map +1 -0
- package/lib/components/card.d.ts +22 -0
- package/lib/components/card.d.ts.map +1 -0
- package/lib/components/card.jsx +36 -0
- package/lib/components/card.jsx.map +1 -0
- package/lib/components/checkbox.d.ts +12 -0
- package/lib/components/checkbox.d.ts.map +1 -0
- package/lib/components/checkbox.jsx +16 -0
- package/lib/components/checkbox.jsx.map +1 -0
- package/lib/components/connection-settings.d.ts +41 -0
- package/lib/components/connection-settings.d.ts.map +1 -0
- package/lib/components/connection-settings.jsx +354 -0
- package/lib/components/connection-settings.jsx.map +1 -0
- package/lib/components/context-menu.d.ts +52 -0
- package/lib/components/context-menu.d.ts.map +1 -0
- package/lib/components/context-menu.jsx +24 -0
- package/lib/components/context-menu.jsx.map +1 -0
- package/lib/components/data-table.d.ts +59 -0
- package/lib/components/data-table.d.ts.map +1 -0
- package/lib/components/data-table.jsx +101 -0
- package/lib/components/data-table.jsx.map +1 -0
- package/lib/components/dialog.d.ts +58 -0
- package/lib/components/dialog.d.ts.map +1 -0
- package/lib/components/dialog.jsx +197 -0
- package/lib/components/dialog.jsx.map +1 -0
- package/lib/components/dropdown-menu.d.ts +55 -0
- package/lib/components/dropdown-menu.d.ts.map +1 -0
- package/lib/components/dropdown-menu.jsx +38 -0
- package/lib/components/dropdown-menu.jsx.map +1 -0
- package/lib/components/entropy-boot-splash.d.ts +24 -0
- package/lib/components/entropy-boot-splash.d.ts.map +1 -0
- package/lib/components/entropy-boot-splash.jsx +83 -0
- package/lib/components/entropy-boot-splash.jsx.map +1 -0
- package/lib/components/entropy-mark-animated.d.ts +20 -0
- package/lib/components/entropy-mark-animated.d.ts.map +1 -0
- package/lib/components/entropy-mark-animated.jsx +148 -0
- package/lib/components/entropy-mark-animated.jsx.map +1 -0
- package/lib/components/entropy-mark-geometry.d.ts +8 -0
- package/lib/components/entropy-mark-geometry.d.ts.map +1 -0
- package/lib/components/entropy-mark-geometry.js +10 -0
- package/lib/components/entropy-mark-geometry.js.map +1 -0
- package/lib/components/entropy-mark-sequential.d.ts +12 -0
- package/lib/components/entropy-mark-sequential.d.ts.map +1 -0
- package/lib/components/entropy-mark-sequential.jsx +53 -0
- package/lib/components/entropy-mark-sequential.jsx.map +1 -0
- package/lib/components/entropy-mark.d.ts +29 -0
- package/lib/components/entropy-mark.d.ts.map +1 -0
- package/lib/components/entropy-mark.jsx +66 -0
- package/lib/components/entropy-mark.jsx.map +1 -0
- package/lib/components/error-boundary.d.ts +31 -0
- package/lib/components/error-boundary.d.ts.map +1 -0
- package/lib/components/error-boundary.jsx +40 -0
- package/lib/components/error-boundary.jsx.map +1 -0
- package/lib/components/index.d.ts +41 -0
- package/lib/components/index.d.ts.map +1 -0
- package/lib/components/index.js +43 -0
- package/lib/components/index.js.map +1 -0
- package/lib/components/input.d.ts +26 -0
- package/lib/components/input.d.ts.map +1 -0
- package/lib/components/input.jsx +95 -0
- package/lib/components/input.jsx.map +1 -0
- package/lib/components/item-icon.d.ts +32 -0
- package/lib/components/item-icon.d.ts.map +1 -0
- package/lib/components/item-icon.jsx +54 -0
- package/lib/components/item-icon.jsx.map +1 -0
- package/lib/components/label.d.ts +13 -0
- package/lib/components/label.d.ts.map +1 -0
- package/lib/components/label.jsx +9 -0
- package/lib/components/label.jsx.map +1 -0
- package/lib/components/legal-dialog.d.ts +18 -0
- package/lib/components/legal-dialog.d.ts.map +1 -0
- package/lib/components/legal-dialog.jsx +31 -0
- package/lib/components/legal-dialog.jsx.map +1 -0
- package/lib/components/license-gate.d.ts +17 -0
- package/lib/components/license-gate.d.ts.map +1 -0
- package/lib/components/license-gate.jsx +21 -0
- package/lib/components/license-gate.jsx.map +1 -0
- package/lib/components/logo.d.ts +15 -0
- package/lib/components/logo.d.ts.map +1 -0
- package/lib/components/logo.jsx +20 -0
- package/lib/components/logo.jsx.map +1 -0
- package/lib/components/onboarding-wizard.d.ts +89 -0
- package/lib/components/onboarding-wizard.d.ts.map +1 -0
- package/lib/components/onboarding-wizard.jsx +185 -0
- package/lib/components/onboarding-wizard.jsx.map +1 -0
- package/lib/components/pagination.d.ts +43 -0
- package/lib/components/pagination.d.ts.map +1 -0
- package/lib/components/pagination.jsx +72 -0
- package/lib/components/pagination.jsx.map +1 -0
- package/lib/components/password-generator.d.ts +15 -0
- package/lib/components/password-generator.d.ts.map +1 -0
- package/lib/components/password-generator.jsx +273 -0
- package/lib/components/password-generator.jsx.map +1 -0
- package/lib/components/pin-pad.d.ts +20 -0
- package/lib/components/pin-pad.d.ts.map +1 -0
- package/lib/components/pin-pad.jsx +93 -0
- package/lib/components/pin-pad.jsx.map +1 -0
- package/lib/components/popover.d.ts +27 -0
- package/lib/components/popover.d.ts.map +1 -0
- package/lib/components/popover.jsx +18 -0
- package/lib/components/popover.jsx.map +1 -0
- package/lib/components/profile/ProfileDialog.d.ts +25 -0
- package/lib/components/profile/ProfileDialog.d.ts.map +1 -0
- package/lib/components/profile/ProfileDialog.jsx +71 -0
- package/lib/components/profile/ProfileDialog.jsx.map +1 -0
- package/lib/components/profile/ProfileTab.d.ts +12 -0
- package/lib/components/profile/ProfileTab.d.ts.map +1 -0
- package/lib/components/profile/ProfileTab.jsx +112 -0
- package/lib/components/profile/ProfileTab.jsx.map +1 -0
- package/lib/components/profile/SecurityTab.d.ts +32 -0
- package/lib/components/profile/SecurityTab.d.ts.map +1 -0
- package/lib/components/profile/SecurityTab.jsx +145 -0
- package/lib/components/profile/SecurityTab.jsx.map +1 -0
- package/lib/components/profile/index.d.ts +4 -0
- package/lib/components/profile/index.d.ts.map +1 -0
- package/lib/components/profile/index.js +4 -0
- package/lib/components/profile/index.js.map +1 -0
- package/lib/components/segmented-toggle.d.ts +28 -0
- package/lib/components/segmented-toggle.d.ts.map +1 -0
- package/lib/components/segmented-toggle.jsx +64 -0
- package/lib/components/segmented-toggle.jsx.map +1 -0
- package/lib/components/separator.d.ts +13 -0
- package/lib/components/separator.d.ts.map +1 -0
- package/lib/components/separator.jsx +16 -0
- package/lib/components/separator.jsx.map +1 -0
- package/lib/components/server-settings.d.ts +27 -0
- package/lib/components/server-settings.d.ts.map +1 -0
- package/lib/components/server-settings.jsx +307 -0
- package/lib/components/server-settings.jsx.map +1 -0
- package/lib/components/settings/AccountSection.d.ts +26 -0
- package/lib/components/settings/AccountSection.d.ts.map +1 -0
- package/lib/components/settings/AccountSection.jsx +32 -0
- package/lib/components/settings/AccountSection.jsx.map +1 -0
- package/lib/components/settings/DangerZoneSection.d.ts +13 -0
- package/lib/components/settings/DangerZoneSection.d.ts.map +1 -0
- package/lib/components/settings/DangerZoneSection.jsx +16 -0
- package/lib/components/settings/DangerZoneSection.jsx.map +1 -0
- package/lib/components/settings/GeneralSection.d.ts +11 -0
- package/lib/components/settings/GeneralSection.d.ts.map +1 -0
- package/lib/components/settings/GeneralSection.jsx +12 -0
- package/lib/components/settings/GeneralSection.jsx.map +1 -0
- package/lib/components/settings/SupportSection.d.ts +11 -0
- package/lib/components/settings/SupportSection.d.ts.map +1 -0
- package/lib/components/settings/SupportSection.jsx +22 -0
- package/lib/components/settings/SupportSection.jsx.map +1 -0
- package/lib/components/settings/index.d.ts +5 -0
- package/lib/components/settings/index.d.ts.map +1 -0
- package/lib/components/settings/index.js +5 -0
- package/lib/components/settings/index.js.map +1 -0
- package/lib/components/settings-row.d.ts +28 -0
- package/lib/components/settings-row.d.ts.map +1 -0
- package/lib/components/settings-row.jsx +68 -0
- package/lib/components/settings-row.jsx.map +1 -0
- package/lib/components/skeleton.d.ts +8 -0
- package/lib/components/skeleton.d.ts.map +1 -0
- package/lib/components/skeleton.jsx +24 -0
- package/lib/components/skeleton.jsx.map +1 -0
- package/lib/components/social-connections.d.ts +15 -0
- package/lib/components/social-connections.d.ts.map +1 -0
- package/lib/components/social-connections.jsx +31 -0
- package/lib/components/social-connections.jsx.map +1 -0
- package/lib/components/stat-card.d.ts +29 -0
- package/lib/components/stat-card.d.ts.map +1 -0
- package/lib/components/stat-card.jsx +36 -0
- package/lib/components/stat-card.jsx.map +1 -0
- package/lib/components/tag-chip.d.ts +18 -0
- package/lib/components/tag-chip.d.ts.map +1 -0
- package/lib/components/tag-chip.jsx +54 -0
- package/lib/components/tag-chip.jsx.map +1 -0
- package/lib/components/tag-multi-select.d.ts +27 -0
- package/lib/components/tag-multi-select.d.ts.map +1 -0
- package/lib/components/tag-multi-select.jsx +65 -0
- package/lib/components/tag-multi-select.jsx.map +1 -0
- package/lib/components/text.d.ts +22 -0
- package/lib/components/text.d.ts.map +1 -0
- package/lib/components/text.jsx +43 -0
- package/lib/components/text.jsx.map +1 -0
- package/lib/components/toast/ToastPortal.d.ts +11 -0
- package/lib/components/toast/ToastPortal.d.ts.map +1 -0
- package/lib/components/toast/ToastPortal.jsx +15 -0
- package/lib/components/toast/ToastPortal.jsx.map +1 -0
- package/lib/components/toast/ToastPortal.web.d.ts +14 -0
- package/lib/components/toast/ToastPortal.web.d.ts.map +1 -0
- package/lib/components/toast/ToastPortal.web.jsx +39 -0
- package/lib/components/toast/ToastPortal.web.jsx.map +1 -0
- package/lib/components/toast/index.d.ts +3 -0
- package/lib/components/toast/index.d.ts.map +1 -0
- package/lib/components/toast/index.js +3 -0
- package/lib/components/toast/index.js.map +1 -0
- package/lib/components/toast/toast-config.d.ts +14 -0
- package/lib/components/toast/toast-config.d.ts.map +1 -0
- package/lib/components/toast/toast-config.jsx +24 -0
- package/lib/components/toast/toast-config.jsx.map +1 -0
- package/lib/components/tooltip.d.ts +30 -0
- package/lib/components/tooltip.d.ts.map +1 -0
- package/lib/components/tooltip.jsx +14 -0
- package/lib/components/tooltip.jsx.map +1 -0
- package/lib/components/totp-display.d.ts +23 -0
- package/lib/components/totp-display.d.ts.map +1 -0
- package/lib/components/totp-display.jsx +132 -0
- package/lib/components/totp-display.jsx.map +1 -0
- package/lib/components/user-avatar.d.ts +18 -0
- package/lib/components/user-avatar.d.ts.map +1 -0
- package/lib/components/user-avatar.jsx +25 -0
- package/lib/components/user-avatar.jsx.map +1 -0
- package/lib/context/AppConfigContext.d.ts +56 -0
- package/lib/context/AppConfigContext.d.ts.map +1 -0
- package/lib/context/AppConfigContext.jsx +14 -0
- package/lib/context/AppConfigContext.jsx.map +1 -0
- package/lib/context/NavigationContext.d.ts +42 -0
- package/lib/context/NavigationContext.d.ts.map +1 -0
- package/lib/context/NavigationContext.jsx +53 -0
- package/lib/context/NavigationContext.jsx.map +1 -0
- package/lib/context/NotificationContext.d.ts +32 -0
- package/lib/context/NotificationContext.d.ts.map +1 -0
- package/lib/context/NotificationContext.jsx +49 -0
- package/lib/context/NotificationContext.jsx.map +1 -0
- package/lib/context/ThemeContext.d.ts +12 -0
- package/lib/context/ThemeContext.d.ts.map +1 -0
- package/lib/context/ThemeContext.jsx +66 -0
- package/lib/context/ThemeContext.jsx.map +1 -0
- package/lib/context/index.d.ts +5 -0
- package/lib/context/index.d.ts.map +1 -0
- package/lib/context/index.js +5 -0
- package/lib/context/index.js.map +1 -0
- package/lib/flags.d.ts +9 -0
- package/lib/flags.d.ts.map +1 -0
- package/lib/flags.js +37 -0
- package/lib/flags.js.map +1 -0
- package/lib/forms/form-error.d.ts +12 -0
- package/lib/forms/form-error.d.ts.map +1 -0
- package/lib/forms/form-error.jsx +14 -0
- package/lib/forms/form-error.jsx.map +1 -0
- package/lib/forms/index.d.ts +3 -0
- package/lib/forms/index.d.ts.map +1 -0
- package/lib/forms/index.js +3 -0
- package/lib/forms/index.js.map +1 -0
- package/lib/forms/shake-field.d.ts +18 -0
- package/lib/forms/shake-field.d.ts.map +1 -0
- package/lib/forms/shake-field.jsx +30 -0
- package/lib/forms/shake-field.jsx.map +1 -0
- package/lib/hooks/index.d.ts +6 -0
- package/lib/hooks/index.d.ts.map +1 -0
- package/lib/hooks/index.js +6 -0
- package/lib/hooks/index.js.map +1 -0
- package/lib/hooks/useAuth.d.ts +109 -0
- package/lib/hooks/useAuth.d.ts.map +1 -0
- package/lib/hooks/useAuth.jsx +404 -0
- package/lib/hooks/useAuth.jsx.map +1 -0
- package/lib/hooks/useAutoLock.d.ts +22 -0
- package/lib/hooks/useAutoLock.d.ts.map +1 -0
- package/lib/hooks/useAutoLock.js +85 -0
- package/lib/hooks/useAutoLock.js.map +1 -0
- package/lib/hooks/useDebouncedValue.d.ts +19 -0
- package/lib/hooks/useDebouncedValue.d.ts.map +1 -0
- package/lib/hooks/useDebouncedValue.js +29 -0
- package/lib/hooks/useDebouncedValue.js.map +1 -0
- package/lib/hooks/useShakeAnimation.d.ts +17 -0
- package/lib/hooks/useShakeAnimation.d.ts.map +1 -0
- package/lib/hooks/useShakeAnimation.js +22 -0
- package/lib/hooks/useShakeAnimation.js.map +1 -0
- package/lib/hooks/useUploadBlobUrl.d.ts +13 -0
- package/lib/hooks/useUploadBlobUrl.d.ts.map +1 -0
- package/lib/hooks/useUploadBlobUrl.js +60 -0
- package/lib/hooks/useUploadBlobUrl.js.map +1 -0
- package/lib/index.d.ts +10 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +47 -0
- package/lib/index.js.map +1 -0
- package/lib/screens/auth/AccountPickerScreen.d.ts +24 -0
- package/lib/screens/auth/AccountPickerScreen.d.ts.map +1 -0
- package/lib/screens/auth/AccountPickerScreen.jsx +47 -0
- package/lib/screens/auth/AccountPickerScreen.jsx.map +1 -0
- package/lib/screens/auth/AuthScreen.d.ts +59 -0
- package/lib/screens/auth/AuthScreen.d.ts.map +1 -0
- package/lib/screens/auth/AuthScreen.jsx +594 -0
- package/lib/screens/auth/AuthScreen.jsx.map +1 -0
- package/lib/screens/auth/ConsentScreen.d.ts +27 -0
- package/lib/screens/auth/ConsentScreen.d.ts.map +1 -0
- package/lib/screens/auth/ConsentScreen.jsx +55 -0
- package/lib/screens/auth/ConsentScreen.jsx.map +1 -0
- package/lib/screens/auth/ErrorScreen.d.ts +20 -0
- package/lib/screens/auth/ErrorScreen.d.ts.map +1 -0
- package/lib/screens/auth/ErrorScreen.jsx +43 -0
- package/lib/screens/auth/ErrorScreen.jsx.map +1 -0
- package/lib/screens/auth/ExpiredLinkScreen.d.ts +19 -0
- package/lib/screens/auth/ExpiredLinkScreen.d.ts.map +1 -0
- package/lib/screens/auth/ExpiredLinkScreen.jsx +38 -0
- package/lib/screens/auth/ExpiredLinkScreen.jsx.map +1 -0
- package/lib/screens/auth/ForgotPasswordScreen.d.ts +4 -0
- package/lib/screens/auth/ForgotPasswordScreen.d.ts.map +1 -0
- package/lib/screens/auth/ForgotPasswordScreen.jsx +123 -0
- package/lib/screens/auth/ForgotPasswordScreen.jsx.map +1 -0
- package/lib/screens/auth/ImportDataScreen.d.ts +17 -0
- package/lib/screens/auth/ImportDataScreen.d.ts.map +1 -0
- package/lib/screens/auth/ImportDataScreen.jsx +73 -0
- package/lib/screens/auth/ImportDataScreen.jsx.map +1 -0
- package/lib/screens/auth/LoginScreen.d.ts +38 -0
- package/lib/screens/auth/LoginScreen.d.ts.map +1 -0
- package/lib/screens/auth/LoginScreen.jsx +326 -0
- package/lib/screens/auth/LoginScreen.jsx.map +1 -0
- package/lib/screens/auth/MfaChallengeScreen.d.ts +4 -0
- package/lib/screens/auth/MfaChallengeScreen.d.ts.map +1 -0
- package/lib/screens/auth/MfaChallengeScreen.jsx +139 -0
- package/lib/screens/auth/MfaChallengeScreen.jsx.map +1 -0
- package/lib/screens/auth/MfaEnrollScreen.d.ts +12 -0
- package/lib/screens/auth/MfaEnrollScreen.d.ts.map +1 -0
- package/lib/screens/auth/MfaEnrollScreen.jsx +267 -0
- package/lib/screens/auth/MfaEnrollScreen.jsx.map +1 -0
- package/lib/screens/auth/PasskeyEnrollScreen.d.ts +18 -0
- package/lib/screens/auth/PasskeyEnrollScreen.d.ts.map +1 -0
- package/lib/screens/auth/PasskeyEnrollScreen.jsx +51 -0
- package/lib/screens/auth/PasskeyEnrollScreen.jsx.map +1 -0
- package/lib/screens/auth/PrivacyPolicyScreen.d.ts +19 -0
- package/lib/screens/auth/PrivacyPolicyScreen.d.ts.map +1 -0
- package/lib/screens/auth/PrivacyPolicyScreen.jsx +143 -0
- package/lib/screens/auth/PrivacyPolicyScreen.jsx.map +1 -0
- package/lib/screens/auth/RegisterScreen.d.ts +14 -0
- package/lib/screens/auth/RegisterScreen.d.ts.map +1 -0
- package/lib/screens/auth/RegisterScreen.jsx +296 -0
- package/lib/screens/auth/RegisterScreen.jsx.map +1 -0
- package/lib/screens/auth/ResetPasswordScreen.d.ts +12 -0
- package/lib/screens/auth/ResetPasswordScreen.d.ts.map +1 -0
- package/lib/screens/auth/ResetPasswordScreen.jsx +276 -0
- package/lib/screens/auth/ResetPasswordScreen.jsx.map +1 -0
- package/lib/screens/auth/ServerConfigScreen.d.ts +18 -0
- package/lib/screens/auth/ServerConfigScreen.d.ts.map +1 -0
- package/lib/screens/auth/ServerConfigScreen.jsx +259 -0
- package/lib/screens/auth/ServerConfigScreen.jsx.map +1 -0
- package/lib/screens/auth/TermsOfServiceScreen.d.ts +30 -0
- package/lib/screens/auth/TermsOfServiceScreen.d.ts.map +1 -0
- package/lib/screens/auth/TermsOfServiceScreen.jsx +130 -0
- package/lib/screens/auth/TermsOfServiceScreen.jsx.map +1 -0
- package/lib/screens/auth/VerifyEmailScreen.d.ts +4 -0
- package/lib/screens/auth/VerifyEmailScreen.d.ts.map +1 -0
- package/lib/screens/auth/VerifyEmailScreen.jsx +249 -0
- package/lib/screens/auth/VerifyEmailScreen.jsx.map +1 -0
- package/lib/screens/auth/WelcomeScreen.d.ts +17 -0
- package/lib/screens/auth/WelcomeScreen.d.ts.map +1 -0
- package/lib/screens/auth/WelcomeScreen.jsx +58 -0
- package/lib/screens/auth/WelcomeScreen.jsx.map +1 -0
- package/lib/screens/auth/index.d.ts +19 -0
- package/lib/screens/auth/index.d.ts.map +1 -0
- package/lib/screens/auth/index.js +19 -0
- package/lib/screens/auth/index.js.map +1 -0
- package/lib/screens/index.d.ts +2 -0
- package/lib/screens/index.d.ts.map +1 -0
- package/lib/screens/index.js +2 -0
- package/lib/screens/index.js.map +1 -0
- package/lib/services/api-config.d.ts +87 -0
- package/lib/services/api-config.d.ts.map +1 -0
- package/lib/services/api-config.js +202 -0
- package/lib/services/api-config.js.map +1 -0
- package/lib/services/auth.service.d.ts +140 -0
- package/lib/services/auth.service.d.ts.map +1 -0
- package/lib/services/auth.service.js +376 -0
- package/lib/services/auth.service.js.map +1 -0
- package/lib/services/favicon.d.ts +46 -0
- package/lib/services/favicon.d.ts.map +1 -0
- package/lib/services/favicon.js +84 -0
- package/lib/services/favicon.js.map +1 -0
- package/lib/services/hibp-cache.d.ts +23 -0
- package/lib/services/hibp-cache.d.ts.map +1 -0
- package/lib/services/hibp-cache.js +56 -0
- package/lib/services/hibp-cache.js.map +1 -0
- package/lib/services/hibp.d.ts +28 -0
- package/lib/services/hibp.d.ts.map +1 -0
- package/lib/services/hibp.js +92 -0
- package/lib/services/hibp.js.map +1 -0
- package/lib/services/index.d.ts +8 -0
- package/lib/services/index.d.ts.map +1 -0
- package/lib/services/index.js +7 -0
- package/lib/services/index.js.map +1 -0
- package/lib/services/passkey.d.ts +10 -0
- package/lib/services/passkey.d.ts.map +1 -0
- package/lib/services/passkey.js +192 -0
- package/lib/services/passkey.js.map +1 -0
- package/lib/utils/api-fetch.d.ts +11 -0
- package/lib/utils/api-fetch.d.ts.map +1 -0
- package/lib/utils/api-fetch.js +52 -0
- package/lib/utils/api-fetch.js.map +1 -0
- package/lib/utils/clipboard.d.ts +31 -0
- package/lib/utils/clipboard.d.ts.map +1 -0
- package/lib/utils/clipboard.js +66 -0
- package/lib/utils/clipboard.js.map +1 -0
- package/lib/utils/cn.d.ts +9 -0
- package/lib/utils/cn.d.ts.map +1 -0
- package/lib/utils/cn.js +12 -0
- package/lib/utils/cn.js.map +1 -0
- package/lib/utils/debounce.d.ts +13 -0
- package/lib/utils/debounce.d.ts.map +1 -0
- package/lib/utils/debounce.js +28 -0
- package/lib/utils/debounce.js.map +1 -0
- package/lib/utils/error.d.ts +9 -0
- package/lib/utils/error.d.ts.map +1 -0
- package/lib/utils/error.js +11 -0
- package/lib/utils/error.js.map +1 -0
- package/lib/utils/fetch.d.ts +17 -0
- package/lib/utils/fetch.d.ts.map +1 -0
- package/lib/utils/fetch.js +29 -0
- package/lib/utils/fetch.js.map +1 -0
- package/lib/utils/http-error.d.ts +41 -0
- package/lib/utils/http-error.d.ts.map +1 -0
- package/lib/utils/http-error.js +63 -0
- package/lib/utils/http-error.js.map +1 -0
- package/lib/utils/index.d.ts +11 -0
- package/lib/utils/index.d.ts.map +1 -0
- package/lib/utils/index.js +11 -0
- package/lib/utils/index.js.map +1 -0
- package/lib/utils/palette.d.ts +46 -0
- package/lib/utils/palette.d.ts.map +1 -0
- package/lib/utils/palette.js +75 -0
- package/lib/utils/palette.js.map +1 -0
- package/lib/utils/password.d.ts +20 -0
- package/lib/utils/password.d.ts.map +1 -0
- package/lib/utils/password.js +51 -0
- package/lib/utils/password.js.map +1 -0
- package/lib/utils/settings-storage.d.ts +3 -0
- package/lib/utils/settings-storage.d.ts.map +1 -0
- package/lib/utils/settings-storage.js +62 -0
- package/lib/utils/settings-storage.js.map +1 -0
- package/lib/utils/validation.d.ts +29 -0
- package/lib/utils/validation.d.ts.map +1 -0
- package/lib/utils/validation.js +58 -0
- package/lib/utils/validation.js.map +1 -0
- package/package.json +204 -0
- package/src/components/__tests__/data-table.test.ts +94 -0
- package/src/components/__tests__/pagination.test.ts +73 -0
- package/src/components/__tests__/stat-card.test.ts +21 -0
- package/src/components/auth/LockOverlay.tsx +122 -0
- package/src/components/auth/PasswordStrengthMeter.tsx +96 -0
- package/src/components/auth/ProtectedRoute.tsx +91 -0
- package/src/components/auth/PwnedPasswordWarning.tsx +54 -0
- package/src/components/auth/index.ts +10 -0
- package/src/components/bottom-nav.tsx +99 -0
- package/src/components/button.tsx +144 -0
- package/src/components/card.tsx +82 -0
- package/src/components/checkbox.tsx +48 -0
- package/src/components/connection-settings.tsx +583 -0
- package/src/components/context-menu.tsx +95 -0
- package/src/components/data-table.tsx +223 -0
- package/src/components/dialog.tsx +376 -0
- package/src/components/dropdown-menu.tsx +120 -0
- package/src/components/entropy-boot-splash.tsx +114 -0
- package/src/components/entropy-mark-animated.tsx +260 -0
- package/src/components/entropy-mark-geometry.ts +11 -0
- package/src/components/entropy-mark-sequential.tsx +132 -0
- package/src/components/entropy-mark.tsx +135 -0
- package/src/components/error-boundary.tsx +70 -0
- package/src/components/index.ts +156 -0
- package/src/components/input.tsx +246 -0
- package/src/components/item-icon.tsx +111 -0
- package/src/components/label.tsx +25 -0
- package/src/components/legal-dialog.tsx +47 -0
- package/src/components/license-gate.tsx +28 -0
- package/src/components/logo.tsx +34 -0
- package/src/components/onboarding-wizard.tsx +353 -0
- package/src/components/pagination.tsx +154 -0
- package/src/components/password-generator.tsx +393 -0
- package/src/components/pin-pad.tsx +156 -0
- package/src/components/popover.tsx +38 -0
- package/src/components/profile/ProfileDialog.tsx +129 -0
- package/src/components/profile/ProfileTab.tsx +151 -0
- package/src/components/profile/SecurityTab.tsx +229 -0
- package/src/components/profile/index.ts +3 -0
- package/src/components/segmented-toggle.tsx +119 -0
- package/src/components/separator.tsx +41 -0
- package/src/components/server-settings.tsx +442 -0
- package/src/components/settings/AccountSection.tsx +76 -0
- package/src/components/settings/DangerZoneSection.tsx +37 -0
- package/src/components/settings/GeneralSection.tsx +39 -0
- package/src/components/settings/SupportSection.tsx +53 -0
- package/src/components/settings/index.ts +4 -0
- package/src/components/settings-row.tsx +126 -0
- package/src/components/skeleton.tsx +48 -0
- package/src/components/social-connections.tsx +55 -0
- package/src/components/stat-card.tsx +64 -0
- package/src/components/tag-chip.tsx +78 -0
- package/src/components/tag-multi-select.tsx +136 -0
- package/src/components/text.tsx +77 -0
- package/src/components/toast/ToastPortal.tsx +16 -0
- package/src/components/toast/ToastPortal.web.tsx +47 -0
- package/src/components/toast/index.ts +2 -0
- package/src/components/toast/toast-config.tsx +31 -0
- package/src/components/tooltip.tsx +30 -0
- package/src/components/totp-display.tsx +207 -0
- package/src/components/user-avatar.tsx +46 -0
- package/src/context/AppConfigContext.tsx +76 -0
- package/src/context/NavigationContext.tsx +75 -0
- package/src/context/NotificationContext.tsx +69 -0
- package/src/context/ThemeContext.tsx +83 -0
- package/src/context/__tests__/NavigationContext.test.tsx +53 -0
- package/src/context/index.ts +24 -0
- package/src/flags.ts +44 -0
- package/src/forms/form-error.tsx +20 -0
- package/src/forms/index.ts +2 -0
- package/src/forms/shake-field.tsx +52 -0
- package/src/hooks/__tests__/useUploadBlobUrl.test.tsx +77 -0
- package/src/hooks/index.ts +18 -0
- package/src/hooks/useAuth.tsx +567 -0
- package/src/hooks/useAutoLock.ts +110 -0
- package/src/hooks/useDebouncedValue.ts +32 -0
- package/src/hooks/useShakeAnimation.ts +42 -0
- package/src/hooks/useUploadBlobUrl.ts +75 -0
- package/src/index.ts +48 -0
- package/src/screens/auth/AccountPickerScreen.tsx +103 -0
- package/src/screens/auth/AuthScreen.tsx +941 -0
- package/src/screens/auth/ConsentScreen.tsx +118 -0
- package/src/screens/auth/ErrorScreen.tsx +96 -0
- package/src/screens/auth/ExpiredLinkScreen.tsx +87 -0
- package/src/screens/auth/ForgotPasswordScreen.tsx +182 -0
- package/src/screens/auth/ImportDataScreen.tsx +112 -0
- package/src/screens/auth/LoginScreen.tsx +484 -0
- package/src/screens/auth/MfaChallengeScreen.tsx +216 -0
- package/src/screens/auth/MfaEnrollScreen.tsx +388 -0
- package/src/screens/auth/PasskeyEnrollScreen.tsx +96 -0
- package/src/screens/auth/PrivacyPolicyScreen.tsx +249 -0
- package/src/screens/auth/RegisterScreen.tsx +430 -0
- package/src/screens/auth/ResetPasswordScreen.tsx +377 -0
- package/src/screens/auth/ServerConfigScreen.tsx +388 -0
- package/src/screens/auth/TermsOfServiceScreen.tsx +236 -0
- package/src/screens/auth/VerifyEmailScreen.tsx +310 -0
- package/src/screens/auth/WelcomeScreen.tsx +78 -0
- package/src/screens/auth/index.ts +36 -0
- package/src/screens/index.ts +1 -0
- package/src/services/__tests__/api-config.test.ts +67 -0
- package/src/services/__tests__/favicon.test.ts +88 -0
- package/src/services/__tests__/hibp-cache.test.ts +37 -0
- package/src/services/__tests__/hibp.test.ts +39 -0
- package/src/services/api-config.ts +260 -0
- package/src/services/auth.service.ts +498 -0
- package/src/services/favicon.ts +102 -0
- package/src/services/hibp-cache.ts +71 -0
- package/src/services/hibp.ts +120 -0
- package/src/services/index.ts +52 -0
- package/src/services/passkey.ts +213 -0
- package/src/types/external.d.ts +24 -0
- package/src/utils/__tests__/clipboard.test.ts +59 -0
- package/src/utils/__tests__/cn.test.ts +24 -0
- package/src/utils/__tests__/debounce.test.ts +42 -0
- package/src/utils/__tests__/error.test.ts +18 -0
- package/src/utils/__tests__/http-error.test.ts +33 -0
- package/src/utils/__tests__/palette.test.ts +22 -0
- package/src/utils/__tests__/password.test.ts +55 -0
- package/src/utils/__tests__/settings-storage.test.ts +15 -0
- package/src/utils/__tests__/validation.test.ts +52 -0
- package/src/utils/api-fetch.ts +61 -0
- package/src/utils/clipboard.ts +69 -0
- package/src/utils/cn.ts +12 -0
- package/src/utils/debounce.ts +33 -0
- package/src/utils/error.ts +10 -0
- package/src/utils/fetch.ts +33 -0
- package/src/utils/http-error.ts +81 -0
- package/src/utils/index.ts +23 -0
- package/src/utils/palette.ts +105 -0
- package/src/utils/password.ts +64 -0
- package/src/utils/settings-storage.ts +68 -0
- package/src/utils/validation.ts +71 -0
- package/styles/globals.css +262 -0
- package/tailwind-preset.js +163 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Have-I-Been-Pwned password lookup using `k`-anonymity.
|
|
3
|
+
*
|
|
4
|
+
* Sends only the first five hex characters of the SHA-1 hash to the HIBP
|
|
5
|
+
* API. The full hash and plaintext never leave the device. Designed to be
|
|
6
|
+
* called from a debounced password-input change handler — see `debounce`
|
|
7
|
+
* below.
|
|
8
|
+
*/
|
|
9
|
+
import { Platform } from "react-native";
|
|
10
|
+
import * as Crypto from "expo-crypto";
|
|
11
|
+
import { fetchWithTimeout } from "../utils/fetch";
|
|
12
|
+
import { getCachedPolicy } from "./hibp-cache";
|
|
13
|
+
export async function checkPasswordPwned(password) {
|
|
14
|
+
try {
|
|
15
|
+
const hash = await Crypto.digestStringAsync(Crypto.CryptoDigestAlgorithm.SHA1, password, {
|
|
16
|
+
encoding: Crypto.CryptoEncoding.HEX,
|
|
17
|
+
});
|
|
18
|
+
const hashUpperCase = hash.toUpperCase();
|
|
19
|
+
const prefix = hashUpperCase.substring(0, 5);
|
|
20
|
+
const suffix = hashUpperCase.substring(5);
|
|
21
|
+
const response = await fetchWithTimeout(`https://api.pwnedpasswords.com/range/${prefix}`, {
|
|
22
|
+
method: "GET",
|
|
23
|
+
headers: {
|
|
24
|
+
// User-Agent is a forbidden header in browsers and cannot be set
|
|
25
|
+
// via fetch — the browser sends its own. On native, expo handles it.
|
|
26
|
+
...(Platform.OS !== "web" ? { "User-Agent": "Entropy Softworks Client" } : {}),
|
|
27
|
+
"Add-Padding": "true",
|
|
28
|
+
},
|
|
29
|
+
}, 10_000);
|
|
30
|
+
if (!response.ok) {
|
|
31
|
+
throw new Error(`HIBP API returned status ${response.status}`);
|
|
32
|
+
}
|
|
33
|
+
const text = await response.text();
|
|
34
|
+
const hashes = text.split("\r\n").filter((line) => line.length > 0);
|
|
35
|
+
for (const hashLine of hashes) {
|
|
36
|
+
const [hashSuffix, count] = hashLine.split(":");
|
|
37
|
+
if (hashSuffix === suffix && count) {
|
|
38
|
+
return { isPwned: true, count: parseInt(count, 10) };
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return { isPwned: false, count: 0 };
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return {
|
|
45
|
+
isPwned: null,
|
|
46
|
+
count: 0,
|
|
47
|
+
error: "Unable to verify password security. Please try again later.",
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Build a user-friendly message for a HIBP result. The policy comes from
|
|
53
|
+
* the shared cache populated by the consumer (see `hibp-cache.ts`). If no
|
|
54
|
+
* policy is cached, falls back to a non-enforcing default.
|
|
55
|
+
*/
|
|
56
|
+
export function getPwnedMessage(result) {
|
|
57
|
+
if (result.error) {
|
|
58
|
+
return {
|
|
59
|
+
title: "Unable to Verify",
|
|
60
|
+
message: result.error,
|
|
61
|
+
severity: "info",
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
if (result.isPwned === false) {
|
|
65
|
+
return {
|
|
66
|
+
title: "Password Is Safe",
|
|
67
|
+
message: "This password has not been found in any known data breaches.",
|
|
68
|
+
severity: "info",
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
const policy = getCachedPolicy() ?? {
|
|
72
|
+
enabled: true,
|
|
73
|
+
enforce: false,
|
|
74
|
+
block_threshold: 0,
|
|
75
|
+
};
|
|
76
|
+
if (policy.enforce && result.count > policy.block_threshold) {
|
|
77
|
+
return {
|
|
78
|
+
title: "Password Compromised!",
|
|
79
|
+
message: `This password has appeared in ${result.count.toLocaleString()} known data breaches. Please choose a different password.`,
|
|
80
|
+
severity: "error",
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
return {
|
|
84
|
+
title: "Password Found in Breach",
|
|
85
|
+
message: `This password has appeared ${result.count.toLocaleString()} time${result.count > 1 ? "s" : ""} in data breaches. Consider choosing a different password.`,
|
|
86
|
+
severity: "warning",
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
// `debounce` moved to `utils/debounce`; re-exported here for back-compat
|
|
90
|
+
// with existing `@entropy-softworks/ui/services/hibp` consumers.
|
|
91
|
+
export { debounce } from "../utils/debounce";
|
|
92
|
+
//# sourceMappingURL=hibp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hibp.js","sourceRoot":"","sources":["../../src/services/hibp.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { default as AuthService } from "./auth.service";
|
|
2
|
+
export type { User, AuthResponse, LoginRequest, RegisterRequest, ErrorResponse, MfaSetupResponse, ServerConfig, } from "./auth.service";
|
|
3
|
+
export { isPasskeySupported, registerPasskey, authenticateWithPasskey } from "./passkey";
|
|
4
|
+
export { configureApi, getBaseUrl, getDefaultBaseUrl, getStoragePrefix, setBaseUrl, resetBaseUrl, loadServerUrlOverride, getSessionToken, storeSessionToken, clearSessionToken, getAuthMode, getTenant, setTenant, type ApiConfig, } from "./api-config";
|
|
5
|
+
export { checkPasswordPwned, getPwnedMessage, type PwnedPasswordResult, type PwnedMessage, } from "./hibp";
|
|
6
|
+
export { getCachedPolicy as getCachedHibpPolicy, fetchHibpPolicy, getHibpPolicy, type HibpPolicy, } from "./hibp-cache";
|
|
7
|
+
export { buildFaviconUrl, customIconId, customIconRef, isCustomIconRef, resolveIcon, type ResolvedIcon, } from "./favicon";
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,gBAAgB,CAAC;AACxD,YAAY,EACV,IAAI,EACJ,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,aAAa,EACb,gBAAgB,EAChB,YAAY,GACb,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAC;AAEzF,OAAO,EACL,YAAY,EACZ,UAAU,EACV,iBAAiB,EACjB,gBAAgB,EAChB,UAAU,EACV,YAAY,EACZ,qBAAqB,EACrB,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,WAAW,EACX,SAAS,EACT,SAAS,EACT,KAAK,SAAS,GACf,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,KAAK,mBAAmB,EACxB,KAAK,YAAY,GAClB,MAAM,QAAQ,CAAC;AAEhB,OAAO,EACL,eAAe,IAAI,mBAAmB,EACtC,eAAe,EACf,aAAa,EACb,KAAK,UAAU,GAChB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,eAAe,EACf,YAAY,EACZ,aAAa,EACb,eAAe,EACf,WAAW,EACX,KAAK,YAAY,GAClB,MAAM,WAAW,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { default as AuthService } from "./auth.service";
|
|
2
|
+
export { isPasskeySupported, registerPasskey, authenticateWithPasskey } from "./passkey";
|
|
3
|
+
export { configureApi, getBaseUrl, getDefaultBaseUrl, getStoragePrefix, setBaseUrl, resetBaseUrl, loadServerUrlOverride, getSessionToken, storeSessionToken, clearSessionToken, getAuthMode, getTenant, setTenant, } from "./api-config";
|
|
4
|
+
export { checkPasswordPwned, getPwnedMessage, } from "./hibp";
|
|
5
|
+
export { getCachedPolicy as getCachedHibpPolicy, fetchHibpPolicy, getHibpPolicy, } from "./hibp-cache";
|
|
6
|
+
export { buildFaviconUrl, customIconId, customIconRef, isCustomIconRef, resolveIcon, } from "./favicon";
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAWxD,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAC;AAEzF,OAAO,EACL,YAAY,EACZ,UAAU,EACV,iBAAiB,EACjB,gBAAgB,EAChB,UAAU,EACV,YAAY,EACZ,qBAAqB,EACrB,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,WAAW,EACX,SAAS,EACT,SAAS,GAEV,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,kBAAkB,EAClB,eAAe,GAGhB,MAAM,QAAQ,CAAC;AAEhB,OAAO,EACL,eAAe,IAAI,mBAAmB,EACtC,eAAe,EACf,aAAa,GAEd,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,eAAe,EACf,YAAY,EACZ,aAAa,EACb,eAAe,EACf,WAAW,GAEZ,MAAM,WAAW,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { AuthResponse } from "./auth.service";
|
|
2
|
+
/** Whether this platform can do WebAuthn at all. */
|
|
3
|
+
export declare function isPasskeySupported(): Promise<boolean>;
|
|
4
|
+
/** Register a new passkey for the signed-in user. Triggers the OS biometric. */
|
|
5
|
+
export declare function registerPasskey(label: string): Promise<{
|
|
6
|
+
label: string;
|
|
7
|
+
}>;
|
|
8
|
+
/** Sign in with a passkey. Returns the authenticated session. */
|
|
9
|
+
export declare function authenticateWithPasskey(email?: string): Promise<AuthResponse>;
|
|
10
|
+
//# sourceMappingURL=passkey.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"passkey.d.ts","sourceRoot":"","sources":["../../src/services/passkey.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAmEnD,oDAAoD;AACpD,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,OAAO,CAAC,CAc3D;AAwFD,gFAAgF;AAChF,wBAAsB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAS/E;AAED,iEAAiE;AACjE,wBAAsB,uBAAuB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAYnF"}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
// WebAuthn passkey client (auth-only — no PRF / key-wrapping). Shared across
|
|
2
|
+
// Entropy Softworks Expo apps. Drives the OS authenticator (Face ID / Touch ID
|
|
3
|
+
// / device passkey) and talks to the server's /auth/passkey/* ceremony
|
|
4
|
+
// endpoints.
|
|
5
|
+
//
|
|
6
|
+
// Native (Expo dev build / store build) uses `react-native-passkey`, which
|
|
7
|
+
// consumes/produces the WebAuthn JSON shapes directly (base64url strings). Web
|
|
8
|
+
// uses the DOM `navigator.credentials` API, which needs ArrayBuffers, so the
|
|
9
|
+
// base64url fields are rewritten in and serialized back out.
|
|
10
|
+
//
|
|
11
|
+
// NOTE: passkeys require a native build (not Expo Go) and an associated-domain
|
|
12
|
+
// / asset-link binding the app to the server's WEBAUTHN_RP_ID. `react-native-
|
|
13
|
+
// passkey` is a lazy import so apps/platforms that never call these functions
|
|
14
|
+
// don't need it linked.
|
|
15
|
+
import { Platform } from "react-native";
|
|
16
|
+
import { getBaseUrl, getSessionToken, storeSessionToken } from "./api-config";
|
|
17
|
+
// ── base64url ⇄ ArrayBuffer (web path only) ────────────────────────────────
|
|
18
|
+
function b64urlToBuffer(value) {
|
|
19
|
+
const pad = "=".repeat((4 - (value.length % 4)) % 4);
|
|
20
|
+
const base64 = (value + pad).replace(/-/g, "+").replace(/_/g, "/");
|
|
21
|
+
const bin = atob(base64);
|
|
22
|
+
const bytes = new Uint8Array(bin.length);
|
|
23
|
+
for (let i = 0; i < bin.length; i++) {
|
|
24
|
+
bytes[i] = bin.charCodeAt(i);
|
|
25
|
+
}
|
|
26
|
+
return bytes.buffer;
|
|
27
|
+
}
|
|
28
|
+
function bufferToB64url(buf) {
|
|
29
|
+
const bytes = new Uint8Array(buf);
|
|
30
|
+
let bin = "";
|
|
31
|
+
for (const b of bytes) {
|
|
32
|
+
bin += String.fromCharCode(b);
|
|
33
|
+
}
|
|
34
|
+
return btoa(bin).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
35
|
+
}
|
|
36
|
+
// ── transport ───────────────────────────────────────────────────────────────
|
|
37
|
+
async function post(path, body) {
|
|
38
|
+
const headers = { "Content-Type": "application/json" };
|
|
39
|
+
const token = await getSessionToken();
|
|
40
|
+
if (token) {
|
|
41
|
+
headers.Authorization = `Bearer ${token}`;
|
|
42
|
+
}
|
|
43
|
+
return fetch(`${getBaseUrl()}${path}`, {
|
|
44
|
+
method: "POST",
|
|
45
|
+
headers,
|
|
46
|
+
credentials: "include",
|
|
47
|
+
body: JSON.stringify(body),
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
async function postJson(path, body) {
|
|
51
|
+
const res = await post(path, body);
|
|
52
|
+
if (!res.ok) {
|
|
53
|
+
let message = `request failed (${res.status})`;
|
|
54
|
+
try {
|
|
55
|
+
const data = await res.json();
|
|
56
|
+
message = data?.error?.message ?? message;
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
// non-JSON error body; keep the status message
|
|
60
|
+
}
|
|
61
|
+
throw new Error(message);
|
|
62
|
+
}
|
|
63
|
+
return (await res.json());
|
|
64
|
+
}
|
|
65
|
+
// react-native-passkey is a native module; import lazily so the web bundle and
|
|
66
|
+
// type-checking don't hard-depend on it being linked.
|
|
67
|
+
async function nativePasskey() {
|
|
68
|
+
const mod = await import("react-native-passkey");
|
|
69
|
+
return mod.Passkey;
|
|
70
|
+
}
|
|
71
|
+
/** Whether this platform can do WebAuthn at all. */
|
|
72
|
+
export async function isPasskeySupported() {
|
|
73
|
+
if (Platform.OS === "web") {
|
|
74
|
+
return (typeof globalThis !== "undefined" &&
|
|
75
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
76
|
+
!!globalThis.PublicKeyCredential);
|
|
77
|
+
}
|
|
78
|
+
try {
|
|
79
|
+
const Passkey = await nativePasskey();
|
|
80
|
+
return Boolean(Passkey.isSupported?.());
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/** The inner `publicKey` object webauthn-rs wraps its options in. */
|
|
87
|
+
function inner(options) {
|
|
88
|
+
const pk = options.publicKey;
|
|
89
|
+
return (pk && typeof pk === "object" ? pk : options);
|
|
90
|
+
}
|
|
91
|
+
async function createCredential(options) {
|
|
92
|
+
if (Platform.OS === "web") {
|
|
93
|
+
const pk = { ...inner(options) };
|
|
94
|
+
pk.challenge = b64urlToBuffer(pk.challenge);
|
|
95
|
+
const user = pk.user;
|
|
96
|
+
if (user && typeof user.id === "string") {
|
|
97
|
+
pk.user = { ...user, id: b64urlToBuffer(user.id) };
|
|
98
|
+
}
|
|
99
|
+
if (Array.isArray(pk.excludeCredentials)) {
|
|
100
|
+
pk.excludeCredentials = pk.excludeCredentials.map((c) => ({
|
|
101
|
+
...c,
|
|
102
|
+
id: typeof c.id === "string" ? b64urlToBuffer(c.id) : c.id,
|
|
103
|
+
}));
|
|
104
|
+
}
|
|
105
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
106
|
+
const cred = (await navigator.credentials.create({ publicKey: pk }));
|
|
107
|
+
return serializeWebCredential(cred);
|
|
108
|
+
}
|
|
109
|
+
const Passkey = await nativePasskey();
|
|
110
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
111
|
+
return Passkey.create(inner(options));
|
|
112
|
+
}
|
|
113
|
+
async function getCredential(options) {
|
|
114
|
+
if (Platform.OS === "web") {
|
|
115
|
+
const pk = { ...inner(options) };
|
|
116
|
+
pk.challenge = b64urlToBuffer(pk.challenge);
|
|
117
|
+
if (Array.isArray(pk.allowCredentials)) {
|
|
118
|
+
pk.allowCredentials = pk.allowCredentials.map((c) => ({
|
|
119
|
+
...c,
|
|
120
|
+
id: typeof c.id === "string" ? b64urlToBuffer(c.id) : c.id,
|
|
121
|
+
}));
|
|
122
|
+
}
|
|
123
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
124
|
+
const cred = (await navigator.credentials.get({ publicKey: pk }));
|
|
125
|
+
return serializeWebCredential(cred);
|
|
126
|
+
}
|
|
127
|
+
const Passkey = await nativePasskey();
|
|
128
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
129
|
+
return Passkey.get(inner(options));
|
|
130
|
+
}
|
|
131
|
+
// Convert a DOM PublicKeyCredential into the base64url JSON the server expects.
|
|
132
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
133
|
+
function serializeWebCredential(cred) {
|
|
134
|
+
const r = cred.response;
|
|
135
|
+
const out = {
|
|
136
|
+
id: cred.id,
|
|
137
|
+
rawId: bufferToB64url(cred.rawId),
|
|
138
|
+
type: cred.type,
|
|
139
|
+
response: {},
|
|
140
|
+
};
|
|
141
|
+
const resp = out.response;
|
|
142
|
+
if (r.attestationObject) {
|
|
143
|
+
resp.attestationObject = bufferToB64url(r.attestationObject);
|
|
144
|
+
}
|
|
145
|
+
if (r.clientDataJSON) {
|
|
146
|
+
resp.clientDataJSON = bufferToB64url(r.clientDataJSON);
|
|
147
|
+
}
|
|
148
|
+
if (r.authenticatorData) {
|
|
149
|
+
resp.authenticatorData = bufferToB64url(r.authenticatorData);
|
|
150
|
+
}
|
|
151
|
+
if (r.signature) {
|
|
152
|
+
resp.signature = bufferToB64url(r.signature);
|
|
153
|
+
}
|
|
154
|
+
if (r.userHandle) {
|
|
155
|
+
resp.userHandle = bufferToB64url(r.userHandle);
|
|
156
|
+
}
|
|
157
|
+
return out;
|
|
158
|
+
}
|
|
159
|
+
function clientExtensionResults(cred) {
|
|
160
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
161
|
+
const c = cred;
|
|
162
|
+
if (typeof c?.getClientExtensionResults === "function") {
|
|
163
|
+
return c.getClientExtensionResults();
|
|
164
|
+
}
|
|
165
|
+
return c?.clientExtensionResults;
|
|
166
|
+
}
|
|
167
|
+
/** Register a new passkey for the signed-in user. Triggers the OS biometric. */
|
|
168
|
+
export async function registerPasskey(label) {
|
|
169
|
+
const begin = await postJson("/auth/passkey/register/begin", { label });
|
|
170
|
+
const credential = await createCredential(begin.publickeyOptions);
|
|
171
|
+
return postJson("/auth/passkey/register/finish", {
|
|
172
|
+
ceremonyId: begin.ceremonyId,
|
|
173
|
+
label,
|
|
174
|
+
credential,
|
|
175
|
+
clientExtensionResults: clientExtensionResults(credential),
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
/** Sign in with a passkey. Returns the authenticated session. */
|
|
179
|
+
export async function authenticateWithPasskey(email) {
|
|
180
|
+
const begin = await postJson("/auth/passkey/authenticate/begin", { email });
|
|
181
|
+
const credential = await getCredential(begin.publickeyOptions);
|
|
182
|
+
const auth = await postJson("/auth/passkey/authenticate/finish", {
|
|
183
|
+
ceremonyId: begin.ceremonyId,
|
|
184
|
+
credential,
|
|
185
|
+
clientExtensionResults: clientExtensionResults(credential),
|
|
186
|
+
});
|
|
187
|
+
if (auth.session_token) {
|
|
188
|
+
await storeSessionToken(auth.session_token);
|
|
189
|
+
}
|
|
190
|
+
return auth;
|
|
191
|
+
}
|
|
192
|
+
//# sourceMappingURL=passkey.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"passkey.js","sourceRoot":"","sources":["../../src/services/passkey.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-platform authed `fetch` for the entropy-ui auth flows.
|
|
3
|
+
*
|
|
4
|
+
* **Web**: HttpOnly session cookie (auto-attached, used in same-origin /
|
|
5
|
+
* production) + `X-CSRF-Token` on writes. Also attaches a `Bearer` token when
|
|
6
|
+
* one is stored (sessionStorage) — needed for split-origin dev where the Lax
|
|
7
|
+
* cookie can't ride cross-origin XHR.
|
|
8
|
+
* **Native**: Bearer token loaded from SecureStore.
|
|
9
|
+
*/
|
|
10
|
+
export declare function apiFetch(path: string, init?: RequestInit, timeoutMs?: number): Promise<Response>;
|
|
11
|
+
//# sourceMappingURL=api-fetch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-fetch.d.ts","sourceRoot":"","sources":["../../src/utils/api-fetch.ts"],"names":[],"mappings":"AAuBA;;;;;;;;GAQG;AACH,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,WAAgB,EACtB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,QAAQ,CAAC,CAwBnB"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { Platform } from "react-native";
|
|
2
|
+
import { fetchWithTimeout } from "./fetch";
|
|
3
|
+
import { getBaseUrl, getSessionToken } from "../services/api-config";
|
|
4
|
+
const SAFE_METHODS = new Set(["GET", "HEAD", "OPTIONS"]);
|
|
5
|
+
const CSRF_COOKIE_NAME = "csrf_token";
|
|
6
|
+
const CSRF_HEADER_NAME = "X-CSRF-Token";
|
|
7
|
+
function readCookie(name) {
|
|
8
|
+
if (typeof document === "undefined") {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
const prefix = `${name}=`;
|
|
12
|
+
for (const part of document.cookie.split(";")) {
|
|
13
|
+
const trimmed = part.trim();
|
|
14
|
+
if (trimmed.startsWith(prefix)) {
|
|
15
|
+
return decodeURIComponent(trimmed.slice(prefix.length));
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Cross-platform authed `fetch` for the entropy-ui auth flows.
|
|
22
|
+
*
|
|
23
|
+
* **Web**: HttpOnly session cookie (auto-attached, used in same-origin /
|
|
24
|
+
* production) + `X-CSRF-Token` on writes. Also attaches a `Bearer` token when
|
|
25
|
+
* one is stored (sessionStorage) — needed for split-origin dev where the Lax
|
|
26
|
+
* cookie can't ride cross-origin XHR.
|
|
27
|
+
* **Native**: Bearer token loaded from SecureStore.
|
|
28
|
+
*/
|
|
29
|
+
export async function apiFetch(path, init = {}, timeoutMs) {
|
|
30
|
+
const url = `${getBaseUrl()}${path}`;
|
|
31
|
+
const method = (init.method ?? "GET").toUpperCase();
|
|
32
|
+
const headers = new Headers(init.headers);
|
|
33
|
+
if (Platform.OS === "web") {
|
|
34
|
+
if (!SAFE_METHODS.has(method)) {
|
|
35
|
+
const csrf = readCookie(CSRF_COOKIE_NAME);
|
|
36
|
+
if (csrf) {
|
|
37
|
+
headers.set(CSRF_HEADER_NAME, csrf);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
const webToken = await getSessionToken();
|
|
41
|
+
if (webToken && !headers.has("Authorization")) {
|
|
42
|
+
headers.set("Authorization", `Bearer ${webToken}`);
|
|
43
|
+
}
|
|
44
|
+
return fetchWithTimeout(url, { ...init, headers, credentials: "include" }, timeoutMs);
|
|
45
|
+
}
|
|
46
|
+
const token = await getSessionToken();
|
|
47
|
+
if (token) {
|
|
48
|
+
headers.set("Authorization", `Bearer ${token}`);
|
|
49
|
+
}
|
|
50
|
+
return fetchWithTimeout(url, { ...init, headers }, timeoutMs);
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=api-fetch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-fetch.js","sourceRoot":"","sources":["../../src/utils/api-fetch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAErE,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;AAEzD,MAAM,gBAAgB,GAAG,YAAY,CAAC;AACtC,MAAM,gBAAgB,GAAG,cAAc,CAAC;AAExC,SAAS,UAAU,CAAC,IAAY;IAC9B,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE,CAAC;QACpC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC;IAC1B,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YAC/B,OAAO,kBAAkB,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,IAAY,EACZ,OAAoB,EAAE,EACtB,SAAkB;IAElB,MAAM,GAAG,GAAG,GAAG,UAAU,EAAE,GAAG,IAAI,EAAE,CAAC;IACrC,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;IACpD,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAE1C,IAAI,QAAQ,CAAC,EAAE,KAAK,KAAK,EAAE,CAAC;QAC1B,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YAC9B,MAAM,IAAI,GAAG,UAAU,CAAC,gBAAgB,CAAC,CAAC;YAC1C,IAAI,IAAI,EAAE,CAAC;gBACT,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC;YACtC,CAAC;QACH,CAAC;QACD,MAAM,QAAQ,GAAG,MAAM,eAAe,EAAE,CAAC;QACzC,IAAI,QAAQ,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,EAAE,CAAC;YAC9C,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,UAAU,QAAQ,EAAE,CAAC,CAAC;QACrD,CAAC;QACD,OAAO,gBAAgB,CAAC,GAAG,EAAE,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,EAAE,SAAS,CAAC,CAAC;IACxF,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,eAAe,EAAE,CAAC;IACtC,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,UAAU,KAAK,EAAE,CAAC,CAAC;IAClD,CAAC;IACD,OAAO,gBAAgB,CAAC,GAAG,EAAE,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;AAChE,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Centralised copy-to-clipboard with a single, module-scope auto-clear
|
|
3
|
+
* timer.
|
|
4
|
+
*
|
|
5
|
+
* Why module scope: tying the timer to a React component (via `useRef`)
|
|
6
|
+
* means it gets cancelled when the screen unmounts — which happens
|
|
7
|
+
* routinely (auto-lock on tab-switch, navigation to another item). The
|
|
8
|
+
* user's just-completed copy then either gets wiped immediately
|
|
9
|
+
* (component cleanup runs `setStringAsync("")`) or sits indefinitely.
|
|
10
|
+
*
|
|
11
|
+
* Behaviour:
|
|
12
|
+
* * `copyToClipboard(value)` writes the value, returns `true` on
|
|
13
|
+
* success.
|
|
14
|
+
* * On success, schedules a 30-second auto-wipe.
|
|
15
|
+
* * Subsequent copies cancel the prior timer and reschedule, so the
|
|
16
|
+
* wipe is always 30 seconds from the *last* copy regardless of
|
|
17
|
+
* which screen issued it.
|
|
18
|
+
*
|
|
19
|
+
* Limitation: we don't read the clipboard back (would require the
|
|
20
|
+
* clipboard-read permission), so if the user copies from another app
|
|
21
|
+
* between our copy and the auto-clear firing, we'll still wipe their
|
|
22
|
+
* value at the 30s mark. Acceptable trade-off for a password manager.
|
|
23
|
+
*/
|
|
24
|
+
/** Write `value` to the clipboard. Returns `true` if the write succeeded. */
|
|
25
|
+
export declare function copyToClipboard(value: string): Promise<boolean>;
|
|
26
|
+
/**
|
|
27
|
+
* Wipe the clipboard now (e.g. on explicit logout). Cancels the pending
|
|
28
|
+
* auto-clear so we don't fire a redundant wipe later.
|
|
29
|
+
*/
|
|
30
|
+
export declare function clearClipboardNow(): Promise<void>;
|
|
31
|
+
//# sourceMappingURL=clipboard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clipboard.d.ts","sourceRoot":"","sources":["../../src/utils/clipboard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAQH,6EAA6E;AAC7E,wBAAsB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAqBrE;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAUvD"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Centralised copy-to-clipboard with a single, module-scope auto-clear
|
|
3
|
+
* timer.
|
|
4
|
+
*
|
|
5
|
+
* Why module scope: tying the timer to a React component (via `useRef`)
|
|
6
|
+
* means it gets cancelled when the screen unmounts — which happens
|
|
7
|
+
* routinely (auto-lock on tab-switch, navigation to another item). The
|
|
8
|
+
* user's just-completed copy then either gets wiped immediately
|
|
9
|
+
* (component cleanup runs `setStringAsync("")`) or sits indefinitely.
|
|
10
|
+
*
|
|
11
|
+
* Behaviour:
|
|
12
|
+
* * `copyToClipboard(value)` writes the value, returns `true` on
|
|
13
|
+
* success.
|
|
14
|
+
* * On success, schedules a 30-second auto-wipe.
|
|
15
|
+
* * Subsequent copies cancel the prior timer and reschedule, so the
|
|
16
|
+
* wipe is always 30 seconds from the *last* copy regardless of
|
|
17
|
+
* which screen issued it.
|
|
18
|
+
*
|
|
19
|
+
* Limitation: we don't read the clipboard back (would require the
|
|
20
|
+
* clipboard-read permission), so if the user copies from another app
|
|
21
|
+
* between our copy and the auto-clear firing, we'll still wipe their
|
|
22
|
+
* value at the 30s mark. Acceptable trade-off for a password manager.
|
|
23
|
+
*/
|
|
24
|
+
import * as Clipboard from "expo-clipboard";
|
|
25
|
+
const AUTO_CLEAR_MS = 30_000;
|
|
26
|
+
let clearTimer = null;
|
|
27
|
+
/** Write `value` to the clipboard. Returns `true` if the write succeeded. */
|
|
28
|
+
export async function copyToClipboard(value) {
|
|
29
|
+
let ok;
|
|
30
|
+
try {
|
|
31
|
+
ok = await Clipboard.setStringAsync(value);
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
ok = false;
|
|
35
|
+
}
|
|
36
|
+
if (!ok) {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
if (clearTimer !== null) {
|
|
40
|
+
clearTimeout(clearTimer);
|
|
41
|
+
}
|
|
42
|
+
clearTimer = setTimeout(() => {
|
|
43
|
+
clearTimer = null;
|
|
44
|
+
void Clipboard.setStringAsync("").catch(() => {
|
|
45
|
+
// Best-effort.
|
|
46
|
+
});
|
|
47
|
+
}, AUTO_CLEAR_MS);
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Wipe the clipboard now (e.g. on explicit logout). Cancels the pending
|
|
52
|
+
* auto-clear so we don't fire a redundant wipe later.
|
|
53
|
+
*/
|
|
54
|
+
export async function clearClipboardNow() {
|
|
55
|
+
if (clearTimer !== null) {
|
|
56
|
+
clearTimeout(clearTimer);
|
|
57
|
+
clearTimer = null;
|
|
58
|
+
}
|
|
59
|
+
try {
|
|
60
|
+
await Clipboard.setStringAsync("");
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
// Best-effort.
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=clipboard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clipboard.js","sourceRoot":"","sources":["../../src/utils/clipboard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAC;AAE5C,MAAM,aAAa,GAAG,MAAM,CAAC;AAE7B,IAAI,UAAU,GAAyC,IAAI,CAAC;AAE5D,6EAA6E;AAC7E,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,KAAa;IACjD,IAAI,EAAW,CAAC;IAChB,IAAI,CAAC;QACH,EAAE,GAAG,MAAM,SAAS,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IAC7C,CAAC;IAAC,MAAM,CAAC;QACP,EAAE,GAAG,KAAK,CAAC;IACb,CAAC;IACD,IAAI,CAAC,EAAE,EAAE,CAAC;QACR,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;QACxB,YAAY,CAAC,UAAU,CAAC,CAAC;IAC3B,CAAC;IACD,UAAU,GAAG,UAAU,CAAC,GAAG,EAAE;QAC3B,UAAU,GAAG,IAAI,CAAC;QAClB,KAAK,SAAS,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;YAC3C,eAAe;QACjB,CAAC,CAAC,CAAC;IACL,CAAC,EAAE,aAAa,CAAC,CAAC;IAClB,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB;IACrC,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;QACxB,YAAY,CAAC,UAAU,CAAC,CAAC;QACzB,UAAU,GAAG,IAAI,CAAC;IACpB,CAAC;IACD,IAAI,CAAC;QACH,MAAM,SAAS,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,eAAe;IACjB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type ClassValue } from "clsx";
|
|
2
|
+
/**
|
|
3
|
+
* Combines class names using clsx and merges Tailwind CSS classes intelligently.
|
|
4
|
+
*
|
|
5
|
+
* @param inputs - Class values to combine
|
|
6
|
+
* @returns Merged class string
|
|
7
|
+
*/
|
|
8
|
+
export declare function cn(...inputs: ClassValue[]): string;
|
|
9
|
+
//# sourceMappingURL=cn.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cn.d.ts","sourceRoot":"","sources":["../../src/utils/cn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,UAAU,EAAE,MAAM,MAAM,CAAC;AAG7C;;;;;GAKG;AACH,wBAAgB,EAAE,CAAC,GAAG,MAAM,EAAE,UAAU,EAAE,UAEzC"}
|
package/lib/utils/cn.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { clsx } from "clsx";
|
|
2
|
+
import { twMerge } from "tailwind-merge";
|
|
3
|
+
/**
|
|
4
|
+
* Combines class names using clsx and merges Tailwind CSS classes intelligently.
|
|
5
|
+
*
|
|
6
|
+
* @param inputs - Class values to combine
|
|
7
|
+
* @returns Merged class string
|
|
8
|
+
*/
|
|
9
|
+
export function cn(...inputs) {
|
|
10
|
+
return twMerge(clsx(inputs));
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=cn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cn.js","sourceRoot":"","sources":["../../src/utils/cn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAmB,MAAM,MAAM,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAEzC;;;;;GAKG;AACH,MAAM,UAAU,EAAE,CAAC,GAAG,MAAoB;IACxC,OAAO,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;AAC/B,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Debounce a function. The returned function has a `.cancel()` method
|
|
3
|
+
* so a pending invocation can be cleared in a `useEffect` cleanup to
|
|
4
|
+
* avoid a setState-after-unmount on the trailing call.
|
|
5
|
+
*
|
|
6
|
+
* Intentionally a tiny, no-dependency implementation — `lodash.debounce`
|
|
7
|
+
* pulls 200kB of lodash with it; this is 15 lines, type-safe, and tree-
|
|
8
|
+
* shake-friendly.
|
|
9
|
+
*/
|
|
10
|
+
export declare function debounce<T extends (...args: Parameters<T>) => void>(func: T, wait: number): ((...args: Parameters<T>) => void) & {
|
|
11
|
+
cancel: () => void;
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=debounce.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debounce.d.ts","sourceRoot":"","sources":["../../src/utils/debounce.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,IAAI,EACjE,IAAI,EAAE,CAAC,EACP,IAAI,EAAE,MAAM,GACX,CAAC,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,GAAG;IAAE,MAAM,EAAE,MAAM,IAAI,CAAA;CAAE,CAoB7D"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Debounce a function. The returned function has a `.cancel()` method
|
|
3
|
+
* so a pending invocation can be cleared in a `useEffect` cleanup to
|
|
4
|
+
* avoid a setState-after-unmount on the trailing call.
|
|
5
|
+
*
|
|
6
|
+
* Intentionally a tiny, no-dependency implementation — `lodash.debounce`
|
|
7
|
+
* pulls 200kB of lodash with it; this is 15 lines, type-safe, and tree-
|
|
8
|
+
* shake-friendly.
|
|
9
|
+
*/
|
|
10
|
+
export function debounce(func, wait) {
|
|
11
|
+
let timeout = null;
|
|
12
|
+
const debounced = (...args) => {
|
|
13
|
+
if (timeout) {
|
|
14
|
+
clearTimeout(timeout);
|
|
15
|
+
}
|
|
16
|
+
timeout = setTimeout(() => {
|
|
17
|
+
func(...args);
|
|
18
|
+
}, wait);
|
|
19
|
+
};
|
|
20
|
+
debounced.cancel = () => {
|
|
21
|
+
if (timeout) {
|
|
22
|
+
clearTimeout(timeout);
|
|
23
|
+
timeout = null;
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
return debounced;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=debounce.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debounce.js","sourceRoot":"","sources":["../../src/utils/debounce.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,UAAU,QAAQ,CACtB,IAAO,EACP,IAAY;IAEZ,IAAI,OAAO,GAAyC,IAAI,CAAC;IAEzD,MAAM,SAAS,GAAG,CAAC,GAAG,IAAmB,EAAE,EAAE;QAC3C,IAAI,OAAO,EAAE,CAAC;YACZ,YAAY,CAAC,OAAO,CAAC,CAAC;QACxB,CAAC;QACD,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;YACxB,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;QAChB,CAAC,EAAE,IAAI,CAAC,CAAC;IACX,CAAC,CAAC;IAEF,SAAS,CAAC,MAAM,GAAG,GAAG,EAAE;QACtB,IAAI,OAAO,EAAE,CAAC;YACZ,YAAY,CAAC,OAAO,CAAC,CAAC;YACtB,OAAO,GAAG,IAAI,CAAC;QACjB,CAAC;IACH,CAAC,CAAC;IAEF,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extract a human-readable message from an unknown error value.
|
|
3
|
+
*
|
|
4
|
+
* Use this in every `catch (e: unknown)` block instead of accessing
|
|
5
|
+
* `e?.message` directly — TypeScript's `unknown` type prevents property
|
|
6
|
+
* access without a type guard.
|
|
7
|
+
*/
|
|
8
|
+
export declare function getErrorMessage(e: unknown, fallback?: string): string;
|
|
9
|
+
//# sourceMappingURL=error.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../src/utils/error.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,OAAO,EAAE,QAAQ,SAAiC,GAAG,MAAM,CAE7F"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extract a human-readable message from an unknown error value.
|
|
3
|
+
*
|
|
4
|
+
* Use this in every `catch (e: unknown)` block instead of accessing
|
|
5
|
+
* `e?.message` directly — TypeScript's `unknown` type prevents property
|
|
6
|
+
* access without a type guard.
|
|
7
|
+
*/
|
|
8
|
+
export function getErrorMessage(e, fallback = "An unexpected error occurred") {
|
|
9
|
+
return e instanceof Error ? e.message : fallback;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error.js","sourceRoot":"","sources":["../../src/utils/error.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,CAAU,EAAE,QAAQ,GAAG,8BAA8B;IACnF,OAAO,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC;AACnD,CAAC"}
|