@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
package/src/core/OxyServices.ts
CHANGED
|
@@ -56,7 +56,6 @@
|
|
|
56
56
|
*
|
|
57
57
|
* See method JSDoc for more details and options.
|
|
58
58
|
*/
|
|
59
|
-
import axios, { type AxiosInstance, type InternalAxiosRequestConfig } from 'axios';
|
|
60
59
|
import { jwtDecode } from 'jwt-decode';
|
|
61
60
|
import type {
|
|
62
61
|
OxyConfig as OxyConfigBase,
|
|
@@ -67,6 +66,8 @@ import type {
|
|
|
67
66
|
AssetUrlResponse,
|
|
68
67
|
AssetVariant
|
|
69
68
|
} from '../models/interfaces';
|
|
69
|
+
import { normalizeLanguageCode, getLanguageMetadata, getLanguageName, getNativeLanguageName } from '../utils/languageUtils';
|
|
70
|
+
import type { LanguageMetadata } from '../utils/languageUtils';
|
|
70
71
|
/**
|
|
71
72
|
* OxyConfig - Configuration for OxyServices
|
|
72
73
|
* @property baseURL - The Oxy API base URL (e.g., https://api.oxy.so)
|
|
@@ -78,6 +79,8 @@ export interface OxyConfig extends OxyConfigBase {
|
|
|
78
79
|
import type { SessionLoginResponse } from '../models/session';
|
|
79
80
|
import { handleHttpError } from '../utils/errorUtils';
|
|
80
81
|
import { buildSearchParams, buildPaginationParams, type PaginationParams } from '../utils/apiUtils';
|
|
82
|
+
import { HttpClient } from './HttpClient';
|
|
83
|
+
import { RequestManager, type RequestOptions } from './RequestManager';
|
|
81
84
|
|
|
82
85
|
interface JwtPayload {
|
|
83
86
|
exp?: number;
|
|
@@ -117,55 +120,18 @@ export class OxyAuthenticationTimeoutError extends OxyAuthenticationError {
|
|
|
117
120
|
* OxyServices - Unified client library for interacting with the Oxy API
|
|
118
121
|
*
|
|
119
122
|
* This class provides all API functionality in one simple, easy-to-use interface.
|
|
120
|
-
*
|
|
123
|
+
* Architecture:
|
|
124
|
+
* - HttpClient: Handles HTTP communication and authentication
|
|
125
|
+
* - RequestManager: Handles caching, deduplication, queuing, and retry
|
|
126
|
+
* - OxyServices: Provides high-level API methods
|
|
121
127
|
*/
|
|
122
|
-
// Centralized token store
|
|
123
|
-
class TokenStore {
|
|
124
|
-
private static instance: TokenStore;
|
|
125
|
-
private accessToken: string | null = null;
|
|
126
|
-
private refreshToken: string | null = null;
|
|
127
|
-
|
|
128
|
-
private constructor() {}
|
|
129
|
-
|
|
130
|
-
static getInstance(): TokenStore {
|
|
131
|
-
if (!TokenStore.instance) {
|
|
132
|
-
TokenStore.instance = new TokenStore();
|
|
133
|
-
}
|
|
134
|
-
return TokenStore.instance;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
setTokens(accessToken: string, refreshToken = ''): void {
|
|
138
|
-
this.accessToken = accessToken;
|
|
139
|
-
this.refreshToken = refreshToken;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
getAccessToken(): string | null {
|
|
143
|
-
return this.accessToken;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
getRefreshToken(): string | null {
|
|
147
|
-
return this.refreshToken;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
clearTokens(): void {
|
|
151
|
-
this.accessToken = null;
|
|
152
|
-
this.refreshToken = null;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
hasAccessToken(): boolean {
|
|
156
|
-
return !!this.accessToken;
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
128
|
export class OxyServices {
|
|
161
|
-
|
|
162
|
-
private
|
|
129
|
+
private httpClient: HttpClient;
|
|
130
|
+
private requestManager: RequestManager;
|
|
163
131
|
private cloudURL: string;
|
|
132
|
+
private config: OxyConfig;
|
|
133
|
+
|
|
164
134
|
|
|
165
|
-
/**
|
|
166
|
-
* Creates a new instance of the OxyServices client
|
|
167
|
-
* @param config - Configuration for the client
|
|
168
|
-
*/
|
|
169
135
|
/**
|
|
170
136
|
* Creates a new instance of the OxyServices client
|
|
171
137
|
* @param config - Configuration for the client
|
|
@@ -173,99 +139,33 @@ export class OxyServices {
|
|
|
173
139
|
* config.cloudURL: Oxy Cloud URL (e.g., https://cloud.oxy.so)
|
|
174
140
|
*/
|
|
175
141
|
constructor(config: OxyConfig) {
|
|
176
|
-
this.
|
|
177
|
-
baseURL: config.baseURL,
|
|
178
|
-
timeout: 5000 // 5 second timeout
|
|
179
|
-
});
|
|
142
|
+
this.config = config;
|
|
180
143
|
this.cloudURL = config.cloudURL || OXY_CLOUD_URL;
|
|
181
|
-
|
|
182
|
-
|
|
144
|
+
|
|
145
|
+
// Initialize HTTP client (handles authentication and interceptors)
|
|
146
|
+
this.httpClient = new HttpClient(config);
|
|
147
|
+
|
|
148
|
+
// Initialize request manager (handles caching, deduplication, queuing, retry)
|
|
149
|
+
this.requestManager = new RequestManager(this.httpClient, config);
|
|
183
150
|
}
|
|
184
151
|
|
|
185
152
|
// Test-only utility to reset global tokens between jest tests
|
|
186
153
|
static __resetTokensForTests(): void {
|
|
187
|
-
|
|
188
|
-
TokenStore.getInstance().clearTokens();
|
|
189
|
-
} catch {}
|
|
154
|
+
HttpClient.__resetTokensForTests();
|
|
190
155
|
}
|
|
191
156
|
|
|
157
|
+
|
|
192
158
|
/**
|
|
193
|
-
*
|
|
159
|
+
* Make a request with all performance optimizations
|
|
160
|
+
* This is the main method for all API calls - ensures authentication and performance features
|
|
194
161
|
*/
|
|
195
|
-
private
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
const accessToken = this.tokenStore.getAccessToken();
|
|
203
|
-
if (!accessToken) {
|
|
204
|
-
console.log('❌ Interceptor - No token available');
|
|
205
|
-
return req;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
try {
|
|
209
|
-
console.log('✅ Interceptor - Adding Authorization header');
|
|
210
|
-
|
|
211
|
-
const decoded = jwtDecode<JwtPayload>(accessToken);
|
|
212
|
-
const currentTime = Math.floor(Date.now() / 1000);
|
|
213
|
-
|
|
214
|
-
// If token expires in less than 60 seconds, refresh it
|
|
215
|
-
if (decoded.exp && decoded.exp - currentTime < 60) {
|
|
216
|
-
// For session-based tokens, get a new token from the session
|
|
217
|
-
if (decoded.sessionId) {
|
|
218
|
-
try {
|
|
219
|
-
// Create a new axios instance to avoid interceptor recursion
|
|
220
|
-
const refreshClient = axios.create({
|
|
221
|
-
baseURL: this.client.defaults.baseURL,
|
|
222
|
-
timeout: this.client.defaults.timeout
|
|
223
|
-
});
|
|
224
|
-
const res = await refreshClient.get(`/api/session/token/${decoded.sessionId}`);
|
|
225
|
-
this.tokenStore.setTokens(res.data.accessToken);
|
|
226
|
-
req.headers.Authorization = `Bearer ${res.data.accessToken}`;
|
|
227
|
-
console.log('✅ Interceptor - Token refreshed and Authorization header set');
|
|
228
|
-
} catch (refreshError) {
|
|
229
|
-
// If refresh fails, use current token anyway
|
|
230
|
-
req.headers.Authorization = `Bearer ${accessToken}`;
|
|
231
|
-
console.log('❌ Interceptor - Token refresh failed, using current token');
|
|
232
|
-
}
|
|
233
|
-
} else {
|
|
234
|
-
// No session ID, use current token
|
|
235
|
-
req.headers.Authorization = `Bearer ${accessToken}`;
|
|
236
|
-
console.log('✅ Interceptor - No session ID, using current token');
|
|
237
|
-
}
|
|
238
|
-
} else {
|
|
239
|
-
// Add authorization header with current token
|
|
240
|
-
req.headers.Authorization = `Bearer ${accessToken}`;
|
|
241
|
-
console.log('✅ Interceptor - Authorization header set with current token');
|
|
242
|
-
}
|
|
243
|
-
} catch (error) {
|
|
244
|
-
console.log('❌ Interceptor - Error processing token:', error);
|
|
245
|
-
// Even if there's an error, still try to use the token
|
|
246
|
-
req.headers.Authorization = `Bearer ${accessToken}`;
|
|
247
|
-
console.log('⚠️ Interceptor - Using token despite error');
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
return req;
|
|
251
|
-
},
|
|
252
|
-
(error) => {
|
|
253
|
-
console.log('❌ Interceptor - Request error:', error);
|
|
254
|
-
return Promise.reject(error);
|
|
255
|
-
}
|
|
256
|
-
);
|
|
257
|
-
|
|
258
|
-
// Response interceptor for handling auth errors
|
|
259
|
-
this.client.interceptors.response.use(
|
|
260
|
-
(response) => response,
|
|
261
|
-
(error) => {
|
|
262
|
-
if (error.response?.status === 401) {
|
|
263
|
-
console.log('❌ Response interceptor - 401 Unauthorized, clearing tokens');
|
|
264
|
-
this.clearTokens();
|
|
265
|
-
}
|
|
266
|
-
return Promise.reject(error);
|
|
267
|
-
}
|
|
268
|
-
);
|
|
162
|
+
private async makeRequest<T>(
|
|
163
|
+
method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE',
|
|
164
|
+
url: string,
|
|
165
|
+
data?: any,
|
|
166
|
+
options: RequestOptions = {}
|
|
167
|
+
): Promise<T> {
|
|
168
|
+
return this.requestManager.request<T>(method, url, data, options);
|
|
269
169
|
}
|
|
270
170
|
|
|
271
171
|
// ============================================================================
|
|
@@ -276,7 +176,35 @@ export class OxyServices {
|
|
|
276
176
|
* Get the configured Oxy API base URL
|
|
277
177
|
*/
|
|
278
178
|
public getBaseURL(): string {
|
|
279
|
-
return this.
|
|
179
|
+
return this.httpClient.getBaseURL();
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Get performance metrics
|
|
184
|
+
*/
|
|
185
|
+
public getMetrics() {
|
|
186
|
+
return this.requestManager.getMetrics();
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Clear request cache
|
|
191
|
+
*/
|
|
192
|
+
public clearCache(): void {
|
|
193
|
+
this.requestManager.clearCache();
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Clear specific cache entry
|
|
198
|
+
*/
|
|
199
|
+
public clearCacheEntry(key: string): void {
|
|
200
|
+
this.requestManager.clearCacheEntry(key);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Get cache statistics
|
|
205
|
+
*/
|
|
206
|
+
public getCacheStats() {
|
|
207
|
+
return this.requestManager.getCacheStats();
|
|
280
208
|
}
|
|
281
209
|
|
|
282
210
|
/**
|
|
@@ -290,21 +218,21 @@ export class OxyServices {
|
|
|
290
218
|
* Set authentication tokens
|
|
291
219
|
*/
|
|
292
220
|
public setTokens(accessToken: string, refreshToken = ''): void {
|
|
293
|
-
this.
|
|
221
|
+
this.httpClient.setTokens(accessToken, refreshToken);
|
|
294
222
|
}
|
|
295
223
|
|
|
296
224
|
/**
|
|
297
225
|
* Clear stored authentication tokens
|
|
298
226
|
*/
|
|
299
227
|
public clearTokens(): void {
|
|
300
|
-
this.
|
|
228
|
+
this.httpClient.clearTokens();
|
|
301
229
|
}
|
|
302
230
|
|
|
303
231
|
/**
|
|
304
232
|
* Get the current user ID from the access token
|
|
305
233
|
*/
|
|
306
234
|
public getCurrentUserId(): string | null {
|
|
307
|
-
const accessToken = this.
|
|
235
|
+
const accessToken = this.httpClient.getAccessToken();
|
|
308
236
|
if (!accessToken) {
|
|
309
237
|
return null;
|
|
310
238
|
}
|
|
@@ -321,21 +249,21 @@ export class OxyServices {
|
|
|
321
249
|
* Check if the client has a valid access token
|
|
322
250
|
*/
|
|
323
251
|
private hasAccessToken(): boolean {
|
|
324
|
-
return this.
|
|
252
|
+
return this.httpClient.hasAccessToken();
|
|
325
253
|
}
|
|
326
254
|
|
|
327
255
|
/**
|
|
328
256
|
* Check if the client has a valid access token (public method)
|
|
329
257
|
*/
|
|
330
258
|
public hasValidToken(): boolean {
|
|
331
|
-
return this.
|
|
259
|
+
return this.httpClient.hasAccessToken();
|
|
332
260
|
}
|
|
333
261
|
|
|
334
262
|
/**
|
|
335
263
|
* Get the raw access token (for constructing anchor URLs when needed)
|
|
336
264
|
*/
|
|
337
265
|
public getAccessToken(): string | null {
|
|
338
|
-
return this.
|
|
266
|
+
return this.httpClient.getAccessToken();
|
|
339
267
|
}
|
|
340
268
|
|
|
341
269
|
/**
|
|
@@ -354,7 +282,7 @@ export class OxyServices {
|
|
|
354
282
|
const checkInterval = 100; // Check every 100ms
|
|
355
283
|
|
|
356
284
|
while (Date.now() - startTime < timeoutMs) {
|
|
357
|
-
if (this.
|
|
285
|
+
if (this.httpClient.hasAccessToken()) {
|
|
358
286
|
return true;
|
|
359
287
|
}
|
|
360
288
|
await new Promise(resolve => setTimeout(resolve, checkInterval));
|
|
@@ -385,17 +313,14 @@ export class OxyServices {
|
|
|
385
313
|
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
386
314
|
try {
|
|
387
315
|
// First attempt: check if we have a token
|
|
388
|
-
if (!this.
|
|
316
|
+
if (!this.httpClient.hasAccessToken()) {
|
|
389
317
|
if (attempt === 0) {
|
|
390
318
|
// On first attempt, wait briefly for authentication to complete
|
|
391
|
-
console.log(`🔄 ${operationName} - Waiting for authentication...`);
|
|
392
319
|
const authReady = await this.waitForAuthentication(authTimeoutMs);
|
|
393
320
|
|
|
394
321
|
if (!authReady) {
|
|
395
322
|
throw new OxyAuthenticationTimeoutError(operationName, authTimeoutMs);
|
|
396
323
|
}
|
|
397
|
-
|
|
398
|
-
console.log(`✅ ${operationName} - Authentication ready, proceeding...`);
|
|
399
324
|
} else {
|
|
400
325
|
// On retry attempts, fail immediately if no token
|
|
401
326
|
throw new OxyAuthenticationError(
|
|
@@ -416,7 +341,6 @@ export class OxyServices {
|
|
|
416
341
|
error instanceof OxyAuthenticationError;
|
|
417
342
|
|
|
418
343
|
if (isAuthError && !isLastAttempt && !(error instanceof OxyAuthenticationTimeoutError)) {
|
|
419
|
-
console.log(`🔄 ${operationName} - Auth error on attempt ${attempt + 1}, retrying in ${retryDelay}ms...`);
|
|
420
344
|
await new Promise(resolve => setTimeout(resolve, retryDelay));
|
|
421
345
|
continue;
|
|
422
346
|
}
|
|
@@ -442,19 +366,16 @@ export class OxyServices {
|
|
|
442
366
|
}
|
|
443
367
|
|
|
444
368
|
try {
|
|
445
|
-
const res = await this.
|
|
446
|
-
|
|
369
|
+
const res = await this.makeRequest<{ valid: boolean }>('GET', '/api/auth/validate', undefined, {
|
|
370
|
+
cache: false,
|
|
371
|
+
retry: false,
|
|
372
|
+
});
|
|
373
|
+
return res.valid === true;
|
|
447
374
|
} catch (error) {
|
|
448
375
|
return false;
|
|
449
376
|
}
|
|
450
377
|
}
|
|
451
378
|
|
|
452
|
-
/**
|
|
453
|
-
* Get the HTTP client instance (public for external use)
|
|
454
|
-
*/
|
|
455
|
-
public getClient(): AxiosInstance {
|
|
456
|
-
return this.client;
|
|
457
|
-
}
|
|
458
379
|
|
|
459
380
|
/**
|
|
460
381
|
* Centralized error handling
|
|
@@ -478,8 +399,7 @@ export class OxyServices {
|
|
|
478
399
|
[key: string]: any
|
|
479
400
|
}> {
|
|
480
401
|
try {
|
|
481
|
-
|
|
482
|
-
return res.data;
|
|
402
|
+
return await this.makeRequest('GET', '/health', undefined, { cache: false });
|
|
483
403
|
} catch (error) {
|
|
484
404
|
throw this.handleError(error);
|
|
485
405
|
}
|
|
@@ -494,15 +414,15 @@ export class OxyServices {
|
|
|
494
414
|
*/
|
|
495
415
|
async signUp(username: string, email: string, password: string): Promise<{ message: string; token: string; user: User }> {
|
|
496
416
|
try {
|
|
497
|
-
const res = await this.
|
|
417
|
+
const res = await this.makeRequest<{ message: string; token: string; user: User }>('POST', '/api/auth/signup', {
|
|
498
418
|
username,
|
|
499
419
|
email,
|
|
500
420
|
password
|
|
501
|
-
});
|
|
502
|
-
if (!res ||
|
|
421
|
+
}, { cache: false });
|
|
422
|
+
if (!res || (typeof res === 'object' && Object.keys(res).length === 0)) {
|
|
503
423
|
throw new OxyAuthenticationError('Sign up failed', 'SIGNUP_FAILED', 400);
|
|
504
424
|
}
|
|
505
|
-
return res
|
|
425
|
+
return res;
|
|
506
426
|
} catch (error) {
|
|
507
427
|
throw this.handleError(error);
|
|
508
428
|
}
|
|
@@ -513,8 +433,7 @@ export class OxyServices {
|
|
|
513
433
|
*/
|
|
514
434
|
async requestRecovery(identifier: string): Promise<{ delivery?: string; destination?: string }> {
|
|
515
435
|
try {
|
|
516
|
-
|
|
517
|
-
return res.data;
|
|
436
|
+
return await this.makeRequest('POST', '/api/auth/recover/request', { identifier }, { cache: false });
|
|
518
437
|
} catch (error: any) {
|
|
519
438
|
throw this.handleError(error);
|
|
520
439
|
}
|
|
@@ -525,8 +444,7 @@ export class OxyServices {
|
|
|
525
444
|
*/
|
|
526
445
|
async verifyRecoveryCode(identifier: string, code: string): Promise<{ verified: boolean }> {
|
|
527
446
|
try {
|
|
528
|
-
|
|
529
|
-
return res.data;
|
|
447
|
+
return await this.makeRequest('POST', '/api/auth/recover/verify', { identifier, code }, { cache: false });
|
|
530
448
|
} catch (error: any) {
|
|
531
449
|
throw this.handleError(error);
|
|
532
450
|
}
|
|
@@ -537,8 +455,7 @@ export class OxyServices {
|
|
|
537
455
|
*/
|
|
538
456
|
async resetPassword(identifier: string, code: string, newPassword: string): Promise<{ success: boolean }> {
|
|
539
457
|
try {
|
|
540
|
-
|
|
541
|
-
return res.data;
|
|
458
|
+
return await this.makeRequest('POST', '/api/auth/recover/reset', { identifier, code, newPassword }, { cache: false });
|
|
542
459
|
} catch (error: any) {
|
|
543
460
|
throw this.handleError(error);
|
|
544
461
|
}
|
|
@@ -549,8 +466,7 @@ export class OxyServices {
|
|
|
549
466
|
*/
|
|
550
467
|
async resetPasswordWithTotp(identifier: string, code: string, newPassword: string): Promise<{ success: boolean }> {
|
|
551
468
|
try {
|
|
552
|
-
|
|
553
|
-
return res.data;
|
|
469
|
+
return await this.makeRequest('POST', '/api/auth/recover/totp/reset', { identifier, code, newPassword }, { cache: false });
|
|
554
470
|
} catch (error: any) {
|
|
555
471
|
throw this.handleError(error);
|
|
556
472
|
}
|
|
@@ -558,8 +474,7 @@ export class OxyServices {
|
|
|
558
474
|
|
|
559
475
|
async resetPasswordWithBackupCode(identifier: string, backupCode: string, newPassword: string): Promise<{ success: boolean }> {
|
|
560
476
|
try {
|
|
561
|
-
|
|
562
|
-
return res.data;
|
|
477
|
+
return await this.makeRequest('POST', '/api/auth/recover/backup/reset', { identifier, backupCode, newPassword }, { cache: false });
|
|
563
478
|
} catch (error: any) {
|
|
564
479
|
throw this.handleError(error);
|
|
565
480
|
}
|
|
@@ -567,8 +482,7 @@ export class OxyServices {
|
|
|
567
482
|
|
|
568
483
|
async resetPasswordWithRecoveryKey(identifier: string, recoveryKey: string, newPassword: string): Promise<{ success: boolean; nextRecoveryKey?: string }> {
|
|
569
484
|
try {
|
|
570
|
-
|
|
571
|
-
return res.data;
|
|
485
|
+
return await this.makeRequest('POST', '/api/auth/recover/recovery-key/reset', { identifier, recoveryKey, newPassword }, { cache: false });
|
|
572
486
|
} catch (error: any) {
|
|
573
487
|
throw this.handleError(error);
|
|
574
488
|
}
|
|
@@ -584,13 +498,12 @@ export class OxyServices {
|
|
|
584
498
|
deviceFingerprint?: any
|
|
585
499
|
): Promise<SessionLoginResponse | { mfaRequired: true; mfaToken: string; expiresAt: string }> {
|
|
586
500
|
try {
|
|
587
|
-
|
|
501
|
+
return await this.makeRequest<SessionLoginResponse | { mfaRequired: true; mfaToken: string; expiresAt: string }>('POST', '/api/auth/login', {
|
|
588
502
|
username,
|
|
589
503
|
password,
|
|
590
504
|
deviceName,
|
|
591
505
|
deviceFingerprint
|
|
592
|
-
});
|
|
593
|
-
return res.data;
|
|
506
|
+
}, { cache: false });
|
|
594
507
|
} catch (error) {
|
|
595
508
|
throw this.handleError(error);
|
|
596
509
|
}
|
|
@@ -601,8 +514,7 @@ export class OxyServices {
|
|
|
601
514
|
*/
|
|
602
515
|
async verifyTotpLogin(mfaToken: string, code: string): Promise<SessionLoginResponse> {
|
|
603
516
|
try {
|
|
604
|
-
|
|
605
|
-
return res.data;
|
|
517
|
+
return await this.makeRequest<SessionLoginResponse>('POST', '/api/auth/totp/verify-login', { mfaToken, code }, { cache: false });
|
|
606
518
|
} catch (error) {
|
|
607
519
|
throw this.handleError(error);
|
|
608
520
|
}
|
|
@@ -613,8 +525,38 @@ export class OxyServices {
|
|
|
613
525
|
*/
|
|
614
526
|
async getUserBySession(sessionId: string): Promise<User> {
|
|
615
527
|
try {
|
|
616
|
-
|
|
617
|
-
|
|
528
|
+
return await this.makeRequest<User>('GET', `/api/session/user/${sessionId}`, undefined, {
|
|
529
|
+
cache: true,
|
|
530
|
+
cacheTTL: 2 * 60 * 1000, // 2 minutes cache for user data
|
|
531
|
+
});
|
|
532
|
+
} catch (error) {
|
|
533
|
+
throw this.handleError(error);
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
/**
|
|
538
|
+
* Batch get multiple user profiles by session IDs (optimized for account switching)
|
|
539
|
+
* Returns array of { sessionId, user } objects
|
|
540
|
+
*/
|
|
541
|
+
async getUsersBySessions(sessionIds: string[]): Promise<Array<{ sessionId: string; user: User | null }>> {
|
|
542
|
+
try {
|
|
543
|
+
if (!Array.isArray(sessionIds) || sessionIds.length === 0) {
|
|
544
|
+
return [];
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
// Deduplicate and sort sessionIds for consistent cache keys
|
|
548
|
+
const uniqueSessionIds = Array.from(new Set(sessionIds)).sort();
|
|
549
|
+
|
|
550
|
+
return await this.makeRequest<Array<{ sessionId: string; user: User | null }>>(
|
|
551
|
+
'POST',
|
|
552
|
+
'/api/session/users/batch',
|
|
553
|
+
{ sessionIds: uniqueSessionIds },
|
|
554
|
+
{
|
|
555
|
+
cache: true,
|
|
556
|
+
cacheTTL: 2 * 60 * 1000, // 2 minutes cache
|
|
557
|
+
deduplicate: true, // Important for batch requests
|
|
558
|
+
}
|
|
559
|
+
);
|
|
618
560
|
} catch (error) {
|
|
619
561
|
throw this.handleError(error);
|
|
620
562
|
}
|
|
@@ -625,19 +567,16 @@ export class OxyServices {
|
|
|
625
567
|
*/
|
|
626
568
|
async getTokenBySession(sessionId: string): Promise<{ accessToken: string; expiresAt: string }> {
|
|
627
569
|
try {
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
console.log('🔑 getTokenBySession - Token received:', !!accessToken);
|
|
570
|
+
const res = await this.makeRequest<{ accessToken: string; expiresAt: string }>('GET', `/api/session/token/${sessionId}`, undefined, {
|
|
571
|
+
cache: false,
|
|
572
|
+
retry: false,
|
|
573
|
+
});
|
|
633
574
|
|
|
634
575
|
// Set the token in the centralized token store
|
|
635
|
-
this.setTokens(accessToken);
|
|
636
|
-
console.log('🔑 getTokenBySession - Token set in store');
|
|
576
|
+
this.setTokens(res.accessToken);
|
|
637
577
|
|
|
638
|
-
return res
|
|
578
|
+
return res;
|
|
639
579
|
} catch (error) {
|
|
640
|
-
console.log('❌ getTokenBySession - Error:', error);
|
|
641
580
|
throw this.handleError(error);
|
|
642
581
|
}
|
|
643
582
|
}
|
|
@@ -647,8 +586,9 @@ export class OxyServices {
|
|
|
647
586
|
*/
|
|
648
587
|
async getSessionsBySessionId(sessionId: string): Promise<any[]> {
|
|
649
588
|
try {
|
|
650
|
-
|
|
651
|
-
|
|
589
|
+
return await this.makeRequest('GET', `/api/session/sessions/${sessionId}`, undefined, {
|
|
590
|
+
cache: false,
|
|
591
|
+
});
|
|
652
592
|
} catch (error) {
|
|
653
593
|
throw this.handleError(error);
|
|
654
594
|
}
|
|
@@ -663,7 +603,7 @@ export class OxyServices {
|
|
|
663
603
|
? `/api/session/logout/${sessionId}/${targetSessionId}`
|
|
664
604
|
: `/api/session/logout/${sessionId}`;
|
|
665
605
|
|
|
666
|
-
await this.
|
|
606
|
+
await this.makeRequest('POST', url, undefined, { cache: false });
|
|
667
607
|
} catch (error) {
|
|
668
608
|
throw this.handleError(error);
|
|
669
609
|
}
|
|
@@ -674,7 +614,7 @@ export class OxyServices {
|
|
|
674
614
|
*/
|
|
675
615
|
async logoutAllSessions(sessionId: string): Promise<void> {
|
|
676
616
|
try {
|
|
677
|
-
await this.
|
|
617
|
+
await this.makeRequest('POST', `/api/session/logout-all/${sessionId}`, undefined, { cache: false });
|
|
678
618
|
} catch (error) {
|
|
679
619
|
throw this.handleError(error);
|
|
680
620
|
}
|
|
@@ -706,9 +646,11 @@ export class OxyServices {
|
|
|
706
646
|
params.append('useHeaderValidation', 'true');
|
|
707
647
|
}
|
|
708
648
|
|
|
709
|
-
const url = `/api/session/validate/${sessionId}
|
|
710
|
-
const
|
|
711
|
-
|
|
649
|
+
const url = `/api/session/validate/${sessionId}`;
|
|
650
|
+
const urlParams: any = {};
|
|
651
|
+
if (options.deviceFingerprint) urlParams.deviceFingerprint = options.deviceFingerprint;
|
|
652
|
+
if (options.useHeaderValidation) urlParams.useHeaderValidation = 'true';
|
|
653
|
+
return await this.makeRequest('GET', url, urlParams, { cache: false });
|
|
712
654
|
} catch (error) {
|
|
713
655
|
throw this.handleError(error);
|
|
714
656
|
}
|
|
@@ -719,8 +661,7 @@ export class OxyServices {
|
|
|
719
661
|
*/
|
|
720
662
|
async checkUsernameAvailability(username: string): Promise<{ available: boolean; message: string }> {
|
|
721
663
|
try {
|
|
722
|
-
|
|
723
|
-
return res.data;
|
|
664
|
+
return await this.makeRequest('GET', `/api/auth/check-username/${username}`, undefined, { cache: false });
|
|
724
665
|
} catch (error) {
|
|
725
666
|
throw this.handleError(error);
|
|
726
667
|
}
|
|
@@ -731,8 +672,7 @@ export class OxyServices {
|
|
|
731
672
|
*/
|
|
732
673
|
async checkEmailAvailability(email: string): Promise<{ available: boolean; message: string }> {
|
|
733
674
|
try {
|
|
734
|
-
|
|
735
|
-
return res.data;
|
|
675
|
+
return await this.makeRequest('GET', `/api/auth/check-email/${email}`, undefined, { cache: false });
|
|
736
676
|
} catch (error) {
|
|
737
677
|
throw this.handleError(error);
|
|
738
678
|
}
|
|
@@ -747,8 +687,10 @@ export class OxyServices {
|
|
|
747
687
|
*/
|
|
748
688
|
async getProfileByUsername(username: string): Promise<User> {
|
|
749
689
|
try {
|
|
750
|
-
|
|
751
|
-
|
|
690
|
+
return await this.makeRequest<User>('GET', `/api/profiles/username/${username}`, undefined, {
|
|
691
|
+
cache: true,
|
|
692
|
+
cacheTTL: 5 * 60 * 1000, // 5 minutes cache for profiles
|
|
693
|
+
});
|
|
752
694
|
} catch (error) {
|
|
753
695
|
throw this.handleError(error);
|
|
754
696
|
}
|
|
@@ -760,10 +702,8 @@ export class OxyServices {
|
|
|
760
702
|
|
|
761
703
|
async startTotpEnrollment(sessionId: string): Promise<{ secret: string; otpauthUrl: string; issuer: string; label: string }> {
|
|
762
704
|
try {
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
});
|
|
766
|
-
return res.data;
|
|
705
|
+
// Note: x-session-id header is handled by HttpClient interceptors if needed
|
|
706
|
+
return await this.makeRequest('POST', '/api/auth/totp/enroll/start', { sessionId }, { cache: false });
|
|
767
707
|
} catch (error) {
|
|
768
708
|
throw this.handleError(error);
|
|
769
709
|
}
|
|
@@ -771,10 +711,7 @@ export class OxyServices {
|
|
|
771
711
|
|
|
772
712
|
async verifyTotpEnrollment(sessionId: string, code: string): Promise<{ enabled: boolean; backupCodes?: string[]; recoveryKey?: string }> {
|
|
773
713
|
try {
|
|
774
|
-
|
|
775
|
-
headers: { 'x-session-id': sessionId }
|
|
776
|
-
});
|
|
777
|
-
return res.data;
|
|
714
|
+
return await this.makeRequest('POST', '/api/auth/totp/enroll/verify', { sessionId, code }, { cache: false });
|
|
778
715
|
} catch (error) {
|
|
779
716
|
throw this.handleError(error);
|
|
780
717
|
}
|
|
@@ -782,10 +719,7 @@ export class OxyServices {
|
|
|
782
719
|
|
|
783
720
|
async disableTotp(sessionId: string, code: string): Promise<{ disabled: boolean }> {
|
|
784
721
|
try {
|
|
785
|
-
|
|
786
|
-
headers: { 'x-session-id': sessionId }
|
|
787
|
-
});
|
|
788
|
-
return res.data;
|
|
722
|
+
return await this.makeRequest('POST', '/api/auth/totp/disable', { sessionId, code }, { cache: false });
|
|
789
723
|
} catch (error) {
|
|
790
724
|
throw this.handleError(error);
|
|
791
725
|
}
|
|
@@ -798,9 +732,14 @@ export class OxyServices {
|
|
|
798
732
|
try {
|
|
799
733
|
const params = { query, ...pagination };
|
|
800
734
|
const searchParams = buildSearchParams(params);
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
735
|
+
const paramsObj: any = {};
|
|
736
|
+
searchParams.forEach((value, key) => {
|
|
737
|
+
paramsObj[key] = value;
|
|
738
|
+
});
|
|
739
|
+
return await this.makeRequest<User[]>('GET', '/api/profiles/search', paramsObj, {
|
|
740
|
+
cache: true,
|
|
741
|
+
cacheTTL: 2 * 60 * 1000, // 2 minutes cache
|
|
742
|
+
});
|
|
804
743
|
} catch (error) {
|
|
805
744
|
throw this.handleError(error);
|
|
806
745
|
}
|
|
@@ -818,8 +757,7 @@ export class OxyServices {
|
|
|
818
757
|
[key: string]: any;
|
|
819
758
|
}>> {
|
|
820
759
|
return this.withAuthRetry(async () => {
|
|
821
|
-
|
|
822
|
-
return res.data;
|
|
760
|
+
return await this.makeRequest('GET', '/api/profiles/recommendations', undefined, { cache: true });
|
|
823
761
|
}, 'getProfileRecommendations');
|
|
824
762
|
}
|
|
825
763
|
|
|
@@ -828,8 +766,10 @@ export class OxyServices {
|
|
|
828
766
|
*/
|
|
829
767
|
async getUserById(userId: string): Promise<User> {
|
|
830
768
|
try {
|
|
831
|
-
|
|
832
|
-
|
|
769
|
+
return await this.makeRequest<User>('GET', `/api/users/${userId}`, undefined, {
|
|
770
|
+
cache: true,
|
|
771
|
+
cacheTTL: 5 * 60 * 1000, // 5 minutes cache
|
|
772
|
+
});
|
|
833
773
|
} catch (error) {
|
|
834
774
|
throw this.handleError(error);
|
|
835
775
|
}
|
|
@@ -840,8 +780,10 @@ export class OxyServices {
|
|
|
840
780
|
*/
|
|
841
781
|
async getCurrentUser(): Promise<User> {
|
|
842
782
|
return this.withAuthRetry(async () => {
|
|
843
|
-
|
|
844
|
-
|
|
783
|
+
return await this.makeRequest<User>('GET', '/api/users/me', undefined, {
|
|
784
|
+
cache: true,
|
|
785
|
+
cacheTTL: 1 * 60 * 1000, // 1 minute cache for current user
|
|
786
|
+
});
|
|
845
787
|
}, 'getCurrentUser');
|
|
846
788
|
}
|
|
847
789
|
|
|
@@ -850,20 +792,136 @@ export class OxyServices {
|
|
|
850
792
|
*/
|
|
851
793
|
async updateProfile(updates: Record<string, any>): Promise<User> {
|
|
852
794
|
try {
|
|
853
|
-
|
|
854
|
-
return res.data;
|
|
795
|
+
return await this.makeRequest<User>('PUT', '/api/users/me', updates, { cache: false });
|
|
855
796
|
} catch (error) {
|
|
856
797
|
throw this.handleError(error);
|
|
857
798
|
}
|
|
858
799
|
}
|
|
859
800
|
|
|
801
|
+
// ============================================================================
|
|
802
|
+
// LANGUAGE METHODS
|
|
803
|
+
// ============================================================================
|
|
804
|
+
|
|
805
|
+
/**
|
|
806
|
+
* Get the current language from storage or user profile
|
|
807
|
+
* @param storageKeyPrefix - Optional prefix for storage key (default: 'oxy_session')
|
|
808
|
+
* @returns The current language code (e.g., 'en-US') or null if not set
|
|
809
|
+
*/
|
|
810
|
+
async getCurrentLanguage(storageKeyPrefix: string = 'oxy_session'): Promise<string | null> {
|
|
811
|
+
try {
|
|
812
|
+
// First try to get from user profile if authenticated
|
|
813
|
+
try {
|
|
814
|
+
const user = await this.getCurrentUser();
|
|
815
|
+
const userLanguage = (user as Record<string, unknown>)?.language as string | undefined;
|
|
816
|
+
if (userLanguage) {
|
|
817
|
+
return normalizeLanguageCode(userLanguage) || userLanguage;
|
|
818
|
+
}
|
|
819
|
+
} catch (e) {
|
|
820
|
+
// User not authenticated or error, continue to storage
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
// Fall back to storage
|
|
824
|
+
const storage = await this.getStorage();
|
|
825
|
+
const storageKey = `${storageKeyPrefix}_language`;
|
|
826
|
+
const storedLanguage = await storage.getItem(storageKey);
|
|
827
|
+
if (storedLanguage) {
|
|
828
|
+
return normalizeLanguageCode(storedLanguage) || storedLanguage;
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
return null;
|
|
832
|
+
} catch (error) {
|
|
833
|
+
if (__DEV__) {
|
|
834
|
+
console.warn('Failed to get current language:', error);
|
|
835
|
+
}
|
|
836
|
+
return null;
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
/**
|
|
841
|
+
* Get the current language with metadata (name, nativeName, etc.)
|
|
842
|
+
* @param storageKeyPrefix - Optional prefix for storage key (default: 'oxy_session')
|
|
843
|
+
* @returns Language metadata object or null if not set
|
|
844
|
+
*/
|
|
845
|
+
async getCurrentLanguageMetadata(storageKeyPrefix: string = 'oxy_session'): Promise<LanguageMetadata | null> {
|
|
846
|
+
const languageCode = await this.getCurrentLanguage(storageKeyPrefix);
|
|
847
|
+
return getLanguageMetadata(languageCode);
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
/**
|
|
851
|
+
* Get the current language name (e.g., 'English')
|
|
852
|
+
* @param storageKeyPrefix - Optional prefix for storage key (default: 'oxy_session')
|
|
853
|
+
* @returns Language name or null if not set
|
|
854
|
+
*/
|
|
855
|
+
async getCurrentLanguageName(storageKeyPrefix: string = 'oxy_session'): Promise<string | null> {
|
|
856
|
+
const languageCode = await this.getCurrentLanguage(storageKeyPrefix);
|
|
857
|
+
if (!languageCode) return null;
|
|
858
|
+
return getLanguageName(languageCode);
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
/**
|
|
862
|
+
* Get the current native language name (e.g., 'Español')
|
|
863
|
+
* @param storageKeyPrefix - Optional prefix for storage key (default: 'oxy_session')
|
|
864
|
+
* @returns Native language name or null if not set
|
|
865
|
+
*/
|
|
866
|
+
async getCurrentNativeLanguageName(storageKeyPrefix: string = 'oxy_session'): Promise<string | null> {
|
|
867
|
+
const languageCode = await this.getCurrentLanguage(storageKeyPrefix);
|
|
868
|
+
if (!languageCode) return null;
|
|
869
|
+
return getNativeLanguageName(languageCode);
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
/**
|
|
873
|
+
* Get appropriate storage for the platform (similar to DeviceManager)
|
|
874
|
+
* @private
|
|
875
|
+
*/
|
|
876
|
+
private async getStorage(): Promise<{
|
|
877
|
+
getItem: (key: string) => Promise<string | null>;
|
|
878
|
+
setItem: (key: string, value: string) => Promise<void>;
|
|
879
|
+
removeItem: (key: string) => Promise<void>;
|
|
880
|
+
}> {
|
|
881
|
+
const isReactNative = typeof navigator !== 'undefined' && navigator.product === 'ReactNative';
|
|
882
|
+
|
|
883
|
+
if (isReactNative) {
|
|
884
|
+
try {
|
|
885
|
+
const asyncStorageModule = await import('@react-native-async-storage/async-storage');
|
|
886
|
+
const storage = (asyncStorageModule.default as unknown) as import('@react-native-async-storage/async-storage').AsyncStorageStatic;
|
|
887
|
+
return {
|
|
888
|
+
getItem: storage.getItem.bind(storage),
|
|
889
|
+
setItem: storage.setItem.bind(storage),
|
|
890
|
+
removeItem: storage.removeItem.bind(storage),
|
|
891
|
+
};
|
|
892
|
+
} catch (error) {
|
|
893
|
+
console.error('AsyncStorage not available in React Native:', error);
|
|
894
|
+
throw new Error('AsyncStorage is required in React Native environment');
|
|
895
|
+
}
|
|
896
|
+
} else {
|
|
897
|
+
// Use localStorage for web
|
|
898
|
+
return {
|
|
899
|
+
getItem: async (key: string) => {
|
|
900
|
+
if (typeof window !== 'undefined' && window.localStorage) {
|
|
901
|
+
return localStorage.getItem(key);
|
|
902
|
+
}
|
|
903
|
+
return null;
|
|
904
|
+
},
|
|
905
|
+
setItem: async (key: string, value: string) => {
|
|
906
|
+
if (typeof window !== 'undefined' && window.localStorage) {
|
|
907
|
+
localStorage.setItem(key, value);
|
|
908
|
+
}
|
|
909
|
+
},
|
|
910
|
+
removeItem: async (key: string) => {
|
|
911
|
+
if (typeof window !== 'undefined' && window.localStorage) {
|
|
912
|
+
localStorage.removeItem(key);
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
};
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
|
|
860
919
|
/**
|
|
861
920
|
* Update user by ID (admin function)
|
|
862
921
|
*/
|
|
863
922
|
async updateUser(userId: string, updates: Record<string, any>): Promise<User> {
|
|
864
923
|
try {
|
|
865
|
-
|
|
866
|
-
return res.data;
|
|
924
|
+
return await this.makeRequest<User>('PUT', `/api/users/${userId}`, updates, { cache: false });
|
|
867
925
|
} catch (error) {
|
|
868
926
|
throw this.handleError(error);
|
|
869
927
|
}
|
|
@@ -874,8 +932,7 @@ export class OxyServices {
|
|
|
874
932
|
*/
|
|
875
933
|
async followUser(userId: string): Promise<{ success: boolean; message: string }> {
|
|
876
934
|
try {
|
|
877
|
-
|
|
878
|
-
return res.data;
|
|
935
|
+
return await this.makeRequest('POST', `/api/users/${userId}/follow`, undefined, { cache: false });
|
|
879
936
|
} catch (error) {
|
|
880
937
|
throw this.handleError(error);
|
|
881
938
|
}
|
|
@@ -886,8 +943,7 @@ export class OxyServices {
|
|
|
886
943
|
*/
|
|
887
944
|
async unfollowUser(userId: string): Promise<{ success: boolean; message: string }> {
|
|
888
945
|
try {
|
|
889
|
-
|
|
890
|
-
return res.data;
|
|
946
|
+
return await this.makeRequest('DELETE', `/api/users/${userId}/follow`, undefined, { cache: false });
|
|
891
947
|
} catch (error) {
|
|
892
948
|
throw this.handleError(error);
|
|
893
949
|
}
|
|
@@ -898,8 +954,10 @@ export class OxyServices {
|
|
|
898
954
|
*/
|
|
899
955
|
async getFollowStatus(userId: string): Promise<{ isFollowing: boolean }> {
|
|
900
956
|
try {
|
|
901
|
-
|
|
902
|
-
|
|
957
|
+
return await this.makeRequest('GET', `/api/users/${userId}/follow-status`, undefined, {
|
|
958
|
+
cache: true,
|
|
959
|
+
cacheTTL: 1 * 60 * 1000, // 1 minute cache
|
|
960
|
+
});
|
|
903
961
|
} catch (error) {
|
|
904
962
|
throw this.handleError(error);
|
|
905
963
|
}
|
|
@@ -914,8 +972,15 @@ export class OxyServices {
|
|
|
914
972
|
): Promise<{ followers: User[]; total: number; hasMore: boolean }> {
|
|
915
973
|
try {
|
|
916
974
|
const params = buildPaginationParams(pagination || {});
|
|
917
|
-
const
|
|
918
|
-
|
|
975
|
+
const response = await this.makeRequest<{ data: User[]; pagination: { total: number; hasMore: boolean } }>('GET', `/api/users/${userId}/followers`, params, {
|
|
976
|
+
cache: true,
|
|
977
|
+
cacheTTL: 2 * 60 * 1000, // 2 minutes cache
|
|
978
|
+
});
|
|
979
|
+
return {
|
|
980
|
+
followers: response.data || [],
|
|
981
|
+
total: response.pagination.total,
|
|
982
|
+
hasMore: response.pagination.hasMore,
|
|
983
|
+
};
|
|
919
984
|
} catch (error) {
|
|
920
985
|
throw this.handleError(error);
|
|
921
986
|
}
|
|
@@ -930,8 +995,15 @@ export class OxyServices {
|
|
|
930
995
|
): Promise<{ following: User[]; total: number; hasMore: boolean }> {
|
|
931
996
|
try {
|
|
932
997
|
const params = buildPaginationParams(pagination || {});
|
|
933
|
-
const
|
|
934
|
-
|
|
998
|
+
const response = await this.makeRequest<{ data: User[]; pagination: { total: number; hasMore: boolean } }>('GET', `/api/users/${userId}/following`, params, {
|
|
999
|
+
cache: true,
|
|
1000
|
+
cacheTTL: 2 * 60 * 1000, // 2 minutes cache
|
|
1001
|
+
});
|
|
1002
|
+
return {
|
|
1003
|
+
following: response.data || [],
|
|
1004
|
+
total: response.pagination.total,
|
|
1005
|
+
hasMore: response.pagination.hasMore,
|
|
1006
|
+
};
|
|
935
1007
|
} catch (error) {
|
|
936
1008
|
throw this.handleError(error);
|
|
937
1009
|
}
|
|
@@ -942,8 +1014,9 @@ export class OxyServices {
|
|
|
942
1014
|
*/
|
|
943
1015
|
async getNotifications(): Promise<Notification[]> {
|
|
944
1016
|
return this.withAuthRetry(async () => {
|
|
945
|
-
|
|
946
|
-
|
|
1017
|
+
return await this.makeRequest<Notification[]>('GET', '/api/notifications', undefined, {
|
|
1018
|
+
cache: false, // Don't cache notifications - always get fresh data
|
|
1019
|
+
});
|
|
947
1020
|
}, 'getNotifications');
|
|
948
1021
|
}
|
|
949
1022
|
|
|
@@ -952,8 +1025,10 @@ export class OxyServices {
|
|
|
952
1025
|
*/
|
|
953
1026
|
async getUnreadCount(): Promise<number> {
|
|
954
1027
|
try {
|
|
955
|
-
const res = await this.
|
|
956
|
-
|
|
1028
|
+
const res = await this.makeRequest<{ count: number }>('GET', '/api/notifications/unread-count', undefined, {
|
|
1029
|
+
cache: false, // Don't cache unread count - always get fresh data
|
|
1030
|
+
});
|
|
1031
|
+
return res.count;
|
|
957
1032
|
} catch (error) {
|
|
958
1033
|
throw this.handleError(error);
|
|
959
1034
|
}
|
|
@@ -964,8 +1039,7 @@ export class OxyServices {
|
|
|
964
1039
|
*/
|
|
965
1040
|
async createNotification(data: Partial<Notification>): Promise<Notification> {
|
|
966
1041
|
try {
|
|
967
|
-
|
|
968
|
-
return res.data;
|
|
1042
|
+
return await this.makeRequest<Notification>('POST', '/api/notifications', data, { cache: false });
|
|
969
1043
|
} catch (error) {
|
|
970
1044
|
throw this.handleError(error);
|
|
971
1045
|
}
|
|
@@ -976,7 +1050,7 @@ export class OxyServices {
|
|
|
976
1050
|
*/
|
|
977
1051
|
async markNotificationAsRead(notificationId: string): Promise<void> {
|
|
978
1052
|
try {
|
|
979
|
-
await this.
|
|
1053
|
+
await this.makeRequest('PUT', `/api/notifications/${notificationId}/read`, undefined, { cache: false });
|
|
980
1054
|
} catch (error) {
|
|
981
1055
|
throw this.handleError(error);
|
|
982
1056
|
}
|
|
@@ -987,7 +1061,7 @@ export class OxyServices {
|
|
|
987
1061
|
*/
|
|
988
1062
|
async markAllNotificationsAsRead(): Promise<void> {
|
|
989
1063
|
try {
|
|
990
|
-
await this.
|
|
1064
|
+
await this.makeRequest('PUT', '/api/notifications/read-all', undefined, { cache: false });
|
|
991
1065
|
} catch (error) {
|
|
992
1066
|
throw this.handleError(error);
|
|
993
1067
|
}
|
|
@@ -998,7 +1072,7 @@ export class OxyServices {
|
|
|
998
1072
|
*/
|
|
999
1073
|
async deleteNotification(notificationId: string): Promise<void> {
|
|
1000
1074
|
try {
|
|
1001
|
-
await this.
|
|
1075
|
+
await this.makeRequest('DELETE', `/api/notifications/${notificationId}`, undefined, { cache: false });
|
|
1002
1076
|
} catch (error) {
|
|
1003
1077
|
throw this.handleError(error);
|
|
1004
1078
|
}
|
|
@@ -1013,8 +1087,7 @@ export class OxyServices {
|
|
|
1013
1087
|
*/
|
|
1014
1088
|
async createPayment(data: any): Promise<any> {
|
|
1015
1089
|
try {
|
|
1016
|
-
|
|
1017
|
-
return res.data;
|
|
1090
|
+
return await this.makeRequest('POST', '/api/payments', data, { cache: false });
|
|
1018
1091
|
} catch (error) {
|
|
1019
1092
|
throw this.handleError(error);
|
|
1020
1093
|
}
|
|
@@ -1025,8 +1098,10 @@ export class OxyServices {
|
|
|
1025
1098
|
*/
|
|
1026
1099
|
async getPayment(paymentId: string): Promise<any> {
|
|
1027
1100
|
try {
|
|
1028
|
-
|
|
1029
|
-
|
|
1101
|
+
return await this.makeRequest('GET', `/api/payments/${paymentId}`, undefined, {
|
|
1102
|
+
cache: true,
|
|
1103
|
+
cacheTTL: 5 * 60 * 1000, // 5 minutes cache
|
|
1104
|
+
});
|
|
1030
1105
|
} catch (error) {
|
|
1031
1106
|
throw this.handleError(error);
|
|
1032
1107
|
}
|
|
@@ -1037,8 +1112,9 @@ export class OxyServices {
|
|
|
1037
1112
|
*/
|
|
1038
1113
|
async getUserPayments(): Promise<any[]> {
|
|
1039
1114
|
try {
|
|
1040
|
-
|
|
1041
|
-
|
|
1115
|
+
return await this.makeRequest('GET', '/api/payments/user', undefined, {
|
|
1116
|
+
cache: false, // Don't cache user payments - always get fresh data
|
|
1117
|
+
});
|
|
1042
1118
|
} catch (error) {
|
|
1043
1119
|
throw this.handleError(error);
|
|
1044
1120
|
}
|
|
@@ -1053,8 +1129,10 @@ export class OxyServices {
|
|
|
1053
1129
|
*/
|
|
1054
1130
|
async getUserKarma(userId: string): Promise<any> {
|
|
1055
1131
|
try {
|
|
1056
|
-
|
|
1057
|
-
|
|
1132
|
+
return await this.makeRequest('GET', `/api/karma/${userId}`, undefined, {
|
|
1133
|
+
cache: true,
|
|
1134
|
+
cacheTTL: 2 * 60 * 1000, // 2 minutes cache
|
|
1135
|
+
});
|
|
1058
1136
|
} catch (error) {
|
|
1059
1137
|
throw this.handleError(error);
|
|
1060
1138
|
}
|
|
@@ -1065,11 +1143,10 @@ export class OxyServices {
|
|
|
1065
1143
|
*/
|
|
1066
1144
|
async giveKarma(userId: string, amount: number, reason?: string): Promise<any> {
|
|
1067
1145
|
try {
|
|
1068
|
-
|
|
1146
|
+
return await this.makeRequest('POST', `/api/karma/${userId}/give`, {
|
|
1069
1147
|
amount,
|
|
1070
1148
|
reason
|
|
1071
|
-
});
|
|
1072
|
-
return res.data;
|
|
1149
|
+
}, { cache: false });
|
|
1073
1150
|
} catch (error) {
|
|
1074
1151
|
throw this.handleError(error);
|
|
1075
1152
|
}
|
|
@@ -1080,8 +1157,10 @@ export class OxyServices {
|
|
|
1080
1157
|
*/
|
|
1081
1158
|
async getUserKarmaTotal(userId: string): Promise<any> {
|
|
1082
1159
|
try {
|
|
1083
|
-
|
|
1084
|
-
|
|
1160
|
+
return await this.makeRequest('GET', `/api/karma/${userId}/total`, undefined, {
|
|
1161
|
+
cache: true,
|
|
1162
|
+
cacheTTL: 2 * 60 * 1000, // 2 minutes cache
|
|
1163
|
+
});
|
|
1085
1164
|
} catch (error) {
|
|
1086
1165
|
throw this.handleError(error);
|
|
1087
1166
|
}
|
|
@@ -1092,12 +1171,14 @@ export class OxyServices {
|
|
|
1092
1171
|
*/
|
|
1093
1172
|
async getUserKarmaHistory(userId: string, limit?: number, offset?: number): Promise<any> {
|
|
1094
1173
|
try {
|
|
1095
|
-
const params =
|
|
1096
|
-
if (limit) params.
|
|
1097
|
-
if (offset) params.
|
|
1174
|
+
const params: any = {};
|
|
1175
|
+
if (limit) params.limit = limit;
|
|
1176
|
+
if (offset) params.offset = offset;
|
|
1098
1177
|
|
|
1099
|
-
|
|
1100
|
-
|
|
1178
|
+
return await this.makeRequest('GET', `/api/karma/${userId}/history`, params, {
|
|
1179
|
+
cache: true,
|
|
1180
|
+
cacheTTL: 2 * 60 * 1000, // 2 minutes cache
|
|
1181
|
+
});
|
|
1101
1182
|
} catch (error) {
|
|
1102
1183
|
throw this.handleError(error);
|
|
1103
1184
|
}
|
|
@@ -1108,8 +1189,10 @@ export class OxyServices {
|
|
|
1108
1189
|
*/
|
|
1109
1190
|
async getKarmaLeaderboard(): Promise<any> {
|
|
1110
1191
|
try {
|
|
1111
|
-
|
|
1112
|
-
|
|
1192
|
+
return await this.makeRequest('GET', '/api/karma/leaderboard', undefined, {
|
|
1193
|
+
cache: true,
|
|
1194
|
+
cacheTTL: 5 * 60 * 1000, // 5 minutes cache
|
|
1195
|
+
});
|
|
1113
1196
|
} catch (error) {
|
|
1114
1197
|
throw this.handleError(error);
|
|
1115
1198
|
}
|
|
@@ -1120,8 +1203,10 @@ export class OxyServices {
|
|
|
1120
1203
|
*/
|
|
1121
1204
|
async getKarmaRules(): Promise<any> {
|
|
1122
1205
|
try {
|
|
1123
|
-
|
|
1124
|
-
|
|
1206
|
+
return await this.makeRequest('GET', '/api/karma/rules', undefined, {
|
|
1207
|
+
cache: true,
|
|
1208
|
+
cacheTTL: 30 * 60 * 1000, // 30 minutes cache (rules don't change often)
|
|
1209
|
+
});
|
|
1125
1210
|
} catch (error) {
|
|
1126
1211
|
throw this.handleError(error);
|
|
1127
1212
|
}
|
|
@@ -1137,8 +1222,7 @@ export class OxyServices {
|
|
|
1137
1222
|
async deleteFile(fileId: string): Promise<any> {
|
|
1138
1223
|
try {
|
|
1139
1224
|
// Central Asset Service delete with force=true behavior controlled by caller via assetDelete
|
|
1140
|
-
|
|
1141
|
-
return res.data;
|
|
1225
|
+
return await this.makeRequest('DELETE', `/api/assets/${encodeURIComponent(fileId)}`, undefined, { cache: false });
|
|
1142
1226
|
} catch (error) {
|
|
1143
1227
|
throw this.handleError(error);
|
|
1144
1228
|
}
|
|
@@ -1153,7 +1237,7 @@ export class OxyServices {
|
|
|
1153
1237
|
if (variant) params.set('variant', variant);
|
|
1154
1238
|
if (expiresIn) params.set('expiresIn', String(expiresIn));
|
|
1155
1239
|
params.set('fallback', 'placeholderVisible');
|
|
1156
|
-
const token = this.
|
|
1240
|
+
const token = this.httpClient.getAccessToken();
|
|
1157
1241
|
if (token) params.set('token', token);
|
|
1158
1242
|
|
|
1159
1243
|
// Use params.toString() to detect whether there are query params.
|
|
@@ -1179,12 +1263,12 @@ export class OxyServices {
|
|
|
1179
1263
|
*/
|
|
1180
1264
|
async listUserFiles(limit?: number, offset?: number): Promise<{ files: any[]; total: number; hasMore: boolean }> {
|
|
1181
1265
|
try {
|
|
1182
|
-
const
|
|
1183
|
-
if (limit)
|
|
1184
|
-
if (offset)
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1266
|
+
const paramsObj: any = {};
|
|
1267
|
+
if (limit) paramsObj.limit = limit;
|
|
1268
|
+
if (offset) paramsObj.offset = offset;
|
|
1269
|
+
return await this.makeRequest('GET', '/api/assets', paramsObj, {
|
|
1270
|
+
cache: false, // Don't cache file lists - always get fresh data
|
|
1271
|
+
});
|
|
1188
1272
|
} catch (error) {
|
|
1189
1273
|
throw this.handleError(error);
|
|
1190
1274
|
}
|
|
@@ -1197,8 +1281,12 @@ export class OxyServices {
|
|
|
1197
1281
|
*/
|
|
1198
1282
|
async getFileContentAsText(fileId: string, variant?: string): Promise<string> {
|
|
1199
1283
|
try {
|
|
1200
|
-
const
|
|
1201
|
-
const
|
|
1284
|
+
const params: any = variant ? { variant } : undefined;
|
|
1285
|
+
const urlRes = await this.makeRequest<{ url: string }>('GET', `/api/assets/${encodeURIComponent(fileId)}/url`, params, {
|
|
1286
|
+
cache: true,
|
|
1287
|
+
cacheTTL: 10 * 60 * 1000, // 10 minutes cache for URLs
|
|
1288
|
+
});
|
|
1289
|
+
const downloadUrl = urlRes?.url;
|
|
1202
1290
|
const response = await fetch(downloadUrl);
|
|
1203
1291
|
return await response.text();
|
|
1204
1292
|
} catch (error) {
|
|
@@ -1211,8 +1299,12 @@ export class OxyServices {
|
|
|
1211
1299
|
*/
|
|
1212
1300
|
async getFileContentAsBlob(fileId: string, variant?: string): Promise<Blob> {
|
|
1213
1301
|
try {
|
|
1214
|
-
const
|
|
1215
|
-
const
|
|
1302
|
+
const params: any = variant ? { variant } : undefined;
|
|
1303
|
+
const urlRes = await this.makeRequest<{ url: string }>('GET', `/api/assets/${encodeURIComponent(fileId)}/url`, params, {
|
|
1304
|
+
cache: true,
|
|
1305
|
+
cacheTTL: 10 * 60 * 1000, // 10 minutes cache for URLs
|
|
1306
|
+
});
|
|
1307
|
+
const downloadUrl = urlRes?.url;
|
|
1216
1308
|
const response = await fetch(downloadUrl);
|
|
1217
1309
|
return await response.blob();
|
|
1218
1310
|
} catch (error) {
|
|
@@ -1247,12 +1339,11 @@ export class OxyServices {
|
|
|
1247
1339
|
*/
|
|
1248
1340
|
async assetInit(sha256: string, size: number, mime: string): Promise<AssetInitResponse> {
|
|
1249
1341
|
try {
|
|
1250
|
-
|
|
1342
|
+
return await this.makeRequest<AssetInitResponse>('POST', '/api/assets/init', {
|
|
1251
1343
|
sha256,
|
|
1252
1344
|
size,
|
|
1253
1345
|
mime
|
|
1254
|
-
});
|
|
1255
|
-
return res.data;
|
|
1346
|
+
}, { cache: false });
|
|
1256
1347
|
} catch (error) {
|
|
1257
1348
|
throw this.handleError(error);
|
|
1258
1349
|
}
|
|
@@ -1263,15 +1354,14 @@ export class OxyServices {
|
|
|
1263
1354
|
*/
|
|
1264
1355
|
async assetComplete(fileId: string, originalName: string, size: number, mime: string, visibility?: 'private' | 'public' | 'unlisted', metadata?: Record<string, any>): Promise<any> {
|
|
1265
1356
|
try {
|
|
1266
|
-
|
|
1357
|
+
return await this.makeRequest('POST', '/api/assets/complete', {
|
|
1267
1358
|
fileId,
|
|
1268
1359
|
originalName,
|
|
1269
1360
|
size,
|
|
1270
1361
|
mime,
|
|
1271
1362
|
visibility,
|
|
1272
1363
|
metadata
|
|
1273
|
-
});
|
|
1274
|
-
return res.data;
|
|
1364
|
+
}, { cache: false });
|
|
1275
1365
|
} catch (error) {
|
|
1276
1366
|
throw this.handleError(error);
|
|
1277
1367
|
}
|
|
@@ -1295,8 +1385,11 @@ export class OxyServices {
|
|
|
1295
1385
|
// Fallback: direct upload via API to avoid CORS issues
|
|
1296
1386
|
const fd = new FormData();
|
|
1297
1387
|
fd.append('file', file);
|
|
1298
|
-
|
|
1299
|
-
|
|
1388
|
+
// Use httpClient directly for FormData uploads (bypasses RequestManager for special handling)
|
|
1389
|
+
await this.httpClient.request({
|
|
1390
|
+
method: 'POST',
|
|
1391
|
+
url: `/api/assets/${encodeURIComponent(initResponse.fileId)}/upload-direct`,
|
|
1392
|
+
data: fd,
|
|
1300
1393
|
});
|
|
1301
1394
|
}
|
|
1302
1395
|
|
|
@@ -1354,8 +1447,7 @@ export class OxyServices {
|
|
|
1354
1447
|
const body: any = { app, entityType, entityId };
|
|
1355
1448
|
if (visibility) body.visibility = visibility;
|
|
1356
1449
|
if (webhookUrl) body.webhookUrl = webhookUrl;
|
|
1357
|
-
|
|
1358
|
-
return res.data;
|
|
1450
|
+
return await this.makeRequest('POST', `/api/assets/${fileId}/links`, body, { cache: false });
|
|
1359
1451
|
} catch (error) {
|
|
1360
1452
|
throw this.handleError(error);
|
|
1361
1453
|
}
|
|
@@ -1366,14 +1458,11 @@ export class OxyServices {
|
|
|
1366
1458
|
*/
|
|
1367
1459
|
async assetUnlink(fileId: string, app: string, entityType: string, entityId: string): Promise<any> {
|
|
1368
1460
|
try {
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
}
|
|
1375
|
-
});
|
|
1376
|
-
return res.data;
|
|
1461
|
+
return await this.makeRequest('DELETE', `/api/assets/${fileId}/links`, {
|
|
1462
|
+
app,
|
|
1463
|
+
entityType,
|
|
1464
|
+
entityId
|
|
1465
|
+
}, { cache: false });
|
|
1377
1466
|
} catch (error) {
|
|
1378
1467
|
throw this.handleError(error);
|
|
1379
1468
|
}
|
|
@@ -1384,8 +1473,10 @@ export class OxyServices {
|
|
|
1384
1473
|
*/
|
|
1385
1474
|
async assetGet(fileId: string): Promise<any> {
|
|
1386
1475
|
try {
|
|
1387
|
-
|
|
1388
|
-
|
|
1476
|
+
return await this.makeRequest('GET', `/api/assets/${fileId}`, undefined, {
|
|
1477
|
+
cache: true,
|
|
1478
|
+
cacheTTL: 5 * 60 * 1000, // 5 minutes cache
|
|
1479
|
+
});
|
|
1389
1480
|
} catch (error) {
|
|
1390
1481
|
throw this.handleError(error);
|
|
1391
1482
|
}
|
|
@@ -1396,15 +1487,14 @@ export class OxyServices {
|
|
|
1396
1487
|
*/
|
|
1397
1488
|
async assetGetUrl(fileId: string, variant?: string, expiresIn?: number): Promise<AssetUrlResponse> {
|
|
1398
1489
|
try {
|
|
1399
|
-
const params =
|
|
1400
|
-
if (variant) params.
|
|
1401
|
-
if (expiresIn) params.
|
|
1402
|
-
|
|
1403
|
-
const queryString = params.toString();
|
|
1404
|
-
const url = `/api/assets/${fileId}/url${queryString ? `?${queryString}` : ''}`;
|
|
1490
|
+
const params: any = {};
|
|
1491
|
+
if (variant) params.variant = variant;
|
|
1492
|
+
if (expiresIn) params.expiresIn = expiresIn;
|
|
1405
1493
|
|
|
1406
|
-
|
|
1407
|
-
|
|
1494
|
+
return await this.makeRequest<AssetUrlResponse>('GET', `/api/assets/${fileId}/url`, params, {
|
|
1495
|
+
cache: true,
|
|
1496
|
+
cacheTTL: 10 * 60 * 1000, // 10 minutes cache for URLs
|
|
1497
|
+
});
|
|
1408
1498
|
} catch (error) {
|
|
1409
1499
|
throw this.handleError(error);
|
|
1410
1500
|
}
|
|
@@ -1415,8 +1505,7 @@ export class OxyServices {
|
|
|
1415
1505
|
*/
|
|
1416
1506
|
async assetRestore(fileId: string): Promise<any> {
|
|
1417
1507
|
try {
|
|
1418
|
-
|
|
1419
|
-
return res.data;
|
|
1508
|
+
return await this.makeRequest('POST', `/api/assets/${fileId}/restore`, undefined, { cache: false });
|
|
1420
1509
|
} catch (error) {
|
|
1421
1510
|
throw this.handleError(error);
|
|
1422
1511
|
}
|
|
@@ -1427,9 +1516,8 @@ export class OxyServices {
|
|
|
1427
1516
|
*/
|
|
1428
1517
|
async assetDelete(fileId: string, force: boolean = false): Promise<any> {
|
|
1429
1518
|
try {
|
|
1430
|
-
const params = force ? '
|
|
1431
|
-
|
|
1432
|
-
return res.data;
|
|
1519
|
+
const params: any = force ? { force: 'true' } : undefined;
|
|
1520
|
+
return await this.makeRequest('DELETE', `/api/assets/${fileId}`, params, { cache: false });
|
|
1433
1521
|
} catch (error) {
|
|
1434
1522
|
throw this.handleError(error);
|
|
1435
1523
|
}
|
|
@@ -1455,10 +1543,9 @@ export class OxyServices {
|
|
|
1455
1543
|
*/
|
|
1456
1544
|
async assetUpdateVisibility(fileId: string, visibility: 'private' | 'public' | 'unlisted'): Promise<any> {
|
|
1457
1545
|
try {
|
|
1458
|
-
|
|
1546
|
+
return await this.makeRequest('PATCH', `/api/assets/${fileId}/visibility`, {
|
|
1459
1547
|
visibility
|
|
1460
|
-
});
|
|
1461
|
-
return res.data;
|
|
1548
|
+
}, { cache: false });
|
|
1462
1549
|
} catch (error) {
|
|
1463
1550
|
throw this.handleError(error);
|
|
1464
1551
|
}
|
|
@@ -1515,8 +1602,11 @@ export class OxyServices {
|
|
|
1515
1602
|
*/
|
|
1516
1603
|
async getDeveloperApps(): Promise<any[]> {
|
|
1517
1604
|
try {
|
|
1518
|
-
const res = await this.
|
|
1519
|
-
|
|
1605
|
+
const res = await this.makeRequest<{ apps?: any[] }>('GET', '/api/developer/apps', undefined, {
|
|
1606
|
+
cache: true,
|
|
1607
|
+
cacheTTL: 2 * 60 * 1000, // 2 minutes cache
|
|
1608
|
+
});
|
|
1609
|
+
return res.apps || [];
|
|
1520
1610
|
} catch (error) {
|
|
1521
1611
|
throw this.handleError(error);
|
|
1522
1612
|
}
|
|
@@ -1528,12 +1618,13 @@ export class OxyServices {
|
|
|
1528
1618
|
async createDeveloperApp(data: {
|
|
1529
1619
|
name: string;
|
|
1530
1620
|
description?: string;
|
|
1531
|
-
webhookUrl
|
|
1621
|
+
webhookUrl: string;
|
|
1622
|
+
devWebhookUrl?: string;
|
|
1532
1623
|
scopes?: string[];
|
|
1533
1624
|
}): Promise<any> {
|
|
1534
1625
|
try {
|
|
1535
|
-
const res = await this.
|
|
1536
|
-
return res.
|
|
1626
|
+
const res = await this.makeRequest<{ app: any }>('POST', '/api/developer/apps', data, { cache: false });
|
|
1627
|
+
return res.app;
|
|
1537
1628
|
} catch (error) {
|
|
1538
1629
|
throw this.handleError(error);
|
|
1539
1630
|
}
|
|
@@ -1544,8 +1635,11 @@ export class OxyServices {
|
|
|
1544
1635
|
*/
|
|
1545
1636
|
async getDeveloperApp(appId: string): Promise<any> {
|
|
1546
1637
|
try {
|
|
1547
|
-
const res = await this.
|
|
1548
|
-
|
|
1638
|
+
const res = await this.makeRequest<{ app: any }>('GET', `/api/developer/apps/${appId}`, undefined, {
|
|
1639
|
+
cache: true,
|
|
1640
|
+
cacheTTL: 5 * 60 * 1000, // 5 minutes cache
|
|
1641
|
+
});
|
|
1642
|
+
return res.app;
|
|
1549
1643
|
} catch (error) {
|
|
1550
1644
|
throw this.handleError(error);
|
|
1551
1645
|
}
|
|
@@ -1558,11 +1652,12 @@ export class OxyServices {
|
|
|
1558
1652
|
name?: string;
|
|
1559
1653
|
description?: string;
|
|
1560
1654
|
webhookUrl?: string;
|
|
1655
|
+
devWebhookUrl?: string;
|
|
1561
1656
|
scopes?: string[];
|
|
1562
1657
|
}): Promise<any> {
|
|
1563
1658
|
try {
|
|
1564
|
-
const res = await this.
|
|
1565
|
-
return res.
|
|
1659
|
+
const res = await this.makeRequest<{ app: any }>('PATCH', `/api/developer/apps/${appId}`, data, { cache: false });
|
|
1660
|
+
return res.app;
|
|
1566
1661
|
} catch (error) {
|
|
1567
1662
|
throw this.handleError(error);
|
|
1568
1663
|
}
|
|
@@ -1573,8 +1668,7 @@ export class OxyServices {
|
|
|
1573
1668
|
*/
|
|
1574
1669
|
async regenerateDeveloperAppSecret(appId: string): Promise<any> {
|
|
1575
1670
|
try {
|
|
1576
|
-
|
|
1577
|
-
return res.data;
|
|
1671
|
+
return await this.makeRequest('POST', `/api/developer/apps/${appId}/regenerate-secret`, undefined, { cache: false });
|
|
1578
1672
|
} catch (error) {
|
|
1579
1673
|
throw this.handleError(error);
|
|
1580
1674
|
}
|
|
@@ -1585,8 +1679,7 @@ export class OxyServices {
|
|
|
1585
1679
|
*/
|
|
1586
1680
|
async deleteDeveloperApp(appId: string): Promise<any> {
|
|
1587
1681
|
try {
|
|
1588
|
-
|
|
1589
|
-
return res.data;
|
|
1682
|
+
return await this.makeRequest('DELETE', `/api/developer/apps/${appId}`, undefined, { cache: false });
|
|
1590
1683
|
} catch (error) {
|
|
1591
1684
|
throw this.handleError(error);
|
|
1592
1685
|
}
|
|
@@ -1601,11 +1694,10 @@ export class OxyServices {
|
|
|
1601
1694
|
*/
|
|
1602
1695
|
async updateLocation(latitude: number, longitude: number): Promise<any> {
|
|
1603
1696
|
try {
|
|
1604
|
-
|
|
1697
|
+
return await this.makeRequest('POST', '/api/location', {
|
|
1605
1698
|
latitude,
|
|
1606
1699
|
longitude
|
|
1607
|
-
});
|
|
1608
|
-
return res.data;
|
|
1700
|
+
}, { cache: false });
|
|
1609
1701
|
} catch (error) {
|
|
1610
1702
|
throw this.handleError(error);
|
|
1611
1703
|
}
|
|
@@ -1616,9 +1708,10 @@ export class OxyServices {
|
|
|
1616
1708
|
*/
|
|
1617
1709
|
async getNearbyUsers(radius?: number): Promise<any[]> {
|
|
1618
1710
|
try {
|
|
1619
|
-
const params = radius ?
|
|
1620
|
-
|
|
1621
|
-
|
|
1711
|
+
const params: any = radius ? { radius } : undefined;
|
|
1712
|
+
return await this.makeRequest('GET', '/api/location/nearby', params, {
|
|
1713
|
+
cache: false, // Don't cache location data - always get fresh data
|
|
1714
|
+
});
|
|
1622
1715
|
} catch (error) {
|
|
1623
1716
|
throw this.handleError(error);
|
|
1624
1717
|
}
|
|
@@ -1633,10 +1726,10 @@ export class OxyServices {
|
|
|
1633
1726
|
*/
|
|
1634
1727
|
async trackEvent(eventName: string, properties?: Record<string, any>): Promise<void> {
|
|
1635
1728
|
try {
|
|
1636
|
-
await this.
|
|
1729
|
+
await this.makeRequest('POST', '/api/analytics/events', {
|
|
1637
1730
|
event: eventName,
|
|
1638
1731
|
properties
|
|
1639
|
-
});
|
|
1732
|
+
}, { cache: false, retry: false }); // Don't retry analytics events
|
|
1640
1733
|
} catch (error) {
|
|
1641
1734
|
throw this.handleError(error);
|
|
1642
1735
|
}
|
|
@@ -1647,12 +1740,14 @@ export class OxyServices {
|
|
|
1647
1740
|
*/
|
|
1648
1741
|
async getAnalytics(startDate?: string, endDate?: string): Promise<any> {
|
|
1649
1742
|
try {
|
|
1650
|
-
const params =
|
|
1651
|
-
if (startDate) params.
|
|
1652
|
-
if (endDate) params.
|
|
1743
|
+
const params: any = {};
|
|
1744
|
+
if (startDate) params.startDate = startDate;
|
|
1745
|
+
if (endDate) params.endDate = endDate;
|
|
1653
1746
|
|
|
1654
|
-
|
|
1655
|
-
|
|
1747
|
+
return await this.makeRequest('GET', '/api/analytics', params, {
|
|
1748
|
+
cache: true,
|
|
1749
|
+
cacheTTL: 5 * 60 * 1000, // 5 minutes cache
|
|
1750
|
+
});
|
|
1656
1751
|
} catch (error) {
|
|
1657
1752
|
throw this.handleError(error);
|
|
1658
1753
|
}
|
|
@@ -1667,8 +1762,7 @@ export class OxyServices {
|
|
|
1667
1762
|
*/
|
|
1668
1763
|
async registerDevice(deviceData: any): Promise<any> {
|
|
1669
1764
|
try {
|
|
1670
|
-
|
|
1671
|
-
return res.data;
|
|
1765
|
+
return await this.makeRequest('POST', '/api/devices', deviceData, { cache: false });
|
|
1672
1766
|
} catch (error) {
|
|
1673
1767
|
throw this.handleError(error);
|
|
1674
1768
|
}
|
|
@@ -1679,8 +1773,9 @@ export class OxyServices {
|
|
|
1679
1773
|
*/
|
|
1680
1774
|
async getUserDevices(): Promise<any[]> {
|
|
1681
1775
|
try {
|
|
1682
|
-
|
|
1683
|
-
|
|
1776
|
+
return await this.makeRequest('GET', '/api/devices', undefined, {
|
|
1777
|
+
cache: false, // Don't cache device list - always get fresh data
|
|
1778
|
+
});
|
|
1684
1779
|
} catch (error) {
|
|
1685
1780
|
throw this.handleError(error);
|
|
1686
1781
|
}
|
|
@@ -1691,7 +1786,7 @@ export class OxyServices {
|
|
|
1691
1786
|
*/
|
|
1692
1787
|
async removeDevice(deviceId: string): Promise<void> {
|
|
1693
1788
|
try {
|
|
1694
|
-
await this.
|
|
1789
|
+
await this.makeRequest('DELETE', `/api/devices/${deviceId}`, undefined, { cache: false });
|
|
1695
1790
|
} catch (error) {
|
|
1696
1791
|
throw this.handleError(error);
|
|
1697
1792
|
}
|
|
@@ -1699,11 +1794,16 @@ export class OxyServices {
|
|
|
1699
1794
|
|
|
1700
1795
|
/**
|
|
1701
1796
|
* Get device sessions
|
|
1797
|
+
* Note: Not cached by default to ensure fresh data, but can be cached via makeRequest if needed
|
|
1702
1798
|
*/
|
|
1703
1799
|
async getDeviceSessions(sessionId: string): Promise<any[]> {
|
|
1704
1800
|
try {
|
|
1705
|
-
|
|
1706
|
-
|
|
1801
|
+
// Use makeRequest for consistent error handling and optional caching
|
|
1802
|
+
// Cache disabled by default to ensure fresh session data
|
|
1803
|
+
return await this.makeRequest<any[]>('GET', `/api/session/device/sessions/${sessionId}`, undefined, {
|
|
1804
|
+
cache: false, // Don't cache sessions - always get fresh data
|
|
1805
|
+
deduplicate: true, // Deduplicate concurrent requests for same sessionId
|
|
1806
|
+
});
|
|
1707
1807
|
} catch (error) {
|
|
1708
1808
|
throw this.handleError(error);
|
|
1709
1809
|
}
|
|
@@ -1718,8 +1818,11 @@ export class OxyServices {
|
|
|
1718
1818
|
if (deviceId) params.append('deviceId', deviceId);
|
|
1719
1819
|
if (excludeCurrent) params.append('excludeCurrent', 'true');
|
|
1720
1820
|
|
|
1721
|
-
const
|
|
1722
|
-
|
|
1821
|
+
const urlParams: any = {};
|
|
1822
|
+
params.forEach((value, key) => {
|
|
1823
|
+
urlParams[key] = value;
|
|
1824
|
+
});
|
|
1825
|
+
return await this.makeRequest('POST', `/api/session/device/logout-all/${sessionId}`, urlParams, { cache: false });
|
|
1723
1826
|
} catch (error) {
|
|
1724
1827
|
throw this.handleError(error);
|
|
1725
1828
|
}
|
|
@@ -1730,8 +1833,7 @@ export class OxyServices {
|
|
|
1730
1833
|
*/
|
|
1731
1834
|
async updateDeviceName(sessionId: string, deviceName: string): Promise<any> {
|
|
1732
1835
|
try {
|
|
1733
|
-
|
|
1734
|
-
return res.data;
|
|
1836
|
+
return await this.makeRequest('PUT', `/api/session/device/name/${sessionId}`, { deviceName }, { cache: false });
|
|
1735
1837
|
} catch (error) {
|
|
1736
1838
|
throw this.handleError(error);
|
|
1737
1839
|
}
|
|
@@ -1751,8 +1853,15 @@ export class OxyServices {
|
|
|
1751
1853
|
image?: string;
|
|
1752
1854
|
}> {
|
|
1753
1855
|
try {
|
|
1754
|
-
|
|
1755
|
-
|
|
1856
|
+
return await this.makeRequest<{
|
|
1857
|
+
url: string;
|
|
1858
|
+
title: string;
|
|
1859
|
+
description: string;
|
|
1860
|
+
image?: string;
|
|
1861
|
+
}>('GET', '/api/link-metadata', { url }, {
|
|
1862
|
+
cache: true,
|
|
1863
|
+
cacheTTL: 30 * 60 * 1000, // 30 minutes cache for link metadata
|
|
1864
|
+
});
|
|
1756
1865
|
} catch (error) {
|
|
1757
1866
|
throw this.handleError(error);
|
|
1758
1867
|
}
|