@stokr/components-library 3.0.16 → 3.0.17
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/README.md +261 -262
- package/dist/analytics/index.js +180 -0
- package/dist/api/auth.js +15 -0
- package/dist/api/fetchData.js +27 -0
- package/dist/api/fetchDataPublic.js +19 -0
- package/dist/auth/index.js +32 -0
- package/dist/components/2FA/Connect2FA.js +55 -0
- package/dist/components/2FA/EnterCode.js +63 -0
- package/dist/components/2FA/InstallAuthApp.js +64 -0
- package/dist/components/2FA/ResetCode.js +33 -0
- package/dist/components/2FA/Sucess2FA.js +51 -0
- package/dist/components/2FA/disable-2fa-flow.js +91 -0
- package/dist/components/2FA/enable-2fa-flow.js +137 -0
- package/dist/components/2FA/login-with-otp-flow.js +206 -0
- package/dist/components/2FA/main-flow.js +217 -0
- package/dist/components/AccountBalance/AccountBalance.js +35 -0
- package/dist/components/AccountBalance/AccountBalance.styles.js +48 -0
- package/dist/components/AdminDashboard/Table/ReactTable.js +266 -0
- package/dist/components/AdminDashboard/Table/ReactTableWrapper.js +65 -0
- package/dist/components/AdminDashboard/Table/Table.js +123 -0
- package/dist/components/AdminDashboard/Table/Table.styles.js +263 -0
- package/dist/components/AgreementItem/AgreementItem.js +39 -0
- package/dist/components/AgreementItem/AgreementItem.styles.js +32 -0
- package/dist/components/BackButton/BackButton.js +34 -0
- package/dist/components/BackButton/BackButton.styles.js +123 -0
- package/dist/components/Background/Background.js +45 -0
- package/dist/components/Background/Background.styles.js +119 -0
- package/dist/components/BasicTable/BasicTable.js +25 -0
- package/dist/components/BasicTable/BasicTable.styles.js +76 -0
- package/dist/components/BlogPost/BlogPost.js +98 -0
- package/dist/components/BlogPost/BlogPost.styles.js +230 -0
- package/dist/components/Button/Button.styles.js +207 -0
- package/dist/components/ButtonContainer/ButtonContainer.styles.js +51 -0
- package/dist/components/CapitalRaisedSummary/CaptialRaisedSummary.js +18 -0
- package/dist/components/CapitalRaisedSummary/CaptialRaisedSummary.styles.js +41 -0
- package/dist/components/Card/Card.styles.js +97 -0
- package/dist/components/ChartLegend/ChartLegend.js +62 -0
- package/dist/components/ChartLegend/ChartLegend.styles.js +133 -0
- package/dist/components/Checkbox/Checkbox.js +80 -0
- package/dist/components/Checkbox/Checkbox.styles.js +133 -0
- package/dist/components/Checklist/ChecklistCard.js +71 -0
- package/dist/components/Checklist/ChecklistCard.styles.js +82 -0
- package/dist/components/Chips/Chip.js +23 -0
- package/dist/components/Chips/Chip.styles.js +72 -0
- package/dist/components/Chips/ChipWrapper.js +50 -0
- package/dist/components/ComponentScroll/ComponentScroll.js +70 -0
- package/dist/components/ComponentScroll/ComponentScroll.styles.js +127 -0
- package/dist/components/ComponentWrapper/ComponentWrapper.styles.js +165 -0
- package/dist/components/ConfirmModal/ConfirmModal.js +187 -0
- package/dist/components/ConfirmModal/ConfirmModal.styles.js +44 -0
- package/dist/components/CryptoAddress/ComponentWrap.js +16 -0
- package/dist/components/CryptoAddress/CryptoAddress.js +151 -0
- package/dist/components/CryptoAddress/CryptoAddress.styles.js +443 -0
- package/dist/components/CryptoAddress/RadioWrap.js +47 -0
- package/dist/components/CryptoAddressDetails/CryptoAddressDetails.js +34 -0
- package/dist/components/CryptoAddressDetails/CryptoAddressDetails.styles.js +125 -0
- package/dist/components/CryptoAddressWrapper/CryptoAddressWrapper.js +25 -0
- package/dist/components/CryptoAddressWrapper/CryptoAddressWrapper.styles.js +111 -0
- package/dist/components/DoubleButton/DoubleButton.styles.js +27 -0
- package/dist/components/ErrorMessage/ErrorMessage.styles.js +9 -0
- package/dist/components/FAQ/FAQ.js +73 -0
- package/dist/components/FAQ/FAQ.styles.js +128 -0
- package/dist/components/Footer/Footer.js +55 -0
- package/dist/components/Footer/Footer.styles.js +256 -0
- package/dist/components/Footer/FooterLayout.js +145 -0
- package/dist/components/Footer/FooterMenu.js +100 -0
- package/dist/components/Footer/FooterMenu.styles.js +321 -0
- package/dist/components/ForgotPasswordModal/ForgotPasswordModal.js +100 -0
- package/dist/components/Form/Form.js +21 -0
- package/dist/components/Form/Form.styles.js +72 -0
- package/dist/components/Grid/Grid.styles.js +212 -0
- package/dist/components/Header/Header.js +425 -0
- package/dist/components/Header/Header.styles.js +567 -0
- package/dist/components/HeroBlock/HeroVideoBlock.js +105 -0
- package/dist/components/Icon/Icon.style.js +92 -0
- package/dist/components/Icon/Icon2.js +12 -0
- package/dist/components/InfoIcon/InfoIcon.js +62 -0
- package/dist/components/InfoIcon/InfoIcon.styles.js +64 -0
- package/dist/components/Input/DatePickerInput.js +139 -0
- package/dist/components/Input/DatePickerInput.styles.js +165 -0
- package/dist/components/Input/Input.js +108 -0
- package/dist/components/Input/Input.styles.js +154 -0
- package/dist/components/Input/InputPassword.js +122 -0
- package/dist/components/Input/InputPassword.styles.js +166 -0
- package/dist/components/Input/InputUsername.js +92 -0
- package/dist/components/Input/InputWithButton.js +53 -0
- package/dist/components/Input/InputWithButton.styles.js +57 -0
- package/dist/components/Input/MultiSelect.js +306 -0
- package/dist/components/Input/OtpInput.js +70 -0
- package/dist/components/Input/RangeInput.js +80 -0
- package/dist/components/Input/RangeInput.styles.js +129 -0
- package/dist/components/Input/SearchInput.js +68 -0
- package/dist/components/Input/SearchInput.styles.js +92 -0
- package/dist/components/Input/Select.js +151 -0
- package/dist/components/Input/Select.styles.js +148 -0
- package/dist/components/Input/TableFilterDropdown.js +247 -0
- package/dist/components/Input/Textarea.js +51 -0
- package/dist/components/Input/Textarea.styles.js +62 -0
- package/dist/components/InvestCalculator/InvestCalculator.js +283 -0
- package/dist/components/InvestCalculator/InvestCalculator.styles.js +94 -0
- package/dist/components/InvestmentStat/InvestmentStat.js +24 -0
- package/dist/components/InvestmentStat/InvestmentStat.styles.js +62 -0
- package/dist/components/LatestUpdate/LatestUpdate.js +24 -0
- package/dist/components/LatestUpdate/LatestUpdate.styles.js +90 -0
- package/dist/components/Layout/Layout.js +69 -0
- package/dist/components/LearnMoreCarousel/LearnMoreCarousel.js +32 -0
- package/dist/components/LearnMoreCarousel/LearnMoreCarousel.styles.js +208 -0
- package/dist/components/LearnMorePage/LearnMore.js +190 -0
- package/dist/components/LearnMorePage/LearnMore.propTypes.js +20 -0
- package/dist/components/LearnMorePage/LearnMore.shared.styles.js +56 -0
- package/dist/components/LearnMorePage/LearnMore.styles.js +276 -0
- package/dist/components/LearnMorePage/LearnMoreExampleObject.js +120 -0
- package/dist/components/LearnMorePage/LearnMoreItem.js +57 -0
- package/dist/components/LearnMorePage/LearnMoreItem.styles.js +234 -0
- package/dist/components/LearnMoreSection/LearnMore.js +138 -0
- package/dist/components/LearnMoreSection/LearnMore.styles.js +147 -0
- package/dist/components/LearnMoreSection/LearnMoreItem.js +33 -0
- package/dist/components/LearnMoreSection/LearnMoreItem.styles.js +60 -0
- package/dist/components/LoginModal/LoginModal.js +142 -0
- package/dist/components/MainMenu/DynamicMainMenu.js +38 -0
- package/dist/components/MainMenu/MainMenu.js +210 -0
- package/dist/components/MainMenu/MainMenu.styles.js +362 -0
- package/dist/components/MenuNav/MenuNav.styles.js +66 -0
- package/dist/components/Modal/Modal.js +119 -0
- package/dist/components/Modal/Modal.styles.js +450 -0
- package/dist/components/Modal/NewVentureModal/NewVentureModal.js +262 -0
- package/dist/components/Modal/PaymentModal.js +149 -0
- package/dist/components/Modal/SideModal.js +89 -0
- package/dist/components/Modal/SideModal.styles.js +55 -0
- package/dist/components/Modal/SuccessModal/SuccessModal.js +170 -0
- package/dist/components/Modal/SuccessModal/SuccessModal.styles.js +53 -0
- package/dist/components/MultiProgressBar/MultiProgressBar.js +30 -0
- package/dist/components/MultiProgressBar/MultiProgressBar.styles.js +105 -0
- package/dist/components/Newsletter/Newsletter.js +122 -0
- package/dist/components/Newsletter/Newsletter.styles.js +186 -0
- package/dist/components/NotificationCounter/NotificationCounter.styles.js +38 -0
- package/dist/components/Number/Number.js +50 -0
- package/dist/components/Number/Number.styles.js +23 -0
- package/dist/components/PageTransition/PageTransition.js +51 -0
- package/dist/components/Pagination/Pagination.js +58 -0
- package/dist/components/Pagination/Pagination.styles.js +59 -0
- package/dist/components/Pagination/PaginationControls.js +113 -0
- package/dist/components/Pagination/usePagination.js +40 -0
- package/dist/components/Payment/PaymentDetailsCard.js +224 -0
- package/dist/components/Payment/PaymentDisplay.js +199 -0
- package/dist/components/Payment/TimerComponent.js +92 -0
- package/dist/components/Process/Process.styles.js +84 -0
- package/dist/components/ProfileBadge/ProfileBadge.js +35 -0
- package/dist/components/ProfileBadge/ProfileBadge.styles.js +53 -0
- package/dist/components/ProfileBox/ProfileBox.js +27 -0
- package/dist/components/ProfileBox/ProfileBox.styles.js +67 -0
- package/dist/components/ProfileStat/ProfileStat.js +29 -0
- package/dist/components/ProfileStat/ProfileStat.styles.js +90 -0
- package/dist/components/QRCode/QRCode.js +51 -0
- package/dist/components/Radio/Radio.js +51 -0
- package/dist/components/Radio/Radio.styles.js +100 -0
- package/dist/components/RefreshButton/RefreshButton.js +21 -0
- package/dist/components/RefreshButton/RefreshButton.styles.js +64 -0
- package/dist/components/RegisterConfirmModal/RegisterConfirmModal.js +65 -0
- package/dist/components/RegisterConfirmModal/RegisterConfirmModal.styles.js +20 -0
- package/dist/components/RegisterModal/RegisterModal.js +248 -0
- package/dist/components/RequestDataBox/RequestDataBox.js +21 -0
- package/dist/components/RequestDataBox/RequestDataBox.styles.js +43 -0
- package/dist/components/ResetConfirmModal/ResetConfirmModal.js +44 -0
- package/dist/components/ResetConfirmModal/ResetConfirmModal.styles.js +41 -0
- package/dist/components/ResetPasswordModal/ResetPasswordModal.js +134 -0
- package/dist/components/SEO/SEO.js +66 -0
- package/dist/components/SectionTitle/SectionTitle.styles.js +26 -0
- package/dist/components/SideLine/SideLine.js +7 -0
- package/dist/components/SideLine/SideLine.styles.js +33 -0
- package/dist/components/Slider/Slider.js +31 -0
- package/dist/components/Slider/Slider.styles.js +120 -0
- package/dist/components/Snackbar/Snackbar.js +111 -0
- package/dist/components/Snackbar/Snackbar.styles.js +230 -0
- package/dist/components/Snackbar/SnackbarProvider.js +66 -0
- package/dist/components/Snackbar/useSnackbar.js +12 -0
- package/dist/components/SpanButton/SpanButton.styles.js +19 -0
- package/dist/components/StatusBadge/StatusBadge.styles.js +18 -0
- package/dist/components/StatusTag/StatusTag.js +105 -0
- package/dist/components/StatusTag/StatusTag.styles.js +88 -0
- package/dist/components/StepController/StepController.js +86 -0
- package/dist/components/StepController/StepController.styles.js +33 -0
- package/dist/components/StepController/StepControllerContext.js +65 -0
- package/dist/components/StepController/StepControllerProgress.js +37 -0
- package/dist/components/StepsProgress/StepIndicator.js +40 -0
- package/dist/components/StepsProgress/StepIndicator.styles.js +69 -0
- package/dist/components/StepsProgress/StepsProgress.js +67 -0
- package/dist/components/StepsProgress/StepsProgress.styles.js +105 -0
- package/dist/components/StokrLoader/StokrLoader.js +111 -0
- package/dist/components/StokrLoader/media.js +23 -0
- package/dist/components/SvgIcons/AdminBadgeSvg.js +27 -0
- package/dist/components/SvgIcons/CameraSvg.js +31 -0
- package/dist/components/SvgIcons/CapsLockSvg.js +36 -0
- package/dist/components/SvgIcons/DocumentBackSvg.js +20 -0
- package/dist/components/SvgIcons/DocumentSmallSvg.js +41 -0
- package/dist/components/SvgIcons/DocumentSvg.js +39 -0
- package/dist/components/SvgIcons/EthSvg.js +28 -0
- package/dist/components/SvgIcons/EurSvg.js +27 -0
- package/dist/components/SvgIcons/FaceScanIconSvg.js +17 -0
- package/dist/components/SvgIcons/FourSvg.js +7 -0
- package/dist/components/SvgIcons/Glassess.js +26 -0
- package/dist/components/SvgIcons/LogoSvg.js +17 -0
- package/dist/components/SvgIcons/OneSvg.js +10 -0
- package/dist/components/SvgIcons/PassportSvg.js +37 -0
- package/dist/components/SvgIcons/RefreshSvg.js +28 -0
- package/dist/components/SvgIcons/SocialFacebook.js +22 -0
- package/dist/components/SvgIcons/SocialInstagram.js +13 -0
- package/dist/components/SvgIcons/SocialLinkedIn.js +31 -0
- package/dist/components/SvgIcons/SocialMedium.js +21 -0
- package/dist/components/SvgIcons/SocialReddit.js +21 -0
- package/dist/components/SvgIcons/SocialTelegram.js +60 -0
- package/dist/components/SvgIcons/SocialTwitter.js +62 -0
- package/dist/components/SvgIcons/SocialYoutube.js +22 -0
- package/dist/components/SvgIcons/ThreeSvg.js +7 -0
- package/dist/components/SvgIcons/TwoSidedDocumentSvg.js +48 -0
- package/dist/components/SvgIcons/TwoSvg.js +10 -0
- package/dist/components/SvgIcons/UpdateDefaultSvg.js +12 -0
- package/dist/components/SvgIcons/UpdateHardSvg.js +10 -0
- package/dist/components/SvgIcons/UpdateSoftSvg.js +11 -0
- package/dist/components/SvgIcons/UploadSvg.js +12 -0
- package/dist/components/SvgIcons/VerifiedBadge.js +16 -0
- package/dist/components/Switch/Switch.js +63 -0
- package/dist/components/Switch/Switch.styles.js +126 -0
- package/dist/components/Tabs/Tabs.js +54 -0
- package/dist/components/Tabs/Tabs.styles.js +15 -0
- package/dist/components/TabsNav/TabNav.js +16 -0
- package/dist/components/TabsNav/TabsNav.js +30 -0
- package/dist/components/TabsNav/TabsNav.styles.js +103 -0
- package/dist/components/TeamOverview/TeamOverview.js +80 -0
- package/dist/components/TeamOverview/TeamOverview.styles.js +167 -0
- package/dist/components/TermsModal/TermsModal.js +145 -0
- package/dist/components/TermsModal/_styles.js +313 -0
- package/dist/components/Text/Text.styles.js +220 -0
- package/dist/components/TextLink/TextLink.styles.js +67 -0
- package/dist/components/Timeline/Timeline.js +44 -0
- package/dist/components/Timeline/Timeline.styles.js +147 -0
- package/dist/components/Timeline/TimelineStep.js +58 -0
- package/dist/components/ToDoList/ToDoList.js +172 -0
- package/dist/components/ToDoList/ToDoList.styles.js +122 -0
- package/dist/components/ToDoList/ToDoListTask.js +95 -0
- package/dist/components/ToDoList/ToDoListTask.styles.js +119 -0
- package/dist/components/TransactionDetails/TransactionDetails.js +27 -0
- package/dist/components/TransactionDetails/TransactionDetails.styles.js +38 -0
- package/dist/components/TransactionInfo/TransactionInfo.js +41 -0
- package/dist/components/TransactionInfo/TransactionInfo.styles.js +75 -0
- package/dist/components/VerifyEmailModal/VerifyEmailModal.js +122 -0
- package/dist/components/breakdown/Breakdown.js +126 -0
- package/dist/components/headerHo/HeaderHo.js +709 -0
- package/dist/components/icons/Arrow.js +38 -0
- package/dist/components/icons/ArrowSimple.js +34 -0
- package/dist/components/icons/Check.js +16 -0
- package/dist/components/icons/Facebook.js +10 -0
- package/dist/components/icons/Info.js +27 -0
- package/dist/components/icons/Instagram.js +10 -0
- package/dist/components/icons/LinkIcon.js +49 -0
- package/dist/components/icons/LinkedIn.js +13 -0
- package/dist/components/icons/Medium.js +13 -0
- package/dist/components/icons/Reddit.js +16 -0
- package/dist/components/icons/Share.js +31 -0
- package/dist/components/icons/Telegram.js +13 -0
- package/dist/components/icons/Twitter.js +10 -0
- package/dist/components/icons/X.js +10 -0
- package/dist/components/icons/Youtube.js +10 -0
- package/dist/components/icons/index.js +32 -0
- package/dist/components/landing-page/List.js +51 -0
- package/dist/components/landing-page/PageContent.js +65 -0
- package/dist/components/landing-page/PageText.js +171 -0
- package/dist/components/landing-page/PageTitle.js +259 -0
- package/dist/components/logo/Logo.js +57 -0
- package/dist/components/taxId/complete.js +24 -0
- package/dist/components/taxId/flow.js +53 -0
- package/dist/components/taxId/register-taxid.js +166 -0
- package/dist/config.js +44 -0
- package/dist/constants/globalVariables.js +87 -0
- package/dist/constants/style.js +48 -0
- package/dist/context/Auth.js +396 -0
- package/dist/context/AuthContext.js +781 -0
- package/dist/context/Checkbox/CheckboxContext.js +151 -0
- package/dist/firebase-config.js +73 -0
- package/dist/hooks/useNewVentureForm.js +262 -0
- package/dist/hooks/useTimer.js +89 -0
- package/dist/index.js +628 -25463
- package/dist/model/axios.js +10 -0
- package/dist/model/axiosPublic.js +9 -0
- package/dist/services/TimerService.js +80 -0
- package/dist/static/animations/checked.lottie.js +4 -0
- package/dist/static/animations/progress.lottie.js +4 -0
- package/dist/static/fonts/Ionicons/Ionicons.ttf.js +4 -0
- package/dist/static/fonts/Ionicons/Ionicons.woff.js +4 -0
- package/dist/static/fonts/Ionicons/Ionicons.woff2.js +4 -0
- package/dist/static/fonts/Ionicons/ionicons.min.css.js +4 -0
- package/dist/static/fonts/OpenSans/OpenSans-Bold.ttf.js +4 -0
- package/dist/static/fonts/OpenSans/OpenSans-Bold.woff.js +4 -0
- package/dist/static/fonts/OpenSans/OpenSans-Bold.woff2.js +4 -0
- package/dist/static/fonts/OpenSans/OpenSans-ExtraBold.ttf.js +4 -0
- package/dist/static/fonts/OpenSans/OpenSans-ExtraBold.woff.js +4 -0
- package/dist/static/fonts/OpenSans/OpenSans-ExtraBold.woff2.js +4 -0
- package/dist/static/fonts/OpenSans/OpenSans-Light.ttf.js +4 -0
- package/dist/static/fonts/OpenSans/OpenSans-Light.woff.js +4 -0
- package/dist/static/fonts/OpenSans/OpenSans-Light.woff2.js +4 -0
- package/dist/static/fonts/OpenSans/OpenSans-Regular.ttf.js +4 -0
- package/dist/static/fonts/OpenSans/OpenSans-Regular.woff.js +4 -0
- package/dist/static/fonts/OpenSans/OpenSans-Regular.woff2.js +4 -0
- package/dist/static/fonts/OpenSans/OpenSans-SemiBold.ttf.js +4 -0
- package/dist/static/fonts/OpenSans/OpenSans-SemiBold.woff.js +4 -0
- package/dist/static/fonts/OpenSans/OpenSans-SemiBold.woff2.js +4 -0
- package/dist/static/fonts/icomoon/icomoon.eot.js +4 -0
- package/dist/static/fonts/icomoon/icomoon.svg.js +4 -0
- package/dist/static/fonts/icomoon/icomoon.ttf.js +4 -0
- package/dist/static/fonts/icomoon/icomoon.woff.js +4 -0
- package/dist/static/images/add-folder-icon.svg.js +5 -0
- package/dist/static/images/address-refreshing.gif.js +4 -0
- package/dist/static/images/arrow-down-black.svg.js +4 -0
- package/dist/static/images/avatar-placeholder.png.js +4 -0
- package/dist/static/images/background3.png.js +4 -0
- package/dist/static/images/bitcoin-logo.svg.js +4 -0
- package/dist/static/images/bmn2-logo.svg.js +4 -0
- package/dist/static/images/check-icon.svg.js +5 -0
- package/dist/static/images/checkmark-circle-icon.svg.js +5 -0
- package/dist/static/images/close-circle-icon.svg.js +5 -0
- package/dist/static/images/copy_icon.svg.js +5 -0
- package/dist/static/images/cross-icon.svg.js +5 -0
- package/dist/static/images/early-adopter.png.js +4 -0
- package/dist/static/images/eth_logo.svg.js +4 -0
- package/dist/static/images/filter-icon.svg.js +5 -0
- package/dist/static/images/google_auth.png.js +4 -0
- package/dist/static/images/graduation.png.js +4 -0
- package/dist/static/images/mangopay.svg.js +4 -0
- package/dist/static/images/numbers/number_eight.svg.js +5 -0
- package/dist/static/images/numbers/number_five.svg.js +5 -0
- package/dist/static/images/numbers/number_four.svg.js +5 -0
- package/dist/static/images/numbers/number_nine.svg.js +5 -0
- package/dist/static/images/numbers/number_one.svg.js +5 -0
- package/dist/static/images/numbers/number_seven.svg.js +5 -0
- package/dist/static/images/numbers/number_six.svg.js +5 -0
- package/dist/static/images/numbers/number_three.svg.js +5 -0
- package/dist/static/images/numbers/number_two.svg.js +5 -0
- package/dist/static/images/numbers/number_zero.svg.js +5 -0
- package/dist/static/images/process-waiting.gif.js +4 -0
- package/dist/static/images/search-icon.svg.js +5 -0
- package/dist/static/images/social/Facebook_Logo.png.js +4 -0
- package/dist/static/images/social/LI-In-Bug.png.js +4 -0
- package/dist/static/images/social/Telegram-Logo.png.js +4 -0
- package/dist/static/images/social/X-logo-black.png.js +4 -0
- package/dist/static/images/social/youtube_social_circle_red.png.js +4 -0
- package/dist/static/images/transfer-icon.svg.js +5 -0
- package/dist/static/images/usdc-logo.svg.js +4 -0
- package/dist/static/images/usdq-logo.png.js +4 -0
- package/dist/static/images/warning-filled.svg.js +5 -0
- package/dist/styles/colors.js +56 -0
- package/dist/styles/fonts.js +100 -0
- package/dist/styles/global.js +74 -0
- package/dist/styles/grid.js +11 -0
- package/dist/styles/ioniconsStyles.js +31 -0
- package/dist/styles/reactTippy.js +40 -0
- package/dist/styles/rwd.js +56 -0
- package/dist/styles/semanticUi.js +84 -0
- package/dist/styles/spacing.js +8 -0
- package/dist/styles/theme.js +34 -0
- package/dist/utils/check-sale-time-left.js +85 -0
- package/dist/utils/check-todo-status.js +11 -0
- package/dist/utils/checklistGenerator.js +195 -0
- package/dist/utils/copyToClipboard.js +92 -0
- package/dist/utils/customHooks.js +126 -0
- package/dist/utils/delete-redirect-cookie-and-navigate.js +12 -0
- package/dist/utils/fix-decimals.js +5 -0
- package/dist/utils/formatCurrencyValue.js +95 -0
- package/dist/utils/get-cookie-domain.js +10 -0
- package/dist/utils/get-short-address.js +4 -0
- package/dist/utils/isUSInvestor.js +6 -0
- package/dist/utils/km_ify.js +33 -0
- package/dist/utils/moment.js +26 -0
- package/dist/utils/redirect-url.js +5 -0
- package/dist/utils/saveAs.js +17 -0
- package/dist/utils/scrollUtils.js +63 -0
- package/dist/utils/set-redirect-cookie.js +16 -0
- package/dist/utils/transition.js +101 -0
- package/dist/utils/withRouter.js +24 -0
- package/package.json +146 -146
|
@@ -0,0 +1,781 @@
|
|
|
1
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
+
import PropTypes from "prop-types";
|
|
3
|
+
import axiosInstance from "../model/axios.js";
|
|
4
|
+
import React__default, { Component } from "react";
|
|
5
|
+
import fetchData from "../api/fetchData.js";
|
|
6
|
+
import { identify, reset } from "../analytics/index.js";
|
|
7
|
+
import { withRouter } from "../utils/withRouter.js";
|
|
8
|
+
import { configure, getConfig } from "../config.js";
|
|
9
|
+
import { Text } from "../components/Text/Text.styles.js";
|
|
10
|
+
import { getFirebaseAuth } from "../firebase-config.js";
|
|
11
|
+
import { Auth } from "./Auth.js";
|
|
12
|
+
import { DEFAULT_TOKEN_EXPIRY_MS } from "./Auth.js";
|
|
13
|
+
import { ConfirmModal as ConfirmModalComponent } from "../components/ConfirmModal/ConfirmModal.js";
|
|
14
|
+
import avatarPlaceholder from "../static/images/avatar-placeholder.png.js";
|
|
15
|
+
import { signOut, getMultiFactorResolver, PhoneMultiFactorGenerator, TotpMultiFactorGenerator, multiFactor } from "firebase/auth";
|
|
16
|
+
const AuthContext = React__default.createContext();
|
|
17
|
+
const INACTIVITY_TIME_MS = 5 * 60 * 1e3;
|
|
18
|
+
const INACTIVITY_EVENTS = ["mousemove", "keydown", "click", "scroll", "touchstart"];
|
|
19
|
+
class AuthProviderClass extends Component {
|
|
20
|
+
userRef = React__default.createRef(null);
|
|
21
|
+
inactivityTimerRef = null;
|
|
22
|
+
cookieExpiryTimerRef = null;
|
|
23
|
+
// Timestamp of the last inactivity timer reset; used to throttle the reset
|
|
24
|
+
// to at most once per second so frequent DOM events (mousemove fires 30-60×/s)
|
|
25
|
+
// don't continuously create and destroy setTimeout objects.
|
|
26
|
+
_lastActivityAt = 0;
|
|
27
|
+
state = {
|
|
28
|
+
user: void 0,
|
|
29
|
+
firebaseUser: void 0,
|
|
30
|
+
// Start as `true` when a session cookie already exists so the app
|
|
31
|
+
// shows a loader immediately instead of flashing the login form
|
|
32
|
+
// for a frame before componentDidMount fires getUser().
|
|
33
|
+
// When there is no cookie the value stays `false` so the login
|
|
34
|
+
// page appears instantly without any loader.
|
|
35
|
+
isFetchingUser: !!Auth.getAccessToken(),
|
|
36
|
+
avatar: avatarPlaceholder,
|
|
37
|
+
userMfaEnrollment: null,
|
|
38
|
+
waitingFor2fa: false,
|
|
39
|
+
firebaseError: null,
|
|
40
|
+
verifyEmailError: null,
|
|
41
|
+
isVerifyingEmail: false,
|
|
42
|
+
loggedOutDueToInactivity: false,
|
|
43
|
+
loggedOutDueToCookieExpiry: false
|
|
44
|
+
};
|
|
45
|
+
componentDidMount() {
|
|
46
|
+
if (this.props.config) {
|
|
47
|
+
configure(this.props.config);
|
|
48
|
+
if (this.props.config.firebase == null && typeof console !== "undefined" && console.warn) {
|
|
49
|
+
console.warn(
|
|
50
|
+
"[@stokr/components-library] <AuthProvider> config has no `firebase` property. Auth (login, 2FA, session) may fail with auth/internal-error or auth/network-request-failed. Pass config.firebase with your Firebase project config (apiKey, authDomain, projectId, etc.)."
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
} else if (typeof console !== "undefined" && console.warn) {
|
|
54
|
+
console.warn(
|
|
55
|
+
"[@stokr/components-library] <AuthProvider> rendered without a `config` prop. API URLs, Firebase, and cookie domain will use values baked at library build time. Pass a config prop to use your app’s environment variables at runtime. See: https://github.com/stokr-io/components-library#runtime-config"
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
const isActivatingUser = window.location.href.includes("verifyEmail");
|
|
59
|
+
if (isActivatingUser) {
|
|
60
|
+
this.handleVerifyEmail();
|
|
61
|
+
} else if (getFirebaseAuth()) {
|
|
62
|
+
this.getUser().catch((err) => {
|
|
63
|
+
if (typeof console !== "undefined" && console.debug) {
|
|
64
|
+
console.debug("[AuthProvider] getUser() on mount failed:", err?.message || err);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
} else if (typeof console !== "undefined" && console.debug) {
|
|
68
|
+
console.debug(
|
|
69
|
+
"[@stokr/components-library] getUser() not run on mount: Firebase not initialized. Pass config.firebase to AuthProvider."
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
INACTIVITY_EVENTS.forEach((event) => window.addEventListener(event, this.resetInactivityTimer));
|
|
73
|
+
}
|
|
74
|
+
componentDidUpdate(prevProps, prevState) {
|
|
75
|
+
const hadUser = prevState.user || prevState.firebaseUser;
|
|
76
|
+
const hasUser = this.state.user || this.state.firebaseUser;
|
|
77
|
+
if (!hadUser && hasUser) {
|
|
78
|
+
this.resetInactivityTimer();
|
|
79
|
+
this.scheduleCookieExpiryLogout();
|
|
80
|
+
} else if (hadUser && !hasUser) {
|
|
81
|
+
this.clearInactivityTimer();
|
|
82
|
+
this.clearCookieExpiryTimer();
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
componentWillUnmount() {
|
|
86
|
+
INACTIVITY_EVENTS.forEach((event) => window.removeEventListener(event, this.resetInactivityTimer));
|
|
87
|
+
this.clearInactivityTimer();
|
|
88
|
+
this.clearCookieExpiryTimer();
|
|
89
|
+
}
|
|
90
|
+
checkTokenIsValid = (redirect = false) => {
|
|
91
|
+
const accessToken = Auth.getAccessToken();
|
|
92
|
+
if (!accessToken) {
|
|
93
|
+
this.logoutUser(redirect, { dueToCookieExpiry: true });
|
|
94
|
+
}
|
|
95
|
+
return !!accessToken;
|
|
96
|
+
};
|
|
97
|
+
clearInactivityTimer = () => {
|
|
98
|
+
if (this.inactivityTimerRef) {
|
|
99
|
+
clearTimeout(this.inactivityTimerRef);
|
|
100
|
+
this.inactivityTimerRef = null;
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
clearCookieExpiryTimer = () => {
|
|
104
|
+
if (this.cookieExpiryTimerRef != null) {
|
|
105
|
+
clearTimeout(this.cookieExpiryTimerRef);
|
|
106
|
+
this.cookieExpiryTimerRef = null;
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
scheduleCookieExpiryLogout = () => {
|
|
110
|
+
if (this.cookieExpiryTimerRef != null) {
|
|
111
|
+
clearTimeout(this.cookieExpiryTimerRef);
|
|
112
|
+
this.cookieExpiryTimerRef = null;
|
|
113
|
+
}
|
|
114
|
+
const { user, firebaseUser } = this.state;
|
|
115
|
+
if (!user && !firebaseUser) return;
|
|
116
|
+
const expiresAt = Auth.getAccessTokenExpiresAt();
|
|
117
|
+
if (!expiresAt) return;
|
|
118
|
+
const delay = expiresAt - Date.now();
|
|
119
|
+
if (delay <= 0) {
|
|
120
|
+
this.logoutUser(false, { dueToCookieExpiry: true });
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
this.cookieExpiryTimerRef = setTimeout(() => {
|
|
124
|
+
this.cookieExpiryTimerRef = null;
|
|
125
|
+
this.logoutUser(false, { dueToCookieExpiry: true });
|
|
126
|
+
}, delay);
|
|
127
|
+
};
|
|
128
|
+
getInactivityTimeMs = () => {
|
|
129
|
+
const { inactivityTimeMs } = this.props;
|
|
130
|
+
return typeof inactivityTimeMs === "number" && inactivityTimeMs > 0 ? inactivityTimeMs : INACTIVITY_TIME_MS;
|
|
131
|
+
};
|
|
132
|
+
resetInactivityTimer = () => {
|
|
133
|
+
const now = Date.now();
|
|
134
|
+
if (now - this._lastActivityAt < 1e3) return;
|
|
135
|
+
this._lastActivityAt = now;
|
|
136
|
+
this.clearInactivityTimer();
|
|
137
|
+
const { user, firebaseUser } = this.state;
|
|
138
|
+
if (user || firebaseUser) {
|
|
139
|
+
const delay = this.getInactivityTimeMs();
|
|
140
|
+
this.inactivityTimerRef = setTimeout(() => {
|
|
141
|
+
this.inactivityTimerRef = null;
|
|
142
|
+
this.logoutUser(false, { dueToInactivity: true });
|
|
143
|
+
}, delay);
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
loginUser = async (email, password, customToken) => {
|
|
147
|
+
try {
|
|
148
|
+
let user;
|
|
149
|
+
if (customToken) {
|
|
150
|
+
user = await Auth.signInWithToken(customToken);
|
|
151
|
+
} else {
|
|
152
|
+
user = await Auth.login(email, password);
|
|
153
|
+
}
|
|
154
|
+
const token = await user.getIdToken();
|
|
155
|
+
const expiryMs = Number(this.props.accessTokenExpiryMs);
|
|
156
|
+
Auth.setAccessToken(token, Number.isFinite(expiryMs) && expiryMs > 0 ? { expiresInMs: expiryMs } : void 0);
|
|
157
|
+
this.setState({
|
|
158
|
+
firebaseUser: user
|
|
159
|
+
});
|
|
160
|
+
await this.getUser(token, user);
|
|
161
|
+
return user;
|
|
162
|
+
} catch (error) {
|
|
163
|
+
console.log("🚀 ~ file: AuthContext.js:56 ~ error:", error);
|
|
164
|
+
const httpStatus = error?.response?.status;
|
|
165
|
+
if (httpStatus != null) {
|
|
166
|
+
const auth = getFirebaseAuth();
|
|
167
|
+
if (auth) signOut(auth).catch(() => {
|
|
168
|
+
});
|
|
169
|
+
Auth.logout();
|
|
170
|
+
this.setState({ firebaseUser: null });
|
|
171
|
+
if (httpStatus === 401 || httpStatus === 403) {
|
|
172
|
+
error.message = "Your account was authenticated but the server rejected the session. Please verify that the API and Firebase environments match, or contact support.";
|
|
173
|
+
}
|
|
174
|
+
throw error;
|
|
175
|
+
}
|
|
176
|
+
switch (error.code) {
|
|
177
|
+
case "auth/internal-error":
|
|
178
|
+
error.message = "Authentication service error. Ensure AuthProvider receives config.firebase and your domain is authorized in Firebase Console.";
|
|
179
|
+
throw error;
|
|
180
|
+
case "auth/multi-factor-auth-required":
|
|
181
|
+
this.setState({ waitingFor2fa: true, firebaseError: error });
|
|
182
|
+
throw error;
|
|
183
|
+
case "auth/requires-recent-login":
|
|
184
|
+
this.logoutUser();
|
|
185
|
+
break;
|
|
186
|
+
case "auth/invalid-login-credentials":
|
|
187
|
+
case "auth/invalid-credential":
|
|
188
|
+
error.message = "The credentials are not correct. Try again?";
|
|
189
|
+
throw error;
|
|
190
|
+
case "auth/invalid-custom-token":
|
|
191
|
+
case "auth/argument-error":
|
|
192
|
+
error.message = "This sign-in link is invalid, expired, or was already used. Please sign in again or request a new link.";
|
|
193
|
+
throw error;
|
|
194
|
+
case "auth/network-request-failed":
|
|
195
|
+
error.message = "Unable to reach the authentication server. Check your connection and try again.";
|
|
196
|
+
throw error;
|
|
197
|
+
default:
|
|
198
|
+
console.log({ error });
|
|
199
|
+
throw error;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
createUser = async (email, password) => {
|
|
204
|
+
try {
|
|
205
|
+
await Auth.createUser(email, password);
|
|
206
|
+
} catch (error) {
|
|
207
|
+
console.log("🚀 ~ file: AuthContext.js:56 ~ error:", error);
|
|
208
|
+
throw error;
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
loginUserWithTotp = async (verificationCode, error) => {
|
|
212
|
+
const auth = getFirebaseAuth();
|
|
213
|
+
if (!auth) {
|
|
214
|
+
throw new Error("Firebase is not configured.");
|
|
215
|
+
}
|
|
216
|
+
const mfaResolver = getMultiFactorResolver(auth, error);
|
|
217
|
+
const selectedIndex = 0;
|
|
218
|
+
switch (mfaResolver.hints[selectedIndex].factorId) {
|
|
219
|
+
case TotpMultiFactorGenerator.FACTOR_ID: {
|
|
220
|
+
const otpFromAuthenticator = verificationCode;
|
|
221
|
+
const multiFactorAssertion = TotpMultiFactorGenerator.assertionForSignIn(
|
|
222
|
+
mfaResolver.hints[selectedIndex].uid,
|
|
223
|
+
otpFromAuthenticator
|
|
224
|
+
);
|
|
225
|
+
try {
|
|
226
|
+
const userCredential = await mfaResolver.resolveSignIn(multiFactorAssertion);
|
|
227
|
+
const user = userCredential.user;
|
|
228
|
+
const token = await user.getIdToken();
|
|
229
|
+
const expiryMs = Number(this.props.accessTokenExpiryMs);
|
|
230
|
+
Auth.setAccessToken(token, Number.isFinite(expiryMs) && expiryMs > 0 ? { expiresInMs: expiryMs } : void 0);
|
|
231
|
+
this.setState({ firebaseUser: user, waitingFor2fa: false });
|
|
232
|
+
await this.getUser(token, user);
|
|
233
|
+
} catch (_error) {
|
|
234
|
+
console.log({ _error });
|
|
235
|
+
throw _error;
|
|
236
|
+
}
|
|
237
|
+
break;
|
|
238
|
+
}
|
|
239
|
+
case PhoneMultiFactorGenerator.FACTOR_ID:
|
|
240
|
+
break;
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
generateTotpSecret = async (user = getFirebaseAuth()?.currentUser, appName = "STOKR") => {
|
|
244
|
+
try {
|
|
245
|
+
const multiFactorSession = await multiFactor(user).getSession();
|
|
246
|
+
const totpSecret = await TotpMultiFactorGenerator.generateSecret(multiFactorSession);
|
|
247
|
+
const totpUri = totpSecret.generateQrCodeUrl(user.email, appName);
|
|
248
|
+
return { totpUri, totpSecret };
|
|
249
|
+
} catch (error) {
|
|
250
|
+
console.log("🚀 ~ file: AuthContext.js:51 ~ error:", error);
|
|
251
|
+
throw error;
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
unenrollUser2FA = async () => {
|
|
255
|
+
const { userMfaEnrollment, user } = this.state;
|
|
256
|
+
if (userMfaEnrollment?.length === 0) {
|
|
257
|
+
console.log("User is not enrolled in 2FA");
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
try {
|
|
261
|
+
for (let i = 0; i < userMfaEnrollment.length; i++) {
|
|
262
|
+
await multiFactor(user).unenroll(userMfaEnrollment[i].uid);
|
|
263
|
+
}
|
|
264
|
+
} catch (error) {
|
|
265
|
+
console.log({ error });
|
|
266
|
+
throw error;
|
|
267
|
+
}
|
|
268
|
+
};
|
|
269
|
+
checkMfaEnrollment = (user = getFirebaseAuth()?.currentUser) => {
|
|
270
|
+
const checkMfaEnrollment = multiFactor(user).enrolledFactors;
|
|
271
|
+
this.setState({
|
|
272
|
+
userMfaEnrollment: checkMfaEnrollment
|
|
273
|
+
});
|
|
274
|
+
return checkMfaEnrollment;
|
|
275
|
+
};
|
|
276
|
+
enrollUserToTotp = async (user, totpSecret, verificationCode, displayName) => {
|
|
277
|
+
const multiFactorAssertion = TotpMultiFactorGenerator.assertionForEnrollment(totpSecret, verificationCode);
|
|
278
|
+
await multiFactor(user).enroll(multiFactorAssertion, displayName);
|
|
279
|
+
};
|
|
280
|
+
logoutUser = async (redirect = false, options = {}) => {
|
|
281
|
+
console.log("🚀 ~ file: AuthContext.js:303 ~ logoutUser ~ redirect:", redirect);
|
|
282
|
+
this.clearCookieExpiryTimer();
|
|
283
|
+
try {
|
|
284
|
+
const auth = getFirebaseAuth();
|
|
285
|
+
if (auth) signOut(auth).then(() => {
|
|
286
|
+
});
|
|
287
|
+
Auth.logout();
|
|
288
|
+
} catch (_e) {
|
|
289
|
+
}
|
|
290
|
+
delete axiosInstance.defaults.headers.common.Authorization;
|
|
291
|
+
reset();
|
|
292
|
+
this.setUser(null);
|
|
293
|
+
this.setState({
|
|
294
|
+
firebaseUser: null,
|
|
295
|
+
firebaseError: null,
|
|
296
|
+
verifyEmailError: null,
|
|
297
|
+
userMfaEnrollment: null,
|
|
298
|
+
waitingFor2fa: false,
|
|
299
|
+
isVerifyingEmail: false,
|
|
300
|
+
avatar: avatarPlaceholder,
|
|
301
|
+
isFetchingUser: false,
|
|
302
|
+
loggedOutDueToInactivity: options.dueToInactivity === true,
|
|
303
|
+
loggedOutDueToCookieExpiry: options.dueToCookieExpiry === true
|
|
304
|
+
});
|
|
305
|
+
if (redirect) {
|
|
306
|
+
window.location.href = `https://${getConfig("websiteDomain")}`;
|
|
307
|
+
}
|
|
308
|
+
};
|
|
309
|
+
clearLoggedOutDueToInactivity = () => {
|
|
310
|
+
this.setState({ loggedOutDueToInactivity: false });
|
|
311
|
+
};
|
|
312
|
+
clearLoggedOutDueToCookieExpiry = () => {
|
|
313
|
+
this.setState({ loggedOutDueToCookieExpiry: false });
|
|
314
|
+
};
|
|
315
|
+
/** Call when user cancels the 2FA step (e.g. goes back to login to try another account). */
|
|
316
|
+
reset2faFlow = () => {
|
|
317
|
+
this.setState({ waitingFor2fa: false, firebaseError: null });
|
|
318
|
+
};
|
|
319
|
+
patchUserObject = (user, firebaseUser) => {
|
|
320
|
+
if (!user || !firebaseUser) return;
|
|
321
|
+
const merged = Object.assign(Object.create(Object.getPrototypeOf(firebaseUser)), firebaseUser, user);
|
|
322
|
+
merged.active = merged.emailVerified;
|
|
323
|
+
return merged;
|
|
324
|
+
};
|
|
325
|
+
checkUserPhoto = (avatar) => {
|
|
326
|
+
try {
|
|
327
|
+
const http = new XMLHttpRequest();
|
|
328
|
+
http.open("HEAD", avatar, true);
|
|
329
|
+
http.onload = () => {
|
|
330
|
+
if (http.status === 200) {
|
|
331
|
+
this.setState({ avatar });
|
|
332
|
+
}
|
|
333
|
+
};
|
|
334
|
+
http.send();
|
|
335
|
+
} catch (error) {
|
|
336
|
+
console.log("error: ", error);
|
|
337
|
+
}
|
|
338
|
+
};
|
|
339
|
+
getUser = async (accessToken = Auth.getAccessToken(), firebaseUserOverride) => {
|
|
340
|
+
if (!accessToken) {
|
|
341
|
+
this.setState({
|
|
342
|
+
isFetchingUser: false,
|
|
343
|
+
user: null,
|
|
344
|
+
firebaseUser: null
|
|
345
|
+
});
|
|
346
|
+
if (typeof console !== "undefined" && console.debug) {
|
|
347
|
+
console.debug(
|
|
348
|
+
"[@stokr/components-library] getUser() skipped: no access token. If you expected a session, ensure config.cookieDomain matches this origin (e.g. omit or use empty for localhost)."
|
|
349
|
+
);
|
|
350
|
+
}
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
this.setState({
|
|
354
|
+
isFetchingUser: true
|
|
355
|
+
});
|
|
356
|
+
axiosInstance.defaults.headers.common.Authorization = `Bearer ${accessToken}`;
|
|
357
|
+
const { customValidateGetUser } = this.props;
|
|
358
|
+
try {
|
|
359
|
+
const existingFirebaseUser = firebaseUserOverride || this.state.firebaseUser || getFirebaseAuth()?.currentUser;
|
|
360
|
+
const [result, tokenRes] = await Promise.all([
|
|
361
|
+
Auth.getUser(),
|
|
362
|
+
!existingFirebaseUser ? fetchData("auth/get-custom-token") : Promise.resolve(null)
|
|
363
|
+
]);
|
|
364
|
+
let firebaseUser = existingFirebaseUser;
|
|
365
|
+
if (!firebaseUser) {
|
|
366
|
+
const customToken = tokenRes?.customToken ?? tokenRes?.custom_token ?? tokenRes?.token ?? tokenRes;
|
|
367
|
+
firebaseUser = await Auth.signInWithToken(customToken);
|
|
368
|
+
}
|
|
369
|
+
const user = this.patchUserObject(result.user, firebaseUser);
|
|
370
|
+
this.checkUserIsValid(user);
|
|
371
|
+
customValidateGetUser?.(user);
|
|
372
|
+
const userAvatar = `${getConfig("photoApiUrl")}/media/picture/view/${user._id}`;
|
|
373
|
+
this.checkUserPhoto(userAvatar);
|
|
374
|
+
this.setUser(user);
|
|
375
|
+
this.setState({
|
|
376
|
+
isFetchingUser: false
|
|
377
|
+
});
|
|
378
|
+
identify(user._id, {
|
|
379
|
+
role: user.user_type,
|
|
380
|
+
is_internal: user.email?.endsWith("@stokr.io") ?? false
|
|
381
|
+
});
|
|
382
|
+
this.replaceLocationPathName();
|
|
383
|
+
return user;
|
|
384
|
+
} catch (error) {
|
|
385
|
+
this.setState({
|
|
386
|
+
isFetchingUser: false
|
|
387
|
+
});
|
|
388
|
+
const code = error?.code;
|
|
389
|
+
if (code === "auth/internal-error" || code === "auth/network-request-failed") {
|
|
390
|
+
Auth.logout();
|
|
391
|
+
if (typeof console !== "undefined" && console.warn) {
|
|
392
|
+
console.warn(
|
|
393
|
+
"[@stokr/components-library] getUser() failed with",
|
|
394
|
+
code,
|
|
395
|
+
"— session cleared. Ensure AuthProvider receives config.firebase for this origin and that the domain is authorized in Firebase Console (Authentication → Settings → Authorized domains)."
|
|
396
|
+
);
|
|
397
|
+
}
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
console.log(`Error in getUser: ${error}`);
|
|
401
|
+
throw error;
|
|
402
|
+
}
|
|
403
|
+
};
|
|
404
|
+
checkUserIsValid = (user) => {
|
|
405
|
+
if (!user) {
|
|
406
|
+
throw new Error("User is not defined");
|
|
407
|
+
} else if (!user?.emailVerified && !window.location.href.includes("signup.")) {
|
|
408
|
+
window.location.href = `https://signup.${getConfig("websiteDomain")}/resend-activation-email`;
|
|
409
|
+
return false;
|
|
410
|
+
} else if (!user?.country && user?.user_type === "investor" && !window.location.href.includes("signup.")) {
|
|
411
|
+
window.location.href = `https://signup.${getConfig("websiteDomain")}/welcome`;
|
|
412
|
+
return false;
|
|
413
|
+
}
|
|
414
|
+
return true;
|
|
415
|
+
};
|
|
416
|
+
uploadPhoto = async (file) => {
|
|
417
|
+
try {
|
|
418
|
+
const { user } = this.state;
|
|
419
|
+
if (!user || !file) {
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
const formData = new FormData();
|
|
423
|
+
formData.append("userId", user._id);
|
|
424
|
+
formData.append("file", file);
|
|
425
|
+
const result = await Auth.uploadPhoto(formData);
|
|
426
|
+
this.setState({
|
|
427
|
+
avatar: `${getConfig("photoApiUrl")}/media/picture/view/${user._id}?ignore=${Date.now()}`
|
|
428
|
+
});
|
|
429
|
+
return result;
|
|
430
|
+
} catch (error) {
|
|
431
|
+
console.log(`Error: ${error}`);
|
|
432
|
+
throw error;
|
|
433
|
+
}
|
|
434
|
+
};
|
|
435
|
+
deletePhoto = async () => {
|
|
436
|
+
const { user } = this.state;
|
|
437
|
+
if (!user) {
|
|
438
|
+
return;
|
|
439
|
+
}
|
|
440
|
+
const formData = new FormData();
|
|
441
|
+
formData.append("userId", user._id);
|
|
442
|
+
await Auth.deletePhoto(formData);
|
|
443
|
+
this.setState({
|
|
444
|
+
avatar: void 0
|
|
445
|
+
});
|
|
446
|
+
};
|
|
447
|
+
replaceLocationPathName = () => {
|
|
448
|
+
const pathname = this.props.location?.pathname ?? "";
|
|
449
|
+
console.log("🚀 ~ file: AuthContext.js:511 ~ replaceLocationPathName ~ pathname:", pathname);
|
|
450
|
+
if (pathname === "/login" || pathname === "/signup") {
|
|
451
|
+
this.props.navigate("/");
|
|
452
|
+
}
|
|
453
|
+
};
|
|
454
|
+
updateUser = async (data) => {
|
|
455
|
+
try {
|
|
456
|
+
const existingFirebaseUser = this.state.firebaseUser;
|
|
457
|
+
const [{ user }, tokenRes] = await Promise.all([
|
|
458
|
+
Auth.updateUser(data),
|
|
459
|
+
!existingFirebaseUser ? fetchData("auth/get-custom-token") : Promise.resolve(null)
|
|
460
|
+
]);
|
|
461
|
+
let firebaseUser = existingFirebaseUser;
|
|
462
|
+
if (!firebaseUser) {
|
|
463
|
+
const customToken = tokenRes?.customToken ?? tokenRes?.custom_token ?? tokenRes?.token ?? tokenRes;
|
|
464
|
+
firebaseUser = await Auth.signInWithToken(customToken);
|
|
465
|
+
}
|
|
466
|
+
const newUser = this.patchUserObject(user, firebaseUser);
|
|
467
|
+
this.setUser(newUser);
|
|
468
|
+
return user;
|
|
469
|
+
} catch (error) {
|
|
470
|
+
console.log(`Error updating the user: ${error}`);
|
|
471
|
+
throw error;
|
|
472
|
+
}
|
|
473
|
+
};
|
|
474
|
+
checkIfPrivateInvestor = async (project, user = this.state.user, returnData = false) => {
|
|
475
|
+
if (!user || !project) {
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
478
|
+
try {
|
|
479
|
+
let dataToSend = {
|
|
480
|
+
userId: user._id,
|
|
481
|
+
projectId: project._id
|
|
482
|
+
};
|
|
483
|
+
const isPrivateInvestor = await Auth.checkPrivateInvestor(dataToSend);
|
|
484
|
+
const userCopy = { ...user };
|
|
485
|
+
userCopy.isPrivateInvestor = isPrivateInvestor.isAllowed;
|
|
486
|
+
userCopy.privateInvestorStatus = isPrivateInvestor.status;
|
|
487
|
+
if (returnData) {
|
|
488
|
+
return userCopy;
|
|
489
|
+
} else {
|
|
490
|
+
this.setState({ user: userCopy });
|
|
491
|
+
}
|
|
492
|
+
} catch (error) {
|
|
493
|
+
console.log("🚀 ~ error in checkPrivateInvestor", error);
|
|
494
|
+
throw error;
|
|
495
|
+
}
|
|
496
|
+
};
|
|
497
|
+
checkPrivateInvestorAll = async (user = this.state.user, returnData = false) => {
|
|
498
|
+
try {
|
|
499
|
+
const { list } = await Auth.checkPrivateInvestor();
|
|
500
|
+
if (list) {
|
|
501
|
+
const userCopy = { ...user };
|
|
502
|
+
userCopy.privateInvestorProjects = list;
|
|
503
|
+
if (returnData) {
|
|
504
|
+
return userCopy;
|
|
505
|
+
} else {
|
|
506
|
+
this.setState({ user: userCopy });
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
} catch (error) {
|
|
510
|
+
console.log("🚀 ~ error in checkPrivateInvestorAll", error);
|
|
511
|
+
throw error;
|
|
512
|
+
}
|
|
513
|
+
};
|
|
514
|
+
checkIfUserSubscribed = async (project, user = this.state.user, returnData = false) => {
|
|
515
|
+
if (!user || !project) {
|
|
516
|
+
return;
|
|
517
|
+
}
|
|
518
|
+
try {
|
|
519
|
+
let dataToSend = {
|
|
520
|
+
listName: project.name,
|
|
521
|
+
email: user.email
|
|
522
|
+
};
|
|
523
|
+
const isSubscribed = await Auth.checkIfUserSubscribed(dataToSend);
|
|
524
|
+
const userCopy = { ...user };
|
|
525
|
+
userCopy.isSubscribed = isSubscribed;
|
|
526
|
+
if (returnData) {
|
|
527
|
+
return userCopy;
|
|
528
|
+
} else {
|
|
529
|
+
this.setState({ user: userCopy });
|
|
530
|
+
}
|
|
531
|
+
} catch (error) {
|
|
532
|
+
console.log("🚀 ~ error in checkIfUserSubscribed", error);
|
|
533
|
+
throw error;
|
|
534
|
+
}
|
|
535
|
+
};
|
|
536
|
+
checkIfUserSubscribedAll = async (user = this.state.user, returnData = false) => {
|
|
537
|
+
if (!user) {
|
|
538
|
+
return;
|
|
539
|
+
}
|
|
540
|
+
try {
|
|
541
|
+
let dataToSend = {
|
|
542
|
+
email: user.email
|
|
543
|
+
};
|
|
544
|
+
const result = await Auth.checkIfUserSubscribed(dataToSend);
|
|
545
|
+
const userCopy = { ...user };
|
|
546
|
+
userCopy.subscribedProjects = result;
|
|
547
|
+
if (returnData) {
|
|
548
|
+
return userCopy;
|
|
549
|
+
} else {
|
|
550
|
+
this.setState({ user: userCopy });
|
|
551
|
+
}
|
|
552
|
+
} catch (error) {
|
|
553
|
+
console.log("🚀 ~ error in checkIfUserSubscribed", error);
|
|
554
|
+
throw error;
|
|
555
|
+
}
|
|
556
|
+
};
|
|
557
|
+
handleVerifyEmail = async () => {
|
|
558
|
+
this.setState({ isVerifyingEmail: true });
|
|
559
|
+
const { location } = this.props;
|
|
560
|
+
const query = new URLSearchParams(location.search);
|
|
561
|
+
try {
|
|
562
|
+
let oobCode = query.get("oobCode");
|
|
563
|
+
await Auth.handleVerifyEmail(oobCode);
|
|
564
|
+
this.setState({ isVerifyingEmail: false });
|
|
565
|
+
let customToken = query.get("customtoken");
|
|
566
|
+
if (customToken) {
|
|
567
|
+
await this.loginUser(null, null, customToken);
|
|
568
|
+
}
|
|
569
|
+
} catch (error) {
|
|
570
|
+
switch (error?.code) {
|
|
571
|
+
case "auth/expired-action-code": {
|
|
572
|
+
error.message = "The activation link has expired. We are sending you a new one right now.";
|
|
573
|
+
let email = query.get("email");
|
|
574
|
+
if (email) {
|
|
575
|
+
error.email = email;
|
|
576
|
+
}
|
|
577
|
+
break;
|
|
578
|
+
}
|
|
579
|
+
case "auth/invalid-action-code":
|
|
580
|
+
error.message = "This link is invalid. Please try verifying email again.";
|
|
581
|
+
break;
|
|
582
|
+
case "auth/user-disabled":
|
|
583
|
+
error.message = "Your account has been disabled. Please contact our support.";
|
|
584
|
+
break;
|
|
585
|
+
}
|
|
586
|
+
console.log("🚀 ~ file: AuthContext.js:446 ~ error:", error);
|
|
587
|
+
this.setState({
|
|
588
|
+
verifyEmailError: error,
|
|
589
|
+
isVerifyingEmail: false,
|
|
590
|
+
isFetchingUser: false
|
|
591
|
+
});
|
|
592
|
+
}
|
|
593
|
+
};
|
|
594
|
+
handleResetPassword = async (password) => {
|
|
595
|
+
const { location } = this.props;
|
|
596
|
+
try {
|
|
597
|
+
const query = new URLSearchParams(location.search);
|
|
598
|
+
let oobCode = query.get("oobCode");
|
|
599
|
+
await Auth.handleResetPassword(oobCode, password);
|
|
600
|
+
} catch (error) {
|
|
601
|
+
switch (error?.code) {
|
|
602
|
+
case "auth/expired-action-code":
|
|
603
|
+
error.message = "This link has expired. Please try reseting password again.";
|
|
604
|
+
break;
|
|
605
|
+
case "auth/invalid-action-code":
|
|
606
|
+
error.message = "This link is invalid. Please try reseting password again.";
|
|
607
|
+
break;
|
|
608
|
+
case "auth/user-disabled":
|
|
609
|
+
error.message = "Your account has been disabled. Please contact our support.";
|
|
610
|
+
break;
|
|
611
|
+
}
|
|
612
|
+
throw error;
|
|
613
|
+
}
|
|
614
|
+
};
|
|
615
|
+
sendWelcomeEmail = async () => {
|
|
616
|
+
try {
|
|
617
|
+
await Auth.sendWelcomeEmail();
|
|
618
|
+
} catch (error) {
|
|
619
|
+
console.log(`Error sending welcome email: ${error}`);
|
|
620
|
+
}
|
|
621
|
+
};
|
|
622
|
+
uploaProofOfAddress = async (data, ip) => {
|
|
623
|
+
try {
|
|
624
|
+
const user = await Auth.uploaProofOfAddress(data, ip);
|
|
625
|
+
this.setUser(user);
|
|
626
|
+
} catch (error) {
|
|
627
|
+
console.log(`Error uploading proof of address: ${error}`);
|
|
628
|
+
throw error;
|
|
629
|
+
}
|
|
630
|
+
};
|
|
631
|
+
validateGreenWalletId = async (id) => {
|
|
632
|
+
try {
|
|
633
|
+
return await Auth.validateGreenWalletId(id);
|
|
634
|
+
} catch (error) {
|
|
635
|
+
console.log(`Error validating Green Wallet ID: ${error}`);
|
|
636
|
+
throw error;
|
|
637
|
+
}
|
|
638
|
+
};
|
|
639
|
+
createWallet = async (data) => {
|
|
640
|
+
try {
|
|
641
|
+
const wallet = await Auth.createWallet(data);
|
|
642
|
+
return wallet;
|
|
643
|
+
} catch (error) {
|
|
644
|
+
console.log(`Error creating wallet: ${error}`);
|
|
645
|
+
throw error;
|
|
646
|
+
}
|
|
647
|
+
};
|
|
648
|
+
setUser = (user) => {
|
|
649
|
+
this.userRef.current = user;
|
|
650
|
+
this.setState({ user });
|
|
651
|
+
};
|
|
652
|
+
fetchLastTime = async (projectName, page, userId) => {
|
|
653
|
+
try {
|
|
654
|
+
let filterBody = {
|
|
655
|
+
projectName,
|
|
656
|
+
page
|
|
657
|
+
};
|
|
658
|
+
if (userId) {
|
|
659
|
+
filterBody.userId = userId;
|
|
660
|
+
}
|
|
661
|
+
let response = await Auth.fetchTrackingUserLastTime({
|
|
662
|
+
filter: filterBody
|
|
663
|
+
});
|
|
664
|
+
return response;
|
|
665
|
+
} catch (error) {
|
|
666
|
+
console.log(" error", error);
|
|
667
|
+
}
|
|
668
|
+
};
|
|
669
|
+
render() {
|
|
670
|
+
const { children } = this.props;
|
|
671
|
+
return /* @__PURE__ */ jsxs(
|
|
672
|
+
AuthContext.Provider,
|
|
673
|
+
{
|
|
674
|
+
value: {
|
|
675
|
+
...this.state,
|
|
676
|
+
userRef: this.userRef,
|
|
677
|
+
checkUserIsValid: this.checkUserIsValid,
|
|
678
|
+
checkTokenIsValid: this.checkTokenIsValid,
|
|
679
|
+
checkUserPhoto: this.checkUserPhoto,
|
|
680
|
+
uploadPhoto: this.uploadPhoto,
|
|
681
|
+
deletePhoto: this.deletePhoto,
|
|
682
|
+
unenrollUser2FA: this.unenrollUser2FA,
|
|
683
|
+
loginUserWithTotp: this.loginUserWithTotp,
|
|
684
|
+
checkMfaEnrollment: this.checkMfaEnrollment,
|
|
685
|
+
generateTotpSecret: this.generateTotpSecret,
|
|
686
|
+
enrollUserToTotp: this.enrollUserToTotp,
|
|
687
|
+
loginUser: this.loginUser,
|
|
688
|
+
logoutUser: this.logoutUser,
|
|
689
|
+
getUser: this.getUser,
|
|
690
|
+
updateUser: this.updateUser,
|
|
691
|
+
checkIfPrivateInvestor: this.checkIfPrivateInvestor,
|
|
692
|
+
checkPrivateInvestorAll: this.checkPrivateInvestorAll,
|
|
693
|
+
checkIfUserSubscribed: this.checkIfUserSubscribed,
|
|
694
|
+
checkIfUserSubscribedAll: this.checkIfUserSubscribedAll,
|
|
695
|
+
sendWelcomeEmail: this.sendWelcomeEmail,
|
|
696
|
+
resendActivationEmail: Auth.resendActivationEmail,
|
|
697
|
+
uploaProofOfAddress: this.uploaProofOfAddress,
|
|
698
|
+
validateGreenWalletId: this.validateGreenWalletId,
|
|
699
|
+
fetchLastTime: this.fetchLastTime,
|
|
700
|
+
createWallet: this.createWallet,
|
|
701
|
+
requestUpdateEmail: Auth.requestUpdateEmail,
|
|
702
|
+
updatePassword: Auth.updateUserPassword,
|
|
703
|
+
createUser: this.createUser,
|
|
704
|
+
updateFirebaseUser: Auth.updateFirebaseUser,
|
|
705
|
+
handleResetPassword: this.handleResetPassword,
|
|
706
|
+
handleVerifyEmail: this.handleVerifyEmail,
|
|
707
|
+
setUser: this.setUser,
|
|
708
|
+
refreshIdToken: Auth.refreshIdToken,
|
|
709
|
+
clearLoggedOutDueToInactivity: this.clearLoggedOutDueToInactivity,
|
|
710
|
+
clearLoggedOutDueToCookieExpiry: this.clearLoggedOutDueToCookieExpiry,
|
|
711
|
+
reset2faFlow: this.reset2faFlow
|
|
712
|
+
},
|
|
713
|
+
children: [
|
|
714
|
+
children,
|
|
715
|
+
this.state.loggedOutDueToInactivity && !this.props.hideInactivityModal && /* @__PURE__ */ jsx(
|
|
716
|
+
ConfirmModalComponent,
|
|
717
|
+
{
|
|
718
|
+
isOpen: true,
|
|
719
|
+
maxWidth: "600px",
|
|
720
|
+
confirmText: "OK",
|
|
721
|
+
onCancel: this.clearLoggedOutDueToInactivity,
|
|
722
|
+
onConfirm: this.clearLoggedOutDueToInactivity,
|
|
723
|
+
showRedBar: true,
|
|
724
|
+
title: "Session expired",
|
|
725
|
+
content: /* @__PURE__ */ jsx(Text, { children: /* @__PURE__ */ jsx("p", { style: { fontSize: 16 }, children: "You have been logged out due to inactivity." }) })
|
|
726
|
+
}
|
|
727
|
+
),
|
|
728
|
+
this.state.loggedOutDueToCookieExpiry && !this.props.hideInactivityModal && /* @__PURE__ */ jsx(
|
|
729
|
+
ConfirmModalComponent,
|
|
730
|
+
{
|
|
731
|
+
isOpen: true,
|
|
732
|
+
maxWidth: "600px",
|
|
733
|
+
confirmText: "OK",
|
|
734
|
+
onCancel: this.clearLoggedOutDueToCookieExpiry,
|
|
735
|
+
onConfirm: this.clearLoggedOutDueToCookieExpiry,
|
|
736
|
+
showRedBar: true,
|
|
737
|
+
title: "Session expired",
|
|
738
|
+
content: /* @__PURE__ */ jsx(Text, { children: /* @__PURE__ */ jsx("p", { style: { fontSize: 16 }, children: "Your session has expired. Please log in again." }) })
|
|
739
|
+
}
|
|
740
|
+
)
|
|
741
|
+
]
|
|
742
|
+
}
|
|
743
|
+
);
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
AuthProviderClass.propTypes = {
|
|
747
|
+
children: PropTypes.node.isRequired,
|
|
748
|
+
/** Runtime config for the library. Sets API URLs, Firebase config, cookie domain, etc.
|
|
749
|
+
* When omitted, the library falls back to import.meta.env.VITE_* (Storybook / dev).
|
|
750
|
+
* When consumed as an npm package, pass this prop so values are available at runtime. */
|
|
751
|
+
config: PropTypes.shape({
|
|
752
|
+
apiUrl: PropTypes.string,
|
|
753
|
+
baseUrlPublic: PropTypes.string,
|
|
754
|
+
cookieDomain: PropTypes.string,
|
|
755
|
+
websiteDomain: PropTypes.string,
|
|
756
|
+
photoApiUrl: PropTypes.string,
|
|
757
|
+
firebase: PropTypes.shape({
|
|
758
|
+
apiKey: PropTypes.string,
|
|
759
|
+
authDomain: PropTypes.string,
|
|
760
|
+
projectId: PropTypes.string,
|
|
761
|
+
storageBucket: PropTypes.string,
|
|
762
|
+
messagingSenderId: PropTypes.string,
|
|
763
|
+
appId: PropTypes.string,
|
|
764
|
+
measurementId: PropTypes.string
|
|
765
|
+
})
|
|
766
|
+
}),
|
|
767
|
+
/** Override inactivity timeout in ms (e.g. for Storybook). Production uses 5 minutes. */
|
|
768
|
+
inactivityTimeMs: PropTypes.number,
|
|
769
|
+
/** When true, the inactivity modal is not shown after auto-logout. Default false. */
|
|
770
|
+
hideInactivityModal: PropTypes.bool,
|
|
771
|
+
/** Override access token cookie lifetime in ms (e.g. for Storybook). Production uses 1 hour. */
|
|
772
|
+
accessTokenExpiryMs: PropTypes.number
|
|
773
|
+
};
|
|
774
|
+
const AuthConsumer = AuthContext.Consumer;
|
|
775
|
+
const AuthProvider = withRouter(AuthProviderClass);
|
|
776
|
+
export {
|
|
777
|
+
AuthConsumer,
|
|
778
|
+
AuthContext,
|
|
779
|
+
AuthProvider,
|
|
780
|
+
DEFAULT_TOKEN_EXPIRY_MS
|
|
781
|
+
};
|