@oxy.so/core 1.2.1 → 1.3.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/crypto/identityMove.js +123 -0
- package/dist/cjs/crypto/keyManager.js +60 -21
- package/dist/cjs/crypto/webIdentityCarrier.js +262 -0
- package/dist/cjs/i18n/locales/ar-SA.json +16 -13
- package/dist/cjs/i18n/locales/ca-ES.json +16 -13
- package/dist/cjs/i18n/locales/de-DE.json +16 -13
- package/dist/cjs/i18n/locales/en-US.json +16 -17
- package/dist/cjs/i18n/locales/es-ES.json +16 -17
- package/dist/cjs/i18n/locales/fr-FR.json +16 -13
- package/dist/cjs/i18n/locales/it-IT.json +16 -13
- package/dist/cjs/i18n/locales/ja-JP.json +16 -13
- package/dist/cjs/i18n/locales/ko-KR.json +16 -13
- package/dist/cjs/i18n/locales/locales/ar-SA.json +16 -13
- package/dist/cjs/i18n/locales/locales/ca-ES.json +16 -13
- package/dist/cjs/i18n/locales/locales/de-DE.json +16 -13
- package/dist/cjs/i18n/locales/locales/en-US.json +16 -17
- package/dist/cjs/i18n/locales/locales/es-ES.json +16 -17
- package/dist/cjs/i18n/locales/locales/fr-FR.json +16 -13
- package/dist/cjs/i18n/locales/locales/it-IT.json +16 -13
- package/dist/cjs/i18n/locales/locales/ja-JP.json +16 -13
- package/dist/cjs/i18n/locales/locales/ko-KR.json +16 -13
- package/dist/cjs/i18n/locales/locales/pt-PT.json +16 -13
- package/dist/cjs/i18n/locales/locales/zh-CN.json +16 -13
- package/dist/cjs/i18n/locales/pt-PT.json +16 -13
- package/dist/cjs/i18n/locales/zh-CN.json +16 -13
- package/dist/cjs/index.js +38 -4
- package/dist/cjs/mixins/OxyServices.auth.js +14 -4
- package/dist/cjs/mixins/OxyServices.identity.js +14 -0
- package/dist/cjs/session/accountDialogController.js +333 -142
- package/dist/cjs/utils/authWebUrl.js +8 -1
- package/dist/esm/.tsbuildinfo +1 -1
- package/dist/esm/crypto/identityMove.js +110 -0
- package/dist/esm/crypto/keyManager.js +60 -21
- package/dist/esm/crypto/webIdentityCarrier.js +243 -0
- package/dist/esm/i18n/locales/ar-SA.json +16 -13
- package/dist/esm/i18n/locales/ca-ES.json +16 -13
- package/dist/esm/i18n/locales/de-DE.json +16 -13
- package/dist/esm/i18n/locales/en-US.json +16 -17
- package/dist/esm/i18n/locales/es-ES.json +16 -17
- package/dist/esm/i18n/locales/fr-FR.json +16 -13
- package/dist/esm/i18n/locales/it-IT.json +16 -13
- package/dist/esm/i18n/locales/ja-JP.json +16 -13
- package/dist/esm/i18n/locales/ko-KR.json +16 -13
- package/dist/esm/i18n/locales/locales/ar-SA.json +16 -13
- package/dist/esm/i18n/locales/locales/ca-ES.json +16 -13
- package/dist/esm/i18n/locales/locales/de-DE.json +16 -13
- package/dist/esm/i18n/locales/locales/en-US.json +16 -17
- package/dist/esm/i18n/locales/locales/es-ES.json +16 -17
- package/dist/esm/i18n/locales/locales/fr-FR.json +16 -13
- package/dist/esm/i18n/locales/locales/it-IT.json +16 -13
- package/dist/esm/i18n/locales/locales/ja-JP.json +16 -13
- package/dist/esm/i18n/locales/locales/ko-KR.json +16 -13
- package/dist/esm/i18n/locales/locales/pt-PT.json +16 -13
- package/dist/esm/i18n/locales/locales/zh-CN.json +16 -13
- package/dist/esm/i18n/locales/pt-PT.json +16 -13
- package/dist/esm/i18n/locales/zh-CN.json +16 -13
- package/dist/esm/index.js +5 -1
- package/dist/esm/mixins/OxyServices.auth.js +14 -4
- package/dist/esm/mixins/OxyServices.identity.js +14 -0
- package/dist/esm/session/accountDialogController.js +334 -143
- package/dist/esm/utils/authWebUrl.js +7 -0
- package/dist/types/.tsbuildinfo +1 -1
- package/dist/types/crypto/identityMove.d.ts +59 -0
- package/dist/types/crypto/keyManager.d.ts +35 -5
- package/dist/types/crypto/webIdentityCarrier.d.ts +123 -0
- package/dist/types/index.d.ts +5 -2
- package/dist/types/mixins/OxyServices.auth.d.ts +12 -0
- package/dist/types/models/interfaces.d.ts +15 -0
- package/dist/types/session/accountDialogController.d.ts +169 -17
- package/dist/types/utils/authWebUrl.d.ts +7 -0
- package/package.json +2 -2
- package/src/crypto/__tests__/identityMove.test.ts +104 -0
- package/src/crypto/__tests__/keyManager.sharedSlotSync.test.ts +150 -0
- package/src/crypto/__tests__/webIdentityCarrier.test.ts +211 -0
- package/src/crypto/identityMove.ts +133 -0
- package/src/crypto/keyManager.ts +71 -21
- package/src/crypto/webIdentityCarrier.ts +326 -0
- package/src/i18n/locales/ar-SA.json +16 -13
- package/src/i18n/locales/ca-ES.json +16 -13
- package/src/i18n/locales/de-DE.json +16 -13
- package/src/i18n/locales/en-US.json +16 -17
- package/src/i18n/locales/es-ES.json +16 -17
- package/src/i18n/locales/fr-FR.json +16 -13
- package/src/i18n/locales/it-IT.json +16 -13
- package/src/i18n/locales/ja-JP.json +16 -13
- package/src/i18n/locales/ko-KR.json +16 -13
- package/src/i18n/locales/pt-PT.json +16 -13
- package/src/i18n/locales/zh-CN.json +16 -13
- package/src/index.ts +38 -1
- package/src/mixins/OxyServices.auth.ts +16 -3
- package/src/mixins/OxyServices.identity.ts +14 -0
- package/src/mixins/__tests__/OxyServices.rotateKey.test.ts +47 -0
- package/src/mixins/__tests__/commonsSignIn.test.ts +3 -0
- package/src/mixins/__tests__/verifyChallenge.test.ts +31 -0
- package/src/models/interfaces.ts +15 -0
- package/src/session/__tests__/accountDialogController.test.ts +407 -10
- package/src/session/accountDialogController.ts +406 -145
- package/src/utils/__tests__/oauthPkce.test.ts +50 -26
- package/src/utils/authWebUrl.ts +8 -0
package/dist/cjs/index.js
CHANGED
|
@@ -19,10 +19,11 @@
|
|
|
19
19
|
*/
|
|
20
20
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
21
|
exports.AEAD_KEY_LENGTH = exports.decryptAead = exports.encryptAead = exports.hkdfSha256 = exports.RecoveryPhraseService = exports.SignatureService = exports.updateIdentityMarker = exports.readIdentityMarker = exports.IdentityUnavailableError = 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.kindAcceptsAccountCategories = exports.isSelectableAccountCategoryId = exports.SELECTABLE_ACCOUNT_CATEGORY_IDS = exports.MAX_ACCOUNT_CATEGORIES = exports.ACCOUNT_CATEGORY_IDS = exports.normalizeProfileLinks = exports.getNormalizedUserHandle = exports.getCanonicalUserHandle = exports.normalizeUserIdentityOrNull = exports.normalizeUserIdentity = exports.getNormalizedUserId = exports.OxyAppDataIdentifierError = exports.commonsDeliveryPlatform = exports.pushTargetsFromDelivery = exports.selectCommonsDelivery = exports.parseCommonsApprovalExpiresAt = exports.getCommonsApprovalBlockingReason = exports.ServiceCredentialMismatchError = exports.oxyClient = exports.OXY_CLOUD_URL = exports.ServiceAssetMetadataError = exports.OxyAuthenticationTimeoutError = exports.OxyAuthenticationError = exports.AssetUrlResolutionError = exports.OxyServices = void 0;
|
|
22
|
-
exports.
|
|
23
|
-
exports.
|
|
24
|
-
exports.
|
|
25
|
-
exports.
|
|
22
|
+
exports.isNative = exports.isWeb = exports.setPlatformOS = exports.getPlatformOS = exports.coerceToSupportedLocale = exports.getPrimaryLanguage = exports.getUserLanguages = exports.isRTLLocale = exports.getNativeLanguageName = exports.getLanguageName = exports.getLanguageMetadata = exports.isSupportedLocale = exports.normalizeLocale = exports.getBaseLanguage = exports.FALLBACK_LOCALE = exports.SUPPORTED_LANGUAGES = exports.TopicSource = exports.TopicType = exports.SECURITY_EVENT_SEVERITY_MAP = exports.DeviceManager = exports.verifyMoveReceipt = exports.signMoveAction = exports.sealIdentityForMove = exports.parseMoveQrPayload = exports.openMovedIdentity = exports.generateMoveEphemeralKeyPair = exports.deriveMoveSas = exports.deriveMoveKey = exports.buildMoveQrPayload = exports.buildMoveMessage = exports.IDENTITY_MOVE_ACTIONS = exports.wrapDataKey = exports.wipeBytes = exports.unwrapDataKey = exports.unlockWebIdentity = exports.signIdentityAction = exports.sealWebIdentity = exports.removeWrap = exports.openWebIdentity = exports.generateWebIdentity = exports.generateDataKey = exports.deriveTransferSas = exports.deriveKeyEncryptionKey = exports.deriveIdentityFromMnemonic = exports.buildIdentityActionMessage = exports.addWrap = exports.WebIdentityUnlockError = exports.WEB_IDENTITY_PRF_INPUT = exports.deriveSharedSecret = exports.AEAD_NONCE_LENGTH = void 0;
|
|
23
|
+
exports.validateRequiredFields = exports.parseHttpErrorBody = exports.isHttpRequestError = exports.handleHttpError = exports.createApiError = exports.ErrorCodes = exports.safeJsonParse = exports.buildPaginationParams = exports.buildUrl = exports.buildSearchParams = exports.buildQueryParams = exports.trustTierLabel = exports.reputationCategoryLabel = exports.accountRoleLabel = exports.accountCategoryLabel = exports.translate = 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.isWebBrowser = exports.isAndroid = exports.isIOS = void 0;
|
|
24
|
+
exports.generateOAuthState = exports.computeCodeChallenge = exports.buildOAuthAuthorizeUrl = exports.runColdBoot = exports.isOxyRpOrigin = exports.IDENTITY_WEB_ORIGIN = exports.CENTRAL_IDP_APEX = exports.registrableApex = exports.getAccountColor = exports.formatPublicKeyHandle = exports.getAccountFallbackHandle = exports.getAccountDisplayName = exports.createQuickAccount = exports.buildAccountsArray = exports.updateAvatarVisibility = exports.isDev = exports.consoleSink = exports.resetLoggerConfig = exports.getLoggerConfig = exports.configureLogger = exports.createLogger = exports.logger = exports.normalizeMultilineText = exports.normalizeInlineText = 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.DISPLAY_NAME_UNFLANKED_SEPARATOR_SOURCE = exports.DISPLAY_NAME_ORPHANED_MARK_SOURCE = exports.DISPLAY_NAME_DISALLOWED_SOURCE = exports.DISPLAY_NAME_ALLOWED_SCRIPTS = exports.isValidDisplayName = exports.isValidPassword = exports.isValidEmail = exports.DISPLAY_NAME_INVALID_MESSAGE = exports.MAX_DISPLAY_NAME_LENGTH = exports.PASSWORD_REGEX = exports.EMAIL_REGEX = exports.retryAsync = void 0;
|
|
25
|
+
exports.createMemoryIdentityPinStore = exports.createNativeIdentityPinStore = exports.createWebIdentityPinStore = exports.readLocalDeviceCredential = exports.publishProvenDeviceCredential = exports.normalizeSharedDeviceSessionRead = exports.decideSharedDevicePublish = exports.decideSharedDeviceJoin = exports.createSharedMirroringAuthStateStore = exports.AUTH_STATE_STORAGE_KEY = exports.createMemoryAuthStateStore = exports.createNativeAuthStateStore = exports.createWebAuthStateStore = exports.createAccountDialogController = exports.AccountDialogController = exports.resolveAccountDelegationAccess = exports.canSwitchIntoAccount = exports.isSwitchTargetAccount = exports.showsPrincipalHeaders = exports.buildSwitcherRows = exports.resolveDeviceContext = exports.resolveActiveContext = exports.projectDevicePrincipals = exports.directoryHandle = exports.directoryDisplayName = exports.canActivateContext = exports.accountIdsOf = exports.activeUserOf = exports.activeSessionIdOf = exports.deviceStateToClientSessions = exports.createSessionClient = exports.createSessionClientHost = exports.SessionClient = exports.isAllowedDeviceJoinOrigin = exports.isOfficialWebOrigin = exports.isLoopbackOrigin = exports.consumeOAuthReturnPath = exports.persistOAuthReturnPath = exports.clearOAuthHandshake = exports.readOAuthHandshake = exports.persistOAuthHandshake = exports.canonicalizeOAuthRedirectUri = exports.normalizeOAuthRedirectUri = exports.OXY_OAUTH_RETURN_PATH_STORAGE_KEY = exports.OXY_OAUTH_REDIRECT_URI_STORAGE_KEY = exports.OXY_OAUTH_CODE_VERIFIER_STORAGE_KEY = exports.OXY_OAUTH_STATE_STORAGE_KEY = exports.OXY_AUTHORIZE_URL = exports.DEFAULT_OAUTH_SCOPE = exports.generatePkcePair = void 0;
|
|
26
|
+
exports.packageInfo = exports.runSessionColdBoot = exports.OXY_INFERENCE_BASE_URL = exports.OxyInferenceProtocolError = exports.OxyInferenceError = exports.OxyInferenceClient = exports.TOKEN_REFRESH_LEAD_MS = exports.startTokenRefreshScheduler = exports.installAuthRefreshHandler = exports.createAuthRefreshHandler = exports.refreshDeviceSecretArm = exports.refreshPersistedSession = exports.AccountNotOnDeviceError = exports.establishIdentitySession = exports.resolveIdentityPin = exports.IDENTITY_PIN_STORAGE_KEY = exports.identityPinMatches = void 0;
|
|
26
27
|
// Ensure crypto polyfills are loaded before anything else
|
|
27
28
|
require("./crypto/polyfill");
|
|
28
29
|
// ---------------------------------------------------------------------------
|
|
@@ -140,6 +141,38 @@ Object.defineProperty(exports, "AEAD_KEY_LENGTH", { enumerable: true, get: funct
|
|
|
140
141
|
Object.defineProperty(exports, "AEAD_NONCE_LENGTH", { enumerable: true, get: function () { return aead_1.AEAD_NONCE_LENGTH; } });
|
|
141
142
|
var ecdh_1 = require("./crypto/ecdh");
|
|
142
143
|
Object.defineProperty(exports, "deriveSharedSecret", { enumerable: true, get: function () { return ecdh_1.deriveSharedSecret; } });
|
|
144
|
+
// Web identity carrier — the same identity as Commons, sealed under a passkey's
|
|
145
|
+
// PRF output (docs/superpowers/specs/2026-09-15-one-identity-two-carriers-design.md)
|
|
146
|
+
var webIdentityCarrier_1 = require("./crypto/webIdentityCarrier");
|
|
147
|
+
Object.defineProperty(exports, "WEB_IDENTITY_PRF_INPUT", { enumerable: true, get: function () { return webIdentityCarrier_1.WEB_IDENTITY_PRF_INPUT; } });
|
|
148
|
+
Object.defineProperty(exports, "WebIdentityUnlockError", { enumerable: true, get: function () { return webIdentityCarrier_1.WebIdentityUnlockError; } });
|
|
149
|
+
Object.defineProperty(exports, "addWrap", { enumerable: true, get: function () { return webIdentityCarrier_1.addWrap; } });
|
|
150
|
+
Object.defineProperty(exports, "buildIdentityActionMessage", { enumerable: true, get: function () { return webIdentityCarrier_1.buildIdentityActionMessage; } });
|
|
151
|
+
Object.defineProperty(exports, "deriveIdentityFromMnemonic", { enumerable: true, get: function () { return webIdentityCarrier_1.deriveIdentityFromMnemonic; } });
|
|
152
|
+
Object.defineProperty(exports, "deriveKeyEncryptionKey", { enumerable: true, get: function () { return webIdentityCarrier_1.deriveKeyEncryptionKey; } });
|
|
153
|
+
Object.defineProperty(exports, "deriveTransferSas", { enumerable: true, get: function () { return webIdentityCarrier_1.deriveTransferSas; } });
|
|
154
|
+
Object.defineProperty(exports, "generateDataKey", { enumerable: true, get: function () { return webIdentityCarrier_1.generateDataKey; } });
|
|
155
|
+
Object.defineProperty(exports, "generateWebIdentity", { enumerable: true, get: function () { return webIdentityCarrier_1.generateWebIdentity; } });
|
|
156
|
+
Object.defineProperty(exports, "openWebIdentity", { enumerable: true, get: function () { return webIdentityCarrier_1.openWebIdentity; } });
|
|
157
|
+
Object.defineProperty(exports, "removeWrap", { enumerable: true, get: function () { return webIdentityCarrier_1.removeWrap; } });
|
|
158
|
+
Object.defineProperty(exports, "sealWebIdentity", { enumerable: true, get: function () { return webIdentityCarrier_1.sealWebIdentity; } });
|
|
159
|
+
Object.defineProperty(exports, "signIdentityAction", { enumerable: true, get: function () { return webIdentityCarrier_1.signIdentityAction; } });
|
|
160
|
+
Object.defineProperty(exports, "unlockWebIdentity", { enumerable: true, get: function () { return webIdentityCarrier_1.unlockWebIdentity; } });
|
|
161
|
+
Object.defineProperty(exports, "unwrapDataKey", { enumerable: true, get: function () { return webIdentityCarrier_1.unwrapDataKey; } });
|
|
162
|
+
Object.defineProperty(exports, "wipeBytes", { enumerable: true, get: function () { return webIdentityCarrier_1.wipeBytes; } });
|
|
163
|
+
Object.defineProperty(exports, "wrapDataKey", { enumerable: true, get: function () { return webIdentityCarrier_1.wrapDataKey; } });
|
|
164
|
+
var identityMove_1 = require("./crypto/identityMove");
|
|
165
|
+
Object.defineProperty(exports, "IDENTITY_MOVE_ACTIONS", { enumerable: true, get: function () { return identityMove_1.IDENTITY_MOVE_ACTIONS; } });
|
|
166
|
+
Object.defineProperty(exports, "buildMoveMessage", { enumerable: true, get: function () { return identityMove_1.buildMoveMessage; } });
|
|
167
|
+
Object.defineProperty(exports, "buildMoveQrPayload", { enumerable: true, get: function () { return identityMove_1.buildMoveQrPayload; } });
|
|
168
|
+
Object.defineProperty(exports, "deriveMoveKey", { enumerable: true, get: function () { return identityMove_1.deriveMoveKey; } });
|
|
169
|
+
Object.defineProperty(exports, "deriveMoveSas", { enumerable: true, get: function () { return identityMove_1.deriveMoveSas; } });
|
|
170
|
+
Object.defineProperty(exports, "generateMoveEphemeralKeyPair", { enumerable: true, get: function () { return identityMove_1.generateMoveEphemeralKeyPair; } });
|
|
171
|
+
Object.defineProperty(exports, "openMovedIdentity", { enumerable: true, get: function () { return identityMove_1.openMovedIdentity; } });
|
|
172
|
+
Object.defineProperty(exports, "parseMoveQrPayload", { enumerable: true, get: function () { return identityMove_1.parseMoveQrPayload; } });
|
|
173
|
+
Object.defineProperty(exports, "sealIdentityForMove", { enumerable: true, get: function () { return identityMove_1.sealIdentityForMove; } });
|
|
174
|
+
Object.defineProperty(exports, "signMoveAction", { enumerable: true, get: function () { return identityMove_1.signMoveAction; } });
|
|
175
|
+
Object.defineProperty(exports, "verifyMoveReceipt", { enumerable: true, get: function () { return identityMove_1.verifyMoveReceipt; } });
|
|
143
176
|
// ---------------------------------------------------------------------------
|
|
144
177
|
// Devices
|
|
145
178
|
// ---------------------------------------------------------------------------
|
|
@@ -323,6 +356,7 @@ var registrableApex_1 = require("./utils/registrableApex");
|
|
|
323
356
|
Object.defineProperty(exports, "registrableApex", { enumerable: true, get: function () { return registrableApex_1.registrableApex; } });
|
|
324
357
|
var authWebUrl_1 = require("./utils/authWebUrl");
|
|
325
358
|
Object.defineProperty(exports, "CENTRAL_IDP_APEX", { enumerable: true, get: function () { return authWebUrl_1.CENTRAL_IDP_APEX; } });
|
|
359
|
+
Object.defineProperty(exports, "IDENTITY_WEB_ORIGIN", { enumerable: true, get: function () { return authWebUrl_1.IDENTITY_WEB_ORIGIN; } });
|
|
326
360
|
// WebAuthn relying-party origin guard (client side). Mirrors the server's
|
|
327
361
|
// `isOxyApexOrigin` so consumers can decide whether to offer passkey UI on the
|
|
328
362
|
// current page (first-party Oxy origin / loopback only).
|
|
@@ -390,8 +390,12 @@ function OxyServicesAuthMixin(Base) {
|
|
|
390
390
|
* `timeout`). Interactive callers omit it (defaults keep retries); the
|
|
391
391
|
* cold-boot `shared-key-signin` step passes `{ retry: false }` so a slow
|
|
392
392
|
* network cannot multiply boot latency via the inner retry loop.
|
|
393
|
+
* @param options.plantTokens - Install the returned bearer on this client
|
|
394
|
+
* (default `true`). A caller that must decide LATER whether the session is
|
|
395
|
+
* still wanted (the account dialog, whose user may have cancelled while the
|
|
396
|
+
* request was in flight) passes `false` and plants it itself.
|
|
393
397
|
*/
|
|
394
|
-
async verifyChallenge(publicKey, challenge, signature, timestamp, deviceName, deviceFingerprint, requestOptions) {
|
|
398
|
+
async verifyChallenge(publicKey, challenge, signature, timestamp, deviceName, deviceFingerprint, requestOptions, options = {}) {
|
|
395
399
|
try {
|
|
396
400
|
const res = await this.makeRequest('POST', '/auth/verify', {
|
|
397
401
|
publicKey,
|
|
@@ -406,7 +410,7 @@ function OxyServicesAuthMixin(Base) {
|
|
|
406
410
|
// its body, so installing it here means callers get an authenticated
|
|
407
411
|
// client without a second round-trip. Refresh stays in the httpOnly
|
|
408
412
|
// cookie slot set by the API.
|
|
409
|
-
if (res?.accessToken) {
|
|
413
|
+
if (res?.accessToken && options.plantTokens !== false) {
|
|
410
414
|
this.setTokens(res.accessToken);
|
|
411
415
|
}
|
|
412
416
|
return {
|
|
@@ -504,6 +508,9 @@ function OxyServicesAuthMixin(Base) {
|
|
|
504
508
|
* `POST /auth/session/create` at the start of the flow.
|
|
505
509
|
* @param options.deviceFingerprint - Optional fingerprint of the
|
|
506
510
|
* originating client device.
|
|
511
|
+
* @param options.plantTokens - Install the claimed bearer on this client
|
|
512
|
+
* (default `true`). Pass `false` to install it yourself once you know the
|
|
513
|
+
* session is still wanted — see `verifyChallenge`.
|
|
507
514
|
*/
|
|
508
515
|
async claimSessionByToken(sessionToken, options = {}) {
|
|
509
516
|
try {
|
|
@@ -513,7 +520,9 @@ function OxyServicesAuthMixin(Base) {
|
|
|
513
520
|
},
|
|
514
521
|
// Body-authenticated device-flow claim (no bearer) — skip the preflight.
|
|
515
522
|
{ cache: false, retry: false, skipAuth: true });
|
|
516
|
-
|
|
523
|
+
if (options.plantTokens !== false) {
|
|
524
|
+
this.setTokens(res.accessToken);
|
|
525
|
+
}
|
|
517
526
|
return res;
|
|
518
527
|
}
|
|
519
528
|
catch (error) {
|
|
@@ -557,6 +566,7 @@ function OxyServicesAuthMixin(Base) {
|
|
|
557
566
|
* retries); the cold-boot `shared-key-signin` step passes `{ retry: false }`
|
|
558
567
|
* so this network step cannot multiply boot latency via the inner retry
|
|
559
568
|
* loop. The token-refresh scheduler / 401 lane still retry later.
|
|
569
|
+
* @param opts.plantTokens - Forwarded to `verifyChallenge` (default `true`).
|
|
560
570
|
*/
|
|
561
571
|
async signInWithSharedIdentity(opts = {}) {
|
|
562
572
|
try {
|
|
@@ -573,7 +583,7 @@ function OxyServicesAuthMixin(Base) {
|
|
|
573
583
|
const { challenge } = await this.requestChallenge(sharedPublicKey, opts.requestOptions);
|
|
574
584
|
const signed = await signatureService_1.SignatureService.signChallengeWithSharedKey(challenge);
|
|
575
585
|
// `signed.challenge` carries the SIGNATURE (mirrors `signChallenge`).
|
|
576
|
-
return await this.verifyChallenge(signed.publicKey, challenge, signed.challenge, signed.timestamp, opts.deviceName, opts.deviceFingerprint, opts.requestOptions);
|
|
586
|
+
return await this.verifyChallenge(signed.publicKey, challenge, signed.challenge, signed.timestamp, opts.deviceName, opts.deviceFingerprint, opts.requestOptions, { plantTokens: opts.plantTokens });
|
|
577
587
|
}
|
|
578
588
|
catch (error) {
|
|
579
589
|
throw this.handleError(error);
|
|
@@ -266,9 +266,23 @@ function OxyServicesIdentityMixin(Base) {
|
|
|
266
266
|
// re-import the now-live key. Surface the result with
|
|
267
267
|
// `localPersistFailed: true` (mirrors the pendingIdentity
|
|
268
268
|
// show-phrase-first path, where the caller already holds the phrase).
|
|
269
|
+
// The SHARED slot is written FIRST, and that order is load-bearing.
|
|
270
|
+
// Every cross-app reader takes the shared slot before the primary —
|
|
271
|
+
// `deriveScopedSeed` does, which is where Peable's FairCoin wallet
|
|
272
|
+
// comes from. Leaving the replaced key there was silent money loss:
|
|
273
|
+
// payers derive the recipient's address from the key in the DID (now
|
|
274
|
+
// the new one) while the recipient's wallet still watches addresses
|
|
275
|
+
// derived from the old one, so payments land where nobody looks.
|
|
276
|
+
// Writing shared first means a crash between the two writes leaves
|
|
277
|
+
// the money path already on the new key and the primary stale, which
|
|
278
|
+
// fails LOUDLY on the next signature instead of quietly misdirecting
|
|
279
|
+
// funds. `syncSharedIdentity` repairs that case on the next boot.
|
|
269
280
|
let localPersistFailed = false;
|
|
270
281
|
if (!(0, platform_1.isWeb)()) {
|
|
271
282
|
try {
|
|
283
|
+
if (await keyManager_1.KeyManager.hasSharedIdentity()) {
|
|
284
|
+
await keyManager_1.KeyManager.importSharedIdentity(pending.privateKey);
|
|
285
|
+
}
|
|
272
286
|
await keyManager_1.KeyManager.importKeyPair(pending.privateKey, { overwrite: true });
|
|
273
287
|
}
|
|
274
288
|
catch (persistError) {
|