@oxyhq/core 1.0.0

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 (277) hide show
  1. package/README.md +50 -0
  2. package/dist/cjs/AuthManager.js +361 -0
  3. package/dist/cjs/CrossDomainAuth.js +258 -0
  4. package/dist/cjs/HttpService.js +618 -0
  5. package/dist/cjs/OxyServices.base.js +263 -0
  6. package/dist/cjs/OxyServices.errors.js +22 -0
  7. package/dist/cjs/OxyServices.js +63 -0
  8. package/dist/cjs/constants/version.js +16 -0
  9. package/dist/cjs/crypto/index.js +20 -0
  10. package/dist/cjs/crypto/keyManager.js +887 -0
  11. package/dist/cjs/crypto/polyfill.js +64 -0
  12. package/dist/cjs/crypto/recoveryPhrase.js +169 -0
  13. package/dist/cjs/crypto/signatureService.js +296 -0
  14. package/dist/cjs/i18n/index.js +73 -0
  15. package/dist/cjs/i18n/locales/ar-SA.json +120 -0
  16. package/dist/cjs/i18n/locales/ca-ES.json +120 -0
  17. package/dist/cjs/i18n/locales/de-DE.json +120 -0
  18. package/dist/cjs/i18n/locales/en-US.json +956 -0
  19. package/dist/cjs/i18n/locales/es-ES.json +944 -0
  20. package/dist/cjs/i18n/locales/fr-FR.json +120 -0
  21. package/dist/cjs/i18n/locales/it-IT.json +120 -0
  22. package/dist/cjs/i18n/locales/ja-JP.json +119 -0
  23. package/dist/cjs/i18n/locales/ko-KR.json +120 -0
  24. package/dist/cjs/i18n/locales/locales/ar-SA.json +120 -0
  25. package/dist/cjs/i18n/locales/locales/ca-ES.json +120 -0
  26. package/dist/cjs/i18n/locales/locales/de-DE.json +120 -0
  27. package/dist/cjs/i18n/locales/locales/en-US.json +956 -0
  28. package/dist/cjs/i18n/locales/locales/es-ES.json +944 -0
  29. package/dist/cjs/i18n/locales/locales/fr-FR.json +120 -0
  30. package/dist/cjs/i18n/locales/locales/it-IT.json +120 -0
  31. package/dist/cjs/i18n/locales/locales/ja-JP.json +119 -0
  32. package/dist/cjs/i18n/locales/locales/ko-KR.json +120 -0
  33. package/dist/cjs/i18n/locales/locales/pt-PT.json +120 -0
  34. package/dist/cjs/i18n/locales/locales/zh-CN.json +120 -0
  35. package/dist/cjs/i18n/locales/pt-PT.json +120 -0
  36. package/dist/cjs/i18n/locales/zh-CN.json +120 -0
  37. package/dist/cjs/index.js +153 -0
  38. package/dist/cjs/mixins/OxyServices.analytics.js +49 -0
  39. package/dist/cjs/mixins/OxyServices.assets.js +380 -0
  40. package/dist/cjs/mixins/OxyServices.auth.js +259 -0
  41. package/dist/cjs/mixins/OxyServices.developer.js +97 -0
  42. package/dist/cjs/mixins/OxyServices.devices.js +116 -0
  43. package/dist/cjs/mixins/OxyServices.features.js +309 -0
  44. package/dist/cjs/mixins/OxyServices.fedcm.js +435 -0
  45. package/dist/cjs/mixins/OxyServices.karma.js +108 -0
  46. package/dist/cjs/mixins/OxyServices.language.js +154 -0
  47. package/dist/cjs/mixins/OxyServices.location.js +43 -0
  48. package/dist/cjs/mixins/OxyServices.payment.js +158 -0
  49. package/dist/cjs/mixins/OxyServices.popup.js +371 -0
  50. package/dist/cjs/mixins/OxyServices.privacy.js +162 -0
  51. package/dist/cjs/mixins/OxyServices.redirect.js +345 -0
  52. package/dist/cjs/mixins/OxyServices.security.js +81 -0
  53. package/dist/cjs/mixins/OxyServices.user.js +355 -0
  54. package/dist/cjs/mixins/OxyServices.utility.js +156 -0
  55. package/dist/cjs/mixins/index.js +79 -0
  56. package/dist/cjs/mixins/mixinHelpers.js +53 -0
  57. package/dist/cjs/models/interfaces.js +20 -0
  58. package/dist/cjs/models/session.js +2 -0
  59. package/dist/cjs/shared/index.js +70 -0
  60. package/dist/cjs/shared/utils/colorUtils.js +153 -0
  61. package/dist/cjs/shared/utils/debugUtils.js +73 -0
  62. package/dist/cjs/shared/utils/errorUtils.js +183 -0
  63. package/dist/cjs/shared/utils/index.js +49 -0
  64. package/dist/cjs/shared/utils/networkUtils.js +183 -0
  65. package/dist/cjs/shared/utils/themeUtils.js +106 -0
  66. package/dist/cjs/utils/apiUtils.js +61 -0
  67. package/dist/cjs/utils/asyncUtils.js +194 -0
  68. package/dist/cjs/utils/cache.js +226 -0
  69. package/dist/cjs/utils/deviceManager.js +205 -0
  70. package/dist/cjs/utils/errorUtils.js +154 -0
  71. package/dist/cjs/utils/index.js +26 -0
  72. package/dist/cjs/utils/languageUtils.js +165 -0
  73. package/dist/cjs/utils/loggerUtils.js +126 -0
  74. package/dist/cjs/utils/platform.js +144 -0
  75. package/dist/cjs/utils/requestUtils.js +209 -0
  76. package/dist/cjs/utils/sessionUtils.js +181 -0
  77. package/dist/cjs/utils/validationUtils.js +173 -0
  78. package/dist/esm/AuthManager.js +356 -0
  79. package/dist/esm/CrossDomainAuth.js +253 -0
  80. package/dist/esm/HttpService.js +614 -0
  81. package/dist/esm/OxyServices.base.js +259 -0
  82. package/dist/esm/OxyServices.errors.js +17 -0
  83. package/dist/esm/OxyServices.js +59 -0
  84. package/dist/esm/constants/version.js +13 -0
  85. package/dist/esm/crypto/index.js +13 -0
  86. package/dist/esm/crypto/keyManager.js +850 -0
  87. package/dist/esm/crypto/polyfill.js +61 -0
  88. package/dist/esm/crypto/recoveryPhrase.js +132 -0
  89. package/dist/esm/crypto/signatureService.js +259 -0
  90. package/dist/esm/i18n/index.js +69 -0
  91. package/dist/esm/i18n/locales/ar-SA.json +120 -0
  92. package/dist/esm/i18n/locales/ca-ES.json +120 -0
  93. package/dist/esm/i18n/locales/de-DE.json +120 -0
  94. package/dist/esm/i18n/locales/en-US.json +956 -0
  95. package/dist/esm/i18n/locales/es-ES.json +944 -0
  96. package/dist/esm/i18n/locales/fr-FR.json +120 -0
  97. package/dist/esm/i18n/locales/it-IT.json +120 -0
  98. package/dist/esm/i18n/locales/ja-JP.json +119 -0
  99. package/dist/esm/i18n/locales/ko-KR.json +120 -0
  100. package/dist/esm/i18n/locales/locales/ar-SA.json +120 -0
  101. package/dist/esm/i18n/locales/locales/ca-ES.json +120 -0
  102. package/dist/esm/i18n/locales/locales/de-DE.json +120 -0
  103. package/dist/esm/i18n/locales/locales/en-US.json +956 -0
  104. package/dist/esm/i18n/locales/locales/es-ES.json +944 -0
  105. package/dist/esm/i18n/locales/locales/fr-FR.json +120 -0
  106. package/dist/esm/i18n/locales/locales/it-IT.json +120 -0
  107. package/dist/esm/i18n/locales/locales/ja-JP.json +119 -0
  108. package/dist/esm/i18n/locales/locales/ko-KR.json +120 -0
  109. package/dist/esm/i18n/locales/locales/pt-PT.json +120 -0
  110. package/dist/esm/i18n/locales/locales/zh-CN.json +120 -0
  111. package/dist/esm/i18n/locales/pt-PT.json +120 -0
  112. package/dist/esm/i18n/locales/zh-CN.json +120 -0
  113. package/dist/esm/index.js +55 -0
  114. package/dist/esm/mixins/OxyServices.analytics.js +46 -0
  115. package/dist/esm/mixins/OxyServices.assets.js +377 -0
  116. package/dist/esm/mixins/OxyServices.auth.js +256 -0
  117. package/dist/esm/mixins/OxyServices.developer.js +94 -0
  118. package/dist/esm/mixins/OxyServices.devices.js +113 -0
  119. package/dist/esm/mixins/OxyServices.features.js +306 -0
  120. package/dist/esm/mixins/OxyServices.fedcm.js +433 -0
  121. package/dist/esm/mixins/OxyServices.karma.js +105 -0
  122. package/dist/esm/mixins/OxyServices.language.js +118 -0
  123. package/dist/esm/mixins/OxyServices.location.js +40 -0
  124. package/dist/esm/mixins/OxyServices.payment.js +155 -0
  125. package/dist/esm/mixins/OxyServices.popup.js +369 -0
  126. package/dist/esm/mixins/OxyServices.privacy.js +159 -0
  127. package/dist/esm/mixins/OxyServices.redirect.js +343 -0
  128. package/dist/esm/mixins/OxyServices.security.js +78 -0
  129. package/dist/esm/mixins/OxyServices.user.js +352 -0
  130. package/dist/esm/mixins/OxyServices.utility.js +153 -0
  131. package/dist/esm/mixins/index.js +76 -0
  132. package/dist/esm/mixins/mixinHelpers.js +48 -0
  133. package/dist/esm/models/interfaces.js +17 -0
  134. package/dist/esm/models/session.js +1 -0
  135. package/dist/esm/shared/index.js +31 -0
  136. package/dist/esm/shared/utils/colorUtils.js +143 -0
  137. package/dist/esm/shared/utils/debugUtils.js +65 -0
  138. package/dist/esm/shared/utils/errorUtils.js +170 -0
  139. package/dist/esm/shared/utils/index.js +15 -0
  140. package/dist/esm/shared/utils/networkUtils.js +173 -0
  141. package/dist/esm/shared/utils/themeUtils.js +98 -0
  142. package/dist/esm/utils/apiUtils.js +55 -0
  143. package/dist/esm/utils/asyncUtils.js +179 -0
  144. package/dist/esm/utils/cache.js +218 -0
  145. package/dist/esm/utils/deviceManager.js +168 -0
  146. package/dist/esm/utils/errorUtils.js +146 -0
  147. package/dist/esm/utils/index.js +7 -0
  148. package/dist/esm/utils/languageUtils.js +158 -0
  149. package/dist/esm/utils/loggerUtils.js +115 -0
  150. package/dist/esm/utils/platform.js +102 -0
  151. package/dist/esm/utils/requestUtils.js +203 -0
  152. package/dist/esm/utils/sessionUtils.js +171 -0
  153. package/dist/esm/utils/validationUtils.js +153 -0
  154. package/dist/types/AuthManager.d.ts +143 -0
  155. package/dist/types/CrossDomainAuth.d.ts +160 -0
  156. package/dist/types/HttpService.d.ts +163 -0
  157. package/dist/types/OxyServices.base.d.ts +126 -0
  158. package/dist/types/OxyServices.d.ts +81 -0
  159. package/dist/types/OxyServices.errors.d.ts +11 -0
  160. package/dist/types/constants/version.d.ts +13 -0
  161. package/dist/types/crypto/index.d.ts +11 -0
  162. package/dist/types/crypto/keyManager.d.ts +189 -0
  163. package/dist/types/crypto/polyfill.d.ts +11 -0
  164. package/dist/types/crypto/recoveryPhrase.d.ts +58 -0
  165. package/dist/types/crypto/signatureService.d.ts +86 -0
  166. package/dist/types/i18n/index.d.ts +3 -0
  167. package/dist/types/index.d.ts +50 -0
  168. package/dist/types/mixins/OxyServices.analytics.d.ts +66 -0
  169. package/dist/types/mixins/OxyServices.assets.d.ts +135 -0
  170. package/dist/types/mixins/OxyServices.auth.d.ts +186 -0
  171. package/dist/types/mixins/OxyServices.developer.d.ts +99 -0
  172. package/dist/types/mixins/OxyServices.devices.d.ts +96 -0
  173. package/dist/types/mixins/OxyServices.features.d.ts +228 -0
  174. package/dist/types/mixins/OxyServices.fedcm.d.ts +200 -0
  175. package/dist/types/mixins/OxyServices.karma.d.ts +85 -0
  176. package/dist/types/mixins/OxyServices.language.d.ts +81 -0
  177. package/dist/types/mixins/OxyServices.location.d.ts +64 -0
  178. package/dist/types/mixins/OxyServices.payment.d.ts +111 -0
  179. package/dist/types/mixins/OxyServices.popup.d.ts +205 -0
  180. package/dist/types/mixins/OxyServices.privacy.d.ts +122 -0
  181. package/dist/types/mixins/OxyServices.redirect.d.ts +245 -0
  182. package/dist/types/mixins/OxyServices.security.d.ts +78 -0
  183. package/dist/types/mixins/OxyServices.user.d.ts +182 -0
  184. package/dist/types/mixins/OxyServices.utility.d.ts +93 -0
  185. package/dist/types/mixins/index.d.ts +30 -0
  186. package/dist/types/mixins/mixinHelpers.d.ts +31 -0
  187. package/dist/types/models/interfaces.d.ts +415 -0
  188. package/dist/types/models/session.d.ts +27 -0
  189. package/dist/types/shared/index.d.ts +28 -0
  190. package/dist/types/shared/utils/colorUtils.d.ts +104 -0
  191. package/dist/types/shared/utils/debugUtils.d.ts +48 -0
  192. package/dist/types/shared/utils/errorUtils.d.ts +97 -0
  193. package/dist/types/shared/utils/index.d.ts +13 -0
  194. package/dist/types/shared/utils/networkUtils.d.ts +139 -0
  195. package/dist/types/shared/utils/themeUtils.d.ts +90 -0
  196. package/dist/types/utils/apiUtils.d.ts +53 -0
  197. package/dist/types/utils/asyncUtils.d.ts +58 -0
  198. package/dist/types/utils/cache.d.ts +127 -0
  199. package/dist/types/utils/deviceManager.d.ts +65 -0
  200. package/dist/types/utils/errorUtils.d.ts +46 -0
  201. package/dist/types/utils/index.d.ts +6 -0
  202. package/dist/types/utils/languageUtils.d.ts +37 -0
  203. package/dist/types/utils/loggerUtils.d.ts +48 -0
  204. package/dist/types/utils/platform.d.ts +40 -0
  205. package/dist/types/utils/requestUtils.d.ts +123 -0
  206. package/dist/types/utils/sessionUtils.d.ts +54 -0
  207. package/dist/types/utils/validationUtils.d.ts +85 -0
  208. package/package.json +84 -0
  209. package/src/AuthManager.ts +436 -0
  210. package/src/CrossDomainAuth.ts +307 -0
  211. package/src/HttpService.ts +752 -0
  212. package/src/OxyServices.base.ts +334 -0
  213. package/src/OxyServices.errors.ts +26 -0
  214. package/src/OxyServices.ts +129 -0
  215. package/src/constants/version.ts +15 -0
  216. package/src/crypto/index.ts +25 -0
  217. package/src/crypto/keyManager.ts +962 -0
  218. package/src/crypto/polyfill.ts +70 -0
  219. package/src/crypto/recoveryPhrase.ts +166 -0
  220. package/src/crypto/signatureService.ts +323 -0
  221. package/src/i18n/index.ts +75 -0
  222. package/src/i18n/locales/ar-SA.json +120 -0
  223. package/src/i18n/locales/ca-ES.json +120 -0
  224. package/src/i18n/locales/de-DE.json +120 -0
  225. package/src/i18n/locales/en-US.json +956 -0
  226. package/src/i18n/locales/es-ES.json +944 -0
  227. package/src/i18n/locales/fr-FR.json +120 -0
  228. package/src/i18n/locales/it-IT.json +120 -0
  229. package/src/i18n/locales/ja-JP.json +119 -0
  230. package/src/i18n/locales/ko-KR.json +120 -0
  231. package/src/i18n/locales/pt-PT.json +120 -0
  232. package/src/i18n/locales/zh-CN.json +120 -0
  233. package/src/index.ts +153 -0
  234. package/src/mixins/OxyServices.analytics.ts +53 -0
  235. package/src/mixins/OxyServices.assets.ts +412 -0
  236. package/src/mixins/OxyServices.auth.ts +358 -0
  237. package/src/mixins/OxyServices.developer.ts +114 -0
  238. package/src/mixins/OxyServices.devices.ts +119 -0
  239. package/src/mixins/OxyServices.features.ts +428 -0
  240. package/src/mixins/OxyServices.fedcm.ts +494 -0
  241. package/src/mixins/OxyServices.karma.ts +111 -0
  242. package/src/mixins/OxyServices.language.ts +127 -0
  243. package/src/mixins/OxyServices.location.ts +46 -0
  244. package/src/mixins/OxyServices.payment.ts +163 -0
  245. package/src/mixins/OxyServices.popup.ts +443 -0
  246. package/src/mixins/OxyServices.privacy.ts +182 -0
  247. package/src/mixins/OxyServices.redirect.ts +397 -0
  248. package/src/mixins/OxyServices.security.ts +103 -0
  249. package/src/mixins/OxyServices.user.ts +392 -0
  250. package/src/mixins/OxyServices.utility.ts +191 -0
  251. package/src/mixins/index.ts +91 -0
  252. package/src/mixins/mixinHelpers.ts +69 -0
  253. package/src/models/interfaces.ts +511 -0
  254. package/src/models/session.ts +30 -0
  255. package/src/shared/index.ts +82 -0
  256. package/src/shared/utils/colorUtils.ts +155 -0
  257. package/src/shared/utils/debugUtils.ts +73 -0
  258. package/src/shared/utils/errorUtils.ts +181 -0
  259. package/src/shared/utils/index.ts +59 -0
  260. package/src/shared/utils/networkUtils.ts +248 -0
  261. package/src/shared/utils/themeUtils.ts +115 -0
  262. package/src/types/bip39.d.ts +32 -0
  263. package/src/types/buffer.d.ts +97 -0
  264. package/src/types/color.d.ts +20 -0
  265. package/src/types/elliptic.d.ts +62 -0
  266. package/src/utils/apiUtils.ts +88 -0
  267. package/src/utils/asyncUtils.ts +252 -0
  268. package/src/utils/cache.ts +264 -0
  269. package/src/utils/deviceManager.ts +198 -0
  270. package/src/utils/errorUtils.ts +216 -0
  271. package/src/utils/index.ts +21 -0
  272. package/src/utils/languageUtils.ts +174 -0
  273. package/src/utils/loggerUtils.ts +153 -0
  274. package/src/utils/platform.ts +117 -0
  275. package/src/utils/requestUtils.ts +237 -0
  276. package/src/utils/sessionUtils.ts +206 -0
  277. package/src/utils/validationUtils.ts +174 -0
@@ -0,0 +1,345 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OxyServicesRedirectAuthMixin = OxyServicesRedirectAuthMixin;
4
+ exports.RedirectAuthMixin = OxyServicesRedirectAuthMixin;
5
+ const OxyServices_errors_1 = require("../OxyServices.errors");
6
+ /**
7
+ * Redirect-based Cross-Domain Authentication Mixin
8
+ *
9
+ * Implements traditional OAuth2 redirect flow as a fallback when popup or
10
+ * FedCM are not available or fail (e.g., mobile browsers, popup blockers).
11
+ *
12
+ * Flow:
13
+ * 1. Save current URL
14
+ * 2. Redirect to auth.oxy.so/login
15
+ * 3. User signs in
16
+ * 4. Redirect back with token in URL
17
+ * 5. Extract token, restore session, clean URL
18
+ *
19
+ * Features:
20
+ * - Works on all browsers (including old mobile browsers)
21
+ * - Automatic URL cleanup after auth
22
+ * - State preservation option
23
+ * - CSRF protection via state parameter
24
+ *
25
+ * Trade-offs:
26
+ * - Loses JavaScript app state (full page navigation)
27
+ * - Visible redirect (user sees navigation)
28
+ * - Slower perceived performance
29
+ */
30
+ function OxyServicesRedirectAuthMixin(Base) {
31
+ var _a;
32
+ return _a = class extends Base {
33
+ constructor(...args) {
34
+ super(...args);
35
+ }
36
+ /**
37
+ * Sign in using full page redirect
38
+ *
39
+ * Redirects the user to auth.oxy.so for authentication. After successful
40
+ * sign-in, the user will be redirected back to the current page (or custom
41
+ * redirect URI) with authentication tokens in the URL.
42
+ *
43
+ * Call handleAuthCallback() on app startup to complete the flow.
44
+ *
45
+ * @param options - Redirect configuration options
46
+ *
47
+ * @example
48
+ * ```typescript
49
+ * // Initiate sign-in
50
+ * const handleSignIn = () => {
51
+ * oxyServices.signInWithRedirect();
52
+ * };
53
+ *
54
+ * // Handle callback on app startup
55
+ * useEffect(() => {
56
+ * const session = oxyServices.handleAuthCallback();
57
+ * if (session) {
58
+ * setUser(session.user);
59
+ * }
60
+ * }, []);
61
+ * ```
62
+ */
63
+ signInWithRedirect(options = {}) {
64
+ if (typeof window === 'undefined') {
65
+ throw new OxyServices_errors_1.OxyAuthenticationError('Redirect authentication requires browser environment');
66
+ }
67
+ const redirectUri = options.redirectUri || window.location.href;
68
+ const mode = options.mode || 'login';
69
+ const state = this.generateState();
70
+ const nonce = this.generateNonce();
71
+ // Store state for CSRF protection
72
+ this.storeAuthState(state, nonce);
73
+ // Save current URL to restore after auth (optional)
74
+ if (options.preserveUrl !== false) {
75
+ this.savePreAuthUrl(window.location.href);
76
+ }
77
+ const authUrl = this.buildAuthUrl({
78
+ mode,
79
+ redirectUri,
80
+ state,
81
+ nonce,
82
+ clientId: window.location.origin,
83
+ });
84
+ // Perform redirect
85
+ window.location.href = authUrl;
86
+ }
87
+ /**
88
+ * Sign up using full page redirect
89
+ *
90
+ * Same as signInWithRedirect but opens the signup page by default.
91
+ */
92
+ signUpWithRedirect(options = {}) {
93
+ this.signInWithRedirect({ ...options, mode: 'signup' });
94
+ }
95
+ /**
96
+ * Handle authentication callback
97
+ *
98
+ * Call this on app startup to check if the current page load is a
99
+ * redirect back from the authentication server. If it is, this method
100
+ * will extract the tokens, store them, and clean up the URL.
101
+ *
102
+ * @returns Session data if this is a callback, null otherwise
103
+ * @throws {OxyAuthenticationError} If state validation fails (CSRF attack)
104
+ *
105
+ * @example
106
+ * ```typescript
107
+ * // In your app's root component or startup logic
108
+ * useEffect(() => {
109
+ * try {
110
+ * const session = oxyServices.handleAuthCallback();
111
+ * if (session) {
112
+ * console.log('Logged in:', session.user);
113
+ * setUser(session.user);
114
+ * } else {
115
+ * // Not a callback, check for existing session
116
+ * const restored = oxyServices.restoreSession();
117
+ * if (!restored) {
118
+ * // No session, show login button
119
+ * }
120
+ * }
121
+ * } catch (error) {
122
+ * console.error('Auth callback failed:', error);
123
+ * }
124
+ * }, []);
125
+ * ```
126
+ */
127
+ handleAuthCallback() {
128
+ if (typeof window === 'undefined') {
129
+ return null;
130
+ }
131
+ const url = new URL(window.location.href);
132
+ const accessToken = url.searchParams.get('access_token');
133
+ const sessionId = url.searchParams.get('session_id');
134
+ const expiresAt = url.searchParams.get('expires_at');
135
+ const state = url.searchParams.get('state');
136
+ const error = url.searchParams.get('error');
137
+ const errorDescription = url.searchParams.get('error_description');
138
+ // Check if this is an error callback
139
+ if (error) {
140
+ this.clearAuthState();
141
+ throw new OxyServices_errors_1.OxyAuthenticationError(errorDescription || error);
142
+ }
143
+ // Check if this is an auth callback
144
+ if (!accessToken || !sessionId) {
145
+ return null; // Not a callback
146
+ }
147
+ // Verify state to prevent CSRF attacks
148
+ const savedState = this.getStoredState();
149
+ if (!savedState || state !== savedState) {
150
+ this.clearAuthState();
151
+ throw new OxyServices_errors_1.OxyAuthenticationError('Invalid state parameter. Possible CSRF attack.');
152
+ }
153
+ // Store tokens
154
+ this.storeTokens(accessToken, sessionId);
155
+ this.httpService.setTokens(accessToken);
156
+ // Build session response (minimal - we'll fetch full user data separately)
157
+ const session = {
158
+ sessionId,
159
+ deviceId: '', // Not available in redirect flow
160
+ expiresAt: expiresAt || new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(),
161
+ user: {}, // Will be fetched separately
162
+ };
163
+ // Clean up URL (remove auth parameters)
164
+ this.cleanAuthCallbackUrl(url);
165
+ // Clean up storage
166
+ this.clearAuthState();
167
+ return session;
168
+ }
169
+ /**
170
+ * Restore session from storage
171
+ *
172
+ * Attempts to restore a previously authenticated session from localStorage.
173
+ * Call this on app startup if handleAuthCallback() returns null.
174
+ *
175
+ * @returns True if session was restored, false otherwise
176
+ *
177
+ * @example
178
+ * ```typescript
179
+ * useEffect(() => {
180
+ * const session = oxyServices.handleAuthCallback();
181
+ * if (!session) {
182
+ * const restored = oxyServices.restoreSession();
183
+ * if (!restored) {
184
+ * // No session, user needs to sign in
185
+ * setShowLogin(true);
186
+ * }
187
+ * }
188
+ * }, []);
189
+ * ```
190
+ */
191
+ restoreSession() {
192
+ if (typeof window === 'undefined') {
193
+ return false;
194
+ }
195
+ const token = localStorage.getItem(this.constructor.TOKEN_STORAGE_KEY);
196
+ const sessionId = localStorage.getItem(this.constructor.SESSION_STORAGE_KEY);
197
+ if (token && sessionId) {
198
+ this.httpService.setTokens(token);
199
+ return true;
200
+ }
201
+ return false;
202
+ }
203
+ /**
204
+ * Clear stored session
205
+ *
206
+ * Removes all authentication data from storage. Call this on logout.
207
+ */
208
+ clearStoredSession() {
209
+ if (typeof window === 'undefined') {
210
+ return;
211
+ }
212
+ localStorage.removeItem(this.constructor.TOKEN_STORAGE_KEY);
213
+ localStorage.removeItem(this.constructor.SESSION_STORAGE_KEY);
214
+ this.httpService.clearTokens();
215
+ }
216
+ /**
217
+ * Get stored session ID
218
+ */
219
+ getStoredSessionId() {
220
+ if (typeof window === 'undefined') {
221
+ return null;
222
+ }
223
+ return localStorage.getItem(this.constructor.SESSION_STORAGE_KEY);
224
+ }
225
+ /**
226
+ * Build authentication URL with query parameters
227
+ *
228
+ * @private
229
+ */
230
+ buildAuthUrl(params) {
231
+ const url = new URL(`${this.constructor.AUTH_URL}/${params.mode}`);
232
+ url.searchParams.set('redirect_uri', params.redirectUri);
233
+ url.searchParams.set('state', params.state);
234
+ url.searchParams.set('nonce', params.nonce);
235
+ url.searchParams.set('client_id', params.clientId);
236
+ url.searchParams.set('response_type', 'token');
237
+ return url.toString();
238
+ }
239
+ /**
240
+ * Store tokens in localStorage
241
+ *
242
+ * @private
243
+ */
244
+ storeTokens(accessToken, sessionId) {
245
+ if (typeof window === 'undefined') {
246
+ return;
247
+ }
248
+ localStorage.setItem(this.constructor.TOKEN_STORAGE_KEY, accessToken);
249
+ localStorage.setItem(this.constructor.SESSION_STORAGE_KEY, sessionId);
250
+ }
251
+ /**
252
+ * Generate cryptographically secure state for CSRF protection
253
+ *
254
+ * @private
255
+ */
256
+ generateState() {
257
+ if (typeof window !== 'undefined' && window.crypto && window.crypto.randomUUID) {
258
+ return window.crypto.randomUUID();
259
+ }
260
+ return `${Date.now()}-${Math.random().toString(36).substring(2, 15)}`;
261
+ }
262
+ /**
263
+ * Generate nonce for replay attack prevention
264
+ *
265
+ * @private
266
+ */
267
+ generateNonce() {
268
+ if (typeof window !== 'undefined' && window.crypto && window.crypto.randomUUID) {
269
+ return window.crypto.randomUUID();
270
+ }
271
+ return `${Date.now()}-${Math.random().toString(36).substring(2, 15)}`;
272
+ }
273
+ /**
274
+ * Store auth state in session storage
275
+ *
276
+ * @private
277
+ */
278
+ storeAuthState(state, nonce) {
279
+ if (typeof window === 'undefined') {
280
+ return;
281
+ }
282
+ sessionStorage.setItem(this.constructor.STATE_STORAGE_KEY, state);
283
+ sessionStorage.setItem(this.constructor.NONCE_STORAGE_KEY, nonce);
284
+ }
285
+ /**
286
+ * Get stored state
287
+ *
288
+ * @private
289
+ */
290
+ getStoredState() {
291
+ if (typeof window === 'undefined') {
292
+ return null;
293
+ }
294
+ return sessionStorage.getItem(this.constructor.STATE_STORAGE_KEY);
295
+ }
296
+ /**
297
+ * Clear auth state from storage
298
+ *
299
+ * @private
300
+ */
301
+ clearAuthState() {
302
+ if (typeof window === 'undefined') {
303
+ return;
304
+ }
305
+ sessionStorage.removeItem(this.constructor.STATE_STORAGE_KEY);
306
+ sessionStorage.removeItem(this.constructor.NONCE_STORAGE_KEY);
307
+ sessionStorage.removeItem(this.constructor.PRE_AUTH_URL_KEY);
308
+ }
309
+ /**
310
+ * Save pre-authentication URL to restore later
311
+ *
312
+ * @private
313
+ */
314
+ savePreAuthUrl(url) {
315
+ if (typeof window === 'undefined') {
316
+ return;
317
+ }
318
+ sessionStorage.setItem(this.constructor.PRE_AUTH_URL_KEY, url);
319
+ }
320
+ /**
321
+ * Clean authentication parameters from URL
322
+ *
323
+ * @private
324
+ */
325
+ cleanAuthCallbackUrl(url) {
326
+ // Remove auth parameters
327
+ url.searchParams.delete('access_token');
328
+ url.searchParams.delete('session_id');
329
+ url.searchParams.delete('expires_at');
330
+ url.searchParams.delete('state');
331
+ url.searchParams.delete('nonce');
332
+ url.searchParams.delete('error');
333
+ url.searchParams.delete('error_description');
334
+ // Update URL without reloading page
335
+ window.history.replaceState({}, '', url.toString());
336
+ }
337
+ },
338
+ _a.AUTH_URL = 'https://auth.oxy.so',
339
+ _a.TOKEN_STORAGE_KEY = 'oxy_access_token',
340
+ _a.SESSION_STORAGE_KEY = 'oxy_session_id',
341
+ _a.STATE_STORAGE_KEY = 'oxy_auth_state',
342
+ _a.PRE_AUTH_URL_KEY = 'oxy_pre_auth_url',
343
+ _a.NONCE_STORAGE_KEY = 'oxy_auth_nonce',
344
+ _a;
345
+ }
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OxyServicesSecurityMixin = OxyServicesSecurityMixin;
4
+ function OxyServicesSecurityMixin(Base) {
5
+ return class extends Base {
6
+ constructor(...args) {
7
+ super(...args);
8
+ }
9
+ /**
10
+ * Get user's security activity with pagination
11
+ * @param limit - Number of results (default: 50, max: 100)
12
+ * @param offset - Pagination offset (default: 0)
13
+ * @param eventType - Optional filter by event type
14
+ * @returns Security activity response with pagination
15
+ */
16
+ async getSecurityActivity(limit, offset, eventType) {
17
+ try {
18
+ const params = {};
19
+ if (limit !== undefined)
20
+ params.limit = limit;
21
+ if (offset !== undefined)
22
+ params.offset = offset;
23
+ if (eventType)
24
+ params.eventType = eventType;
25
+ const response = await this.makeRequest('GET', '/api/security/activity', params, { cache: false });
26
+ return response;
27
+ }
28
+ catch (error) {
29
+ throw this.handleError(error);
30
+ }
31
+ }
32
+ /**
33
+ * Get recent security activity (convenience method)
34
+ * @param limit - Number of recent events to fetch (default: 10)
35
+ * @returns Array of recent security activities
36
+ */
37
+ async getRecentSecurityActivity(limit = 10) {
38
+ try {
39
+ const response = await this.getSecurityActivity(limit, 0);
40
+ return response.data || [];
41
+ }
42
+ catch (error) {
43
+ throw this.handleError(error);
44
+ }
45
+ }
46
+ /**
47
+ * Log private key exported event
48
+ * @param deviceId - Optional device ID for tracking
49
+ * @returns Promise that resolves when event is logged
50
+ */
51
+ async logPrivateKeyExported(deviceId) {
52
+ try {
53
+ await this.makeRequest('POST', '/api/security/activity/private-key-exported', { deviceId }, { cache: false });
54
+ }
55
+ catch (error) {
56
+ // Don't throw - logging failures shouldn't break user flow
57
+ // But log for monitoring
58
+ if (__DEV__) {
59
+ console.warn('[OxyServices] Failed to log private key exported event:', error);
60
+ }
61
+ }
62
+ }
63
+ /**
64
+ * Log backup created event
65
+ * @param deviceId - Optional device ID for tracking
66
+ * @returns Promise that resolves when event is logged
67
+ */
68
+ async logBackupCreated(deviceId) {
69
+ try {
70
+ await this.makeRequest('POST', '/api/security/activity/backup-created', { deviceId }, { cache: false });
71
+ }
72
+ catch (error) {
73
+ // Don't throw - logging failures shouldn't break user flow
74
+ // But log for monitoring
75
+ if (__DEV__) {
76
+ console.warn('[OxyServices] Failed to log backup created event:', error);
77
+ }
78
+ }
79
+ }
80
+ };
81
+ }