@oxyhq/services 5.13.0 → 5.13.2
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 +71 -0
- package/lib/commonjs/core/HttpClient.js +238 -0
- package/lib/commonjs/core/HttpClient.js.map +1 -0
- package/lib/commonjs/core/OxyServices.js +530 -332
- package/lib/commonjs/core/OxyServices.js.map +1 -1
- package/lib/commonjs/core/RequestManager.js +199 -0
- package/lib/commonjs/core/RequestManager.js.map +1 -0
- package/lib/commonjs/core/index.js +38 -1
- package/lib/commonjs/core/index.js.map +1 -1
- package/lib/commonjs/i18n/index.js +37 -1
- package/lib/commonjs/i18n/index.js.map +1 -1
- package/lib/commonjs/i18n/locales/ar-SA.json +128 -0
- package/lib/commonjs/i18n/locales/ca-ES.json +128 -0
- package/lib/commonjs/i18n/locales/de-DE.json +128 -0
- package/lib/commonjs/i18n/locales/en-US.json +85 -12
- package/lib/commonjs/i18n/locales/es-ES.json +58 -6
- package/lib/commonjs/i18n/locales/fr-FR.json +128 -0
- package/lib/commonjs/i18n/locales/it-IT.json +128 -0
- package/lib/commonjs/i18n/locales/ja-JP.json +127 -0
- package/lib/commonjs/i18n/locales/ko-KR.json +128 -0
- package/lib/commonjs/i18n/locales/pt-PT.json +128 -0
- package/lib/commonjs/i18n/locales/zh-CN.json +128 -0
- package/lib/commonjs/index.js +36 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/ui/components/Avatar.js +94 -27
- package/lib/commonjs/ui/components/Avatar.js.map +1 -1
- package/lib/commonjs/ui/components/FollowButton.js +1 -0
- package/lib/commonjs/ui/components/FollowButton.js.map +1 -1
- package/lib/commonjs/ui/components/FontLoader.js +22 -42
- package/lib/commonjs/ui/components/FontLoader.js.map +1 -1
- package/lib/commonjs/ui/components/OxyProvider.js +5 -8
- package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
- package/lib/commonjs/ui/components/StepBasedScreen.js +64 -44
- package/lib/commonjs/ui/components/StepBasedScreen.js.map +1 -1
- package/lib/commonjs/ui/components/internal/GroupedPillButtons.js +14 -35
- package/lib/commonjs/ui/components/internal/GroupedPillButtons.js.map +1 -1
- package/lib/commonjs/ui/components/internal/PinInput.js +2 -2
- package/lib/commonjs/ui/components/internal/PinInput.js.map +1 -1
- package/lib/commonjs/ui/components/internal/TextField.js +13 -8
- package/lib/commonjs/ui/components/internal/TextField.js.map +1 -1
- package/lib/commonjs/ui/context/OxyContext.js +443 -371
- package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
- package/lib/commonjs/ui/hooks/useSessionSocket.js +80 -22
- package/lib/commonjs/ui/hooks/useSessionSocket.js.map +1 -1
- package/lib/commonjs/ui/index.js +4 -1
- package/lib/commonjs/ui/index.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountSettingsScreen.js +32 -2
- package/lib/commonjs/ui/screens/AccountSettingsScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountSwitcherScreen.js +101 -59
- package/lib/commonjs/ui/screens/AccountSwitcherScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/FileManagementScreen.js +3 -2
- package/lib/commonjs/ui/screens/FileManagementScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/LanguageSelectorScreen.js +75 -117
- package/lib/commonjs/ui/screens/LanguageSelectorScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/SignInScreen.js +43 -50
- package/lib/commonjs/ui/screens/SignInScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/SignUpScreen.js +14 -16
- package/lib/commonjs/ui/screens/SignUpScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/WelcomeNewUserScreen.js +188 -142
- package/lib/commonjs/ui/screens/WelcomeNewUserScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/internal/SignInPasswordStep.js +10 -10
- package/lib/commonjs/ui/screens/internal/SignInPasswordStep.js.map +1 -1
- package/lib/commonjs/ui/screens/internal/SignInUsernameStep.js +2 -4
- package/lib/commonjs/ui/screens/internal/SignInUsernameStep.js.map +1 -1
- package/lib/commonjs/ui/screens/steps/RecoverRequestStep.js +45 -25
- package/lib/commonjs/ui/screens/steps/RecoverRequestStep.js.map +1 -1
- package/lib/commonjs/ui/screens/steps/RecoverResetPasswordStep.js +88 -53
- package/lib/commonjs/ui/screens/steps/RecoverResetPasswordStep.js.map +1 -1
- package/lib/commonjs/ui/screens/steps/RecoverSuccessStep.js +79 -58
- package/lib/commonjs/ui/screens/steps/RecoverSuccessStep.js.map +1 -1
- package/lib/commonjs/ui/screens/steps/RecoverVerifyStep.js +61 -52
- package/lib/commonjs/ui/screens/steps/RecoverVerifyStep.js.map +1 -1
- package/lib/commonjs/ui/screens/steps/SignInPasswordStep.js +218 -39
- package/lib/commonjs/ui/screens/steps/SignInPasswordStep.js.map +1 -1
- package/lib/commonjs/ui/screens/steps/SignInTotpStep.js +77 -50
- package/lib/commonjs/ui/screens/steps/SignInTotpStep.js.map +1 -1
- package/lib/commonjs/ui/screens/steps/SignInUsernameStep.js +424 -71
- package/lib/commonjs/ui/screens/steps/SignInUsernameStep.js.map +1 -1
- package/lib/commonjs/ui/screens/steps/SignUpIdentityStep.js +55 -30
- package/lib/commonjs/ui/screens/steps/SignUpIdentityStep.js.map +1 -1
- package/lib/commonjs/ui/screens/steps/SignUpSecurityStep.js +64 -46
- package/lib/commonjs/ui/screens/steps/SignUpSecurityStep.js.map +1 -1
- package/lib/commonjs/ui/screens/steps/SignUpSummaryStep.js +84 -146
- package/lib/commonjs/ui/screens/steps/SignUpSummaryStep.js.map +1 -1
- package/lib/commonjs/ui/screens/steps/SignUpWelcomeStep.js +113 -34
- package/lib/commonjs/ui/screens/steps/SignUpWelcomeStep.js.map +1 -1
- package/lib/commonjs/ui/stores/accountStore.js +237 -0
- package/lib/commonjs/ui/stores/accountStore.js.map +1 -0
- package/lib/commonjs/ui/stores/authStore.js +17 -20
- package/lib/commonjs/ui/stores/authStore.js.map +1 -1
- package/lib/commonjs/ui/styles/authStyles.js +16 -8
- package/lib/commonjs/ui/styles/authStyles.js.map +1 -1
- package/lib/commonjs/ui/styles/index.js +11 -0
- package/lib/commonjs/ui/styles/index.js.map +1 -1
- package/lib/commonjs/ui/styles/spacing.js +51 -0
- package/lib/commonjs/ui/styles/spacing.js.map +1 -0
- package/lib/commonjs/utils/asyncUtils.js +9 -22
- package/lib/commonjs/utils/asyncUtils.js.map +1 -1
- package/lib/commonjs/utils/cache.js +259 -0
- package/lib/commonjs/utils/cache.js.map +1 -0
- package/lib/commonjs/utils/index.js +99 -0
- package/lib/commonjs/utils/index.js.map +1 -1
- package/lib/commonjs/utils/languageUtils.js +159 -0
- package/lib/commonjs/utils/languageUtils.js.map +1 -0
- package/lib/commonjs/utils/requestUtils.js +217 -0
- package/lib/commonjs/utils/requestUtils.js.map +1 -0
- package/lib/commonjs/utils/sessionUtils.js +191 -0
- package/lib/commonjs/utils/sessionUtils.js.map +1 -0
- package/lib/commonjs/utils/validationUtils.js +1 -1
- package/lib/module/core/HttpClient.js +232 -0
- package/lib/module/core/HttpClient.js.map +1 -0
- package/lib/module/core/OxyServices.js +528 -326
- package/lib/module/core/OxyServices.js.map +1 -1
- package/lib/module/core/RequestManager.js +194 -0
- package/lib/module/core/RequestManager.js.map +1 -0
- package/lib/module/core/index.js +2 -0
- package/lib/module/core/index.js.map +1 -1
- package/lib/module/i18n/index.js +37 -1
- package/lib/module/i18n/index.js.map +1 -1
- package/lib/module/i18n/locales/ar-SA.json +128 -0
- package/lib/module/i18n/locales/ca-ES.json +128 -0
- package/lib/module/i18n/locales/de-DE.json +128 -0
- package/lib/module/i18n/locales/en-US.json +85 -12
- package/lib/module/i18n/locales/es-ES.json +58 -6
- package/lib/module/i18n/locales/fr-FR.json +128 -0
- package/lib/module/i18n/locales/it-IT.json +128 -0
- package/lib/module/i18n/locales/ja-JP.json +127 -0
- package/lib/module/i18n/locales/ko-KR.json +128 -0
- package/lib/module/i18n/locales/pt-PT.json +128 -0
- package/lib/module/i18n/locales/zh-CN.json +128 -0
- package/lib/module/index.js +2 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/ui/components/Avatar.js +94 -27
- package/lib/module/ui/components/Avatar.js.map +1 -1
- package/lib/module/ui/components/FollowButton.js +1 -0
- package/lib/module/ui/components/FollowButton.js.map +1 -1
- package/lib/module/ui/components/FontLoader.js +23 -43
- package/lib/module/ui/components/FontLoader.js.map +1 -1
- package/lib/module/ui/components/OxyProvider.js +6 -8
- package/lib/module/ui/components/OxyProvider.js.map +1 -1
- package/lib/module/ui/components/StepBasedScreen.js +65 -45
- package/lib/module/ui/components/StepBasedScreen.js.map +1 -1
- package/lib/module/ui/components/internal/GroupedPillButtons.js +14 -35
- package/lib/module/ui/components/internal/GroupedPillButtons.js.map +1 -1
- package/lib/module/ui/components/internal/PinInput.js +2 -2
- package/lib/module/ui/components/internal/PinInput.js.map +1 -1
- package/lib/module/ui/components/internal/TextField.js +13 -8
- package/lib/module/ui/components/internal/TextField.js.map +1 -1
- package/lib/module/ui/context/OxyContext.js +442 -370
- package/lib/module/ui/context/OxyContext.js.map +1 -1
- package/lib/module/ui/hooks/useSessionSocket.js +80 -22
- package/lib/module/ui/hooks/useSessionSocket.js.map +1 -1
- package/lib/module/ui/index.js +4 -2
- package/lib/module/ui/index.js.map +1 -1
- package/lib/module/ui/screens/AccountSettingsScreen.js +33 -2
- package/lib/module/ui/screens/AccountSettingsScreen.js.map +1 -1
- package/lib/module/ui/screens/AccountSwitcherScreen.js +102 -60
- package/lib/module/ui/screens/AccountSwitcherScreen.js.map +1 -1
- package/lib/module/ui/screens/FileManagementScreen.js +3 -2
- package/lib/module/ui/screens/FileManagementScreen.js.map +1 -1
- package/lib/module/ui/screens/LanguageSelectorScreen.js +73 -117
- package/lib/module/ui/screens/LanguageSelectorScreen.js.map +1 -1
- package/lib/module/ui/screens/SignInScreen.js +44 -51
- package/lib/module/ui/screens/SignInScreen.js.map +1 -1
- package/lib/module/ui/screens/SignUpScreen.js +14 -16
- package/lib/module/ui/screens/SignUpScreen.js.map +1 -1
- package/lib/module/ui/screens/WelcomeNewUserScreen.js +187 -143
- package/lib/module/ui/screens/WelcomeNewUserScreen.js.map +1 -1
- package/lib/module/ui/screens/internal/SignInPasswordStep.js +10 -10
- package/lib/module/ui/screens/internal/SignInPasswordStep.js.map +1 -1
- package/lib/module/ui/screens/internal/SignInUsernameStep.js +2 -4
- package/lib/module/ui/screens/internal/SignInUsernameStep.js.map +1 -1
- package/lib/module/ui/screens/steps/RecoverRequestStep.js +45 -25
- package/lib/module/ui/screens/steps/RecoverRequestStep.js.map +1 -1
- package/lib/module/ui/screens/steps/RecoverResetPasswordStep.js +89 -54
- package/lib/module/ui/screens/steps/RecoverResetPasswordStep.js.map +1 -1
- package/lib/module/ui/screens/steps/RecoverSuccessStep.js +80 -59
- package/lib/module/ui/screens/steps/RecoverSuccessStep.js.map +1 -1
- package/lib/module/ui/screens/steps/RecoverVerifyStep.js +62 -53
- package/lib/module/ui/screens/steps/RecoverVerifyStep.js.map +1 -1
- package/lib/module/ui/screens/steps/SignInPasswordStep.js +219 -40
- package/lib/module/ui/screens/steps/SignInPasswordStep.js.map +1 -1
- package/lib/module/ui/screens/steps/SignInTotpStep.js +78 -51
- package/lib/module/ui/screens/steps/SignInTotpStep.js.map +1 -1
- package/lib/module/ui/screens/steps/SignInUsernameStep.js +426 -73
- package/lib/module/ui/screens/steps/SignInUsernameStep.js.map +1 -1
- package/lib/module/ui/screens/steps/SignUpIdentityStep.js +55 -30
- package/lib/module/ui/screens/steps/SignUpIdentityStep.js.map +1 -1
- package/lib/module/ui/screens/steps/SignUpSecurityStep.js +65 -47
- package/lib/module/ui/screens/steps/SignUpSecurityStep.js.map +1 -1
- package/lib/module/ui/screens/steps/SignUpSummaryStep.js +84 -146
- package/lib/module/ui/screens/steps/SignUpSummaryStep.js.map +1 -1
- package/lib/module/ui/screens/steps/SignUpWelcomeStep.js +114 -35
- package/lib/module/ui/screens/steps/SignUpWelcomeStep.js.map +1 -1
- package/lib/module/ui/stores/accountStore.js +229 -0
- package/lib/module/ui/stores/accountStore.js.map +1 -0
- package/lib/module/ui/stores/authStore.js +17 -20
- package/lib/module/ui/stores/authStore.js.map +1 -1
- package/lib/module/ui/styles/authStyles.js +16 -8
- package/lib/module/ui/styles/authStyles.js.map +1 -1
- package/lib/module/ui/styles/index.js +1 -0
- package/lib/module/ui/styles/index.js.map +1 -1
- package/lib/module/ui/styles/spacing.js +48 -0
- package/lib/module/ui/styles/spacing.js.map +1 -0
- package/lib/module/utils/asyncUtils.js +10 -22
- package/lib/module/utils/asyncUtils.js.map +1 -1
- package/lib/module/utils/cache.js +250 -0
- package/lib/module/utils/cache.js.map +1 -0
- package/lib/module/utils/index.js +7 -0
- package/lib/module/utils/index.js.map +1 -1
- package/lib/module/utils/languageUtils.js +151 -0
- package/lib/module/utils/languageUtils.js.map +1 -0
- package/lib/module/utils/requestUtils.js +210 -0
- package/lib/module/utils/requestUtils.js.map +1 -0
- package/lib/module/utils/sessionUtils.js +180 -0
- package/lib/module/utils/sessionUtils.js.map +1 -0
- package/lib/module/utils/validationUtils.js +1 -1
- package/lib/typescript/core/HttpClient.d.ts +64 -0
- package/lib/typescript/core/HttpClient.d.ts.map +1 -0
- package/lib/typescript/core/OxyServices.d.ts +86 -73
- package/lib/typescript/core/OxyServices.d.ts.map +1 -1
- package/lib/typescript/core/RequestManager.d.ts +67 -0
- package/lib/typescript/core/RequestManager.d.ts.map +1 -0
- package/lib/typescript/core/index.d.ts +2 -0
- package/lib/typescript/core/index.d.ts.map +1 -1
- package/lib/typescript/i18n/index.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +2 -0
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/models/interfaces.d.ts +15 -0
- package/lib/typescript/models/interfaces.d.ts.map +1 -1
- package/lib/typescript/models/session.d.ts +1 -0
- package/lib/typescript/models/session.d.ts.map +1 -1
- package/lib/typescript/ui/components/Avatar.d.ts +6 -7
- package/lib/typescript/ui/components/Avatar.d.ts.map +1 -1
- package/lib/typescript/ui/components/FollowButton.d.ts.map +1 -1
- package/lib/typescript/ui/components/FontLoader.d.ts +3 -3
- package/lib/typescript/ui/components/FontLoader.d.ts.map +1 -1
- package/lib/typescript/ui/components/OxyProvider.d.ts +2 -2
- package/lib/typescript/ui/components/OxyProvider.d.ts.map +1 -1
- package/lib/typescript/ui/components/StepBasedScreen.d.ts.map +1 -1
- package/lib/typescript/ui/components/internal/GroupedPillButtons.d.ts.map +1 -1
- package/lib/typescript/ui/components/internal/TextField.d.ts.map +1 -1
- package/lib/typescript/ui/context/OxyContext.d.ts +5 -0
- package/lib/typescript/ui/context/OxyContext.d.ts.map +1 -1
- package/lib/typescript/ui/hooks/useSessionSocket.d.ts.map +1 -1
- package/lib/typescript/ui/index.d.ts +2 -2
- package/lib/typescript/ui/index.d.ts.map +1 -1
- package/lib/typescript/ui/screens/AccountSettingsScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/AccountSwitcherScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/LanguageSelectorScreen.d.ts +3 -3
- package/lib/typescript/ui/screens/LanguageSelectorScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/SignInScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/SignUpScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/WelcomeNewUserScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/internal/SignInPasswordStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/steps/RecoverRequestStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/steps/RecoverResetPasswordStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/steps/RecoverSuccessStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/steps/RecoverVerifyStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/steps/SignInPasswordStep.d.ts +2 -0
- package/lib/typescript/ui/screens/steps/SignInPasswordStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/steps/SignInTotpStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/steps/SignInUsernameStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/steps/SignUpIdentityStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/steps/SignUpSecurityStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/steps/SignUpSummaryStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/steps/SignUpWelcomeStep.d.ts.map +1 -1
- package/lib/typescript/ui/stores/accountStore.d.ts +34 -0
- package/lib/typescript/ui/stores/accountStore.d.ts.map +1 -0
- package/lib/typescript/ui/stores/authStore.d.ts +7 -3
- package/lib/typescript/ui/stores/authStore.d.ts.map +1 -1
- package/lib/typescript/ui/styles/authStyles.d.ts +19 -2
- package/lib/typescript/ui/styles/authStyles.d.ts.map +1 -1
- package/lib/typescript/ui/styles/index.d.ts +1 -0
- package/lib/typescript/ui/styles/index.d.ts.map +1 -1
- package/lib/typescript/ui/styles/spacing.d.ts +43 -0
- package/lib/typescript/ui/styles/spacing.d.ts.map +1 -0
- package/lib/typescript/utils/asyncUtils.d.ts +2 -0
- package/lib/typescript/utils/asyncUtils.d.ts.map +1 -1
- package/lib/typescript/utils/cache.d.ts +128 -0
- package/lib/typescript/utils/cache.d.ts.map +1 -0
- package/lib/typescript/utils/index.d.ts +4 -0
- package/lib/typescript/utils/index.d.ts.map +1 -1
- package/lib/typescript/utils/languageUtils.d.ts +38 -0
- package/lib/typescript/utils/languageUtils.d.ts.map +1 -0
- package/lib/typescript/utils/requestUtils.d.ts +122 -0
- package/lib/typescript/utils/requestUtils.d.ts.map +1 -0
- package/lib/typescript/utils/sessionUtils.d.ts +55 -0
- package/lib/typescript/utils/sessionUtils.d.ts.map +1 -0
- package/lib/typescript/utils/validationUtils.d.ts +1 -1
- package/package.json +1 -1
- package/src/core/HttpClient.ts +277 -0
- package/src/core/OxyServices.ts +461 -352
- package/src/core/RequestManager.ts +240 -0
- package/src/core/index.ts +10 -0
- package/src/i18n/index.ts +36 -0
- package/src/i18n/locales/ar-SA.json +128 -0
- package/src/i18n/locales/ca-ES.json +128 -0
- package/src/i18n/locales/de-DE.json +128 -0
- package/src/i18n/locales/en-US.json +85 -12
- package/src/i18n/locales/es-ES.json +58 -6
- package/src/i18n/locales/fr-FR.json +128 -0
- package/src/i18n/locales/it-IT.json +128 -0
- package/src/i18n/locales/ja-JP.json +127 -0
- package/src/i18n/locales/ko-KR.json +128 -0
- package/src/i18n/locales/pt-PT.json +128 -0
- package/src/i18n/locales/zh-CN.json +128 -0
- package/src/index.ts +10 -0
- package/src/models/interfaces.ts +19 -0
- package/src/models/session.ts +1 -1
- package/src/ui/components/Avatar.tsx +151 -35
- package/src/ui/components/FollowButton.tsx +1 -0
- package/src/ui/components/FontLoader.tsx +17 -37
- package/src/ui/components/OxyProvider.tsx +14 -13
- package/src/ui/components/StepBasedScreen.tsx +66 -43
- package/src/ui/components/internal/GroupedPillButtons.tsx +15 -31
- package/src/ui/components/internal/PinInput.tsx +2 -2
- package/src/ui/components/internal/TextField.tsx +7 -6
- package/src/ui/context/OxyContext.tsx +441 -326
- package/src/ui/hooks/useSessionSocket.ts +72 -18
- package/src/ui/index.ts +4 -1
- package/src/ui/screens/AccountSettingsScreen.tsx +34 -2
- package/src/ui/screens/AccountSwitcherScreen.tsx +102 -68
- package/src/ui/screens/FileManagementScreen.tsx +16 -16
- package/src/ui/screens/LanguageSelectorScreen.tsx +86 -143
- package/src/ui/screens/SignInScreen.tsx +59 -43
- package/src/ui/screens/SignUpScreen.tsx +14 -15
- package/src/ui/screens/WelcomeNewUserScreen.tsx +153 -105
- package/src/ui/screens/internal/SignInPasswordStep.tsx +4 -6
- package/src/ui/screens/internal/SignInUsernameStep.tsx +1 -1
- package/src/ui/screens/steps/RecoverRequestStep.tsx +34 -24
- package/src/ui/screens/steps/RecoverResetPasswordStep.tsx +65 -36
- package/src/ui/screens/steps/RecoverSuccessStep.tsx +71 -47
- package/src/ui/screens/steps/RecoverVerifyStep.tsx +60 -50
- package/src/ui/screens/steps/SignInPasswordStep.tsx +190 -32
- package/src/ui/screens/steps/SignInTotpStep.tsx +68 -34
- package/src/ui/screens/steps/SignInUsernameStep.tsx +446 -63
- package/src/ui/screens/steps/SignUpIdentityStep.tsx +49 -35
- package/src/ui/screens/steps/SignUpSecurityStep.tsx +56 -39
- package/src/ui/screens/steps/SignUpSummaryStep.tsx +99 -89
- package/src/ui/screens/steps/SignUpWelcomeStep.tsx +88 -20
- package/src/ui/stores/accountStore.ts +285 -0
- package/src/ui/stores/authStore.ts +16 -19
- package/src/ui/styles/authStyles.ts +16 -8
- package/src/ui/styles/index.ts +1 -0
- package/src/ui/styles/spacing.ts +46 -0
- package/src/utils/asyncUtils.ts +10 -24
- package/src/utils/cache.ts +264 -0
- package/src/utils/index.ts +19 -0
- package/src/utils/languageUtils.ts +174 -0
- package/src/utils/requestUtils.ts +234 -0
- package/src/utils/sessionUtils.ts +206 -0
- package/src/utils/validationUtils.ts +1 -1
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.SimpleLogger = exports.RequestQueue = exports.RequestDeduplicator = void 0;
|
|
7
|
+
/**
|
|
8
|
+
* Request utilities for HTTP clients
|
|
9
|
+
*
|
|
10
|
+
* Provides reusable components for request deduplication, queuing, and logging
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Request deduplication - prevents duplicate concurrent requests
|
|
15
|
+
*
|
|
16
|
+
* When multiple requests with the same key are made simultaneously,
|
|
17
|
+
* only one request is executed and all callers receive the same result.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* const deduplicator = new RequestDeduplicator();
|
|
22
|
+
*
|
|
23
|
+
* // Multiple calls with same key will share the same promise
|
|
24
|
+
* const promise1 = deduplicator.deduplicate('user-123', () => fetchUser('123'));
|
|
25
|
+
* const promise2 = deduplicator.deduplicate('user-123', () => fetchUser('123'));
|
|
26
|
+
* // promise1 === promise2, only one API call is made
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
class RequestDeduplicator {
|
|
30
|
+
pendingRequests = new Map();
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Deduplicate a request by key
|
|
34
|
+
* @param key Unique key for the request
|
|
35
|
+
* @param requestFn Function that returns a promise
|
|
36
|
+
* @returns Promise that will be shared if key already exists
|
|
37
|
+
*/
|
|
38
|
+
async deduplicate(key, requestFn) {
|
|
39
|
+
const existing = this.pendingRequests.get(key);
|
|
40
|
+
if (existing) {
|
|
41
|
+
return existing;
|
|
42
|
+
}
|
|
43
|
+
const promise = requestFn().finally(() => {
|
|
44
|
+
this.pendingRequests.delete(key);
|
|
45
|
+
});
|
|
46
|
+
this.pendingRequests.set(key, promise);
|
|
47
|
+
return promise;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Clear all pending requests
|
|
52
|
+
*/
|
|
53
|
+
clear() {
|
|
54
|
+
this.pendingRequests.clear();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Get number of pending requests
|
|
59
|
+
*/
|
|
60
|
+
size() {
|
|
61
|
+
return this.pendingRequests.size;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Request queue with concurrency control
|
|
67
|
+
*
|
|
68
|
+
* Limits the number of concurrent requests and queues excess requests.
|
|
69
|
+
* Useful for rate limiting and preventing request flooding.
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```typescript
|
|
73
|
+
* const queue = new RequestQueue(5, 100); // Max 5 concurrent, queue up to 100
|
|
74
|
+
*
|
|
75
|
+
* // All requests will be queued and processed with max 5 concurrent
|
|
76
|
+
* await queue.enqueue(() => fetchUser('1'));
|
|
77
|
+
* await queue.enqueue(() => fetchUser('2'));
|
|
78
|
+
* // ...
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
exports.RequestDeduplicator = RequestDeduplicator;
|
|
82
|
+
class RequestQueue {
|
|
83
|
+
queue = [];
|
|
84
|
+
running = 0;
|
|
85
|
+
/**
|
|
86
|
+
* Create a new request queue
|
|
87
|
+
* @param maxConcurrent Maximum number of concurrent requests (default: 10)
|
|
88
|
+
* @param maxQueueSize Maximum queue size (default: 100)
|
|
89
|
+
*/
|
|
90
|
+
constructor(maxConcurrent = 10, maxQueueSize = 100) {
|
|
91
|
+
this.maxConcurrent = maxConcurrent;
|
|
92
|
+
this.maxQueueSize = maxQueueSize;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Enqueue a request
|
|
97
|
+
* @param requestFn Function that returns a promise
|
|
98
|
+
* @returns Promise that resolves when request completes
|
|
99
|
+
*/
|
|
100
|
+
async enqueue(requestFn) {
|
|
101
|
+
if (this.queue.length >= this.maxQueueSize) {
|
|
102
|
+
throw new Error('Request queue is full');
|
|
103
|
+
}
|
|
104
|
+
return new Promise((resolve, reject) => {
|
|
105
|
+
this.queue.push(async () => {
|
|
106
|
+
try {
|
|
107
|
+
const result = await requestFn();
|
|
108
|
+
resolve(result);
|
|
109
|
+
} catch (error) {
|
|
110
|
+
reject(error);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
this.process();
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Process queued requests
|
|
119
|
+
*/
|
|
120
|
+
async process() {
|
|
121
|
+
if (this.running >= this.maxConcurrent || this.queue.length === 0) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
this.running++;
|
|
125
|
+
const requestFn = this.queue.shift();
|
|
126
|
+
if (requestFn) {
|
|
127
|
+
try {
|
|
128
|
+
await requestFn();
|
|
129
|
+
} finally {
|
|
130
|
+
this.running--;
|
|
131
|
+
this.process();
|
|
132
|
+
}
|
|
133
|
+
} else {
|
|
134
|
+
this.running--;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Clear all queued requests
|
|
140
|
+
*/
|
|
141
|
+
clear() {
|
|
142
|
+
this.queue = [];
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Get queue size
|
|
147
|
+
*/
|
|
148
|
+
size() {
|
|
149
|
+
return this.queue.length;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Get number of currently running requests
|
|
154
|
+
*/
|
|
155
|
+
runningCount() {
|
|
156
|
+
return this.running;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Simple logger with level support
|
|
162
|
+
*
|
|
163
|
+
* Lightweight logger for HTTP clients and utilities.
|
|
164
|
+
* For more advanced logging, use loggerUtils.ts
|
|
165
|
+
*
|
|
166
|
+
* @example
|
|
167
|
+
* ```typescript
|
|
168
|
+
* const logger = new SimpleLogger(true, 'debug');
|
|
169
|
+
* logger.debug('Debug message');
|
|
170
|
+
* logger.info('Info message');
|
|
171
|
+
* logger.error('Error message');
|
|
172
|
+
* ```
|
|
173
|
+
*/
|
|
174
|
+
exports.RequestQueue = RequestQueue;
|
|
175
|
+
class SimpleLogger {
|
|
176
|
+
/**
|
|
177
|
+
* Create a new simple logger
|
|
178
|
+
* @param enabled Whether logging is enabled
|
|
179
|
+
* @param level Minimum log level
|
|
180
|
+
* @param prefix Prefix for log messages (default: '')
|
|
181
|
+
*/
|
|
182
|
+
constructor(enabled = false, level = 'error', prefix = '') {
|
|
183
|
+
this.enabled = enabled;
|
|
184
|
+
this.level = level;
|
|
185
|
+
this.prefix = prefix;
|
|
186
|
+
}
|
|
187
|
+
shouldLog(level) {
|
|
188
|
+
if (!this.enabled || this.level === 'none') return false;
|
|
189
|
+
const levels = ['none', 'error', 'warn', 'info', 'debug'];
|
|
190
|
+
return levels.indexOf(level) <= levels.indexOf(this.level);
|
|
191
|
+
}
|
|
192
|
+
formatMessage(...args) {
|
|
193
|
+
return this.prefix ? [`[${this.prefix}]`, ...args] : args;
|
|
194
|
+
}
|
|
195
|
+
error(...args) {
|
|
196
|
+
if (this.shouldLog('error')) {
|
|
197
|
+
console.error(...this.formatMessage(...args));
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
warn(...args) {
|
|
201
|
+
if (this.shouldLog('warn')) {
|
|
202
|
+
console.warn(...this.formatMessage(...args));
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
info(...args) {
|
|
206
|
+
if (this.shouldLog('info')) {
|
|
207
|
+
console.info(...this.formatMessage(...args));
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
debug(...args) {
|
|
211
|
+
if (this.shouldLog('debug')) {
|
|
212
|
+
console.log(...this.formatMessage(...args));
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
exports.SimpleLogger = SimpleLogger;
|
|
217
|
+
//# sourceMappingURL=requestUtils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["RequestDeduplicator","pendingRequests","Map","deduplicate","key","requestFn","existing","get","promise","finally","delete","set","clear","size","exports","RequestQueue","queue","running","constructor","maxConcurrent","maxQueueSize","enqueue","length","Error","Promise","resolve","reject","push","result","error","process","shift","runningCount","SimpleLogger","enabled","level","prefix","shouldLog","levels","indexOf","formatMessage","args","console","warn","info","debug","log"],"sourceRoot":"../../../src","sources":["utils/requestUtils.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.deduplicateSessions = deduplicateSessions;
|
|
7
|
+
exports.deduplicateSessionsByUserId = deduplicateSessionsByUserId;
|
|
8
|
+
exports.mergeSessions = mergeSessions;
|
|
9
|
+
exports.normalizeAndSortSessions = normalizeAndSortSessions;
|
|
10
|
+
exports.normalizeSession = normalizeSession;
|
|
11
|
+
exports.sessionsArraysEqual = sessionsArraysEqual;
|
|
12
|
+
exports.sessionsEqual = sessionsEqual;
|
|
13
|
+
exports.sortSessions = sortSessions;
|
|
14
|
+
/**
|
|
15
|
+
* Session management utilities
|
|
16
|
+
*
|
|
17
|
+
* Provides consistent session normalization, deduplication, and sorting
|
|
18
|
+
* to ensure sessions are always displayed in a predictable order.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Normalize a session to ensure all required fields are present
|
|
23
|
+
*/
|
|
24
|
+
function normalizeSession(session) {
|
|
25
|
+
const now = new Date().toISOString();
|
|
26
|
+
return {
|
|
27
|
+
sessionId: session.sessionId,
|
|
28
|
+
deviceId: session.deviceId || '',
|
|
29
|
+
expiresAt: session.expiresAt || now,
|
|
30
|
+
lastActive: session.lastActive || now,
|
|
31
|
+
userId: session.userId || ''
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Compare two sessions for equality
|
|
37
|
+
*/
|
|
38
|
+
function sessionsEqual(a, b) {
|
|
39
|
+
return a.sessionId === b.sessionId;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Sort sessions by lastActive (most recent first), then by sessionId for stability
|
|
44
|
+
*/
|
|
45
|
+
function sortSessions(sessions) {
|
|
46
|
+
return [...sessions].sort((a, b) => {
|
|
47
|
+
// Sort by lastActive descending (most recent first)
|
|
48
|
+
const timeA = new Date(a.lastActive).getTime();
|
|
49
|
+
const timeB = new Date(b.lastActive).getTime();
|
|
50
|
+
if (timeA !== timeB) {
|
|
51
|
+
return timeB - timeA; // Descending order
|
|
52
|
+
}
|
|
53
|
+
// If lastActive is the same, sort by sessionId for stability
|
|
54
|
+
return a.sessionId.localeCompare(b.sessionId);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Deduplicate sessions by sessionId, keeping the most recent version
|
|
60
|
+
*/
|
|
61
|
+
function deduplicateSessions(sessions) {
|
|
62
|
+
const sessionMap = new Map();
|
|
63
|
+
for (const session of sessions) {
|
|
64
|
+
const existing = sessionMap.get(session.sessionId);
|
|
65
|
+
if (!existing) {
|
|
66
|
+
sessionMap.set(session.sessionId, session);
|
|
67
|
+
} else {
|
|
68
|
+
// Keep the one with more recent lastActive
|
|
69
|
+
const existingTime = new Date(existing.lastActive).getTime();
|
|
70
|
+
const currentTime = new Date(session.lastActive).getTime();
|
|
71
|
+
if (currentTime > existingTime) {
|
|
72
|
+
sessionMap.set(session.sessionId, session);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return Array.from(sessionMap.values());
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Deduplicate sessions by userId, keeping only one session per user
|
|
81
|
+
* Priority: 1) Active session (if provided), 2) Most recent session
|
|
82
|
+
* This prevents showing duplicate accounts for the same user
|
|
83
|
+
*/
|
|
84
|
+
function deduplicateSessionsByUserId(sessions, activeSessionId) {
|
|
85
|
+
if (!sessions.length) return [];
|
|
86
|
+
const userSessionMap = new Map();
|
|
87
|
+
for (const session of sessions) {
|
|
88
|
+
if (!session.userId) continue; // Skip sessions without userId
|
|
89
|
+
|
|
90
|
+
const existing = userSessionMap.get(session.userId);
|
|
91
|
+
if (!existing) {
|
|
92
|
+
userSessionMap.set(session.userId, session);
|
|
93
|
+
} else {
|
|
94
|
+
// Prioritize active session
|
|
95
|
+
const isCurrentActive = activeSessionId && session.sessionId === activeSessionId;
|
|
96
|
+
const isExistingActive = activeSessionId && existing.sessionId === activeSessionId;
|
|
97
|
+
if (isCurrentActive && !isExistingActive) {
|
|
98
|
+
userSessionMap.set(session.userId, session);
|
|
99
|
+
} else if (!isCurrentActive && isExistingActive) {
|
|
100
|
+
// Keep existing (active) session
|
|
101
|
+
continue;
|
|
102
|
+
} else {
|
|
103
|
+
// Neither is active, keep the one with more recent lastActive
|
|
104
|
+
const existingTime = new Date(existing.lastActive).getTime();
|
|
105
|
+
const currentTime = new Date(session.lastActive).getTime();
|
|
106
|
+
if (currentTime > existingTime) {
|
|
107
|
+
userSessionMap.set(session.userId, session);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return Array.from(userSessionMap.values());
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Normalize, deduplicate, and sort sessions
|
|
117
|
+
* This ensures consistent session ordering across the application
|
|
118
|
+
*
|
|
119
|
+
* @param sessions - Array of sessions to normalize
|
|
120
|
+
* @param activeSessionId - Optional active session ID to prioritize
|
|
121
|
+
* @param deduplicateByUserId - If true, deduplicate by userId (one account per user). Default: true
|
|
122
|
+
*/
|
|
123
|
+
function normalizeAndSortSessions(sessions, activeSessionId, deduplicateByUserId = true) {
|
|
124
|
+
if (!sessions.length) return [];
|
|
125
|
+
|
|
126
|
+
// Normalize all sessions
|
|
127
|
+
const normalized = sessions.map(normalizeSession);
|
|
128
|
+
|
|
129
|
+
// First deduplicate by sessionId (exact duplicates)
|
|
130
|
+
const deduplicatedBySessionId = deduplicateSessions(normalized);
|
|
131
|
+
|
|
132
|
+
// Then deduplicate by userId if requested (one account per user)
|
|
133
|
+
const finalSessions = deduplicateByUserId ? deduplicateSessionsByUserId(deduplicatedBySessionId, activeSessionId) : deduplicatedBySessionId;
|
|
134
|
+
|
|
135
|
+
// Sort consistently
|
|
136
|
+
return sortSessions(finalSessions);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Merge two session arrays, prioritizing newer data
|
|
141
|
+
* Returns normalized, deduplicated, and sorted sessions
|
|
142
|
+
*
|
|
143
|
+
* @param existing - Existing sessions array
|
|
144
|
+
* @param incoming - New sessions to merge in
|
|
145
|
+
* @param activeSessionId - Optional active session ID to prioritize
|
|
146
|
+
* @param deduplicateByUserId - If true, deduplicate by userId (one account per user). Default: true
|
|
147
|
+
*/
|
|
148
|
+
function mergeSessions(existing, incoming, activeSessionId, deduplicateByUserId = true) {
|
|
149
|
+
if (!existing.length && !incoming.length) return [];
|
|
150
|
+
if (!existing.length) return normalizeAndSortSessions(incoming, activeSessionId, deduplicateByUserId);
|
|
151
|
+
if (!incoming.length) return normalizeAndSortSessions(existing, activeSessionId, deduplicateByUserId);
|
|
152
|
+
|
|
153
|
+
// Normalize both arrays
|
|
154
|
+
const normalizedExisting = existing.map(normalizeSession);
|
|
155
|
+
const normalizedIncoming = incoming.map(normalizeSession);
|
|
156
|
+
|
|
157
|
+
// Create a map with existing sessions (by sessionId)
|
|
158
|
+
const sessionMap = new Map();
|
|
159
|
+
|
|
160
|
+
// Add existing sessions first
|
|
161
|
+
for (const session of normalizedExisting) {
|
|
162
|
+
sessionMap.set(session.sessionId, session);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Merge incoming sessions - backend data always replaces existing
|
|
166
|
+
for (const session of normalizedIncoming) {
|
|
167
|
+
sessionMap.set(session.sessionId, session);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Convert to array
|
|
171
|
+
const merged = Array.from(sessionMap.values());
|
|
172
|
+
|
|
173
|
+
// Apply userId deduplication if requested
|
|
174
|
+
const finalSessions = deduplicateByUserId ? deduplicateSessionsByUserId(merged, activeSessionId) : merged;
|
|
175
|
+
|
|
176
|
+
// Sort consistently
|
|
177
|
+
return sortSessions(finalSessions);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Check if two session arrays are equal (same sessionIds in same order)
|
|
182
|
+
*/
|
|
183
|
+
function sessionsArraysEqual(a, b) {
|
|
184
|
+
if (a.length !== b.length) {
|
|
185
|
+
return false;
|
|
186
|
+
}
|
|
187
|
+
const sortedA = sortSessions(a);
|
|
188
|
+
const sortedB = sortSessions(b);
|
|
189
|
+
return sortedA.every((session, index) => sessionsEqual(session, sortedB[index]));
|
|
190
|
+
}
|
|
191
|
+
//# sourceMappingURL=sessionUtils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["normalizeSession","session","now","Date","toISOString","sessionId","deviceId","expiresAt","lastActive","userId","sessionsEqual","a","b","sortSessions","sessions","sort","timeA","getTime","timeB","localeCompare","deduplicateSessions","sessionMap","Map","existing","get","set","existingTime","currentTime","Array","from","values","deduplicateSessionsByUserId","activeSessionId","length","userSessionMap","isCurrentActive","isExistingActive","normalizeAndSortSessions","deduplicateByUserId","normalized","map","deduplicatedBySessionId","finalSessions","mergeSessions","incoming","normalizedExisting","normalizedIncoming","merged","sessionsArraysEqual","sortedA","sortedB","every","index"],"sourceRoot":"../../../src","sources":["utils/sessionUtils.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -30,7 +30,7 @@ exports.validateAndSanitizeUserInput = validateAndSanitizeUserInput;
|
|
|
30
30
|
const EMAIL_REGEX = exports.EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
31
31
|
|
|
32
32
|
/**
|
|
33
|
-
* Username validation regex (alphanumeric,
|
|
33
|
+
* Username validation regex (alphanumeric, underscores, and hyphens, 3-30 chars)
|
|
34
34
|
*/
|
|
35
35
|
const USERNAME_REGEX = exports.USERNAME_REGEX = /^[a-zA-Z0-9_-]{3,30}$/;
|
|
36
36
|
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* HTTP Client Service
|
|
5
|
+
*
|
|
6
|
+
* Handles all HTTP communication with authentication, interceptors, and error handling.
|
|
7
|
+
* This is the single source of truth for making authenticated HTTP requests.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import axios from 'axios';
|
|
11
|
+
import { jwtDecode } from 'jwt-decode';
|
|
12
|
+
import { handleHttpError } from '../utils/errorUtils';
|
|
13
|
+
import { SimpleLogger } from '../utils/requestUtils';
|
|
14
|
+
/**
|
|
15
|
+
* Token store for authentication
|
|
16
|
+
*/
|
|
17
|
+
class TokenStore {
|
|
18
|
+
accessToken = null;
|
|
19
|
+
refreshToken = null;
|
|
20
|
+
constructor() {}
|
|
21
|
+
static getInstance() {
|
|
22
|
+
if (!TokenStore.instance) {
|
|
23
|
+
TokenStore.instance = new TokenStore();
|
|
24
|
+
}
|
|
25
|
+
return TokenStore.instance;
|
|
26
|
+
}
|
|
27
|
+
setTokens(accessToken, refreshToken = '') {
|
|
28
|
+
this.accessToken = accessToken;
|
|
29
|
+
this.refreshToken = refreshToken;
|
|
30
|
+
}
|
|
31
|
+
getAccessToken() {
|
|
32
|
+
return this.accessToken;
|
|
33
|
+
}
|
|
34
|
+
getRefreshToken() {
|
|
35
|
+
return this.refreshToken;
|
|
36
|
+
}
|
|
37
|
+
clearTokens() {
|
|
38
|
+
this.accessToken = null;
|
|
39
|
+
this.refreshToken = null;
|
|
40
|
+
}
|
|
41
|
+
hasAccessToken() {
|
|
42
|
+
return !!this.accessToken;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* HTTP Client Service
|
|
48
|
+
*
|
|
49
|
+
* Manages Axios instance with authentication interceptors.
|
|
50
|
+
* All HTTP requests should go through this service to ensure authentication.
|
|
51
|
+
*/
|
|
52
|
+
export class HttpClient {
|
|
53
|
+
constructor(config) {
|
|
54
|
+
this.baseURL = config.baseURL;
|
|
55
|
+
this.tokenStore = TokenStore.getInstance();
|
|
56
|
+
this.logger = new SimpleLogger(config.enableLogging || false, config.logLevel || 'error', 'HttpClient');
|
|
57
|
+
const timeout = config.requestTimeout || 5000;
|
|
58
|
+
|
|
59
|
+
// Create Axios instance with optimized configuration
|
|
60
|
+
this.client = axios.create({
|
|
61
|
+
baseURL: config.baseURL,
|
|
62
|
+
timeout,
|
|
63
|
+
headers: {
|
|
64
|
+
'Accept': 'application/json'
|
|
65
|
+
},
|
|
66
|
+
// Enable HTTP keep-alive for connection reuse (Node.js only)
|
|
67
|
+
...(typeof process !== 'undefined' && process.env && typeof window === 'undefined' && typeof require !== 'undefined' ? {
|
|
68
|
+
httpAgent: new (require('http').Agent)({
|
|
69
|
+
keepAlive: true,
|
|
70
|
+
keepAliveMsecs: 1000,
|
|
71
|
+
maxSockets: 50
|
|
72
|
+
}),
|
|
73
|
+
httpsAgent: new (require('https').Agent)({
|
|
74
|
+
keepAlive: true,
|
|
75
|
+
keepAliveMsecs: 1000,
|
|
76
|
+
maxSockets: 50
|
|
77
|
+
})
|
|
78
|
+
} : {})
|
|
79
|
+
});
|
|
80
|
+
this.setupInterceptors();
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Setup axios interceptors for authentication and error handling
|
|
85
|
+
*/
|
|
86
|
+
setupInterceptors() {
|
|
87
|
+
// Request interceptor: Add authentication header
|
|
88
|
+
this.client.interceptors.request.use(async req => {
|
|
89
|
+
const accessToken = this.tokenStore.getAccessToken();
|
|
90
|
+
if (!accessToken) {
|
|
91
|
+
return req;
|
|
92
|
+
}
|
|
93
|
+
try {
|
|
94
|
+
const decoded = jwtDecode(accessToken);
|
|
95
|
+
const currentTime = Math.floor(Date.now() / 1000);
|
|
96
|
+
|
|
97
|
+
// If token expires in less than 60 seconds, refresh it
|
|
98
|
+
if (decoded.exp && decoded.exp - currentTime < 60) {
|
|
99
|
+
if (decoded.sessionId) {
|
|
100
|
+
try {
|
|
101
|
+
// Create a new axios instance to avoid interceptor recursion
|
|
102
|
+
const refreshClient = axios.create({
|
|
103
|
+
baseURL: this.client.defaults.baseURL,
|
|
104
|
+
timeout: this.client.defaults.timeout
|
|
105
|
+
});
|
|
106
|
+
const res = await refreshClient.get(`/api/session/token/${decoded.sessionId}`);
|
|
107
|
+
this.tokenStore.setTokens(res.data.accessToken);
|
|
108
|
+
req.headers.Authorization = `Bearer ${res.data.accessToken}`;
|
|
109
|
+
this.logger.debug('Token refreshed');
|
|
110
|
+
} catch (refreshError) {
|
|
111
|
+
// If refresh fails, use current token anyway
|
|
112
|
+
req.headers.Authorization = `Bearer ${accessToken}`;
|
|
113
|
+
this.logger.warn('Token refresh failed, using current token');
|
|
114
|
+
}
|
|
115
|
+
} else {
|
|
116
|
+
req.headers.Authorization = `Bearer ${accessToken}`;
|
|
117
|
+
}
|
|
118
|
+
} else {
|
|
119
|
+
req.headers.Authorization = `Bearer ${accessToken}`;
|
|
120
|
+
}
|
|
121
|
+
} catch (error) {
|
|
122
|
+
this.logger.error('Error processing token:', error);
|
|
123
|
+
// Even if there's an error, still try to use the token
|
|
124
|
+
req.headers.Authorization = `Bearer ${accessToken}`;
|
|
125
|
+
}
|
|
126
|
+
return req;
|
|
127
|
+
}, error => {
|
|
128
|
+
this.logger.error('Request interceptor error:', error);
|
|
129
|
+
return Promise.reject(error);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
// Response interceptor: Handle auth errors
|
|
133
|
+
this.client.interceptors.response.use(response => response, error => {
|
|
134
|
+
if (error.response?.status === 401) {
|
|
135
|
+
this.logger.warn('401 Unauthorized, clearing tokens');
|
|
136
|
+
this.tokenStore.clearTokens();
|
|
137
|
+
}
|
|
138
|
+
return Promise.reject(error);
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Get the underlying Axios instance
|
|
144
|
+
* Use this only when you need direct access to Axios features
|
|
145
|
+
*/
|
|
146
|
+
getAxiosInstance() {
|
|
147
|
+
return this.client;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Make a raw HTTP request (no caching, deduplication, etc.)
|
|
152
|
+
* Use this for requests that need to bypass performance features
|
|
153
|
+
*/
|
|
154
|
+
async request(config) {
|
|
155
|
+
try {
|
|
156
|
+
const response = await this.client.request({
|
|
157
|
+
method: config.method,
|
|
158
|
+
url: config.url,
|
|
159
|
+
data: config.data,
|
|
160
|
+
params: config.params,
|
|
161
|
+
timeout: config.timeout,
|
|
162
|
+
signal: config.signal
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
// Unwrap standardized API response format: { data: ... }
|
|
166
|
+
// This handles responses from sendSuccess() and sendPaginated() helpers
|
|
167
|
+
const responseData = response.data;
|
|
168
|
+
|
|
169
|
+
// Handle paginated responses: { data: [...], pagination: {...} }
|
|
170
|
+
// Return the data array directly - the calling method will wrap it appropriately
|
|
171
|
+
if (responseData && typeof responseData === 'object' && 'data' in responseData && 'pagination' in responseData) {
|
|
172
|
+
// For paginated responses, return the data array directly
|
|
173
|
+
// The calling methods like getUserFollowers/getUserFollowing will handle wrapping
|
|
174
|
+
// We return the whole response so methods can access both data and pagination
|
|
175
|
+
return responseData;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Handle regular success responses: { data: ... }
|
|
179
|
+
if (responseData && typeof responseData === 'object' && 'data' in responseData) {
|
|
180
|
+
return responseData.data;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Return as-is for responses that don't use sendSuccess wrapper
|
|
184
|
+
return responseData;
|
|
185
|
+
} catch (error) {
|
|
186
|
+
throw handleHttpError(error);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Get base URL
|
|
192
|
+
*/
|
|
193
|
+
getBaseURL() {
|
|
194
|
+
return this.baseURL;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Set authentication tokens
|
|
199
|
+
*/
|
|
200
|
+
setTokens(accessToken, refreshToken = '') {
|
|
201
|
+
this.tokenStore.setTokens(accessToken, refreshToken);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Clear authentication tokens
|
|
206
|
+
*/
|
|
207
|
+
clearTokens() {
|
|
208
|
+
this.tokenStore.clearTokens();
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Get access token
|
|
213
|
+
*/
|
|
214
|
+
getAccessToken() {
|
|
215
|
+
return this.tokenStore.getAccessToken();
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Check if has access token
|
|
220
|
+
*/
|
|
221
|
+
hasAccessToken() {
|
|
222
|
+
return this.tokenStore.hasAccessToken();
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// Test-only utility to reset global tokens between jest tests
|
|
226
|
+
static __resetTokensForTests() {
|
|
227
|
+
try {
|
|
228
|
+
TokenStore.getInstance().clearTokens();
|
|
229
|
+
} catch {}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
//# sourceMappingURL=HttpClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["axios","jwtDecode","handleHttpError","SimpleLogger","TokenStore","accessToken","refreshToken","constructor","getInstance","instance","setTokens","getAccessToken","getRefreshToken","clearTokens","hasAccessToken","HttpClient","config","baseURL","tokenStore","logger","enableLogging","logLevel","timeout","requestTimeout","client","create","headers","process","env","window","require","httpAgent","Agent","keepAlive","keepAliveMsecs","maxSockets","httpsAgent","setupInterceptors","interceptors","request","use","req","decoded","currentTime","Math","floor","Date","now","exp","sessionId","refreshClient","defaults","res","get","data","Authorization","debug","refreshError","warn","error","Promise","reject","response","status","getAxiosInstance","method","url","params","signal","responseData","getBaseURL","__resetTokensForTests"],"sourceRoot":"../../../src","sources":["core/HttpClient.ts"],"mappings":"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","ignoreList":[]}
|