@oxyhq/services 5.4.2 → 5.4.3

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