@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.
- package/README.md +50 -0
- package/dist/cjs/AuthManager.js +361 -0
- package/dist/cjs/CrossDomainAuth.js +258 -0
- package/dist/cjs/HttpService.js +618 -0
- package/dist/cjs/OxyServices.base.js +263 -0
- package/dist/cjs/OxyServices.errors.js +22 -0
- package/dist/cjs/OxyServices.js +63 -0
- package/dist/cjs/constants/version.js +16 -0
- package/dist/cjs/crypto/index.js +20 -0
- package/dist/cjs/crypto/keyManager.js +887 -0
- package/dist/cjs/crypto/polyfill.js +64 -0
- package/dist/cjs/crypto/recoveryPhrase.js +169 -0
- package/dist/cjs/crypto/signatureService.js +296 -0
- package/dist/cjs/i18n/index.js +73 -0
- package/dist/cjs/i18n/locales/ar-SA.json +120 -0
- package/dist/cjs/i18n/locales/ca-ES.json +120 -0
- package/dist/cjs/i18n/locales/de-DE.json +120 -0
- package/dist/cjs/i18n/locales/en-US.json +956 -0
- package/dist/cjs/i18n/locales/es-ES.json +944 -0
- package/dist/cjs/i18n/locales/fr-FR.json +120 -0
- package/dist/cjs/i18n/locales/it-IT.json +120 -0
- package/dist/cjs/i18n/locales/ja-JP.json +119 -0
- package/dist/cjs/i18n/locales/ko-KR.json +120 -0
- package/dist/cjs/i18n/locales/locales/ar-SA.json +120 -0
- package/dist/cjs/i18n/locales/locales/ca-ES.json +120 -0
- package/dist/cjs/i18n/locales/locales/de-DE.json +120 -0
- package/dist/cjs/i18n/locales/locales/en-US.json +956 -0
- package/dist/cjs/i18n/locales/locales/es-ES.json +944 -0
- package/dist/cjs/i18n/locales/locales/fr-FR.json +120 -0
- package/dist/cjs/i18n/locales/locales/it-IT.json +120 -0
- package/dist/cjs/i18n/locales/locales/ja-JP.json +119 -0
- package/dist/cjs/i18n/locales/locales/ko-KR.json +120 -0
- package/dist/cjs/i18n/locales/locales/pt-PT.json +120 -0
- package/dist/cjs/i18n/locales/locales/zh-CN.json +120 -0
- package/dist/cjs/i18n/locales/pt-PT.json +120 -0
- package/dist/cjs/i18n/locales/zh-CN.json +120 -0
- package/dist/cjs/index.js +153 -0
- package/dist/cjs/mixins/OxyServices.analytics.js +49 -0
- package/dist/cjs/mixins/OxyServices.assets.js +380 -0
- package/dist/cjs/mixins/OxyServices.auth.js +259 -0
- package/dist/cjs/mixins/OxyServices.developer.js +97 -0
- package/dist/cjs/mixins/OxyServices.devices.js +116 -0
- package/dist/cjs/mixins/OxyServices.features.js +309 -0
- package/dist/cjs/mixins/OxyServices.fedcm.js +435 -0
- package/dist/cjs/mixins/OxyServices.karma.js +108 -0
- package/dist/cjs/mixins/OxyServices.language.js +154 -0
- package/dist/cjs/mixins/OxyServices.location.js +43 -0
- package/dist/cjs/mixins/OxyServices.payment.js +158 -0
- package/dist/cjs/mixins/OxyServices.popup.js +371 -0
- package/dist/cjs/mixins/OxyServices.privacy.js +162 -0
- package/dist/cjs/mixins/OxyServices.redirect.js +345 -0
- package/dist/cjs/mixins/OxyServices.security.js +81 -0
- package/dist/cjs/mixins/OxyServices.user.js +355 -0
- package/dist/cjs/mixins/OxyServices.utility.js +156 -0
- package/dist/cjs/mixins/index.js +79 -0
- package/dist/cjs/mixins/mixinHelpers.js +53 -0
- package/dist/cjs/models/interfaces.js +20 -0
- package/dist/cjs/models/session.js +2 -0
- package/dist/cjs/shared/index.js +70 -0
- package/dist/cjs/shared/utils/colorUtils.js +153 -0
- package/dist/cjs/shared/utils/debugUtils.js +73 -0
- package/dist/cjs/shared/utils/errorUtils.js +183 -0
- package/dist/cjs/shared/utils/index.js +49 -0
- package/dist/cjs/shared/utils/networkUtils.js +183 -0
- package/dist/cjs/shared/utils/themeUtils.js +106 -0
- package/dist/cjs/utils/apiUtils.js +61 -0
- package/dist/cjs/utils/asyncUtils.js +194 -0
- package/dist/cjs/utils/cache.js +226 -0
- package/dist/cjs/utils/deviceManager.js +205 -0
- package/dist/cjs/utils/errorUtils.js +154 -0
- package/dist/cjs/utils/index.js +26 -0
- package/dist/cjs/utils/languageUtils.js +165 -0
- package/dist/cjs/utils/loggerUtils.js +126 -0
- package/dist/cjs/utils/platform.js +144 -0
- package/dist/cjs/utils/requestUtils.js +209 -0
- package/dist/cjs/utils/sessionUtils.js +181 -0
- package/dist/cjs/utils/validationUtils.js +173 -0
- package/dist/esm/AuthManager.js +356 -0
- package/dist/esm/CrossDomainAuth.js +253 -0
- package/dist/esm/HttpService.js +614 -0
- package/dist/esm/OxyServices.base.js +259 -0
- package/dist/esm/OxyServices.errors.js +17 -0
- package/dist/esm/OxyServices.js +59 -0
- package/dist/esm/constants/version.js +13 -0
- package/dist/esm/crypto/index.js +13 -0
- package/dist/esm/crypto/keyManager.js +850 -0
- package/dist/esm/crypto/polyfill.js +61 -0
- package/dist/esm/crypto/recoveryPhrase.js +132 -0
- package/dist/esm/crypto/signatureService.js +259 -0
- package/dist/esm/i18n/index.js +69 -0
- package/dist/esm/i18n/locales/ar-SA.json +120 -0
- package/dist/esm/i18n/locales/ca-ES.json +120 -0
- package/dist/esm/i18n/locales/de-DE.json +120 -0
- package/dist/esm/i18n/locales/en-US.json +956 -0
- package/dist/esm/i18n/locales/es-ES.json +944 -0
- package/dist/esm/i18n/locales/fr-FR.json +120 -0
- package/dist/esm/i18n/locales/it-IT.json +120 -0
- package/dist/esm/i18n/locales/ja-JP.json +119 -0
- package/dist/esm/i18n/locales/ko-KR.json +120 -0
- package/dist/esm/i18n/locales/locales/ar-SA.json +120 -0
- package/dist/esm/i18n/locales/locales/ca-ES.json +120 -0
- package/dist/esm/i18n/locales/locales/de-DE.json +120 -0
- package/dist/esm/i18n/locales/locales/en-US.json +956 -0
- package/dist/esm/i18n/locales/locales/es-ES.json +944 -0
- package/dist/esm/i18n/locales/locales/fr-FR.json +120 -0
- package/dist/esm/i18n/locales/locales/it-IT.json +120 -0
- package/dist/esm/i18n/locales/locales/ja-JP.json +119 -0
- package/dist/esm/i18n/locales/locales/ko-KR.json +120 -0
- package/dist/esm/i18n/locales/locales/pt-PT.json +120 -0
- package/dist/esm/i18n/locales/locales/zh-CN.json +120 -0
- package/dist/esm/i18n/locales/pt-PT.json +120 -0
- package/dist/esm/i18n/locales/zh-CN.json +120 -0
- package/dist/esm/index.js +55 -0
- package/dist/esm/mixins/OxyServices.analytics.js +46 -0
- package/dist/esm/mixins/OxyServices.assets.js +377 -0
- package/dist/esm/mixins/OxyServices.auth.js +256 -0
- package/dist/esm/mixins/OxyServices.developer.js +94 -0
- package/dist/esm/mixins/OxyServices.devices.js +113 -0
- package/dist/esm/mixins/OxyServices.features.js +306 -0
- package/dist/esm/mixins/OxyServices.fedcm.js +433 -0
- package/dist/esm/mixins/OxyServices.karma.js +105 -0
- package/dist/esm/mixins/OxyServices.language.js +118 -0
- package/dist/esm/mixins/OxyServices.location.js +40 -0
- package/dist/esm/mixins/OxyServices.payment.js +155 -0
- package/dist/esm/mixins/OxyServices.popup.js +369 -0
- package/dist/esm/mixins/OxyServices.privacy.js +159 -0
- package/dist/esm/mixins/OxyServices.redirect.js +343 -0
- package/dist/esm/mixins/OxyServices.security.js +78 -0
- package/dist/esm/mixins/OxyServices.user.js +352 -0
- package/dist/esm/mixins/OxyServices.utility.js +153 -0
- package/dist/esm/mixins/index.js +76 -0
- package/dist/esm/mixins/mixinHelpers.js +48 -0
- package/dist/esm/models/interfaces.js +17 -0
- package/dist/esm/models/session.js +1 -0
- package/dist/esm/shared/index.js +31 -0
- package/dist/esm/shared/utils/colorUtils.js +143 -0
- package/dist/esm/shared/utils/debugUtils.js +65 -0
- package/dist/esm/shared/utils/errorUtils.js +170 -0
- package/dist/esm/shared/utils/index.js +15 -0
- package/dist/esm/shared/utils/networkUtils.js +173 -0
- package/dist/esm/shared/utils/themeUtils.js +98 -0
- package/dist/esm/utils/apiUtils.js +55 -0
- package/dist/esm/utils/asyncUtils.js +179 -0
- package/dist/esm/utils/cache.js +218 -0
- package/dist/esm/utils/deviceManager.js +168 -0
- package/dist/esm/utils/errorUtils.js +146 -0
- package/dist/esm/utils/index.js +7 -0
- package/dist/esm/utils/languageUtils.js +158 -0
- package/dist/esm/utils/loggerUtils.js +115 -0
- package/dist/esm/utils/platform.js +102 -0
- package/dist/esm/utils/requestUtils.js +203 -0
- package/dist/esm/utils/sessionUtils.js +171 -0
- package/dist/esm/utils/validationUtils.js +153 -0
- package/dist/types/AuthManager.d.ts +143 -0
- package/dist/types/CrossDomainAuth.d.ts +160 -0
- package/dist/types/HttpService.d.ts +163 -0
- package/dist/types/OxyServices.base.d.ts +126 -0
- package/dist/types/OxyServices.d.ts +81 -0
- package/dist/types/OxyServices.errors.d.ts +11 -0
- package/dist/types/constants/version.d.ts +13 -0
- package/dist/types/crypto/index.d.ts +11 -0
- package/dist/types/crypto/keyManager.d.ts +189 -0
- package/dist/types/crypto/polyfill.d.ts +11 -0
- package/dist/types/crypto/recoveryPhrase.d.ts +58 -0
- package/dist/types/crypto/signatureService.d.ts +86 -0
- package/dist/types/i18n/index.d.ts +3 -0
- package/dist/types/index.d.ts +50 -0
- package/dist/types/mixins/OxyServices.analytics.d.ts +66 -0
- package/dist/types/mixins/OxyServices.assets.d.ts +135 -0
- package/dist/types/mixins/OxyServices.auth.d.ts +186 -0
- package/dist/types/mixins/OxyServices.developer.d.ts +99 -0
- package/dist/types/mixins/OxyServices.devices.d.ts +96 -0
- package/dist/types/mixins/OxyServices.features.d.ts +228 -0
- package/dist/types/mixins/OxyServices.fedcm.d.ts +200 -0
- package/dist/types/mixins/OxyServices.karma.d.ts +85 -0
- package/dist/types/mixins/OxyServices.language.d.ts +81 -0
- package/dist/types/mixins/OxyServices.location.d.ts +64 -0
- package/dist/types/mixins/OxyServices.payment.d.ts +111 -0
- package/dist/types/mixins/OxyServices.popup.d.ts +205 -0
- package/dist/types/mixins/OxyServices.privacy.d.ts +122 -0
- package/dist/types/mixins/OxyServices.redirect.d.ts +245 -0
- package/dist/types/mixins/OxyServices.security.d.ts +78 -0
- package/dist/types/mixins/OxyServices.user.d.ts +182 -0
- package/dist/types/mixins/OxyServices.utility.d.ts +93 -0
- package/dist/types/mixins/index.d.ts +30 -0
- package/dist/types/mixins/mixinHelpers.d.ts +31 -0
- package/dist/types/models/interfaces.d.ts +415 -0
- package/dist/types/models/session.d.ts +27 -0
- package/dist/types/shared/index.d.ts +28 -0
- package/dist/types/shared/utils/colorUtils.d.ts +104 -0
- package/dist/types/shared/utils/debugUtils.d.ts +48 -0
- package/dist/types/shared/utils/errorUtils.d.ts +97 -0
- package/dist/types/shared/utils/index.d.ts +13 -0
- package/dist/types/shared/utils/networkUtils.d.ts +139 -0
- package/dist/types/shared/utils/themeUtils.d.ts +90 -0
- package/dist/types/utils/apiUtils.d.ts +53 -0
- package/dist/types/utils/asyncUtils.d.ts +58 -0
- package/dist/types/utils/cache.d.ts +127 -0
- package/dist/types/utils/deviceManager.d.ts +65 -0
- package/dist/types/utils/errorUtils.d.ts +46 -0
- package/dist/types/utils/index.d.ts +6 -0
- package/dist/types/utils/languageUtils.d.ts +37 -0
- package/dist/types/utils/loggerUtils.d.ts +48 -0
- package/dist/types/utils/platform.d.ts +40 -0
- package/dist/types/utils/requestUtils.d.ts +123 -0
- package/dist/types/utils/sessionUtils.d.ts +54 -0
- package/dist/types/utils/validationUtils.d.ts +85 -0
- package/package.json +84 -0
- package/src/AuthManager.ts +436 -0
- package/src/CrossDomainAuth.ts +307 -0
- package/src/HttpService.ts +752 -0
- package/src/OxyServices.base.ts +334 -0
- package/src/OxyServices.errors.ts +26 -0
- package/src/OxyServices.ts +129 -0
- package/src/constants/version.ts +15 -0
- package/src/crypto/index.ts +25 -0
- package/src/crypto/keyManager.ts +962 -0
- package/src/crypto/polyfill.ts +70 -0
- package/src/crypto/recoveryPhrase.ts +166 -0
- package/src/crypto/signatureService.ts +323 -0
- package/src/i18n/index.ts +75 -0
- package/src/i18n/locales/ar-SA.json +120 -0
- package/src/i18n/locales/ca-ES.json +120 -0
- package/src/i18n/locales/de-DE.json +120 -0
- package/src/i18n/locales/en-US.json +956 -0
- package/src/i18n/locales/es-ES.json +944 -0
- package/src/i18n/locales/fr-FR.json +120 -0
- package/src/i18n/locales/it-IT.json +120 -0
- package/src/i18n/locales/ja-JP.json +119 -0
- package/src/i18n/locales/ko-KR.json +120 -0
- package/src/i18n/locales/pt-PT.json +120 -0
- package/src/i18n/locales/zh-CN.json +120 -0
- package/src/index.ts +153 -0
- package/src/mixins/OxyServices.analytics.ts +53 -0
- package/src/mixins/OxyServices.assets.ts +412 -0
- package/src/mixins/OxyServices.auth.ts +358 -0
- package/src/mixins/OxyServices.developer.ts +114 -0
- package/src/mixins/OxyServices.devices.ts +119 -0
- package/src/mixins/OxyServices.features.ts +428 -0
- package/src/mixins/OxyServices.fedcm.ts +494 -0
- package/src/mixins/OxyServices.karma.ts +111 -0
- package/src/mixins/OxyServices.language.ts +127 -0
- package/src/mixins/OxyServices.location.ts +46 -0
- package/src/mixins/OxyServices.payment.ts +163 -0
- package/src/mixins/OxyServices.popup.ts +443 -0
- package/src/mixins/OxyServices.privacy.ts +182 -0
- package/src/mixins/OxyServices.redirect.ts +397 -0
- package/src/mixins/OxyServices.security.ts +103 -0
- package/src/mixins/OxyServices.user.ts +392 -0
- package/src/mixins/OxyServices.utility.ts +191 -0
- package/src/mixins/index.ts +91 -0
- package/src/mixins/mixinHelpers.ts +69 -0
- package/src/models/interfaces.ts +511 -0
- package/src/models/session.ts +30 -0
- package/src/shared/index.ts +82 -0
- package/src/shared/utils/colorUtils.ts +155 -0
- package/src/shared/utils/debugUtils.ts +73 -0
- package/src/shared/utils/errorUtils.ts +181 -0
- package/src/shared/utils/index.ts +59 -0
- package/src/shared/utils/networkUtils.ts +248 -0
- package/src/shared/utils/themeUtils.ts +115 -0
- package/src/types/bip39.d.ts +32 -0
- package/src/types/buffer.d.ts +97 -0
- package/src/types/color.d.ts +20 -0
- package/src/types/elliptic.d.ts +62 -0
- package/src/utils/apiUtils.ts +88 -0
- package/src/utils/asyncUtils.ts +252 -0
- package/src/utils/cache.ts +264 -0
- package/src/utils/deviceManager.ts +198 -0
- package/src/utils/errorUtils.ts +216 -0
- package/src/utils/index.ts +21 -0
- package/src/utils/languageUtils.ts +174 -0
- package/src/utils/loggerUtils.ts +153 -0
- package/src/utils/platform.ts +117 -0
- package/src/utils/requestUtils.ts +237 -0
- package/src/utils/sessionUtils.ts +206 -0
- 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
|
+
}
|