@oxyhq/core 5.4.3 → 5.5.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/dist/cjs/.tsbuildinfo +1 -1
- package/dist/cjs/index.js +2 -1
- package/dist/cjs/session/SessionClient.js +4 -1
- package/dist/cjs/session/createSessionClient.js +8 -2
- package/dist/cjs/utils/ssoBounce.js +22 -0
- package/dist/cjs/utils/ssoReturn.js +8 -0
- package/dist/esm/.tsbuildinfo +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/session/SessionClient.js +4 -1
- package/dist/esm/session/createSessionClient.js +8 -2
- package/dist/esm/utils/ssoBounce.js +21 -0
- package/dist/esm/utils/ssoReturn.js +8 -0
- package/dist/types/.tsbuildinfo +1 -1
- package/dist/types/index.d.ts +2 -1
- package/dist/types/session/SessionClient.d.ts +13 -1
- package/dist/types/session/createSessionClient.d.ts +8 -1
- package/dist/types/utils/ssoBounce.d.ts +18 -0
- package/dist/types/utils/ssoReturn.d.ts +11 -1
- package/package.json +1 -1
- package/src/index.ts +5 -0
- package/src/session/SessionClient.ts +17 -2
- package/src/session/__tests__/SessionClient.socketFactory.test.ts +79 -0
- package/src/session/createSessionClient.ts +9 -1
- package/src/utils/__tests__/ssoReturn.test.ts +25 -0
- package/src/utils/ssoBounce.ts +22 -0
- package/src/utils/ssoReturn.ts +18 -1
package/dist/cjs/index.js
CHANGED
|
@@ -21,7 +21,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
21
21
|
exports.isIOS = exports.isNative = exports.isWeb = exports.setPlatformOS = exports.getPlatformOS = exports.isRTLLocale = exports.normalizeLanguageCode = exports.getNativeLanguageName = exports.getLanguageName = exports.getLanguageMetadata = exports.SUPPORTED_LANGUAGES = exports.TopicSource = exports.TopicType = exports.SECURITY_EVENT_SEVERITY_MAP = exports.DeviceManager = exports.RecoveryPhraseService = exports.SignatureService = exports.IdentityPersistError = exports.IdentityAlreadyExistsError = exports.KeyManager = exports.sessionsArraysEqual = exports.normalizeAndSortSessions = exports.mergeSessions = exports.authenticatedApiCall = exports.withAuthErrorHandling = exports.isAuthenticationError = exports.ensureValidToken = exports.AuthenticationFailedError = exports.SessionSyncRequiredError = exports.verifyPublicCardAttestation = exports.parseAttestPayload = exports.parseIdPayload = exports.buildUserDid = exports.normalizeProfileLinks = exports.getNormalizedUserHandle = exports.getCanonicalUserHandle = exports.normalizeUserIdentityOrNull = exports.normalizeUserIdentity = exports.getNormalizedUserId = exports.OxyAppDataIdentifierError = exports.ServiceCredentialMismatchError = exports.createCrossDomainAuth = exports.CrossDomainAuth = exports.createAuthManager = exports.AuthManager = exports.oxyClient = exports.OXY_CLOUD_URL = exports.OxyAuthenticationTimeoutError = exports.OxyAuthenticationError = exports.OxyServices = void 0;
|
|
22
22
|
exports.PASSWORD_REGEX = exports.USERNAME_REGEX = exports.EMAIL_REGEX = exports.retryAsync = exports.validateRequiredFields = exports.handleHttpError = exports.createApiError = exports.ErrorCodes = exports.safeJsonParse = exports.buildPaginationParams = exports.buildUrl = exports.buildSearchParams = exports.translate = exports.createDebugLogger = exports.debugError = exports.debugWarn = exports.debugLog = exports.isDev = exports.withRetry = exports.delay = exports.shouldAllowRequest = exports.recordSuccess = exports.recordFailure = exports.calculateBackoffInterval = exports.createCircuitBreakerState = exports.DEFAULT_CIRCUIT_BREAKER_CONFIG = exports.isRetryableError = exports.isNetworkError = exports.isServerError = exports.isRateLimitError = exports.isNotFoundError = exports.isForbiddenError = exports.isUnauthorizedError = exports.isAlreadyRegisteredError = exports.getErrorMessage = exports.getErrorStatus = exports.HttpStatus = exports.getSystemColorScheme = exports.systemPrefersDarkMode = exports.getOppositeTheme = exports.normalizeColorScheme = exports.normalizeTheme = exports.getContrastTextColor = exports.isLightColor = exports.withOpacity = exports.rgbToHex = exports.hexToRgb = exports.lightenColor = exports.darkenColor = exports.isAndroid = void 0;
|
|
23
23
|
exports.ssoAttemptedKey = exports.ssoNoSessionKey = exports.ssoDestKey = exports.ssoGuardKey = exports.ssoStateKey = exports.SSO_GUARD_TTL_MS = exports.SSO_CALLBACK_PATH = exports.establishIdpSessionAfterClaim = exports.generateSsoState = exports.consumeSsoReturn = exports.parseSsoReturnFragment = exports.resolveCentralAuthUrl = exports.CENTRAL_IDP_APEX = exports.CENTRAL_AUTH_URL = exports.registrableApex = exports.autoDetectAuthWebUrl = exports.getAccountColor = exports.mergeAccountsFromRefreshAll = exports.formatPublicKeyHandle = exports.getAccountFallbackHandle = exports.getAccountDisplayName = exports.createQuickAccount = exports.buildAccountsArray = exports.updateAvatarVisibility = exports.logPerformance = exports.logPayment = exports.logDevice = exports.logUser = exports.logSession = exports.logApi = exports.logAuth = exports.LogLevel = exports.logger = exports.validateAndSanitizeUserInput = exports.isValidObjectId = exports.sanitizeHTML = exports.sanitizeString = exports.isValidFileType = exports.isValidFileSize = exports.isValidDate = exports.isValidURL = exports.isValidUUID = exports.isValidObject = exports.isValidArray = exports.isRequiredBoolean = exports.isRequiredNumber = exports.isRequiredString = exports.isValidPassword = exports.isValidUsername = exports.isValidEmail = void 0;
|
|
24
|
-
exports.packageInfo = exports.accountIdsOf = exports.activeUserOf = exports.activeSessionIdOf = exports.deviceStateToClientSessions = exports.createSessionClient = exports.createSessionClientHost = exports.SessionClient = exports.runColdBoot = exports.allowSsoBounce = exports.silentRestoreSuppressed = exports.guardActive = exports.isCentralIdPOrigin = exports.buildSsoBounceUrl = exports.getSsoCallbackBootstrapScript = exports.ssoNavigate = exports.ssoCallbackBootstrapKey = exports.ssoSignedOutKey = exports.ssoPriorSessionKey = void 0;
|
|
24
|
+
exports.packageInfo = exports.accountIdsOf = exports.activeUserOf = exports.activeSessionIdOf = exports.deviceStateToClientSessions = exports.createSessionClient = exports.createSessionClientHost = exports.SessionClient = exports.runColdBoot = exports.allowSsoBounce = exports.silentRestoreSuppressed = exports.guardActive = exports.isCentralIdPOrigin = exports.buildSsoBounceUrl = exports.getSsoCallbackBootstrapScript = exports.ssoNavigate = exports.ssoCallbackBootstrapKey = exports.ssoOutcomeKey = exports.ssoSignedOutKey = exports.ssoPriorSessionKey = void 0;
|
|
25
25
|
// Ensure crypto polyfills are loaded before anything else
|
|
26
26
|
require("./crypto/polyfill");
|
|
27
27
|
// ---------------------------------------------------------------------------
|
|
@@ -288,6 +288,7 @@ Object.defineProperty(exports, "ssoNoSessionKey", { enumerable: true, get: funct
|
|
|
288
288
|
Object.defineProperty(exports, "ssoAttemptedKey", { enumerable: true, get: function () { return ssoBounce_1.ssoAttemptedKey; } });
|
|
289
289
|
Object.defineProperty(exports, "ssoPriorSessionKey", { enumerable: true, get: function () { return ssoBounce_1.ssoPriorSessionKey; } });
|
|
290
290
|
Object.defineProperty(exports, "ssoSignedOutKey", { enumerable: true, get: function () { return ssoBounce_1.ssoSignedOutKey; } });
|
|
291
|
+
Object.defineProperty(exports, "ssoOutcomeKey", { enumerable: true, get: function () { return ssoBounce_1.ssoOutcomeKey; } });
|
|
291
292
|
Object.defineProperty(exports, "ssoCallbackBootstrapKey", { enumerable: true, get: function () { return ssoBounce_1.ssoCallbackBootstrapKey; } });
|
|
292
293
|
Object.defineProperty(exports, "ssoNavigate", { enumerable: true, get: function () { return ssoBounce_1.ssoNavigate; } });
|
|
293
294
|
Object.defineProperty(exports, "getSsoCallbackBootstrapScript", { enumerable: true, get: function () { return ssoBounce_1.getSsoCallbackBootstrapScript; } });
|
|
@@ -120,7 +120,10 @@ class SessionClient {
|
|
|
120
120
|
}
|
|
121
121
|
}
|
|
122
122
|
async connectSocket() {
|
|
123
|
-
|
|
123
|
+
// Prefer a statically-injected factory (services/auth-sdk bundle
|
|
124
|
+
// socket.io-client as a real dep); fall back to the lazy loader — and warn
|
|
125
|
+
// if THAT yields nothing — only when no factory was injected.
|
|
126
|
+
const io = this.options.socketFactory ?? (await (0, socketLoader_1.getSocketIO)());
|
|
124
127
|
if (!io) {
|
|
125
128
|
loggerUtils_1.logger.warn('[SessionClient] no socket.io-client; running REST-only (no realtime sync)', { component: 'SessionClient' });
|
|
126
129
|
return;
|
|
@@ -18,9 +18,15 @@ const sessionClientHost_1 = require("./sessionClientHost");
|
|
|
18
18
|
* The host is returned alongside the client (not just the client) so the
|
|
19
19
|
* caller can call `host.setCurrentAccountId(...)` as the active account
|
|
20
20
|
* changes.
|
|
21
|
+
*
|
|
22
|
+
* `socketFactory` is the statically-injected `socket.io-client` `io` export.
|
|
23
|
+
* Consumers that bundle socket.io-client as a real dependency pass it so
|
|
24
|
+
* realtime sync never depends on core's lazy dynamic import of a bare
|
|
25
|
+
* specifier (bundler-fragile in Metro/Expo-web and Vite against the published
|
|
26
|
+
* dist). When omitted, the client falls back to the lazy loader.
|
|
21
27
|
*/
|
|
22
|
-
function createSessionClient(oxyServices, transport) {
|
|
28
|
+
function createSessionClient(oxyServices, transport, socketFactory) {
|
|
23
29
|
const host = (0, sessionClientHost_1.createSessionClientHost)(oxyServices);
|
|
24
|
-
const client = new SessionClient_1.SessionClient(host, { transport });
|
|
30
|
+
const client = new SessionClient_1.SessionClient(host, { transport, socketFactory });
|
|
25
31
|
return { client, host };
|
|
26
32
|
}
|
|
@@ -51,6 +51,7 @@ exports.ssoNoSessionKey = ssoNoSessionKey;
|
|
|
51
51
|
exports.ssoAttemptedKey = ssoAttemptedKey;
|
|
52
52
|
exports.ssoPriorSessionKey = ssoPriorSessionKey;
|
|
53
53
|
exports.ssoSignedOutKey = ssoSignedOutKey;
|
|
54
|
+
exports.ssoOutcomeKey = ssoOutcomeKey;
|
|
54
55
|
exports.ssoCallbackBootstrapKey = ssoCallbackBootstrapKey;
|
|
55
56
|
exports.getSsoCallbackBootstrapScript = getSsoCallbackBootstrapScript;
|
|
56
57
|
exports.ssoNavigate = ssoNavigate;
|
|
@@ -84,6 +85,7 @@ const ATTEMPTED_KEY_PREFIX = 'oxy_sso_attempted:';
|
|
|
84
85
|
const CALLBACK_BOOTSTRAP_KEY_PREFIX = 'oxy_sso_callback_bootstrap:';
|
|
85
86
|
const PRIOR_SESSION_KEY_PREFIX = 'oxy_sso_prior_session:';
|
|
86
87
|
const SIGNED_OUT_KEY_PREFIX = 'oxy_signed_out:';
|
|
88
|
+
const OUTCOME_KEY_PREFIX = 'oxy_sso_outcome:';
|
|
87
89
|
/** Per-origin CSRF state key (matched on return to defeat fragment forgery). */
|
|
88
90
|
function ssoStateKey(origin) {
|
|
89
91
|
return `${STATE_KEY_PREFIX}${origin}`;
|
|
@@ -163,6 +165,26 @@ function ssoPriorSessionKey(origin) {
|
|
|
163
165
|
function ssoSignedOutKey(origin) {
|
|
164
166
|
return `${SIGNED_OUT_KEY_PREFIX}${origin}`;
|
|
165
167
|
}
|
|
168
|
+
/**
|
|
169
|
+
* Per-origin key holding the LAST consumed SSO-return outcome (`ok` | `none` |
|
|
170
|
+
* `error`, plus an optional machine-readable `reason` on the non-`ok` outcomes).
|
|
171
|
+
*
|
|
172
|
+
* Lives in per-tab `sessionStorage` like the other loop-breaker keys, and for
|
|
173
|
+
* the same reason: a `none`/`error` return HARD-navigates the RP off the
|
|
174
|
+
* internal callback path back to its real destination (a fresh document load),
|
|
175
|
+
* so the outcome an RP wants to render ("the central IdP had no session — show a
|
|
176
|
+
* branded sign-in screen instead of bouncing again") must survive that
|
|
177
|
+
* round-trip. The RP reads it on the destination load to decide whether an
|
|
178
|
+
* AUTOMATIC (guard-driven) sign-in should re-bounce or defer to a user gesture.
|
|
179
|
+
*
|
|
180
|
+
* Written as a small JSON blob (`{kind, reason?}`). Set whenever a return is
|
|
181
|
+
* consumed; cleared on a successful session commit and on an explicit
|
|
182
|
+
* user-gesture sign-in / full sign-out (so a deliberate retry is never
|
|
183
|
+
* suppressed by a prior automatic none/error).
|
|
184
|
+
*/
|
|
185
|
+
function ssoOutcomeKey(origin) {
|
|
186
|
+
return `${OUTCOME_KEY_PREFIX}${origin}`;
|
|
187
|
+
}
|
|
166
188
|
/**
|
|
167
189
|
* Per-origin marker written by the pre-hydration callback bootstrap.
|
|
168
190
|
*
|
|
@@ -70,6 +70,14 @@ function parseSsoReturnFragment(hash) {
|
|
|
70
70
|
result.code = code;
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
|
+
else {
|
|
74
|
+
// A machine-readable reason accompanies a NON-`ok` outcome when the IdP
|
|
75
|
+
// supplies one. Success carries no reason, so it is only read here.
|
|
76
|
+
const reason = params.get('reason');
|
|
77
|
+
if (reason !== null && reason.length > 0) {
|
|
78
|
+
result.reason = reason;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
73
81
|
return result;
|
|
74
82
|
}
|
|
75
83
|
/**
|