@oxyhq/services 5.4.2 → 5.4.4
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 +14 -0
- package/lib/commonjs/assets/OxyLogo.svg +1 -0
- package/lib/commonjs/assets/assets/OxyLogo.svg +1 -0
- package/lib/commonjs/assets/assets/fonts/Phudu/Phudu-Black.ttf +0 -0
- package/lib/commonjs/assets/assets/fonts/Phudu/Phudu-Bold.ttf +0 -0
- package/lib/commonjs/assets/assets/fonts/Phudu/Phudu-ExtraBold.ttf +0 -0
- package/lib/commonjs/assets/assets/fonts/Phudu/Phudu-Light.ttf +0 -0
- package/lib/commonjs/assets/assets/fonts/Phudu/Phudu-Medium.ttf +0 -0
- package/lib/commonjs/assets/assets/fonts/Phudu/Phudu-Regular.ttf +0 -0
- package/lib/commonjs/assets/assets/fonts/Phudu/Phudu-SemiBold.ttf +0 -0
- package/lib/commonjs/assets/assets/icons/OxyServices.tsx +67 -0
- package/lib/commonjs/assets/assets/icons/logo_OxyServices.svg +1 -0
- package/lib/commonjs/assets/assets/illustrations/HighFive.tsx +41 -0
- package/lib/commonjs/assets/fonts/Phudu/Phudu-Black.ttf +0 -0
- package/lib/commonjs/assets/fonts/Phudu/Phudu-Bold.ttf +0 -0
- package/lib/commonjs/assets/fonts/Phudu/Phudu-ExtraBold.ttf +0 -0
- package/lib/commonjs/assets/fonts/Phudu/Phudu-Light.ttf +0 -0
- package/lib/commonjs/assets/fonts/Phudu/Phudu-Medium.ttf +0 -0
- package/lib/commonjs/assets/fonts/Phudu/Phudu-Regular.ttf +0 -0
- package/lib/commonjs/assets/fonts/Phudu/Phudu-SemiBold.ttf +0 -0
- package/lib/commonjs/assets/icons/OxyServices.js +53 -0
- package/lib/commonjs/assets/icons/OxyServices.js.map +1 -0
- package/lib/commonjs/assets/icons/logo_OxyServices.svg +1 -0
- package/lib/commonjs/assets/illustrations/HighFive.js +61 -0
- package/lib/commonjs/assets/illustrations/HighFive.js.map +1 -0
- package/lib/commonjs/constants/version.js +28 -0
- package/lib/commonjs/constants/version.js.map +1 -0
- package/lib/commonjs/core/index.js +1660 -0
- package/lib/commonjs/core/index.js.map +1 -0
- package/lib/commonjs/index.js +160 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/lib/sonner.js +21 -0
- package/lib/commonjs/lib/sonner.js.map +1 -0
- package/lib/commonjs/models/interfaces.js +2 -0
- package/lib/commonjs/models/interfaces.js.map +1 -0
- package/lib/commonjs/models/secureSession.js +2 -0
- package/lib/commonjs/models/secureSession.js.map +1 -0
- package/lib/commonjs/node/createAuth.js +95 -0
- package/lib/commonjs/node/createAuth.js.map +1 -0
- package/lib/commonjs/node/index.js +63 -0
- package/lib/commonjs/node/index.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/ui/components/Avatar.js +98 -0
- package/lib/commonjs/ui/components/Avatar.js.map +1 -0
- package/lib/commonjs/ui/components/FollowButton.js +246 -0
- package/lib/commonjs/ui/components/FollowButton.js.map +1 -0
- package/lib/commonjs/ui/components/FontLoader.js +181 -0
- package/lib/commonjs/ui/components/FontLoader.js.map +1 -0
- package/lib/commonjs/ui/components/GroupedItem.js +109 -0
- package/lib/commonjs/ui/components/GroupedItem.js.map +1 -0
- package/lib/commonjs/ui/components/GroupedSection.js +33 -0
- package/lib/commonjs/ui/components/GroupedSection.js.map +1 -0
- package/lib/commonjs/ui/components/OxyLogo.js +56 -0
- package/lib/commonjs/ui/components/OxyLogo.js.map +1 -0
- package/lib/commonjs/ui/components/OxyProvider.js +522 -0
- package/lib/commonjs/ui/components/OxyProvider.js.map +1 -0
- package/lib/commonjs/ui/components/OxySignInButton.js +178 -0
- package/lib/commonjs/ui/components/OxySignInButton.js.map +1 -0
- package/lib/commonjs/ui/components/ProfileCard.js +124 -0
- package/lib/commonjs/ui/components/ProfileCard.js.map +1 -0
- package/lib/commonjs/ui/components/QuickActions.js +87 -0
- package/lib/commonjs/ui/components/QuickActions.js.map +1 -0
- package/lib/commonjs/ui/components/Section.js +36 -0
- package/lib/commonjs/ui/components/Section.js.map +1 -0
- package/lib/commonjs/ui/components/SectionTitle.js +35 -0
- package/lib/commonjs/ui/components/SectionTitle.js.map +1 -0
- package/lib/commonjs/ui/components/bottomSheet/index.js +37 -0
- package/lib/commonjs/ui/components/bottomSheet/index.js.map +1 -0
- package/lib/commonjs/ui/components/icon/OxyIcon.js +27 -0
- package/lib/commonjs/ui/components/icon/OxyIcon.js.map +1 -0
- package/lib/commonjs/ui/components/icon/index.js +14 -0
- package/lib/commonjs/ui/components/icon/index.js.map +1 -0
- package/lib/commonjs/ui/components/index.js +97 -0
- package/lib/commonjs/ui/components/index.js.map +1 -0
- package/lib/commonjs/ui/components/internal/GroupedPillButtons.js +213 -0
- package/lib/commonjs/ui/components/internal/GroupedPillButtons.js.map +1 -0
- package/lib/commonjs/ui/components/internal/TextField.js +576 -0
- package/lib/commonjs/ui/components/internal/TextField.js.map +1 -0
- package/lib/commonjs/ui/context/OxyContext.js +584 -0
- package/lib/commonjs/ui/context/OxyContext.js.map +1 -0
- package/lib/commonjs/ui/index.js +136 -0
- package/lib/commonjs/ui/index.js.map +1 -0
- package/lib/commonjs/ui/navigation/OxyRouter.js +269 -0
- package/lib/commonjs/ui/navigation/OxyRouter.js.map +1 -0
- package/lib/commonjs/ui/navigation/types.js +6 -0
- package/lib/commonjs/ui/navigation/types.js.map +1 -0
- package/lib/commonjs/ui/screens/AccountCenterScreen.js +313 -0
- package/lib/commonjs/ui/screens/AccountCenterScreen.js.map +1 -0
- package/lib/commonjs/ui/screens/AccountManagementDemo.js +299 -0
- package/lib/commonjs/ui/screens/AccountManagementDemo.js.map +1 -0
- package/lib/commonjs/ui/screens/AccountOverviewScreen.js +855 -0
- package/lib/commonjs/ui/screens/AccountOverviewScreen.js.map +1 -0
- package/lib/commonjs/ui/screens/AccountSettingsScreen.js +843 -0
- package/lib/commonjs/ui/screens/AccountSettingsScreen.js.map +1 -0
- package/lib/commonjs/ui/screens/AccountSwitcherScreen.js +788 -0
- package/lib/commonjs/ui/screens/AccountSwitcherScreen.js.map +1 -0
- package/lib/commonjs/ui/screens/AppInfoScreen.js +664 -0
- package/lib/commonjs/ui/screens/AppInfoScreen.js.map +1 -0
- package/lib/commonjs/ui/screens/BillingManagementScreen.js +636 -0
- package/lib/commonjs/ui/screens/BillingManagementScreen.js.map +1 -0
- package/lib/commonjs/ui/screens/FeedbackScreen.js +1169 -0
- package/lib/commonjs/ui/screens/FeedbackScreen.js.map +1 -0
- package/lib/commonjs/ui/screens/FileManagementScreen.js +2515 -0
- package/lib/commonjs/ui/screens/FileManagementScreen.js.map +1 -0
- package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js +1620 -0
- package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js.map +1 -0
- package/lib/commonjs/ui/screens/ProfileScreen.js +450 -0
- package/lib/commonjs/ui/screens/ProfileScreen.js.map +1 -0
- package/lib/commonjs/ui/screens/SessionManagementScreen.js +449 -0
- package/lib/commonjs/ui/screens/SessionManagementScreen.js.map +1 -0
- package/lib/commonjs/ui/screens/SignInScreen.js +882 -0
- package/lib/commonjs/ui/screens/SignInScreen.js.map +1 -0
- package/lib/commonjs/ui/screens/SignUpScreen.js +1036 -0
- package/lib/commonjs/ui/screens/SignUpScreen.js.map +1 -0
- package/lib/commonjs/ui/screens/karma/KarmaAboutScreen.js +88 -0
- package/lib/commonjs/ui/screens/karma/KarmaAboutScreen.js.map +1 -0
- package/lib/commonjs/ui/screens/karma/KarmaCenterScreen.js +364 -0
- package/lib/commonjs/ui/screens/karma/KarmaCenterScreen.js.map +1 -0
- package/lib/commonjs/ui/screens/karma/KarmaFAQScreen.js +227 -0
- package/lib/commonjs/ui/screens/karma/KarmaFAQScreen.js.map +1 -0
- package/lib/commonjs/ui/screens/karma/KarmaLeaderboardScreen.js +148 -0
- package/lib/commonjs/ui/screens/karma/KarmaLeaderboardScreen.js.map +1 -0
- package/lib/commonjs/ui/screens/karma/KarmaRewardsScreen.js +127 -0
- package/lib/commonjs/ui/screens/karma/KarmaRewardsScreen.js.map +1 -0
- package/lib/commonjs/ui/screens/karma/KarmaRulesScreen.js +105 -0
- package/lib/commonjs/ui/screens/karma/KarmaRulesScreen.js.map +1 -0
- package/lib/commonjs/ui/store/index.js +52 -0
- package/lib/commonjs/ui/store/index.js.map +1 -0
- package/lib/commonjs/ui/styles/FONTS.md +126 -0
- package/lib/commonjs/ui/styles/fonts.js +84 -0
- package/lib/commonjs/ui/styles/fonts.js.map +1 -0
- package/lib/commonjs/ui/styles/index.js +28 -0
- package/lib/commonjs/ui/styles/index.js.map +1 -0
- package/lib/commonjs/ui/styles/theme.js +121 -0
- package/lib/commonjs/ui/styles/theme.js.map +1 -0
- package/lib/commonjs/utils/deviceManager.js +173 -0
- package/lib/commonjs/utils/deviceManager.js.map +1 -0
- package/lib/commonjs/utils/index.js +13 -0
- package/lib/commonjs/utils/index.js.map +1 -0
- package/lib/commonjs/utils/polyfills.js +42 -0
- package/lib/commonjs/utils/polyfills.js.map +1 -0
- package/lib/module/assets/OxyLogo.svg +1 -0
- package/lib/module/assets/assets/OxyLogo.svg +1 -0
- package/lib/module/assets/assets/fonts/Phudu/Phudu-Black.ttf +0 -0
- package/lib/module/assets/assets/fonts/Phudu/Phudu-Bold.ttf +0 -0
- package/lib/module/assets/assets/fonts/Phudu/Phudu-ExtraBold.ttf +0 -0
- package/lib/module/assets/assets/fonts/Phudu/Phudu-Light.ttf +0 -0
- package/lib/module/assets/assets/fonts/Phudu/Phudu-Medium.ttf +0 -0
- package/lib/module/assets/assets/fonts/Phudu/Phudu-Regular.ttf +0 -0
- package/lib/module/assets/assets/fonts/Phudu/Phudu-SemiBold.ttf +0 -0
- package/lib/module/assets/assets/icons/OxyServices.tsx +67 -0
- package/lib/module/assets/assets/icons/logo_OxyServices.svg +1 -0
- package/lib/module/assets/assets/illustrations/HighFive.tsx +41 -0
- package/lib/module/assets/fonts/Phudu/Phudu-Black.ttf +0 -0
- package/lib/module/assets/fonts/Phudu/Phudu-Bold.ttf +0 -0
- package/lib/module/assets/fonts/Phudu/Phudu-ExtraBold.ttf +0 -0
- package/lib/module/assets/fonts/Phudu/Phudu-Light.ttf +0 -0
- package/lib/module/assets/fonts/Phudu/Phudu-Medium.ttf +0 -0
- package/lib/module/assets/fonts/Phudu/Phudu-Regular.ttf +0 -0
- package/lib/module/assets/fonts/Phudu/Phudu-SemiBold.ttf +0 -0
- package/lib/module/assets/icons/OxyServices.js +46 -0
- package/lib/module/assets/icons/OxyServices.js.map +1 -0
- package/lib/module/assets/icons/logo_OxyServices.svg +1 -0
- package/lib/module/assets/illustrations/HighFive.js +55 -0
- package/lib/module/assets/illustrations/HighFive.js.map +1 -0
- package/lib/module/constants/version.js +21 -0
- package/lib/module/constants/version.js.map +1 -0
- package/lib/module/core/index.js +1634 -0
- package/lib/module/core/index.js.map +1 -0
- package/lib/module/index.js +48 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/lib/sonner.js +16 -0
- package/lib/module/lib/sonner.js.map +1 -0
- package/lib/module/models/interfaces.js +2 -0
- package/lib/module/models/interfaces.js.map +1 -0
- package/lib/module/models/secureSession.js +2 -0
- package/lib/module/models/secureSession.js.map +1 -0
- package/lib/module/node/createAuth.js +90 -0
- package/lib/module/node/createAuth.js.map +1 -0
- package/lib/module/node/index.js +27 -0
- package/lib/module/node/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/ui/components/Avatar.js +93 -0
- package/lib/module/ui/components/Avatar.js.map +1 -0
- package/lib/module/ui/components/FollowButton.js +241 -0
- package/lib/module/ui/components/FollowButton.js.map +1 -0
- package/lib/module/ui/components/FontLoader.js +176 -0
- package/lib/module/ui/components/FontLoader.js.map +1 -0
- package/lib/module/ui/components/GroupedItem.js +104 -0
- package/lib/module/ui/components/GroupedItem.js.map +1 -0
- package/lib/module/ui/components/GroupedSection.js +28 -0
- package/lib/module/ui/components/GroupedSection.js.map +1 -0
- package/lib/module/ui/components/OxyLogo.js +49 -0
- package/lib/module/ui/components/OxyLogo.js.map +1 -0
- package/lib/module/ui/components/OxyProvider.js +516 -0
- package/lib/module/ui/components/OxyProvider.js.map +1 -0
- package/lib/module/ui/components/OxySignInButton.js +172 -0
- package/lib/module/ui/components/OxySignInButton.js.map +1 -0
- package/lib/module/ui/components/ProfileCard.js +119 -0
- package/lib/module/ui/components/ProfileCard.js.map +1 -0
- package/lib/module/ui/components/QuickActions.js +82 -0
- package/lib/module/ui/components/QuickActions.js.map +1 -0
- package/lib/module/ui/components/Section.js +31 -0
- package/lib/module/ui/components/Section.js.map +1 -0
- package/lib/module/ui/components/SectionTitle.js +30 -0
- package/lib/module/ui/components/SectionTitle.js.map +1 -0
- package/lib/module/ui/components/bottomSheet/index.js +5 -0
- package/lib/module/ui/components/bottomSheet/index.js.map +1 -0
- package/lib/module/ui/components/icon/OxyIcon.js +22 -0
- package/lib/module/ui/components/icon/OxyIcon.js.map +1 -0
- package/lib/module/ui/components/icon/index.js +4 -0
- package/lib/module/ui/components/icon/index.js.map +1 -0
- package/lib/module/ui/components/index.js +18 -0
- package/lib/module/ui/components/index.js.map +1 -0
- package/lib/module/ui/components/internal/GroupedPillButtons.js +208 -0
- package/lib/module/ui/components/internal/GroupedPillButtons.js.map +1 -0
- package/lib/module/ui/components/internal/TextField.js +571 -0
- package/lib/module/ui/components/internal/TextField.js.map +1 -0
- package/lib/module/ui/context/OxyContext.js +579 -0
- package/lib/module/ui/context/OxyContext.js.map +1 -0
- package/lib/module/ui/index.js +26 -0
- package/lib/module/ui/index.js.map +1 -0
- package/lib/module/ui/navigation/OxyRouter.js +262 -0
- package/lib/module/ui/navigation/OxyRouter.js.map +1 -0
- package/lib/module/ui/navigation/types.js +4 -0
- package/lib/module/ui/navigation/types.js.map +1 -0
- package/lib/module/ui/screens/AccountCenterScreen.js +308 -0
- package/lib/module/ui/screens/AccountCenterScreen.js.map +1 -0
- package/lib/module/ui/screens/AccountManagementDemo.js +296 -0
- package/lib/module/ui/screens/AccountManagementDemo.js.map +1 -0
- package/lib/module/ui/screens/AccountOverviewScreen.js +849 -0
- package/lib/module/ui/screens/AccountOverviewScreen.js.map +1 -0
- package/lib/module/ui/screens/AccountSettingsScreen.js +837 -0
- package/lib/module/ui/screens/AccountSettingsScreen.js.map +1 -0
- package/lib/module/ui/screens/AccountSwitcherScreen.js +782 -0
- package/lib/module/ui/screens/AccountSwitcherScreen.js.map +1 -0
- package/lib/module/ui/screens/AppInfoScreen.js +658 -0
- package/lib/module/ui/screens/AppInfoScreen.js.map +1 -0
- package/lib/module/ui/screens/BillingManagementScreen.js +631 -0
- package/lib/module/ui/screens/BillingManagementScreen.js.map +1 -0
- package/lib/module/ui/screens/FeedbackScreen.js +1164 -0
- package/lib/module/ui/screens/FeedbackScreen.js.map +1 -0
- package/lib/module/ui/screens/FileManagementScreen.js +2510 -0
- package/lib/module/ui/screens/FileManagementScreen.js.map +1 -0
- package/lib/module/ui/screens/PremiumSubscriptionScreen.js +1615 -0
- package/lib/module/ui/screens/PremiumSubscriptionScreen.js.map +1 -0
- package/lib/module/ui/screens/ProfileScreen.js +444 -0
- package/lib/module/ui/screens/ProfileScreen.js.map +1 -0
- package/lib/module/ui/screens/SessionManagementScreen.js +444 -0
- package/lib/module/ui/screens/SessionManagementScreen.js.map +1 -0
- package/lib/module/ui/screens/SignInScreen.js +876 -0
- package/lib/module/ui/screens/SignInScreen.js.map +1 -0
- package/lib/module/ui/screens/SignUpScreen.js +1030 -0
- package/lib/module/ui/screens/SignUpScreen.js.map +1 -0
- package/lib/module/ui/screens/karma/KarmaAboutScreen.js +83 -0
- package/lib/module/ui/screens/karma/KarmaAboutScreen.js.map +1 -0
- package/lib/module/ui/screens/karma/KarmaCenterScreen.js +358 -0
- package/lib/module/ui/screens/karma/KarmaCenterScreen.js.map +1 -0
- package/lib/module/ui/screens/karma/KarmaFAQScreen.js +222 -0
- package/lib/module/ui/screens/karma/KarmaFAQScreen.js.map +1 -0
- package/lib/module/ui/screens/karma/KarmaLeaderboardScreen.js +142 -0
- package/lib/module/ui/screens/karma/KarmaLeaderboardScreen.js.map +1 -0
- package/lib/module/ui/screens/karma/KarmaRewardsScreen.js +122 -0
- package/lib/module/ui/screens/karma/KarmaRewardsScreen.js.map +1 -0
- package/lib/module/ui/screens/karma/KarmaRulesScreen.js +100 -0
- package/lib/module/ui/screens/karma/KarmaRulesScreen.js.map +1 -0
- package/lib/module/ui/store/index.js +44 -0
- package/lib/module/ui/store/index.js.map +1 -0
- package/lib/module/ui/styles/FONTS.md +126 -0
- package/lib/module/ui/styles/fonts.js +81 -0
- package/lib/module/ui/styles/fonts.js.map +1 -0
- package/lib/module/ui/styles/index.js +5 -0
- package/lib/module/ui/styles/index.js.map +1 -0
- package/lib/module/ui/styles/theme.js +114 -0
- package/lib/module/ui/styles/theme.js.map +1 -0
- package/lib/module/utils/deviceManager.js +167 -0
- package/lib/module/utils/deviceManager.js.map +1 -0
- package/lib/module/utils/index.js +4 -0
- package/lib/module/utils/index.js.map +1 -0
- package/lib/module/utils/polyfills.js +36 -0
- package/lib/module/utils/polyfills.js.map +1 -0
- package/lib/typescript/assets/icons/OxyServices.d.ts +29 -0
- package/lib/typescript/assets/icons/OxyServices.d.ts.map +1 -0
- package/lib/typescript/assets/illustrations/HighFive.d.ts +9 -0
- package/lib/typescript/assets/illustrations/HighFive.d.ts.map +1 -0
- package/lib/typescript/constants/version.d.ts +14 -0
- package/lib/typescript/constants/version.d.ts.map +1 -0
- package/lib/typescript/core/index.d.ts +603 -0
- package/lib/typescript/core/index.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +20 -0
- package/lib/typescript/index.d.ts.map +1 -0
- package/lib/typescript/lib/sonner.d.ts +6 -0
- package/lib/typescript/lib/sonner.d.ts.map +1 -0
- package/lib/typescript/models/interfaces.d.ts +179 -0
- package/lib/typescript/models/interfaces.d.ts.map +1 -0
- package/lib/typescript/models/secureSession.d.ts +27 -0
- package/lib/typescript/models/secureSession.d.ts.map +1 -0
- package/lib/typescript/node/createAuth.d.ts +7 -0
- package/lib/typescript/node/createAuth.d.ts.map +1 -0
- package/lib/typescript/node/index.d.ts +13 -0
- package/lib/typescript/node/index.d.ts.map +1 -0
- package/lib/typescript/types/expo-vector-icons.d.ts +3 -0
- package/lib/typescript/types/express.d.ts +5 -0
- package/lib/typescript/types/react-redux.d.ts +5 -0
- package/lib/typescript/ui/components/Avatar.d.ts +62 -0
- package/lib/typescript/ui/components/Avatar.d.ts.map +1 -0
- package/lib/typescript/ui/components/FollowButton.d.ts +92 -0
- package/lib/typescript/ui/components/FollowButton.d.ts.map +1 -0
- package/lib/typescript/ui/components/FontLoader.d.ts +15 -0
- package/lib/typescript/ui/components/FontLoader.d.ts.map +1 -0
- package/lib/typescript/ui/components/GroupedItem.d.ts +17 -0
- package/lib/typescript/ui/components/GroupedItem.d.ts.map +1 -0
- package/lib/typescript/ui/components/GroupedSection.d.ts +19 -0
- package/lib/typescript/ui/components/GroupedSection.d.ts.map +1 -0
- package/lib/typescript/ui/components/OxyLogo.d.ts +29 -0
- package/lib/typescript/ui/components/OxyLogo.d.ts.map +1 -0
- package/lib/typescript/ui/components/OxyProvider.d.ts +12 -0
- package/lib/typescript/ui/components/OxyProvider.d.ts.map +1 -0
- package/lib/typescript/ui/components/OxySignInButton.d.ts +70 -0
- package/lib/typescript/ui/components/OxySignInButton.d.ts.map +1 -0
- package/lib/typescript/ui/components/ProfileCard.d.ts +20 -0
- package/lib/typescript/ui/components/ProfileCard.d.ts.map +1 -0
- package/lib/typescript/ui/components/QuickActions.d.ts +15 -0
- package/lib/typescript/ui/components/QuickActions.d.ts.map +1 -0
- package/lib/typescript/ui/components/Section.d.ts +11 -0
- package/lib/typescript/ui/components/Section.d.ts.map +1 -0
- package/lib/typescript/ui/components/SectionTitle.d.ts +9 -0
- package/lib/typescript/ui/components/SectionTitle.d.ts.map +1 -0
- package/lib/typescript/ui/components/bottomSheet/index.d.ts +4 -0
- package/lib/typescript/ui/components/bottomSheet/index.d.ts.map +1 -0
- package/lib/typescript/ui/components/icon/OxyIcon.d.ts +10 -0
- package/lib/typescript/ui/components/icon/OxyIcon.d.ts.map +1 -0
- package/lib/typescript/ui/components/icon/index.d.ts +3 -0
- package/lib/typescript/ui/components/icon/index.d.ts.map +1 -0
- package/lib/typescript/ui/components/index.d.ts +13 -0
- package/lib/typescript/ui/components/index.d.ts.map +1 -0
- package/lib/typescript/ui/components/internal/GroupedPillButtons.d.ts +18 -0
- package/lib/typescript/ui/components/internal/GroupedPillButtons.d.ts.map +1 -0
- package/lib/typescript/ui/components/internal/TextField.d.ts +25 -0
- package/lib/typescript/ui/components/internal/TextField.d.ts.map +1 -0
- package/lib/typescript/ui/context/OxyContext.d.ts +42 -0
- package/lib/typescript/ui/context/OxyContext.d.ts.map +1 -0
- package/lib/typescript/ui/index.d.ts +17 -0
- package/lib/typescript/ui/index.d.ts.map +1 -0
- package/lib/typescript/ui/navigation/OxyRouter.d.ts +5 -0
- package/lib/typescript/ui/navigation/OxyRouter.d.ts.map +1 -0
- package/lib/typescript/ui/navigation/types.d.ts +116 -0
- package/lib/typescript/ui/navigation/types.d.ts.map +1 -0
- package/lib/typescript/ui/screens/AccountCenterScreen.d.ts +5 -0
- package/lib/typescript/ui/screens/AccountCenterScreen.d.ts.map +1 -0
- package/lib/typescript/ui/screens/AccountManagementDemo.d.ts +8 -0
- package/lib/typescript/ui/screens/AccountManagementDemo.d.ts.map +1 -0
- package/lib/typescript/ui/screens/AccountOverviewScreen.d.ts +5 -0
- package/lib/typescript/ui/screens/AccountOverviewScreen.d.ts.map +1 -0
- package/lib/typescript/ui/screens/AccountSettingsScreen.d.ts +5 -0
- package/lib/typescript/ui/screens/AccountSettingsScreen.d.ts.map +1 -0
- package/lib/typescript/ui/screens/AccountSwitcherScreen.d.ts +5 -0
- package/lib/typescript/ui/screens/AccountSwitcherScreen.d.ts.map +1 -0
- package/lib/typescript/ui/screens/AppInfoScreen.d.ts +5 -0
- package/lib/typescript/ui/screens/AppInfoScreen.d.ts.map +1 -0
- package/lib/typescript/ui/screens/BillingManagementScreen.d.ts +5 -0
- package/lib/typescript/ui/screens/BillingManagementScreen.d.ts.map +1 -0
- package/lib/typescript/ui/screens/FeedbackScreen.d.ts +5 -0
- package/lib/typescript/ui/screens/FeedbackScreen.d.ts.map +1 -0
- package/lib/typescript/ui/screens/FileManagementScreen.d.ts +8 -0
- package/lib/typescript/ui/screens/FileManagementScreen.d.ts.map +1 -0
- package/lib/typescript/ui/screens/PremiumSubscriptionScreen.d.ts +5 -0
- package/lib/typescript/ui/screens/PremiumSubscriptionScreen.d.ts.map +1 -0
- package/lib/typescript/ui/screens/ProfileScreen.d.ts +9 -0
- package/lib/typescript/ui/screens/ProfileScreen.d.ts.map +1 -0
- package/lib/typescript/ui/screens/SessionManagementScreen.d.ts +5 -0
- package/lib/typescript/ui/screens/SessionManagementScreen.d.ts.map +1 -0
- package/lib/typescript/ui/screens/SignInScreen.d.ts +5 -0
- package/lib/typescript/ui/screens/SignInScreen.d.ts.map +1 -0
- package/lib/typescript/ui/screens/SignUpScreen.d.ts +5 -0
- package/lib/typescript/ui/screens/SignUpScreen.d.ts.map +1 -0
- package/lib/typescript/ui/screens/karma/KarmaAboutScreen.d.ts +5 -0
- package/lib/typescript/ui/screens/karma/KarmaAboutScreen.d.ts.map +1 -0
- package/lib/typescript/ui/screens/karma/KarmaCenterScreen.d.ts +5 -0
- package/lib/typescript/ui/screens/karma/KarmaCenterScreen.d.ts.map +1 -0
- package/lib/typescript/ui/screens/karma/KarmaFAQScreen.d.ts +5 -0
- package/lib/typescript/ui/screens/karma/KarmaFAQScreen.d.ts.map +1 -0
- package/lib/typescript/ui/screens/karma/KarmaLeaderboardScreen.d.ts +5 -0
- package/lib/typescript/ui/screens/karma/KarmaLeaderboardScreen.d.ts.map +1 -0
- package/lib/typescript/ui/screens/karma/KarmaRewardsScreen.d.ts +5 -0
- package/lib/typescript/ui/screens/karma/KarmaRewardsScreen.d.ts.map +1 -0
- package/lib/typescript/ui/screens/karma/KarmaRulesScreen.d.ts +5 -0
- package/lib/typescript/ui/screens/karma/KarmaRulesScreen.d.ts.map +1 -0
- package/lib/typescript/ui/store/index.d.ts +19 -0
- package/lib/typescript/ui/store/index.d.ts.map +1 -0
- package/lib/typescript/ui/styles/fonts.d.ts +21 -0
- package/lib/typescript/ui/styles/fonts.d.ts.map +1 -0
- package/lib/typescript/ui/styles/index.d.ts +3 -0
- package/lib/typescript/ui/styles/index.d.ts.map +1 -0
- package/lib/typescript/ui/styles/theme.d.ts +68 -0
- package/lib/typescript/ui/styles/theme.d.ts.map +1 -0
- package/lib/typescript/utils/deviceManager.d.ts +66 -0
- package/lib/typescript/utils/deviceManager.d.ts.map +1 -0
- package/lib/typescript/utils/index.d.ts +3 -0
- package/lib/typescript/utils/index.d.ts.map +1 -0
- package/lib/typescript/utils/polyfills.d.ts +6 -0
- package/lib/typescript/utils/polyfills.d.ts.map +1 -0
- package/package.json +7 -6
- package/src/assets/illustrations/HighFive.tsx +41 -0
- package/src/node/createAuth.ts +116 -0
- package/src/node/index.ts +4 -0
- package/src/types/expo-vector-icons.d.ts +3 -0
- package/src/types/express.d.ts +5 -0
- package/src/types/react-redux.d.ts +5 -0
- package/src/ui/components/OxyProvider.tsx +136 -135
- package/src/ui/components/internal/GroupedPillButtons.tsx +253 -0
- package/src/ui/components/internal/TextField.tsx +694 -0
- package/src/ui/index.ts +6 -2
- package/src/ui/navigation/OxyRouter.tsx +8 -3
- package/src/ui/screens/FeedbackScreen.tsx +1042 -0
- package/src/ui/screens/SignInScreen.tsx +179 -222
- package/src/ui/screens/SignUpScreen.tsx +772 -608
- package/src/ui/store/index.ts +51 -0
|
@@ -0,0 +1,1660 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
Object.defineProperty(exports, "DeviceFingerprint", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function () {
|
|
9
|
+
return _deviceManager.DeviceFingerprint;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
Object.defineProperty(exports, "DeviceManager", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () {
|
|
15
|
+
return _deviceManager.DeviceManager;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
exports.OxyServices = exports.OXY_CLOUD_URL = void 0;
|
|
19
|
+
Object.defineProperty(exports, "StoredDeviceInfo", {
|
|
20
|
+
enumerable: true,
|
|
21
|
+
get: function () {
|
|
22
|
+
return _deviceManager.StoredDeviceInfo;
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
exports.default = void 0;
|
|
26
|
+
var _axios = _interopRequireDefault(require("axios"));
|
|
27
|
+
var _jwtDecode = require("jwt-decode");
|
|
28
|
+
var _polyfills = require("../utils/polyfills");
|
|
29
|
+
var _deviceManager = require("../utils/deviceManager");
|
|
30
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
31
|
+
let NodeFormData = null;
|
|
32
|
+
|
|
33
|
+
// Check if we're in Node.js environment
|
|
34
|
+
if (typeof window === 'undefined') {
|
|
35
|
+
try {
|
|
36
|
+
NodeFormData = require('form-data');
|
|
37
|
+
} catch (e) {
|
|
38
|
+
console.warn('form-data module not found, file uploads from Buffer may fail in Node.js');
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Import secure session types
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Default cloud URL for Oxy services, cloud is where the user files are. (e.g. images, videos, etc.). Not the API.
|
|
46
|
+
*/
|
|
47
|
+
const OXY_CLOUD_URL = exports.OXY_CLOUD_URL = 'https://cloud.oxy.so';
|
|
48
|
+
|
|
49
|
+
// Export device management utilities
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* OxyServices - Client library for interacting with the Oxy API
|
|
53
|
+
*/
|
|
54
|
+
class OxyServices {
|
|
55
|
+
accessToken = null;
|
|
56
|
+
refreshToken = null;
|
|
57
|
+
refreshPromise = null;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Creates a new instance of the OxyServices client
|
|
61
|
+
* @param config - Configuration for the client
|
|
62
|
+
*/
|
|
63
|
+
constructor(config) {
|
|
64
|
+
this.client = _axios.default.create({
|
|
65
|
+
baseURL: config.baseURL,
|
|
66
|
+
timeout: 10000 // 10 second timeout
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
// Interceptor for adding auth header and handling token refresh
|
|
70
|
+
this.client.interceptors.request.use(async req => {
|
|
71
|
+
if (!this.accessToken) {
|
|
72
|
+
return req;
|
|
73
|
+
} // Check if token is expired and refresh if needed
|
|
74
|
+
try {
|
|
75
|
+
const decoded = (0, _jwtDecode.jwtDecode)(this.accessToken);
|
|
76
|
+
const currentTime = Math.floor(Date.now() / 1000);
|
|
77
|
+
|
|
78
|
+
// If token expires in less than 60 seconds, refresh it
|
|
79
|
+
if (decoded.exp - currentTime < 60) {
|
|
80
|
+
await this.refreshTokens();
|
|
81
|
+
}
|
|
82
|
+
} catch (error) {
|
|
83
|
+
// If token can't be decoded, continue with request and let server handle it
|
|
84
|
+
console.warn('Error decoding JWT token', error);
|
|
85
|
+
}
|
|
86
|
+
req.headers = req.headers || {};
|
|
87
|
+
req.headers.Authorization = `Bearer ${this.accessToken}`;
|
|
88
|
+
return req;
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
// Response interceptor for handling errors
|
|
92
|
+
this.client.interceptors.response.use(response => response, async error => {
|
|
93
|
+
const originalRequest = error.config;
|
|
94
|
+
// If the error is due to an expired token and we haven't tried refreshing yet
|
|
95
|
+
if (error.response?.status === 401 && this.refreshToken && originalRequest && !originalRequest.headers?.['X-Retry-After-Refresh']) {
|
|
96
|
+
try {
|
|
97
|
+
await this.refreshTokens();
|
|
98
|
+
// Retry the original request with new token
|
|
99
|
+
const newRequest = {
|
|
100
|
+
...originalRequest
|
|
101
|
+
};
|
|
102
|
+
if (newRequest.headers) {
|
|
103
|
+
newRequest.headers.Authorization = `Bearer ${this.accessToken}`;
|
|
104
|
+
newRequest.headers['X-Retry-After-Refresh'] = 'true';
|
|
105
|
+
}
|
|
106
|
+
return this.client(newRequest);
|
|
107
|
+
} catch (refreshError) {
|
|
108
|
+
// If refresh fails, force user to login again
|
|
109
|
+
this.clearTokens();
|
|
110
|
+
return Promise.reject(refreshError);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Format error response
|
|
115
|
+
const apiError = {
|
|
116
|
+
message: error.response?.data?.error || error.response?.data?.message || 'An unknown error occurred',
|
|
117
|
+
code: error.response?.data?.code || 'UNKNOWN_ERROR',
|
|
118
|
+
status: error.response?.status || 500,
|
|
119
|
+
details: error.response?.data
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
// If the error is an invalid session, clear tokens
|
|
123
|
+
if (apiError.code === 'INVALID_SESSION' || apiError.message === 'Invalid session') {
|
|
124
|
+
this.clearTokens();
|
|
125
|
+
}
|
|
126
|
+
return Promise.reject(apiError);
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Gets the base URL configured for this OxyServices instance
|
|
132
|
+
* @returns The base URL
|
|
133
|
+
*/
|
|
134
|
+
getBaseURL() {
|
|
135
|
+
return this.client.defaults.baseURL || '';
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Gets the currently authenticated user ID from the token
|
|
140
|
+
* @returns The user ID or null if not authenticated
|
|
141
|
+
*/
|
|
142
|
+
getCurrentUserId() {
|
|
143
|
+
if (!this.accessToken) return null;
|
|
144
|
+
try {
|
|
145
|
+
const decoded = (0, _jwtDecode.jwtDecode)(this.accessToken);
|
|
146
|
+
|
|
147
|
+
// Check for both userId (preferred) and id (fallback) for compatibility
|
|
148
|
+
return decoded.userId || decoded.id || null;
|
|
149
|
+
} catch (error) {
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Checks if the user is currently authenticated
|
|
156
|
+
* @returns Boolean indicating authentication status
|
|
157
|
+
*/
|
|
158
|
+
isAuthenticated() {
|
|
159
|
+
return this.accessToken !== null;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Sets authentication tokens directly (useful for initializing from storage)
|
|
164
|
+
* @param accessToken - JWT access token
|
|
165
|
+
* @param refreshToken - Refresh token for getting new access tokens
|
|
166
|
+
*/
|
|
167
|
+
setTokens(accessToken, refreshToken) {
|
|
168
|
+
this.accessToken = accessToken;
|
|
169
|
+
this.refreshToken = refreshToken;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Clears all authentication tokens
|
|
174
|
+
*/
|
|
175
|
+
clearTokens() {
|
|
176
|
+
this.accessToken = null;
|
|
177
|
+
this.refreshToken = null;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Sign up a new user
|
|
182
|
+
* @param username - Desired username
|
|
183
|
+
* @param email - User's email address
|
|
184
|
+
* @param password - User's password
|
|
185
|
+
* @returns Object containing the message, token and user data
|
|
186
|
+
*/
|
|
187
|
+
async signUp(username, email, password) {
|
|
188
|
+
try {
|
|
189
|
+
const res = await this.client.post('/auth/signup', {
|
|
190
|
+
username,
|
|
191
|
+
email,
|
|
192
|
+
password
|
|
193
|
+
});
|
|
194
|
+
const {
|
|
195
|
+
message,
|
|
196
|
+
token,
|
|
197
|
+
user
|
|
198
|
+
} = res.data;
|
|
199
|
+
this.accessToken = token;
|
|
200
|
+
return {
|
|
201
|
+
message,
|
|
202
|
+
token,
|
|
203
|
+
user
|
|
204
|
+
};
|
|
205
|
+
} catch (error) {
|
|
206
|
+
throw this.handleError(error);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Log in and store tokens
|
|
212
|
+
* @param username - User's username or email
|
|
213
|
+
* @param password - User's password
|
|
214
|
+
* @returns Login response containing tokens and user data
|
|
215
|
+
*/
|
|
216
|
+
async login(username, password) {
|
|
217
|
+
try {
|
|
218
|
+
const res = await this.client.post('/auth/login', {
|
|
219
|
+
username,
|
|
220
|
+
password
|
|
221
|
+
});
|
|
222
|
+
const {
|
|
223
|
+
accessToken,
|
|
224
|
+
refreshToken,
|
|
225
|
+
user
|
|
226
|
+
} = res.data;
|
|
227
|
+
this.accessToken = accessToken;
|
|
228
|
+
this.refreshToken = refreshToken;
|
|
229
|
+
return {
|
|
230
|
+
accessToken,
|
|
231
|
+
refreshToken,
|
|
232
|
+
user
|
|
233
|
+
};
|
|
234
|
+
} catch (error) {
|
|
235
|
+
throw this.handleError(error);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Log out user
|
|
241
|
+
*/
|
|
242
|
+
async logout() {
|
|
243
|
+
if (!this.refreshToken) return;
|
|
244
|
+
try {
|
|
245
|
+
await this.client.post('/auth/logout', {
|
|
246
|
+
refreshToken: this.refreshToken
|
|
247
|
+
});
|
|
248
|
+
} catch (error) {
|
|
249
|
+
console.warn('Error during logout', error);
|
|
250
|
+
} finally {
|
|
251
|
+
this.accessToken = null;
|
|
252
|
+
this.refreshToken = null;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Refresh access and refresh tokens
|
|
258
|
+
* @returns New tokens
|
|
259
|
+
*/
|
|
260
|
+
async refreshTokens() {
|
|
261
|
+
if (!this.refreshToken) {
|
|
262
|
+
throw new Error('No refresh token available');
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// If a refresh is already in progress, return that promise
|
|
266
|
+
if (this.refreshPromise) {
|
|
267
|
+
return this.refreshPromise;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// Create a new refresh promise
|
|
271
|
+
this.refreshPromise = (async () => {
|
|
272
|
+
try {
|
|
273
|
+
const res = await this.client.post('/auth/refresh', {
|
|
274
|
+
refreshToken: this.refreshToken
|
|
275
|
+
});
|
|
276
|
+
const {
|
|
277
|
+
accessToken,
|
|
278
|
+
refreshToken
|
|
279
|
+
} = res.data;
|
|
280
|
+
this.accessToken = accessToken;
|
|
281
|
+
this.refreshToken = refreshToken;
|
|
282
|
+
return {
|
|
283
|
+
accessToken,
|
|
284
|
+
refreshToken
|
|
285
|
+
};
|
|
286
|
+
} catch (error) {
|
|
287
|
+
this.accessToken = null;
|
|
288
|
+
this.refreshToken = null;
|
|
289
|
+
throw this.handleError(error);
|
|
290
|
+
} finally {
|
|
291
|
+
this.refreshPromise = null;
|
|
292
|
+
}
|
|
293
|
+
})();
|
|
294
|
+
return this.refreshPromise;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Validate current access token
|
|
299
|
+
* @returns Boolean indicating if the token is valid
|
|
300
|
+
*/
|
|
301
|
+
async validate() {
|
|
302
|
+
try {
|
|
303
|
+
const res = await this.client.get('/auth/validate');
|
|
304
|
+
return res.data.valid;
|
|
305
|
+
} catch (error) {
|
|
306
|
+
return false;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/* Session Management Methods */
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Get active sessions for the authenticated user
|
|
314
|
+
* @returns Array of active session objects
|
|
315
|
+
*/
|
|
316
|
+
async getUserSessions() {
|
|
317
|
+
try {
|
|
318
|
+
const res = await this.client.get('/sessions');
|
|
319
|
+
return res.data;
|
|
320
|
+
} catch (error) {
|
|
321
|
+
throw this.handleError(error);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* Logout from a specific session
|
|
327
|
+
* @param sessionId - The session ID to logout from
|
|
328
|
+
* @returns Success status
|
|
329
|
+
*/
|
|
330
|
+
async logoutSession(sessionId) {
|
|
331
|
+
try {
|
|
332
|
+
const res = await this.client.delete(`/sessions/${sessionId}`);
|
|
333
|
+
return res.data;
|
|
334
|
+
} catch (error) {
|
|
335
|
+
throw this.handleError(error);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* Logout from all other sessions (keep current session active)
|
|
341
|
+
* @returns Success status
|
|
342
|
+
*/
|
|
343
|
+
async logoutOtherSessions() {
|
|
344
|
+
try {
|
|
345
|
+
const res = await this.client.post('/sessions/logout-others');
|
|
346
|
+
return res.data;
|
|
347
|
+
} catch (error) {
|
|
348
|
+
throw this.handleError(error);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* Logout from all sessions
|
|
354
|
+
* @returns Success status
|
|
355
|
+
*/
|
|
356
|
+
async logoutAllSessions() {
|
|
357
|
+
try {
|
|
358
|
+
const res = await this.client.post('/sessions/logout-all');
|
|
359
|
+
return res.data;
|
|
360
|
+
} catch (error) {
|
|
361
|
+
throw this.handleError(error);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* Get device sessions for a specific session ID
|
|
367
|
+
* @param sessionId - The session ID to get device sessions for
|
|
368
|
+
* @param deviceId - Optional device ID filter
|
|
369
|
+
* @returns Array of device sessions
|
|
370
|
+
*/
|
|
371
|
+
async getDeviceSessions(sessionId, deviceId) {
|
|
372
|
+
try {
|
|
373
|
+
const params = deviceId ? {
|
|
374
|
+
deviceId
|
|
375
|
+
} : {};
|
|
376
|
+
const res = await this.client.get(`/secure-session/device/sessions/${sessionId}`, {
|
|
377
|
+
params
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
// Map backend response to frontend interface
|
|
381
|
+
return (res.data.sessions || []).map(session => ({
|
|
382
|
+
sessionId: session.sessionId,
|
|
383
|
+
deviceId: res.data.deviceId || '',
|
|
384
|
+
deviceName: session.deviceInfo?.deviceName || 'Unknown Device',
|
|
385
|
+
isActive: true,
|
|
386
|
+
// All returned sessions are active
|
|
387
|
+
lastActive: session.lastActive,
|
|
388
|
+
expiresAt: session.expiresAt || new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString(),
|
|
389
|
+
isCurrent: session.sessionId === sessionId,
|
|
390
|
+
user: session.user,
|
|
391
|
+
createdAt: session.createdAt
|
|
392
|
+
}));
|
|
393
|
+
} catch (error) {
|
|
394
|
+
throw this.handleError(error);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
/**
|
|
399
|
+
* Logout all device sessions for a specific device
|
|
400
|
+
* @param sessionId - The session ID
|
|
401
|
+
* @param deviceId - Optional device ID (uses current session's device if not provided)
|
|
402
|
+
* @param excludeCurrent - Whether to exclude the current session from logout
|
|
403
|
+
* @returns Logout response
|
|
404
|
+
*/
|
|
405
|
+
async logoutAllDeviceSessions(sessionId, deviceId, excludeCurrent) {
|
|
406
|
+
try {
|
|
407
|
+
const data = {};
|
|
408
|
+
if (deviceId) data.deviceId = deviceId;
|
|
409
|
+
if (excludeCurrent !== undefined) data.excludeCurrent = excludeCurrent;
|
|
410
|
+
const res = await this.client.post(`/secure-session/device/logout-all/${sessionId}`, data);
|
|
411
|
+
return res.data;
|
|
412
|
+
} catch (error) {
|
|
413
|
+
throw this.handleError(error);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
/**
|
|
418
|
+
* Update device name for a session
|
|
419
|
+
* @param sessionId - The session ID
|
|
420
|
+
* @param deviceName - The new device name
|
|
421
|
+
* @returns Update response
|
|
422
|
+
*/
|
|
423
|
+
async updateDeviceName(sessionId, deviceName) {
|
|
424
|
+
try {
|
|
425
|
+
const res = await this.client.put(`/secure-session/device/name/${sessionId}`, {
|
|
426
|
+
deviceName
|
|
427
|
+
});
|
|
428
|
+
return res.data;
|
|
429
|
+
} catch (error) {
|
|
430
|
+
throw this.handleError(error);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
/* Profile Methods */
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* Fetch profile by username
|
|
438
|
+
* @param username - The username to look up
|
|
439
|
+
* @returns User profile data
|
|
440
|
+
*/
|
|
441
|
+
async getProfileByUsername(username) {
|
|
442
|
+
try {
|
|
443
|
+
const res = await this.client.get(`/profiles/username/${username}`);
|
|
444
|
+
return res.data;
|
|
445
|
+
} catch (error) {
|
|
446
|
+
throw this.handleError(error);
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
/**
|
|
451
|
+
* Search profiles
|
|
452
|
+
* @param query - Search query string
|
|
453
|
+
* @param limit - Maximum number of results to return
|
|
454
|
+
* @param offset - Number of results to skip for pagination
|
|
455
|
+
* @returns Array of matching user profiles
|
|
456
|
+
*/
|
|
457
|
+
async searchProfiles(query, limit, offset) {
|
|
458
|
+
try {
|
|
459
|
+
const params = {
|
|
460
|
+
query
|
|
461
|
+
};
|
|
462
|
+
if (limit !== undefined) params.limit = limit;
|
|
463
|
+
if (offset !== undefined) params.offset = offset;
|
|
464
|
+
const res = await this.client.get('/profiles/search', {
|
|
465
|
+
params
|
|
466
|
+
});
|
|
467
|
+
return res.data;
|
|
468
|
+
} catch (error) {
|
|
469
|
+
throw this.handleError(error);
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
/**
|
|
474
|
+
* Get recommended profiles for the authenticated user
|
|
475
|
+
* @returns Array of recommended profiles
|
|
476
|
+
*/
|
|
477
|
+
async getProfileRecommendations() {
|
|
478
|
+
try {
|
|
479
|
+
const res = await this.client.get('/profiles/recommendations');
|
|
480
|
+
return res.data;
|
|
481
|
+
} catch (error) {
|
|
482
|
+
throw this.handleError(error);
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
/* User Methods */
|
|
487
|
+
|
|
488
|
+
/**
|
|
489
|
+
* Get general user by ID
|
|
490
|
+
* @param userId - The user ID to look up
|
|
491
|
+
* @returns User data
|
|
492
|
+
*/
|
|
493
|
+
async getUserById(userId) {
|
|
494
|
+
try {
|
|
495
|
+
const res = await this.client.get(`/users/${userId}`);
|
|
496
|
+
return res.data;
|
|
497
|
+
} catch (error) {
|
|
498
|
+
throw this.handleError(error);
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
/**
|
|
503
|
+
* Get the currently authenticated user's profile
|
|
504
|
+
* @returns User data for the current user
|
|
505
|
+
*/
|
|
506
|
+
async getCurrentUser() {
|
|
507
|
+
try {
|
|
508
|
+
const res = await this.client.get('/users/me');
|
|
509
|
+
return res.data;
|
|
510
|
+
} catch (error) {
|
|
511
|
+
throw this.handleError(error);
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
/**
|
|
516
|
+
* Update the authenticated user's profile
|
|
517
|
+
* @param updates - Object containing fields to update
|
|
518
|
+
* @returns Updated user data
|
|
519
|
+
*/
|
|
520
|
+
async updateProfile(updates) {
|
|
521
|
+
try {
|
|
522
|
+
const res = await this.client.put('/users/me', updates);
|
|
523
|
+
return res.data;
|
|
524
|
+
} catch (error) {
|
|
525
|
+
throw this.handleError(error);
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
/**
|
|
530
|
+
* Update user profile (requires auth)
|
|
531
|
+
* @param userId - User ID to update (must match authenticated user or have admin rights)
|
|
532
|
+
* @param updates - Object containing fields to update
|
|
533
|
+
* @returns Updated user data
|
|
534
|
+
*/
|
|
535
|
+
async updateUser(userId, updates) {
|
|
536
|
+
try {
|
|
537
|
+
const res = await this.client.put(`/users/${userId}`, updates);
|
|
538
|
+
return res.data;
|
|
539
|
+
} catch (error) {
|
|
540
|
+
throw this.handleError(error);
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
/**
|
|
545
|
+
* Follow a user
|
|
546
|
+
* @param userId - User ID to follow
|
|
547
|
+
* @returns Status of the follow operation
|
|
548
|
+
*/
|
|
549
|
+
async followUser(userId) {
|
|
550
|
+
try {
|
|
551
|
+
const res = await this.client.post(`/users/${userId}/follow`);
|
|
552
|
+
return res.data;
|
|
553
|
+
} catch (error) {
|
|
554
|
+
throw this.handleError(error);
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
/**
|
|
559
|
+
* Unfollow a user
|
|
560
|
+
* @param userId - User ID to unfollow
|
|
561
|
+
* @returns Status of the unfollow operation
|
|
562
|
+
*/
|
|
563
|
+
async unfollowUser(userId) {
|
|
564
|
+
try {
|
|
565
|
+
const res = await this.client.delete(`/users/${userId}/follow`);
|
|
566
|
+
return res.data;
|
|
567
|
+
} catch (error) {
|
|
568
|
+
throw this.handleError(error);
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
/**
|
|
573
|
+
* Get all followers of a user
|
|
574
|
+
* @param userId - User ID to get followers for
|
|
575
|
+
* @param limit - Maximum number of followers to return
|
|
576
|
+
* @param offset - Number of followers to skip for pagination
|
|
577
|
+
* @returns Array of users who follow the specified user and pagination info
|
|
578
|
+
*/
|
|
579
|
+
async getUserFollowers(userId, limit, offset) {
|
|
580
|
+
try {
|
|
581
|
+
const params = {};
|
|
582
|
+
if (limit !== undefined) params.limit = limit;
|
|
583
|
+
if (offset !== undefined) params.offset = offset;
|
|
584
|
+
const res = await this.client.get(`/users/${userId}/followers`, {
|
|
585
|
+
params
|
|
586
|
+
});
|
|
587
|
+
return res.data;
|
|
588
|
+
} catch (error) {
|
|
589
|
+
throw this.handleError(error);
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
/**
|
|
594
|
+
* Get all users that a user is following
|
|
595
|
+
* @param userId - User ID to get following list for
|
|
596
|
+
* @param limit - Maximum number of users to return
|
|
597
|
+
* @param offset - Number of users to skip for pagination
|
|
598
|
+
* @returns Array of users the specified user follows and pagination info
|
|
599
|
+
*/
|
|
600
|
+
async getUserFollowing(userId, limit, offset) {
|
|
601
|
+
try {
|
|
602
|
+
const params = {};
|
|
603
|
+
if (limit !== undefined) params.limit = limit;
|
|
604
|
+
if (offset !== undefined) params.offset = offset;
|
|
605
|
+
const res = await this.client.get(`/users/${userId}/following`, {
|
|
606
|
+
params
|
|
607
|
+
});
|
|
608
|
+
return res.data;
|
|
609
|
+
} catch (error) {
|
|
610
|
+
throw this.handleError(error);
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
/* Notification Methods */
|
|
615
|
+
|
|
616
|
+
/**
|
|
617
|
+
* Fetch all notifications for the authenticated user
|
|
618
|
+
* @returns Array of notifications
|
|
619
|
+
*/
|
|
620
|
+
async getNotifications() {
|
|
621
|
+
try {
|
|
622
|
+
const res = await this.client.get('/notifications');
|
|
623
|
+
return res.data;
|
|
624
|
+
} catch (error) {
|
|
625
|
+
throw this.handleError(error);
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
/**
|
|
630
|
+
* Get count of unread notifications
|
|
631
|
+
* @returns Number of unread notifications
|
|
632
|
+
*/
|
|
633
|
+
async getUnreadCount() {
|
|
634
|
+
try {
|
|
635
|
+
const res = await this.client.get('/notifications/unread-count');
|
|
636
|
+
return res.data;
|
|
637
|
+
} catch (error) {
|
|
638
|
+
throw this.handleError(error);
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
/**
|
|
643
|
+
* Create a new notification (admin use)
|
|
644
|
+
* @param data - Notification data
|
|
645
|
+
* @returns Created notification
|
|
646
|
+
*/
|
|
647
|
+
async createNotification(data) {
|
|
648
|
+
try {
|
|
649
|
+
const res = await this.client.post('/notifications', data);
|
|
650
|
+
return res.data;
|
|
651
|
+
} catch (error) {
|
|
652
|
+
throw this.handleError(error);
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
/**
|
|
657
|
+
* Mark a single notification as read
|
|
658
|
+
* @param notificationId - ID of notification to mark as read
|
|
659
|
+
*/
|
|
660
|
+
async markNotificationAsRead(notificationId) {
|
|
661
|
+
try {
|
|
662
|
+
await this.client.put(`/notifications/${notificationId}/read`);
|
|
663
|
+
} catch (error) {
|
|
664
|
+
throw this.handleError(error);
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
/**
|
|
669
|
+
* Mark all notifications as read
|
|
670
|
+
*/
|
|
671
|
+
async markAllNotificationsAsRead() {
|
|
672
|
+
try {
|
|
673
|
+
await this.client.put('/notifications/read-all');
|
|
674
|
+
} catch (error) {
|
|
675
|
+
throw this.handleError(error);
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
/**
|
|
680
|
+
* Delete a notification
|
|
681
|
+
* @param notificationId - ID of notification to delete
|
|
682
|
+
*/
|
|
683
|
+
async deleteNotification(notificationId) {
|
|
684
|
+
try {
|
|
685
|
+
await this.client.delete(`/notifications/${notificationId}`);
|
|
686
|
+
} catch (error) {
|
|
687
|
+
throw this.handleError(error);
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
/* Payment Methods */
|
|
692
|
+
|
|
693
|
+
/**
|
|
694
|
+
* Process a payment
|
|
695
|
+
* @param data - Payment data including user ID, plan, and payment method
|
|
696
|
+
* @returns Payment result with transaction ID
|
|
697
|
+
*/
|
|
698
|
+
async processPayment(data) {
|
|
699
|
+
try {
|
|
700
|
+
const res = await this.client.post('/payments/process', data);
|
|
701
|
+
return res.data;
|
|
702
|
+
} catch (error) {
|
|
703
|
+
throw this.handleError(error);
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
/**
|
|
708
|
+
* Validate a payment method
|
|
709
|
+
* @param paymentMethod - Payment method to validate
|
|
710
|
+
* @returns Object indicating if the payment method is valid
|
|
711
|
+
*/
|
|
712
|
+
async validatePaymentMethod(paymentMethod) {
|
|
713
|
+
try {
|
|
714
|
+
const res = await this.client.post('/payments/validate', {
|
|
715
|
+
paymentMethod
|
|
716
|
+
});
|
|
717
|
+
return res.data;
|
|
718
|
+
} catch (error) {
|
|
719
|
+
throw this.handleError(error);
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
/**
|
|
724
|
+
* Get saved payment methods for a user
|
|
725
|
+
* @param userId - User ID to get payment methods for
|
|
726
|
+
* @returns Array of payment methods
|
|
727
|
+
*/
|
|
728
|
+
async getPaymentMethods(userId) {
|
|
729
|
+
try {
|
|
730
|
+
const res = await this.client.get(`/payments/methods/${userId}`);
|
|
731
|
+
return res.data;
|
|
732
|
+
} catch (error) {
|
|
733
|
+
throw this.handleError(error);
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
/* Analytics Methods */
|
|
738
|
+
|
|
739
|
+
/**
|
|
740
|
+
* Get analytics data
|
|
741
|
+
* @param userId - User ID to get analytics for
|
|
742
|
+
* @param period - Time period for analytics (e.g., "day", "week", "month")
|
|
743
|
+
* @returns Analytics data
|
|
744
|
+
*/
|
|
745
|
+
async getAnalytics(userId, period) {
|
|
746
|
+
try {
|
|
747
|
+
const params = {
|
|
748
|
+
userID: userId
|
|
749
|
+
};
|
|
750
|
+
if (period) params.period = period;
|
|
751
|
+
const res = await this.client.get('/analytics', {
|
|
752
|
+
params
|
|
753
|
+
});
|
|
754
|
+
return res.data;
|
|
755
|
+
} catch (error) {
|
|
756
|
+
throw this.handleError(error);
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
/**
|
|
761
|
+
* Update analytics (internal use)
|
|
762
|
+
* @param userId - User ID to update analytics for
|
|
763
|
+
* @param type - Type of analytics to update
|
|
764
|
+
* @param data - Analytics data to update
|
|
765
|
+
* @returns Message indicating success
|
|
766
|
+
*/
|
|
767
|
+
async updateAnalytics(userId, type, data) {
|
|
768
|
+
try {
|
|
769
|
+
const res = await this.client.post('/analytics/update', {
|
|
770
|
+
userID: userId,
|
|
771
|
+
type,
|
|
772
|
+
data
|
|
773
|
+
});
|
|
774
|
+
return res.data;
|
|
775
|
+
} catch (error) {
|
|
776
|
+
throw this.handleError(error);
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
/**
|
|
781
|
+
* Get content viewers analytics
|
|
782
|
+
* @param userId - User ID to get viewer data for
|
|
783
|
+
* @param period - Time period for analytics
|
|
784
|
+
* @returns Array of content viewer data
|
|
785
|
+
*/
|
|
786
|
+
async getContentViewers(userId, period) {
|
|
787
|
+
try {
|
|
788
|
+
const params = {
|
|
789
|
+
userID: userId
|
|
790
|
+
};
|
|
791
|
+
if (period) params.period = period;
|
|
792
|
+
const res = await this.client.get('/analytics/viewers', {
|
|
793
|
+
params
|
|
794
|
+
});
|
|
795
|
+
return res.data;
|
|
796
|
+
} catch (error) {
|
|
797
|
+
throw this.handleError(error);
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
/**
|
|
802
|
+
* Get follower analytics details
|
|
803
|
+
* @param userId - User ID to get follower data for
|
|
804
|
+
* @param period - Time period for follower data
|
|
805
|
+
* @returns Follower details
|
|
806
|
+
*/
|
|
807
|
+
async getFollowerDetails(userId, period) {
|
|
808
|
+
try {
|
|
809
|
+
const params = {
|
|
810
|
+
userID: userId
|
|
811
|
+
};
|
|
812
|
+
if (period) params.period = period;
|
|
813
|
+
const res = await this.client.get('/analytics/followers', {
|
|
814
|
+
params
|
|
815
|
+
});
|
|
816
|
+
return res.data;
|
|
817
|
+
} catch (error) {
|
|
818
|
+
throw this.handleError(error);
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
/* Wallet Methods */
|
|
823
|
+
|
|
824
|
+
/**
|
|
825
|
+
* Get wallet info
|
|
826
|
+
* @param userId - User ID to get wallet for
|
|
827
|
+
* @returns Wallet data
|
|
828
|
+
*/
|
|
829
|
+
async getWallet(userId) {
|
|
830
|
+
try {
|
|
831
|
+
const res = await this.client.get(`/wallet/${userId}`);
|
|
832
|
+
return res.data;
|
|
833
|
+
} catch (error) {
|
|
834
|
+
throw this.handleError(error);
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
/**
|
|
839
|
+
* Get transaction history
|
|
840
|
+
* @param userId - User ID to get transactions for
|
|
841
|
+
* @param limit - Maximum number of transactions to return
|
|
842
|
+
* @param offset - Number of transactions to skip for pagination
|
|
843
|
+
* @returns Array of transactions and pagination info
|
|
844
|
+
*/
|
|
845
|
+
async getTransactionHistory(userId, limit, offset) {
|
|
846
|
+
try {
|
|
847
|
+
const params = {};
|
|
848
|
+
if (limit !== undefined) params.limit = limit;
|
|
849
|
+
if (offset !== undefined) params.offset = offset;
|
|
850
|
+
const res = await this.client.get(`/wallet/transactions/${userId}`, {
|
|
851
|
+
params
|
|
852
|
+
});
|
|
853
|
+
return res.data;
|
|
854
|
+
} catch (error) {
|
|
855
|
+
throw this.handleError(error);
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
/**
|
|
860
|
+
* Get a specific transaction
|
|
861
|
+
* @param transactionId - ID of transaction to retrieve
|
|
862
|
+
* @returns Transaction data
|
|
863
|
+
*/
|
|
864
|
+
async getTransaction(transactionId) {
|
|
865
|
+
try {
|
|
866
|
+
const res = await this.client.get(`/wallet/transaction/${transactionId}`);
|
|
867
|
+
return res.data;
|
|
868
|
+
} catch (error) {
|
|
869
|
+
throw this.handleError(error);
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
/**
|
|
874
|
+
* Transfer funds between users
|
|
875
|
+
* @param data - Transfer details including source, destination, and amount
|
|
876
|
+
* @returns Transaction response
|
|
877
|
+
*/
|
|
878
|
+
async transferFunds(data) {
|
|
879
|
+
try {
|
|
880
|
+
const res = await this.client.post('/wallet/transfer', data);
|
|
881
|
+
return res.data;
|
|
882
|
+
} catch (error) {
|
|
883
|
+
throw this.handleError(error);
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
/**
|
|
888
|
+
* Process a purchase
|
|
889
|
+
* @param data - Purchase details including user, item, and amount
|
|
890
|
+
* @returns Transaction response
|
|
891
|
+
*/
|
|
892
|
+
async processPurchase(data) {
|
|
893
|
+
try {
|
|
894
|
+
const res = await this.client.post('/wallet/purchase', data);
|
|
895
|
+
return res.data;
|
|
896
|
+
} catch (error) {
|
|
897
|
+
throw this.handleError(error);
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
/**
|
|
902
|
+
* Request a withdrawal
|
|
903
|
+
* @param data - Withdrawal details including user, amount, and address
|
|
904
|
+
* @returns Transaction response
|
|
905
|
+
*/
|
|
906
|
+
async requestWithdrawal(data) {
|
|
907
|
+
try {
|
|
908
|
+
const res = await this.client.post('/wallet/withdraw', data);
|
|
909
|
+
return res.data;
|
|
910
|
+
} catch (error) {
|
|
911
|
+
throw this.handleError(error);
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
/* Karma Methods */
|
|
916
|
+
|
|
917
|
+
/**
|
|
918
|
+
* Get karma leaderboard
|
|
919
|
+
* @returns Array of karma leaderboard entries
|
|
920
|
+
*/
|
|
921
|
+
async getKarmaLeaderboard() {
|
|
922
|
+
try {
|
|
923
|
+
const res = await this.client.get('/karma/leaderboard');
|
|
924
|
+
return res.data;
|
|
925
|
+
} catch (error) {
|
|
926
|
+
throw this.handleError(error);
|
|
927
|
+
}
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
/**
|
|
931
|
+
* Get karma rules
|
|
932
|
+
* @returns Array of karma rules
|
|
933
|
+
*/
|
|
934
|
+
async getKarmaRules() {
|
|
935
|
+
try {
|
|
936
|
+
const res = await this.client.get('/karma/rules');
|
|
937
|
+
return res.data;
|
|
938
|
+
} catch (error) {
|
|
939
|
+
throw this.handleError(error);
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
/**
|
|
944
|
+
* Get total karma for a user
|
|
945
|
+
* @param userId - User ID to get karma for
|
|
946
|
+
* @returns Object with total karma points
|
|
947
|
+
*/
|
|
948
|
+
async getUserKarmaTotal(userId) {
|
|
949
|
+
try {
|
|
950
|
+
const res = await this.client.get(`/karma/${userId}/total`);
|
|
951
|
+
return res.data;
|
|
952
|
+
} catch (error) {
|
|
953
|
+
throw this.handleError(error);
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
|
|
957
|
+
/**
|
|
958
|
+
* Get karma history for a user
|
|
959
|
+
* @param userId - User ID to get karma history for
|
|
960
|
+
* @param limit - Maximum number of history entries to return
|
|
961
|
+
* @param offset - Number of entries to skip for pagination
|
|
962
|
+
* @returns Karma history entries and pagination info
|
|
963
|
+
*/
|
|
964
|
+
async getUserKarmaHistory(userId, limit, offset) {
|
|
965
|
+
try {
|
|
966
|
+
const params = {};
|
|
967
|
+
if (limit !== undefined) params.limit = limit;
|
|
968
|
+
if (offset !== undefined) params.offset = offset;
|
|
969
|
+
const res = await this.client.get(`/karma/${userId}/history`, {
|
|
970
|
+
params
|
|
971
|
+
});
|
|
972
|
+
return res.data;
|
|
973
|
+
} catch (error) {
|
|
974
|
+
throw this.handleError(error);
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
/**
|
|
979
|
+
* Award karma points to a user
|
|
980
|
+
* @param data - Karma award details
|
|
981
|
+
* @returns Karma award response
|
|
982
|
+
*/
|
|
983
|
+
async awardKarma(data) {
|
|
984
|
+
try {
|
|
985
|
+
const res = await this.client.post('/karma/award', data);
|
|
986
|
+
return res.data;
|
|
987
|
+
} catch (error) {
|
|
988
|
+
throw this.handleError(error);
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
/**
|
|
993
|
+
* Deduct karma points from a user
|
|
994
|
+
* @param data - Karma deduction details
|
|
995
|
+
* @returns Karma deduction response
|
|
996
|
+
*/
|
|
997
|
+
async deductKarma(data) {
|
|
998
|
+
try {
|
|
999
|
+
const res = await this.client.post('/karma/deduct', data);
|
|
1000
|
+
return res.data;
|
|
1001
|
+
} catch (error) {
|
|
1002
|
+
throw this.handleError(error);
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
/**
|
|
1007
|
+
* Create or update karma rule (admin)
|
|
1008
|
+
* @param data - Karma rule data
|
|
1009
|
+
* @returns Created or updated karma rule
|
|
1010
|
+
*/
|
|
1011
|
+
async createOrUpdateKarmaRule(data) {
|
|
1012
|
+
try {
|
|
1013
|
+
const res = await this.client.post('/karma/rules', data);
|
|
1014
|
+
return res.data;
|
|
1015
|
+
} catch (error) {
|
|
1016
|
+
throw this.handleError(error);
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
/* File Management Methods */
|
|
1021
|
+
|
|
1022
|
+
/**
|
|
1023
|
+
* Upload a file using GridFS
|
|
1024
|
+
* @param file - The file to upload (File or Blob in browser, Buffer in Node.js)
|
|
1025
|
+
* @param filename - The name of the file
|
|
1026
|
+
* @param metadata - Optional metadata to associate with the file
|
|
1027
|
+
* @returns File metadata including ID and download URL
|
|
1028
|
+
*/
|
|
1029
|
+
async uploadFile(file,
|
|
1030
|
+
// Use 'any' to handle Buffer type in cross-platform scenarios
|
|
1031
|
+
filename, metadata) {
|
|
1032
|
+
const response = await this.uploadFiles([file], [filename], metadata);
|
|
1033
|
+
return response.files[0];
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1036
|
+
/**
|
|
1037
|
+
* Upload multiple files using GridFS
|
|
1038
|
+
* @param files - Array of files to upload
|
|
1039
|
+
* @param filenames - Array of filenames (must match files array length)
|
|
1040
|
+
* @param metadata - Optional metadata to associate with all files
|
|
1041
|
+
* @returns Array of file metadata
|
|
1042
|
+
*/
|
|
1043
|
+
async uploadFiles(files, filenames, metadata) {
|
|
1044
|
+
try {
|
|
1045
|
+
if (files.length !== filenames.length) {
|
|
1046
|
+
throw new Error('Files and filenames arrays must have the same length');
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
// Create form data to handle the file upload
|
|
1050
|
+
let formData;
|
|
1051
|
+
if (typeof window === 'undefined' && NodeFormData) {
|
|
1052
|
+
// Node.js environment - prefer node-specific form-data
|
|
1053
|
+
formData = new NodeFormData();
|
|
1054
|
+
} else {
|
|
1055
|
+
// Browser/React Native environment - use polyfilled or native FormData
|
|
1056
|
+
const FormDataConstructor = (0, _polyfills.getFormDataConstructor)();
|
|
1057
|
+
formData = new FormDataConstructor();
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
// Add all files to the form data
|
|
1061
|
+
files.forEach((file, index) => {
|
|
1062
|
+
const filename = filenames[index];
|
|
1063
|
+
|
|
1064
|
+
// Handle different file types (Browser vs Node.js vs React Native)
|
|
1065
|
+
const isNodeBuffer = typeof window === 'undefined' && file && typeof file.constructor === 'function' && file.constructor.name === 'Buffer';
|
|
1066
|
+
if (isNodeBuffer) {
|
|
1067
|
+
// Node.js environment with Buffer
|
|
1068
|
+
if (!NodeFormData) {
|
|
1069
|
+
throw new Error('form-data module is required for file uploads from Buffer but not found.');
|
|
1070
|
+
}
|
|
1071
|
+
// form-data handles Buffers directly.
|
|
1072
|
+
formData.append('files', file, {
|
|
1073
|
+
filename
|
|
1074
|
+
}); // Pass filename in options for form-data
|
|
1075
|
+
} else {
|
|
1076
|
+
// Browser/React Native environment with File or Blob
|
|
1077
|
+
formData.append('files', file, filename);
|
|
1078
|
+
}
|
|
1079
|
+
});
|
|
1080
|
+
|
|
1081
|
+
// Add metadata as JSON string if provided
|
|
1082
|
+
if (metadata) {
|
|
1083
|
+
formData.append('metadata', JSON.stringify(metadata));
|
|
1084
|
+
}
|
|
1085
|
+
const res = await this.client.post('/files/upload', formData, {
|
|
1086
|
+
headers: {
|
|
1087
|
+
'Content-Type': 'multipart/form-data'
|
|
1088
|
+
}
|
|
1089
|
+
});
|
|
1090
|
+
return res.data;
|
|
1091
|
+
} catch (error) {
|
|
1092
|
+
throw this.handleError(error);
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1096
|
+
/**
|
|
1097
|
+
* Get file metadata by ID
|
|
1098
|
+
* @param fileId - ID of the file to retrieve metadata for
|
|
1099
|
+
* @returns File metadata
|
|
1100
|
+
*/
|
|
1101
|
+
async getFileMetadata(fileId) {
|
|
1102
|
+
try {
|
|
1103
|
+
const res = await this.client.get(`/files/${fileId}/metadata`);
|
|
1104
|
+
return res.data;
|
|
1105
|
+
} catch (error) {
|
|
1106
|
+
throw this.handleError(error);
|
|
1107
|
+
}
|
|
1108
|
+
}
|
|
1109
|
+
|
|
1110
|
+
/**
|
|
1111
|
+
* Update file metadata
|
|
1112
|
+
* @param fileId - ID of the file to update
|
|
1113
|
+
* @param updates - Metadata updates to apply
|
|
1114
|
+
* @returns Updated file metadata
|
|
1115
|
+
*/
|
|
1116
|
+
async updateFileMetadata(fileId, updates) {
|
|
1117
|
+
try {
|
|
1118
|
+
const res = await this.client.put(`/files/${fileId}/metadata`, updates);
|
|
1119
|
+
return res.data;
|
|
1120
|
+
} catch (error) {
|
|
1121
|
+
throw this.handleError(error);
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
/**
|
|
1126
|
+
* Delete a file by ID
|
|
1127
|
+
* @param fileId - ID of the file to delete
|
|
1128
|
+
* @returns Status of the delete operation
|
|
1129
|
+
*/
|
|
1130
|
+
async deleteFile(fileId) {
|
|
1131
|
+
try {
|
|
1132
|
+
console.log('Deleting file with ID:', fileId);
|
|
1133
|
+
const res = await this.client.delete(`/files/${fileId}`);
|
|
1134
|
+
console.log('Delete response:', res.data);
|
|
1135
|
+
return res.data;
|
|
1136
|
+
} catch (error) {
|
|
1137
|
+
console.error('Delete file error:', error);
|
|
1138
|
+
console.error('Error response:', error.response?.data);
|
|
1139
|
+
console.error('Error status:', error.response?.status);
|
|
1140
|
+
|
|
1141
|
+
// Provide more specific error messages based on status code
|
|
1142
|
+
if (error.response?.status === 404) {
|
|
1143
|
+
throw new Error('File not found or already deleted');
|
|
1144
|
+
} else if (error.response?.status === 403) {
|
|
1145
|
+
throw new Error('You do not have permission to delete this file');
|
|
1146
|
+
} else if (error.response?.status === 400) {
|
|
1147
|
+
throw new Error('Invalid file ID format');
|
|
1148
|
+
}
|
|
1149
|
+
throw this.handleError(error);
|
|
1150
|
+
}
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1153
|
+
/**
|
|
1154
|
+
* Get download URL for a file
|
|
1155
|
+
* @param fileId - ID of the file to get download URL for
|
|
1156
|
+
* @returns Full URL to download the file
|
|
1157
|
+
*/
|
|
1158
|
+
getFileDownloadUrl(fileId) {
|
|
1159
|
+
return `${this.client.defaults.baseURL}/files/${fileId}`;
|
|
1160
|
+
}
|
|
1161
|
+
|
|
1162
|
+
/**
|
|
1163
|
+
* Stream a file (useful for playing audio/video without full download)
|
|
1164
|
+
* @param fileId - ID of the file to stream
|
|
1165
|
+
* @returns Full URL to stream the file
|
|
1166
|
+
*/
|
|
1167
|
+
getFileStreamUrl(fileId) {
|
|
1168
|
+
return `${this.client.defaults.baseURL}/files/${fileId}`;
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1171
|
+
/**
|
|
1172
|
+
* List files for a specific user
|
|
1173
|
+
* @param userId - User ID to list files for
|
|
1174
|
+
* @param limit - Maximum number of files to return
|
|
1175
|
+
* @param offset - Number of files to skip for pagination
|
|
1176
|
+
* @param filters - Optional filters for the file list (e.g., contentType)
|
|
1177
|
+
* @returns Array of file metadata and pagination info
|
|
1178
|
+
*/
|
|
1179
|
+
async listUserFiles(userId, limit, offset, filters) {
|
|
1180
|
+
try {
|
|
1181
|
+
const params = {};
|
|
1182
|
+
if (limit !== undefined) params.limit = limit;
|
|
1183
|
+
if (offset !== undefined) params.offset = offset;
|
|
1184
|
+
if (filters) Object.assign(params, filters);
|
|
1185
|
+
const res = await this.client.get(`/files/list/${userId}`, {
|
|
1186
|
+
params
|
|
1187
|
+
});
|
|
1188
|
+
|
|
1189
|
+
// Handle backend response format: backend returns FileMetadata[] directly
|
|
1190
|
+
// but interface expects { files: FileMetadata[], total: number, hasMore: boolean }
|
|
1191
|
+
const rawFiles = Array.isArray(res.data) ? res.data : res.data.files || [];
|
|
1192
|
+
|
|
1193
|
+
// Transform GridFS files to match FileMetadata interface (map _id to id)
|
|
1194
|
+
const filesArray = rawFiles.map(file => ({
|
|
1195
|
+
...file,
|
|
1196
|
+
id: file._id?.toString() || file.id,
|
|
1197
|
+
uploadDate: file.uploadDate?.toISOString ? file.uploadDate.toISOString() : file.uploadDate
|
|
1198
|
+
}));
|
|
1199
|
+
return {
|
|
1200
|
+
files: filesArray,
|
|
1201
|
+
total: filesArray.length,
|
|
1202
|
+
hasMore: false // No pagination in current backend implementation
|
|
1203
|
+
};
|
|
1204
|
+
} catch (error) {
|
|
1205
|
+
throw this.handleError(error);
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
|
|
1209
|
+
/**
|
|
1210
|
+
* Secure login that returns only session data (no tokens stored locally)
|
|
1211
|
+
* @param username - User's username or email
|
|
1212
|
+
* @param password - User's password
|
|
1213
|
+
* @param deviceName - Optional device name for session tracking
|
|
1214
|
+
* @param deviceFingerprint - Device fingerprint for enhanced security
|
|
1215
|
+
* @returns Secure login response with session data
|
|
1216
|
+
*/
|
|
1217
|
+
async secureLogin(username, password, deviceName, deviceFingerprint) {
|
|
1218
|
+
try {
|
|
1219
|
+
const payload = {
|
|
1220
|
+
username,
|
|
1221
|
+
password,
|
|
1222
|
+
deviceName
|
|
1223
|
+
};
|
|
1224
|
+
if (deviceFingerprint) {
|
|
1225
|
+
payload.deviceFingerprint = deviceFingerprint;
|
|
1226
|
+
}
|
|
1227
|
+
const res = await this.client.post('/secure-session/login', payload);
|
|
1228
|
+
return res.data;
|
|
1229
|
+
} catch (error) {
|
|
1230
|
+
throw this.handleError(error);
|
|
1231
|
+
}
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1234
|
+
/**
|
|
1235
|
+
* Get full user data by session ID
|
|
1236
|
+
* @param sessionId - The session ID
|
|
1237
|
+
* @returns Full user data
|
|
1238
|
+
*/
|
|
1239
|
+
async getUserBySession(sessionId) {
|
|
1240
|
+
try {
|
|
1241
|
+
const res = await this.client.get(`/secure-session/user/${sessionId}`);
|
|
1242
|
+
return res.data.user;
|
|
1243
|
+
} catch (error) {
|
|
1244
|
+
throw this.handleError(error);
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
|
|
1248
|
+
/**
|
|
1249
|
+
* Get access token by session ID (for API calls)
|
|
1250
|
+
* @param sessionId - The session ID
|
|
1251
|
+
* @returns Access token and expiry info
|
|
1252
|
+
*/
|
|
1253
|
+
async getTokenBySession(sessionId) {
|
|
1254
|
+
try {
|
|
1255
|
+
const res = await this.client.get(`/secure-session/token/${sessionId}`);
|
|
1256
|
+
// Set the token for subsequent API calls
|
|
1257
|
+
this.accessToken = res.data.accessToken;
|
|
1258
|
+
return res.data;
|
|
1259
|
+
} catch (error) {
|
|
1260
|
+
throw this.handleError(error);
|
|
1261
|
+
}
|
|
1262
|
+
}
|
|
1263
|
+
|
|
1264
|
+
/**
|
|
1265
|
+
* Get all active sessions for current user
|
|
1266
|
+
* @param sessionId - Current session ID
|
|
1267
|
+
* @returns Array of user sessions
|
|
1268
|
+
*/
|
|
1269
|
+
async getSessionsBySessionId(sessionId) {
|
|
1270
|
+
try {
|
|
1271
|
+
const res = await this.client.get(`/secure-session/sessions/${sessionId}`);
|
|
1272
|
+
return res.data.sessions;
|
|
1273
|
+
} catch (error) {
|
|
1274
|
+
throw this.handleError(error);
|
|
1275
|
+
}
|
|
1276
|
+
}
|
|
1277
|
+
|
|
1278
|
+
/**
|
|
1279
|
+
* Logout specific session
|
|
1280
|
+
* @param sessionId - Current session ID
|
|
1281
|
+
* @param targetSessionId - Optional target session to logout (defaults to current)
|
|
1282
|
+
*/
|
|
1283
|
+
async logoutSecureSession(sessionId, targetSessionId) {
|
|
1284
|
+
try {
|
|
1285
|
+
await this.client.post(`/secure-session/logout/${sessionId}`, {
|
|
1286
|
+
targetSessionId
|
|
1287
|
+
});
|
|
1288
|
+
|
|
1289
|
+
// If we're logging out the current session, clear the access token
|
|
1290
|
+
if (!targetSessionId || targetSessionId === sessionId) {
|
|
1291
|
+
this.accessToken = null;
|
|
1292
|
+
this.refreshToken = null;
|
|
1293
|
+
}
|
|
1294
|
+
} catch (error) {
|
|
1295
|
+
throw this.handleError(error);
|
|
1296
|
+
}
|
|
1297
|
+
}
|
|
1298
|
+
|
|
1299
|
+
/**
|
|
1300
|
+
* Logout all sessions for current user
|
|
1301
|
+
* @param sessionId - Current session ID
|
|
1302
|
+
*/
|
|
1303
|
+
async logoutAllSecureSessions(sessionId) {
|
|
1304
|
+
console.log('logoutAllSecureSessions called with sessionId:', sessionId);
|
|
1305
|
+
console.log('API client defaults:', this.client.defaults);
|
|
1306
|
+
try {
|
|
1307
|
+
const response = await this.client.post(`/secure-session/logout-all/${sessionId}`);
|
|
1308
|
+
console.log('logoutAllSecureSessions response:', response.status, response.data);
|
|
1309
|
+
|
|
1310
|
+
// Clear tokens since all sessions are logged out
|
|
1311
|
+
this.accessToken = null;
|
|
1312
|
+
this.refreshToken = null;
|
|
1313
|
+
console.log('Tokens cleared successfully');
|
|
1314
|
+
} catch (error) {
|
|
1315
|
+
console.error('logoutAllSecureSessions error:', error);
|
|
1316
|
+
if (error && typeof error === 'object' && 'response' in error) {
|
|
1317
|
+
const axiosError = error;
|
|
1318
|
+
console.error('Error response data:', axiosError.response?.data);
|
|
1319
|
+
console.error('Error response status:', axiosError.response?.status);
|
|
1320
|
+
}
|
|
1321
|
+
throw this.handleError(error);
|
|
1322
|
+
}
|
|
1323
|
+
}
|
|
1324
|
+
|
|
1325
|
+
/**
|
|
1326
|
+
* Validate session
|
|
1327
|
+
* @param sessionId - The session ID to validate
|
|
1328
|
+
* @returns Session validation status with user data
|
|
1329
|
+
*/
|
|
1330
|
+
async validateSession(sessionId) {
|
|
1331
|
+
try {
|
|
1332
|
+
const res = await this.client.get(`/secure-session/validate/${sessionId}`);
|
|
1333
|
+
return res.data;
|
|
1334
|
+
} catch (error) {
|
|
1335
|
+
throw this.handleError(error);
|
|
1336
|
+
}
|
|
1337
|
+
}
|
|
1338
|
+
|
|
1339
|
+
/**
|
|
1340
|
+
* Validate session using x-session-id header
|
|
1341
|
+
* @param sessionId - The session ID to validate (sent as header)
|
|
1342
|
+
* @param deviceFingerprint - Optional device fingerprint for enhanced security
|
|
1343
|
+
* @returns Session validation status with user data
|
|
1344
|
+
*/
|
|
1345
|
+
async validateSessionFromHeader(sessionId, deviceFingerprint) {
|
|
1346
|
+
try {
|
|
1347
|
+
const headers = {
|
|
1348
|
+
'x-session-id': sessionId
|
|
1349
|
+
};
|
|
1350
|
+
if (deviceFingerprint) {
|
|
1351
|
+
headers['x-device-fingerprint'] = deviceFingerprint;
|
|
1352
|
+
}
|
|
1353
|
+
const res = await this.client.get('/secure-session/validate-header', {
|
|
1354
|
+
headers
|
|
1355
|
+
});
|
|
1356
|
+
return res.data;
|
|
1357
|
+
} catch (error) {
|
|
1358
|
+
throw this.handleError(error);
|
|
1359
|
+
}
|
|
1360
|
+
}
|
|
1361
|
+
|
|
1362
|
+
/**
|
|
1363
|
+
* Validate session using automatic header detection
|
|
1364
|
+
* The validateSession endpoint will automatically read from x-session-id header
|
|
1365
|
+
* @param sessionId - The session ID to validate (sent as header)
|
|
1366
|
+
* @param deviceFingerprint - Optional device fingerprint for enhanced security
|
|
1367
|
+
* @returns Session validation status with user data
|
|
1368
|
+
*/
|
|
1369
|
+
async validateSessionAuto(sessionId, deviceFingerprint) {
|
|
1370
|
+
try {
|
|
1371
|
+
const headers = {
|
|
1372
|
+
'x-session-id': sessionId
|
|
1373
|
+
};
|
|
1374
|
+
if (deviceFingerprint) {
|
|
1375
|
+
headers['x-device-fingerprint'] = deviceFingerprint;
|
|
1376
|
+
}
|
|
1377
|
+
|
|
1378
|
+
// Call the regular validateSession endpoint which now auto-reads from headers
|
|
1379
|
+
// Use 'auto' as placeholder since the controller reads from header
|
|
1380
|
+
const res = await this.client.get('/secure-session/validate/auto', {
|
|
1381
|
+
headers
|
|
1382
|
+
});
|
|
1383
|
+
return res.data;
|
|
1384
|
+
} catch (error) {
|
|
1385
|
+
throw this.handleError(error);
|
|
1386
|
+
}
|
|
1387
|
+
}
|
|
1388
|
+
|
|
1389
|
+
/**
|
|
1390
|
+
* Utility method to help implement authentication middleware in Express.js applications
|
|
1391
|
+
* This creates a function that can be used as Express middleware to validate tokens
|
|
1392
|
+
* @param options - Configuration options for the middleware
|
|
1393
|
+
* @returns Express middleware function
|
|
1394
|
+
*/
|
|
1395
|
+
createAuthenticateTokenMiddleware(options = {}) {
|
|
1396
|
+
const {
|
|
1397
|
+
loadFullUser = true,
|
|
1398
|
+
onError
|
|
1399
|
+
} = options;
|
|
1400
|
+
return async (req, res, next) => {
|
|
1401
|
+
try {
|
|
1402
|
+
const authHeader = req.headers['authorization'];
|
|
1403
|
+
const token = authHeader && authHeader.split(' ')[1]; // Bearer TOKEN
|
|
1404
|
+
|
|
1405
|
+
if (!token) {
|
|
1406
|
+
const error = {
|
|
1407
|
+
message: 'Access token required',
|
|
1408
|
+
code: 'MISSING_TOKEN',
|
|
1409
|
+
status: 401
|
|
1410
|
+
};
|
|
1411
|
+
if (onError) {
|
|
1412
|
+
return onError(error);
|
|
1413
|
+
}
|
|
1414
|
+
return res.status(401).json({
|
|
1415
|
+
message: 'Access token required',
|
|
1416
|
+
code: 'MISSING_TOKEN'
|
|
1417
|
+
});
|
|
1418
|
+
}
|
|
1419
|
+
|
|
1420
|
+
// Create a temporary OxyServices instance with the token to validate it
|
|
1421
|
+
const tempOxyServices = new OxyServices({
|
|
1422
|
+
baseURL: this.client.defaults.baseURL || ''
|
|
1423
|
+
});
|
|
1424
|
+
tempOxyServices.setTokens(token, ''); // Set access token
|
|
1425
|
+
|
|
1426
|
+
// Validate token using the validate method
|
|
1427
|
+
const isValid = await tempOxyServices.validate();
|
|
1428
|
+
if (!isValid) {
|
|
1429
|
+
const error = {
|
|
1430
|
+
message: 'Invalid or expired token',
|
|
1431
|
+
code: 'INVALID_TOKEN',
|
|
1432
|
+
status: 403
|
|
1433
|
+
};
|
|
1434
|
+
if (onError) {
|
|
1435
|
+
return onError(error);
|
|
1436
|
+
}
|
|
1437
|
+
return res.status(403).json({
|
|
1438
|
+
message: 'Invalid or expired token',
|
|
1439
|
+
code: 'INVALID_TOKEN'
|
|
1440
|
+
});
|
|
1441
|
+
}
|
|
1442
|
+
|
|
1443
|
+
// Get user ID from token
|
|
1444
|
+
const userId = tempOxyServices.getCurrentUserId();
|
|
1445
|
+
if (!userId) {
|
|
1446
|
+
const error = {
|
|
1447
|
+
message: 'Invalid token payload',
|
|
1448
|
+
code: 'INVALID_PAYLOAD',
|
|
1449
|
+
status: 403
|
|
1450
|
+
};
|
|
1451
|
+
if (onError) {
|
|
1452
|
+
return onError(error);
|
|
1453
|
+
}
|
|
1454
|
+
return res.status(403).json({
|
|
1455
|
+
message: 'Invalid token payload',
|
|
1456
|
+
code: 'INVALID_PAYLOAD'
|
|
1457
|
+
});
|
|
1458
|
+
}
|
|
1459
|
+
|
|
1460
|
+
// Set user information on request object
|
|
1461
|
+
req.userId = userId;
|
|
1462
|
+
req.accessToken = token;
|
|
1463
|
+
|
|
1464
|
+
// Optionally load full user data
|
|
1465
|
+
if (loadFullUser) {
|
|
1466
|
+
try {
|
|
1467
|
+
const userProfile = await tempOxyServices.getUserById(userId);
|
|
1468
|
+
req.user = userProfile;
|
|
1469
|
+
} catch (userError) {
|
|
1470
|
+
// If we can't load user, continue with just ID
|
|
1471
|
+
req.user = {
|
|
1472
|
+
id: userId
|
|
1473
|
+
};
|
|
1474
|
+
}
|
|
1475
|
+
} else {
|
|
1476
|
+
req.user = {
|
|
1477
|
+
id: userId
|
|
1478
|
+
};
|
|
1479
|
+
}
|
|
1480
|
+
next();
|
|
1481
|
+
} catch (error) {
|
|
1482
|
+
const apiError = this.handleError(error);
|
|
1483
|
+
if (onError) {
|
|
1484
|
+
return onError(apiError);
|
|
1485
|
+
}
|
|
1486
|
+
return res.status(apiError.status || 500).json({
|
|
1487
|
+
message: apiError.message,
|
|
1488
|
+
code: apiError.code
|
|
1489
|
+
});
|
|
1490
|
+
}
|
|
1491
|
+
};
|
|
1492
|
+
}
|
|
1493
|
+
|
|
1494
|
+
/**
|
|
1495
|
+
* Helper method for validating tokens without Express middleware
|
|
1496
|
+
* Useful for standalone token validation in various contexts
|
|
1497
|
+
* @param token - The access token to validate
|
|
1498
|
+
* @returns Object with validation result and user information
|
|
1499
|
+
*/
|
|
1500
|
+
async authenticateToken(token) {
|
|
1501
|
+
try {
|
|
1502
|
+
if (!token) {
|
|
1503
|
+
return {
|
|
1504
|
+
valid: false,
|
|
1505
|
+
error: 'Token is required'
|
|
1506
|
+
};
|
|
1507
|
+
}
|
|
1508
|
+
|
|
1509
|
+
// Create a temporary OxyServices instance with the token
|
|
1510
|
+
const tempOxyServices = new OxyServices({
|
|
1511
|
+
baseURL: this.client.defaults.baseURL || ''
|
|
1512
|
+
});
|
|
1513
|
+
tempOxyServices.setTokens(token, '');
|
|
1514
|
+
|
|
1515
|
+
// Validate token
|
|
1516
|
+
const isValid = await tempOxyServices.validate();
|
|
1517
|
+
if (!isValid) {
|
|
1518
|
+
return {
|
|
1519
|
+
valid: false,
|
|
1520
|
+
error: 'Invalid or expired token'
|
|
1521
|
+
};
|
|
1522
|
+
}
|
|
1523
|
+
|
|
1524
|
+
// Get user ID from token
|
|
1525
|
+
const userId = tempOxyServices.getCurrentUserId();
|
|
1526
|
+
if (!userId) {
|
|
1527
|
+
return {
|
|
1528
|
+
valid: false,
|
|
1529
|
+
error: 'Invalid token payload'
|
|
1530
|
+
};
|
|
1531
|
+
}
|
|
1532
|
+
|
|
1533
|
+
// Try to get user profile
|
|
1534
|
+
let user;
|
|
1535
|
+
try {
|
|
1536
|
+
user = await tempOxyServices.getUserById(userId);
|
|
1537
|
+
} catch (error) {
|
|
1538
|
+
// Continue without full user data
|
|
1539
|
+
user = {
|
|
1540
|
+
id: userId
|
|
1541
|
+
};
|
|
1542
|
+
}
|
|
1543
|
+
return {
|
|
1544
|
+
valid: true,
|
|
1545
|
+
userId,
|
|
1546
|
+
user
|
|
1547
|
+
};
|
|
1548
|
+
} catch (error) {
|
|
1549
|
+
return {
|
|
1550
|
+
valid: false,
|
|
1551
|
+
error: error instanceof Error ? error.message : 'Token validation failed'
|
|
1552
|
+
};
|
|
1553
|
+
}
|
|
1554
|
+
}
|
|
1555
|
+
|
|
1556
|
+
/**
|
|
1557
|
+
* Centralized error handling
|
|
1558
|
+
* @private
|
|
1559
|
+
* @param error - Error object from API call
|
|
1560
|
+
* @returns Formatted API error
|
|
1561
|
+
*/
|
|
1562
|
+
handleError(error) {
|
|
1563
|
+
if (error && error.code && error.status) {
|
|
1564
|
+
// Already formatted as ApiError
|
|
1565
|
+
return error;
|
|
1566
|
+
}
|
|
1567
|
+
const apiError = {
|
|
1568
|
+
message: error?.message || error?.response?.data?.message || 'Unknown error occurred',
|
|
1569
|
+
code: error?.response?.data?.code || 'UNKNOWN_ERROR',
|
|
1570
|
+
status: error?.response?.status || 500,
|
|
1571
|
+
details: error?.response?.data
|
|
1572
|
+
};
|
|
1573
|
+
return apiError;
|
|
1574
|
+
}
|
|
1575
|
+
|
|
1576
|
+
/**
|
|
1577
|
+
* Check if a username is available
|
|
1578
|
+
* @param username - The username to check
|
|
1579
|
+
* @returns Promise with availability status
|
|
1580
|
+
*/
|
|
1581
|
+
async checkUsernameAvailability(username) {
|
|
1582
|
+
try {
|
|
1583
|
+
const res = await this.client.get(`/auth/check-username/${username}`);
|
|
1584
|
+
return res.data;
|
|
1585
|
+
} catch (error) {
|
|
1586
|
+
// If the endpoint doesn't exist, fall back to basic validation
|
|
1587
|
+
if (error.response?.status === 404) {
|
|
1588
|
+
console.warn('Username validation endpoint not found, using fallback validation');
|
|
1589
|
+
return {
|
|
1590
|
+
available: true,
|
|
1591
|
+
message: 'Username validation not available'
|
|
1592
|
+
};
|
|
1593
|
+
}
|
|
1594
|
+
|
|
1595
|
+
// If it's a validation error (400), return the error message
|
|
1596
|
+
if (error.response?.status === 400) {
|
|
1597
|
+
return error.response.data;
|
|
1598
|
+
}
|
|
1599
|
+
|
|
1600
|
+
// For other errors, log and return a fallback
|
|
1601
|
+
console.error('Username validation error:', error);
|
|
1602
|
+
return {
|
|
1603
|
+
available: true,
|
|
1604
|
+
message: 'Unable to validate username'
|
|
1605
|
+
};
|
|
1606
|
+
}
|
|
1607
|
+
}
|
|
1608
|
+
|
|
1609
|
+
/**
|
|
1610
|
+
* Check if an email is available
|
|
1611
|
+
* @param email - The email to check
|
|
1612
|
+
* @returns Promise with availability status
|
|
1613
|
+
*/
|
|
1614
|
+
async checkEmailAvailability(email) {
|
|
1615
|
+
try {
|
|
1616
|
+
const res = await this.client.post('/auth/check-email', {
|
|
1617
|
+
email
|
|
1618
|
+
});
|
|
1619
|
+
return res.data;
|
|
1620
|
+
} catch (error) {
|
|
1621
|
+
// If the endpoint doesn't exist, fall back to basic validation
|
|
1622
|
+
if (error.response?.status === 404) {
|
|
1623
|
+
console.warn('Email validation endpoint not found, using fallback validation');
|
|
1624
|
+
return {
|
|
1625
|
+
available: true,
|
|
1626
|
+
message: 'Email validation not available'
|
|
1627
|
+
};
|
|
1628
|
+
}
|
|
1629
|
+
|
|
1630
|
+
// If it's a validation error (400), return the error message
|
|
1631
|
+
if (error.response?.status === 400) {
|
|
1632
|
+
return error.response.data;
|
|
1633
|
+
}
|
|
1634
|
+
|
|
1635
|
+
// For other errors, log and return a fallback
|
|
1636
|
+
console.error('Email validation error:', error);
|
|
1637
|
+
return {
|
|
1638
|
+
available: true,
|
|
1639
|
+
message: 'Unable to validate email'
|
|
1640
|
+
};
|
|
1641
|
+
}
|
|
1642
|
+
}
|
|
1643
|
+
|
|
1644
|
+
/**
|
|
1645
|
+
* Get user profile by username
|
|
1646
|
+
* @param username - The username to look up
|
|
1647
|
+
* @returns Promise with user profile
|
|
1648
|
+
*/
|
|
1649
|
+
async getUserProfileByUsername(username) {
|
|
1650
|
+
try {
|
|
1651
|
+
const res = await this.client.get(`/profiles/username/${username}`);
|
|
1652
|
+
return res.data;
|
|
1653
|
+
} catch (error) {
|
|
1654
|
+
throw this.handleError(error);
|
|
1655
|
+
}
|
|
1656
|
+
}
|
|
1657
|
+
}
|
|
1658
|
+
exports.OxyServices = OxyServices;
|
|
1659
|
+
var _default = exports.default = OxyServices;
|
|
1660
|
+
//# sourceMappingURL=index.js.map
|