@oxy.so/core 4.5.0-oxy-one.0 → 4.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/README.md +1 -1
- package/dist/cjs/HttpService.js +63 -19
- package/dist/cjs/api/accounts.js +10 -3
- package/dist/cjs/api/agency.js +3 -1
- package/dist/cjs/api/apps.js +15 -4
- package/dist/cjs/api/assets.js +49 -12
- package/dist/cjs/api/auth.js +37 -11
- package/dist/cjs/api/billing.js +24 -7
- package/dist/cjs/api/civic.js +14 -4
- package/dist/cjs/api/follows.js +9 -2
- package/dist/cjs/api/identity.js +31 -9
- package/dist/cjs/api/nodes.js +3 -1
- package/dist/cjs/api/privacy.js +8 -2
- package/dist/cjs/api/session.js +15 -4
- package/dist/cjs/api/store.js +15 -5
- package/dist/cjs/api/topics.js +10 -3
- package/dist/cjs/api/users.js +16 -4
- package/dist/cjs/boot/sessionColdBoot.js +40 -13
- package/dist/cjs/constants/version.js +6 -6
- package/dist/cjs/crypto/identityMarker.js +3 -1
- package/dist/cjs/crypto/identityProof.js +6 -1
- package/dist/cjs/crypto/keyManager.js +87 -32
- package/dist/cjs/crypto/recoveryPhrase.js +2 -2
- package/dist/cjs/crypto/signatureService.js +3 -4
- package/dist/cjs/i18n/index.js +16 -3
- package/dist/cjs/i18n/locales/ar-SA.js +366 -366
- package/dist/cjs/i18n/locales/ca-ES.js +366 -366
- package/dist/cjs/i18n/locales/de-DE.js +366 -366
- package/dist/cjs/i18n/locales/en-US.js +1994 -1994
- package/dist/cjs/i18n/locales/es-ES.js +1994 -1994
- package/dist/cjs/i18n/locales/fr-FR.js +366 -366
- package/dist/cjs/i18n/locales/it-IT.js +366 -366
- package/dist/cjs/i18n/locales/ja-JP.js +366 -366
- package/dist/cjs/i18n/locales/ko-KR.js +366 -366
- package/dist/cjs/i18n/locales/pt-PT.js +366 -366
- package/dist/cjs/i18n/locales/zh-CN.js +366 -366
- package/dist/cjs/inference/OxyInferenceClient.js +12 -18
- package/dist/cjs/models/interfaces.js +11 -11
- package/dist/cjs/server/OxyServer.js +86 -28
- package/dist/cjs/server/agentAccount.js +6 -2
- package/dist/cjs/server/aliaMachineCredential.js +39 -14
- package/dist/cjs/server/auth.js +5 -4
- package/dist/cjs/server/capabilityTicket.js +5 -5
- package/dist/cjs/server/index.js +2 -1
- package/dist/cjs/server/liveCapabilityTicket.js +4 -1
- package/dist/cjs/server/middleware.js +61 -42
- package/dist/cjs/server/namespaces.js +28 -7
- package/dist/cjs/server/requesterAssertion.js +36 -30
- package/dist/cjs/server/serviceTokenLifetime.js +7 -4
- package/dist/cjs/server/traffic.js +53 -14
- package/dist/cjs/server/trafficNodeHttp.js +33 -8
- package/dist/cjs/server/workloadIdentity.client.js +4 -0
- package/dist/cjs/server/workloadIdentity.js +28 -1
- package/dist/cjs/session/SessionClient.js +54 -17
- package/dist/cjs/session/accountDelegationAccess.js +4 -6
- package/dist/cjs/session/accountDialogController.js +1 -1
- package/dist/cjs/session/authStateStore.js +18 -9
- package/dist/cjs/session/identityPin.js +6 -2
- package/dist/cjs/session/refresh.js +81 -23
- package/dist/cjs/session/sharedDeviceCredential.js +28 -15
- package/dist/cjs/shared/utils/errorUtils.js +1 -1
- package/dist/cjs/shared/utils/networkUtils.js +1 -1
- package/dist/cjs/shared/utils/themeUtils.js +1 -1
- package/dist/cjs/utils/accountCacheSweep.js +3 -1
- package/dist/cjs/utils/accountUtils.js +1 -3
- package/dist/cjs/utils/asyncUtils.js +1 -1
- package/dist/cjs/utils/authHelpers.js +2 -1
- package/dist/cjs/utils/avatarUtils.js +4 -2
- package/dist/cjs/utils/cache.js +1 -1
- package/dist/cjs/utils/cacheKey.js +3 -1
- package/dist/cjs/utils/deviceManager.js +4 -4
- package/dist/cjs/utils/errorUtils.js +6 -4
- package/dist/cjs/utils/languageUtils.js +404 -57
- package/dist/cjs/utils/profileLinks.js +1 -3
- package/dist/cjs/utils/requestUtils.js +7 -1
- package/dist/cjs/utils/userIdentity.js +1 -1
- package/dist/cjs/utils/validationUtils.js +5 -6
- package/dist/esm/HttpService.js +64 -20
- package/dist/esm/api/accounts.js +11 -4
- package/dist/esm/api/agency.js +3 -1
- package/dist/esm/api/apps.js +15 -4
- package/dist/esm/api/assets.js +49 -12
- package/dist/esm/api/auth.js +37 -11
- package/dist/esm/api/billing.js +25 -8
- package/dist/esm/api/civic.js +14 -4
- package/dist/esm/api/follows.js +9 -2
- package/dist/esm/api/identity.js +31 -9
- package/dist/esm/api/nodes.js +3 -1
- package/dist/esm/api/privacy.js +8 -2
- package/dist/esm/api/session.js +15 -4
- package/dist/esm/api/store.js +15 -5
- package/dist/esm/api/topics.js +10 -3
- package/dist/esm/api/users.js +16 -4
- package/dist/esm/boot/sessionColdBoot.js +41 -14
- package/dist/esm/constants/version.js +6 -6
- package/dist/esm/crypto/identityMarker.js +3 -1
- package/dist/esm/crypto/identityProof.js +6 -1
- package/dist/esm/crypto/internal.js +1 -1
- package/dist/esm/crypto/keyManager.js +87 -32
- package/dist/esm/crypto/recoveryPhrase.js +2 -2
- package/dist/esm/crypto/signatureService.js +3 -4
- package/dist/esm/i18n/index.js +16 -3
- package/dist/esm/i18n/locales/ar-SA.js +366 -366
- package/dist/esm/i18n/locales/ca-ES.js +366 -366
- package/dist/esm/i18n/locales/de-DE.js +366 -366
- package/dist/esm/i18n/locales/en-US.js +1994 -1994
- package/dist/esm/i18n/locales/es-ES.js +1994 -1994
- package/dist/esm/i18n/locales/fr-FR.js +366 -366
- package/dist/esm/i18n/locales/it-IT.js +366 -366
- package/dist/esm/i18n/locales/ja-JP.js +366 -366
- package/dist/esm/i18n/locales/ko-KR.js +366 -366
- package/dist/esm/i18n/locales/pt-PT.js +366 -366
- package/dist/esm/i18n/locales/zh-CN.js +366 -366
- package/dist/esm/index.js +1 -1
- package/dist/esm/inference/OxyInferenceClient.js +13 -19
- package/dist/esm/models/interfaces.js +11 -11
- package/dist/esm/server/OxyServer.js +87 -29
- package/dist/esm/server/agentAccount.js +6 -2
- package/dist/esm/server/aliaMachineCredential.js +39 -14
- package/dist/esm/server/auth.js +6 -5
- package/dist/esm/server/capabilityTicket.js +6 -6
- package/dist/esm/server/index.js +5 -5
- package/dist/esm/server/liveCapabilityTicket.js +6 -3
- package/dist/esm/server/middleware.js +62 -43
- package/dist/esm/server/namespaces.js +31 -10
- package/dist/esm/server/requesterAssertion.js +36 -30
- package/dist/esm/server/serviceTokenLifetime.js +7 -4
- package/dist/esm/server/traffic.js +55 -16
- package/dist/esm/server/trafficNodeHttp.js +34 -9
- package/dist/esm/server/userInvalidation.js +1 -1
- package/dist/esm/server/workloadIdentity.client.js +3 -0
- package/dist/esm/server/workloadIdentity.js +27 -1
- package/dist/esm/session/SessionClient.js +54 -17
- package/dist/esm/session/accountDelegationAccess.js +5 -7
- package/dist/esm/session/accountDialogController.js +1 -1
- package/dist/esm/session/authStateStore.js +18 -9
- package/dist/esm/session/identityPin.js +6 -2
- package/dist/esm/session/refresh.js +82 -24
- package/dist/esm/session/sharedDeviceCredential.js +28 -15
- package/dist/esm/shared/utils/errorUtils.js +1 -1
- package/dist/esm/shared/utils/networkUtils.js +1 -1
- package/dist/esm/shared/utils/themeUtils.js +1 -1
- package/dist/esm/utils/accountCacheSweep.js +3 -1
- package/dist/esm/utils/accountUtils.js +1 -3
- package/dist/esm/utils/asyncUtils.js +1 -1
- package/dist/esm/utils/authHelpers.js +2 -1
- package/dist/esm/utils/avatarUtils.js +4 -2
- package/dist/esm/utils/cache.js +1 -1
- package/dist/esm/utils/cacheKey.js +3 -1
- package/dist/esm/utils/deviceManager.js +4 -4
- package/dist/esm/utils/errorUtils.js +6 -4
- package/dist/esm/utils/languageUtils.js +404 -57
- package/dist/esm/utils/profileLinks.js +1 -3
- package/dist/esm/utils/requestUtils.js +7 -1
- package/dist/esm/utils/userIdentity.js +1 -1
- package/dist/esm/utils/validationUtils.js +5 -6
- package/dist/types/HttpService.d.ts +1 -1
- package/dist/types/api/accounts.d.ts +1 -1
- package/dist/types/api/apps.d.ts +4 -4
- package/dist/types/api/assets.d.ts +2 -0
- package/dist/types/api/auth.d.ts +8 -3
- package/dist/types/crypto/internal.d.ts +1 -1
- package/dist/types/index.d.ts +4 -4
- package/dist/types/server/index.d.ts +6 -6
- package/dist/types/server/requesterAssertion.d.ts +2 -2
- package/dist/types/server/workloadIdentity.client.d.ts +5 -1
- package/dist/types/server/workloadIdentity.d.ts +26 -0
- package/dist/types/session/accountDelegationAccess.d.ts +1 -1
- package/dist/types/session/index.d.ts +1 -1
- package/dist/types/utils/userIdentity.d.ts +1 -1
- package/dist/types/utils/validationUtils.d.ts +4 -5
- package/package.json +2 -3
- package/src/HttpService.ts +183 -53
- package/src/OxyServices.errors.ts +7 -3
- package/src/OxyServices.ts +6 -2
- package/src/api/accounts.ts +76 -26
- package/src/api/agency.ts +24 -9
- package/src/api/appData.ts +12 -2
- package/src/api/apps.ts +81 -31
- package/src/api/assets.ts +122 -40
- package/src/api/auth.ts +154 -79
- package/src/api/billing.ts +112 -65
- package/src/api/civic.ts +61 -19
- package/src/api/contacts.ts +4 -1
- package/src/api/devices.ts +54 -21
- package/src/api/follows.ts +88 -31
- package/src/api/identity.ts +101 -33
- package/src/api/linkedAccounts.ts +26 -8
- package/src/api/nodes.ts +18 -6
- package/src/api/notifications.ts +26 -6
- package/src/api/privacy.ts +42 -8
- package/src/api/reputation.ts +18 -7
- package/src/api/session.ts +23 -5
- package/src/api/store.ts +81 -31
- package/src/api/topics.ts +18 -6
- package/src/api/users.ts +98 -35
- package/src/boot/sessionColdBoot.ts +60 -19
- package/src/civic/payloads.ts +1 -4
- package/src/client/context.ts +6 -1
- package/src/constants/version.ts +7 -6
- package/src/crypto/aead.ts +1 -5
- package/src/crypto/ecdh.ts +1 -4
- package/src/crypto/identityDerivations.ts +5 -1
- package/src/crypto/identityMarker.ts +3 -1
- package/src/crypto/identityProof.ts +6 -1
- package/src/crypto/index.ts +11 -11
- package/src/crypto/internal.ts +6 -1
- package/src/crypto/keyManager.ts +348 -98
- package/src/crypto/recoveryPhrase.ts +14 -9
- package/src/crypto/registrationPow.ts +1 -1
- package/src/crypto/signatureService.ts +14 -6
- package/src/i18n/accountCategoryLabels.ts +1 -4
- package/src/i18n/accountRoleLabels.ts +1 -4
- package/src/i18n/index.ts +25 -7
- package/src/i18n/locales/ar-SA.ts +375 -366
- package/src/i18n/locales/ca-ES.ts +382 -366
- package/src/i18n/locales/de-DE.ts +387 -366
- package/src/i18n/locales/en-US.ts +2034 -1994
- package/src/i18n/locales/es-ES.ts +2043 -1994
- package/src/i18n/locales/fr-FR.ts +387 -366
- package/src/i18n/locales/it-IT.ts +380 -366
- package/src/i18n/locales/ja-JP.ts +380 -366
- package/src/i18n/locales/ko-KR.ts +377 -366
- package/src/i18n/locales/pt-PT.ts +383 -366
- package/src/i18n/locales/zh-CN.ts +373 -366
- package/src/i18n/trustTierLabels.ts +1 -4
- package/src/index.ts +371 -349
- package/src/inference/OxyInferenceClient.ts +784 -780
- package/src/models/interfaces.ts +30 -27
- package/src/server/OxyServer.ts +227 -68
- package/src/server/agentAccount.ts +8 -2
- package/src/server/aliaMachineCredential.ts +57 -16
- package/src/server/auth.ts +9 -5
- package/src/server/capabilityTicket.ts +30 -21
- package/src/server/index.ts +29 -6
- package/src/server/liveCapabilityTicket.ts +31 -9
- package/src/server/middleware.ts +212 -121
- package/src/server/namespaces.ts +247 -94
- package/src/server/rateLimit.ts +2 -4
- package/src/server/requesterAssertion.ts +93 -54
- package/src/server/serviceTokenLifetime.ts +9 -4
- package/src/server/traffic.ts +117 -23
- package/src/server/trafficNodeHttp.ts +61 -14
- package/src/server/userInvalidation.ts +1 -4
- package/src/server/workloadIdentity.client.ts +12 -1
- package/src/server/workloadIdentity.ts +52 -5
- package/src/session/SessionClient.ts +170 -49
- package/src/session/accountDelegationAccess.ts +24 -31
- package/src/session/accountDialogController.ts +59 -14
- package/src/session/accountSwitchTargets.ts +10 -15
- package/src/session/authStateStore.ts +121 -81
- package/src/session/deviceDirectory.ts +1 -3
- package/src/session/identityPin.ts +10 -11
- package/src/session/identitySession.ts +3 -1
- package/src/session/index.ts +87 -82
- package/src/session/refresh.ts +138 -44
- package/src/session/sessionClientHost.ts +1 -3
- package/src/session/sharedDeviceCredential.ts +35 -14
- package/src/session/socketLoader.ts +9 -2
- package/src/shared/utils/errorUtils.ts +5 -2
- package/src/shared/utils/networkUtils.ts +5 -8
- package/src/shared/utils/themeUtils.ts +2 -6
- package/src/types/buffer.d.ts +66 -21
- package/src/types/expo-secure-store.d.ts +5 -1
- package/src/utils/accountCacheSweep.ts +4 -5
- package/src/utils/accountUtils.ts +107 -108
- package/src/utils/apiUtils.ts +3 -3
- package/src/utils/asyncUtils.ts +2 -2
- package/src/utils/authHelpers.ts +10 -5
- package/src/utils/avatarUtils.ts +11 -6
- package/src/utils/cache.ts +9 -10
- package/src/utils/cacheKey.ts +5 -1
- package/src/utils/coldBoot.ts +1 -3
- package/src/utils/commonsDelivery.ts +1 -4
- package/src/utils/deviceManager.ts +15 -14
- package/src/utils/errorUtils.ts +68 -86
- package/src/utils/languageUtils.ts +407 -58
- package/src/utils/oauthPkce.ts +1 -4
- package/src/utils/platform.ts +0 -1
- package/src/utils/profileLinks.ts +2 -5
- package/src/utils/requestUtils.ts +18 -14
- package/src/utils/sessionUtils.ts +34 -33
- package/src/utils/userHandle.ts +3 -1
- package/src/utils/userIdentity.ts +1 -1
- package/src/utils/validationUtils.ts +11 -9
package/README.md
CHANGED
|
@@ -81,7 +81,7 @@ const url = buildOAuthAuthorizeUrl({
|
|
|
81
81
|
|
|
82
82
|
## User Identity And Handles
|
|
83
83
|
|
|
84
|
-
SDK user payloads may arrive with either `id` or
|
|
84
|
+
SDK user payloads may arrive with either `id` or a raw `_id`; normalize
|
|
85
85
|
them before exposing state to apps:
|
|
86
86
|
|
|
87
87
|
```ts
|
package/dist/cjs/HttpService.js
CHANGED
|
@@ -39,14 +39,25 @@ function sameTokenSession(left, right) {
|
|
|
39
39
|
return false;
|
|
40
40
|
// A refresh may rotate exp/iat/jti while preserving its account and session.
|
|
41
41
|
// Opaque/malformed context fields cannot establish that equivalence.
|
|
42
|
-
return [
|
|
42
|
+
return [
|
|
43
|
+
'userId',
|
|
44
|
+
'id',
|
|
45
|
+
'sub',
|
|
46
|
+
'sessionId',
|
|
47
|
+
'operatorId',
|
|
48
|
+
'clientId',
|
|
49
|
+
'appId',
|
|
50
|
+
'authMethodId',
|
|
51
|
+
].every((key) => (a[key] === undefined || typeof a[key] === 'string') && a[key] === b[key]);
|
|
43
52
|
}
|
|
44
53
|
/** Cancel this wait only; the shared mint continues for other callers. */
|
|
45
54
|
function awaitRequestSignal(pending, signal) {
|
|
46
55
|
if (!signal)
|
|
47
56
|
return pending;
|
|
48
57
|
return new Promise((resolve, reject) => {
|
|
49
|
-
const onAbort = () => {
|
|
58
|
+
const onAbort = () => {
|
|
59
|
+
reject((0, errorUtils_1.createCancelledError)());
|
|
60
|
+
};
|
|
50
61
|
if (signal.aborted)
|
|
51
62
|
onAbort();
|
|
52
63
|
else
|
|
@@ -205,7 +216,9 @@ function isAbortLike(error) {
|
|
|
205
216
|
function linkAbort(parent, child) {
|
|
206
217
|
if (parent.aborted) {
|
|
207
218
|
child.abort(parent.reason);
|
|
208
|
-
return () => {
|
|
219
|
+
return () => {
|
|
220
|
+
/* nothing was ever attached */
|
|
221
|
+
};
|
|
209
222
|
}
|
|
210
223
|
const onAbort = () => {
|
|
211
224
|
child.abort(parent.reason);
|
|
@@ -317,8 +330,7 @@ class HttpService {
|
|
|
317
330
|
// the cache for the global cleanup interval. Default (config unset) keeps
|
|
318
331
|
// caching ON with the 5-minute TTL — unchanged for existing consumers.
|
|
319
332
|
this.cacheDisabled =
|
|
320
|
-
config.enableCache === false ||
|
|
321
|
-
(typeof config.cacheTTL === 'number' && config.cacheTTL <= 0);
|
|
333
|
+
config.enableCache === false || (typeof config.cacheTTL === 'number' && config.cacheTTL <= 0);
|
|
322
334
|
this.cache = new cache_1.TTLCache(config.cacheTTL && config.cacheTTL > 0 ? config.cacheTTL : 5 * 60 * 1000);
|
|
323
335
|
if (!this.cacheDisabled) {
|
|
324
336
|
(0, cache_1.registerCacheForCleanup)(this.cache);
|
|
@@ -494,7 +506,7 @@ class HttpService {
|
|
|
494
506
|
const isUrlEncoded = this.isUrlSearchParams(data);
|
|
495
507
|
// Build headers - start with defaults
|
|
496
508
|
const headers = {
|
|
497
|
-
|
|
509
|
+
Accept: 'application/json',
|
|
498
510
|
};
|
|
499
511
|
// Only set Content-Type for non-FormData requests (FormData sets it automatically with boundary)
|
|
500
512
|
if (isUrlEncoded) {
|
|
@@ -528,7 +540,11 @@ class HttpService {
|
|
|
528
540
|
// `fetch` as-is: RN's fetch does not consistently encode it, and doing
|
|
529
541
|
// it here keeps the body identical across every platform.
|
|
530
542
|
const bodyValue = method !== 'GET' && data
|
|
531
|
-
?
|
|
543
|
+
? isFormData
|
|
544
|
+
? data
|
|
545
|
+
: isUrlEncoded
|
|
546
|
+
? data.toString()
|
|
547
|
+
: JSON.stringify(data)
|
|
532
548
|
: undefined;
|
|
533
549
|
// React Native FormData workaround:
|
|
534
550
|
// Expo SDK 56's "winter fetch" rejects RN file descriptors `{uri, type, name}`
|
|
@@ -570,7 +586,13 @@ class HttpService {
|
|
|
570
586
|
// queue slot, so a queued retry waits for a slot while holding one.
|
|
571
587
|
// With every slot held by a 401 (a revoked session under load) no
|
|
572
588
|
// retry could ever start and the whole client stalled.
|
|
573
|
-
return this.request({
|
|
589
|
+
return this.request({
|
|
590
|
+
...config,
|
|
591
|
+
_isAuthRetry: true,
|
|
592
|
+
retry: false,
|
|
593
|
+
deduplicate: false,
|
|
594
|
+
bypassQueue: true,
|
|
595
|
+
});
|
|
574
596
|
}
|
|
575
597
|
// Refresh failed or no token — clear tokens
|
|
576
598
|
this.tokenStore.clearTokens();
|
|
@@ -597,7 +619,11 @@ class HttpService {
|
|
|
597
619
|
const parsed = (0, errorUtils_1.parseHttpErrorBody)(errorBody);
|
|
598
620
|
const error = new Error(parsed.message ?? `HTTP ${response.status}: ${response.statusText}`);
|
|
599
621
|
error.status = response.status;
|
|
600
|
-
error.response = {
|
|
622
|
+
error.response = {
|
|
623
|
+
status: response.status,
|
|
624
|
+
statusText: response.statusText,
|
|
625
|
+
data: errorBody,
|
|
626
|
+
};
|
|
601
627
|
// Only set `code`/`details` when the server actually sent them.
|
|
602
628
|
// Assigning `undefined` would still create the property, which changes
|
|
603
629
|
// how `handleHttpError` classifies the error downstream.
|
|
@@ -644,7 +670,11 @@ class HttpService {
|
|
|
644
670
|
}
|
|
645
671
|
}
|
|
646
672
|
}
|
|
647
|
-
else if (contentType &&
|
|
673
|
+
else if (contentType &&
|
|
674
|
+
(contentType.includes('application/octet-stream') ||
|
|
675
|
+
contentType.includes('image/') ||
|
|
676
|
+
contentType.includes('video/') ||
|
|
677
|
+
contentType.includes('audio/'))) {
|
|
648
678
|
// For binary responses (blobs), return the blob directly without unwrapping
|
|
649
679
|
responseData = await response.blob();
|
|
650
680
|
}
|
|
@@ -710,7 +740,9 @@ class HttpService {
|
|
|
710
740
|
// Control-plane calls the auth lane depends on (`bypassQueue`, e.g. the
|
|
711
741
|
// device-secret mint) run DIRECTLY — a queued mint could never acquire a
|
|
712
742
|
// slot when every slot is parked awaiting it.
|
|
713
|
-
config.bypassQueue
|
|
743
|
+
config.bypassQueue
|
|
744
|
+
? attempt(domain)
|
|
745
|
+
: this.requestQueue.enqueue(() => attempt(domain), domain);
|
|
714
746
|
const execute = (domain) => retry
|
|
715
747
|
? (0, asyncUtils_1.retryAsync)(() => runAttempt(domain), {
|
|
716
748
|
maxRetries,
|
|
@@ -816,7 +848,9 @@ class HttpService {
|
|
|
816
848
|
try {
|
|
817
849
|
xhr.abort();
|
|
818
850
|
}
|
|
819
|
-
catch {
|
|
851
|
+
catch {
|
|
852
|
+
/* xhr already finished */
|
|
853
|
+
}
|
|
820
854
|
};
|
|
821
855
|
if (abortSignal.aborted) {
|
|
822
856
|
reject(new DOMException('The user aborted a request.', 'AbortError'));
|
|
@@ -1229,8 +1263,10 @@ class HttpService {
|
|
|
1229
1263
|
// an auth mint, even when the trusted transport accepts absolute URLs.
|
|
1230
1264
|
const target = new URL(this.buildURL(config.url));
|
|
1231
1265
|
const base = new URL(this.baseURL);
|
|
1232
|
-
if (target.origin !== base.origin ||
|
|
1233
|
-
|
|
1266
|
+
if (target.origin !== base.origin ||
|
|
1267
|
+
!['http:', 'https:'].includes(target.protocol) ||
|
|
1268
|
+
target.username ||
|
|
1269
|
+
target.password) {
|
|
1234
1270
|
throw new Error('Raw response requests must target the configured API origin');
|
|
1235
1271
|
}
|
|
1236
1272
|
if (config.signal?.aborted)
|
|
@@ -1240,7 +1276,8 @@ class HttpService {
|
|
|
1240
1276
|
const contextToken = this.syncAccessTokenFromProvider();
|
|
1241
1277
|
const beforeAuthEpoch = this.sessionEpoch;
|
|
1242
1278
|
const authHeader = await awaitRequestSignal(this.getAuthHeader(), config.signal);
|
|
1243
|
-
if (beforeAuthEpoch !== this.sessionEpoch ||
|
|
1279
|
+
if (beforeAuthEpoch !== this.sessionEpoch ||
|
|
1280
|
+
!sameTokenSession(contextToken, this.tokenStore.getAccessToken())) {
|
|
1244
1281
|
throw new OxyServices_errors_1.OxyAuthenticationError('The request session changed', 'AUTH_SESSION_CHANGED');
|
|
1245
1282
|
}
|
|
1246
1283
|
if (config.signal?.aborted)
|
|
@@ -1253,7 +1290,8 @@ class HttpService {
|
|
|
1253
1290
|
async requestResponseAttempt(config, fullUrl, authHeader, isAuthRetry, epoch, contextToken) {
|
|
1254
1291
|
const assertCurrent = () => {
|
|
1255
1292
|
this.syncAccessTokenFromProvider();
|
|
1256
|
-
if (epoch !== this.sessionEpoch ||
|
|
1293
|
+
if (epoch !== this.sessionEpoch ||
|
|
1294
|
+
!sameTokenSession(contextToken, this.tokenStore.getAccessToken())) {
|
|
1257
1295
|
throw new OxyServices_errors_1.OxyAuthenticationError('The request session changed', 'AUTH_SESSION_CHANGED');
|
|
1258
1296
|
}
|
|
1259
1297
|
};
|
|
@@ -1298,7 +1336,11 @@ class HttpService {
|
|
|
1298
1336
|
throw error;
|
|
1299
1337
|
}
|
|
1300
1338
|
const replayable = body === undefined || typeof body === 'string';
|
|
1301
|
-
if (response.status === 401 &&
|
|
1339
|
+
if (response.status === 401 &&
|
|
1340
|
+
!isAuthRetry &&
|
|
1341
|
+
authHeader &&
|
|
1342
|
+
replayable &&
|
|
1343
|
+
!config.signal?.aborted) {
|
|
1302
1344
|
let refreshed;
|
|
1303
1345
|
try {
|
|
1304
1346
|
refreshed = await awaitRequestSignal(this.refreshAccessToken('response-401'), config.signal);
|
|
@@ -1333,7 +1375,9 @@ class HttpService {
|
|
|
1333
1375
|
this.config.onRequestEnd?.(config.url, config.method, duration, false);
|
|
1334
1376
|
const normalizedError = config.signal?.aborted || (0, errorUtils_1.isCancelledError)(error)
|
|
1335
1377
|
? (0, errorUtils_1.createCancelledError)()
|
|
1336
|
-
: error instanceof Error
|
|
1378
|
+
: error instanceof Error
|
|
1379
|
+
? error
|
|
1380
|
+
: new Error(String(error));
|
|
1337
1381
|
this.config.onRequestError?.(config.url, config.method, normalizedError);
|
|
1338
1382
|
if ((0, errorUtils_1.isCancelledError)(normalizedError) || normalizedError instanceof OxyServices_errors_1.OxyAuthenticationError)
|
|
1339
1383
|
throw normalizedError;
|
|
@@ -1505,7 +1549,7 @@ class HttpService {
|
|
|
1505
1549
|
* per resource.
|
|
1506
1550
|
* @returns Number of entries deleted
|
|
1507
1551
|
*/
|
|
1508
|
-
invalidateCache({ keys = [], prefixes = [] }) {
|
|
1552
|
+
invalidateCache({ keys = [], prefixes = [], }) {
|
|
1509
1553
|
if (keys.length === 0 && prefixes.length === 0)
|
|
1510
1554
|
return 0;
|
|
1511
1555
|
const exact = new Set(keys);
|
package/dist/cjs/api/accounts.js
CHANGED
|
@@ -105,7 +105,9 @@ class AccountAgentKeysApi {
|
|
|
105
105
|
this.ctx = ctx;
|
|
106
106
|
}
|
|
107
107
|
async list(accountId) {
|
|
108
|
-
return contracts_1.agentKeyListResponseSchema.parse(await this.ctx.request('GET', `/accounts/${enc(accountId)}/agent-keys`, undefined, {
|
|
108
|
+
return contracts_1.agentKeyListResponseSchema.parse(await this.ctx.request('GET', `/accounts/${enc(accountId)}/agent-keys`, undefined, {
|
|
109
|
+
cache: false,
|
|
110
|
+
}));
|
|
109
111
|
}
|
|
110
112
|
async requestChallenge(accountId, operation) {
|
|
111
113
|
const response = await this.ctx.request('POST', `/accounts/${enc(accountId)}/agent-keys/challenge`, contracts_1.agentKeyOperationSchema.parse(operation), { cache: false });
|
|
@@ -195,7 +197,9 @@ class AccountsApi {
|
|
|
195
197
|
* @param data - Account configuration: kind, optional parent, and profile.
|
|
196
198
|
*/
|
|
197
199
|
async create(data) {
|
|
198
|
-
const res = await this.ctx.request('POST', '/accounts', data, {
|
|
200
|
+
const res = await this.ctx.request('POST', '/accounts', data, {
|
|
201
|
+
cache: false,
|
|
202
|
+
});
|
|
199
203
|
// A new account changes the accessible forest — bust every cached list.
|
|
200
204
|
(0, accountCacheSweep_1.evictOxyAccountForestCache)(this.ctx.http);
|
|
201
205
|
return res.account;
|
|
@@ -235,7 +239,10 @@ class AccountsApi {
|
|
|
235
239
|
cache: false,
|
|
236
240
|
});
|
|
237
241
|
this.ctx.http.invalidateCache({
|
|
238
|
-
keys: [
|
|
242
|
+
keys: [
|
|
243
|
+
`GET:/accounts/${enc(accountId)}/members`,
|
|
244
|
+
`GET:/accounts/${enc(accountId)}/credentials`,
|
|
245
|
+
],
|
|
239
246
|
});
|
|
240
247
|
(0, accountCacheSweep_1.evictOxyAccountForestCache)(this.ctx.http, accountId);
|
|
241
248
|
return result;
|
package/dist/cjs/api/agency.js
CHANGED
|
@@ -36,7 +36,9 @@ class DelegationGrantsApi {
|
|
|
36
36
|
}
|
|
37
37
|
/** Revoke a grant. */
|
|
38
38
|
async revoke(grantId, ownerAccountId) {
|
|
39
|
-
await this.ctx.request('DELETE', `/capabilities/grants/${enc(grantId)}`, undefined, {
|
|
39
|
+
await this.ctx.request('DELETE', `/capabilities/grants/${enc(grantId)}`, undefined, {
|
|
40
|
+
cache: false,
|
|
41
|
+
});
|
|
40
42
|
this.ctx.oxy.cache.delete(grantsKey(ownerAccountId));
|
|
41
43
|
}
|
|
42
44
|
}
|
package/dist/cjs/api/apps.js
CHANGED
|
@@ -72,7 +72,10 @@ class ConnectedAppsApi {
|
|
|
72
72
|
* `GET /auth/grants`, briefly cached; `revoke` busts it.
|
|
73
73
|
*/
|
|
74
74
|
async list() {
|
|
75
|
-
return this.ctx.request('GET', '/auth/grants', undefined, {
|
|
75
|
+
return this.ctx.request('GET', '/auth/grants', undefined, {
|
|
76
|
+
cache: true,
|
|
77
|
+
cacheTTL: SHORT_TTL,
|
|
78
|
+
});
|
|
76
79
|
}
|
|
77
80
|
/**
|
|
78
81
|
* Revoke this user's grant for a connected application. After this the
|
|
@@ -94,7 +97,9 @@ class ConnectedAppsApi {
|
|
|
94
97
|
}
|
|
95
98
|
/** Revoke one external MCP connection and every token in its family. */
|
|
96
99
|
async revokeMcpClient(grantId) {
|
|
97
|
-
await this.ctx.request('DELETE', `/auth/mcp/oauth/grants/${enc(grantId)}`, undefined, {
|
|
100
|
+
await this.ctx.request('DELETE', `/auth/mcp/oauth/grants/${enc(grantId)}`, undefined, {
|
|
101
|
+
cache: false,
|
|
102
|
+
});
|
|
98
103
|
this.ctx.oxy.cache.delete('GET:/auth/mcp/oauth/grants');
|
|
99
104
|
}
|
|
100
105
|
}
|
|
@@ -154,7 +159,10 @@ class AppsApi {
|
|
|
154
159
|
const result = await this.ctx.request('DELETE', appPath(applicationId), undefined, {
|
|
155
160
|
cache: false,
|
|
156
161
|
});
|
|
157
|
-
this.invalidateLists([
|
|
162
|
+
this.invalidateLists([
|
|
163
|
+
`GET:${appPath(applicationId)}`,
|
|
164
|
+
`GET:${credentialsPath(applicationId)}`,
|
|
165
|
+
]);
|
|
158
166
|
return result;
|
|
159
167
|
}
|
|
160
168
|
/**
|
|
@@ -185,7 +193,10 @@ class AppsApi {
|
|
|
185
193
|
* `GET:/applications/<id>…` detail keys.
|
|
186
194
|
*/
|
|
187
195
|
invalidateLists(extraKeys = []) {
|
|
188
|
-
this.ctx.http.invalidateCache({
|
|
196
|
+
this.ctx.http.invalidateCache({
|
|
197
|
+
keys: ['GET:/applications', ...extraKeys],
|
|
198
|
+
prefixes: ['GET:/applications?'],
|
|
199
|
+
});
|
|
189
200
|
}
|
|
190
201
|
}
|
|
191
202
|
exports.AppsApi = AppsApi;
|
package/dist/cjs/api/assets.js
CHANGED
|
@@ -38,6 +38,12 @@ const ASSET_URL_CACHE_LIFETIME_FRACTION = 0.5;
|
|
|
38
38
|
/** Assumed URL lifetime (seconds) when no `expiresIn` is asked for; the API default. */
|
|
39
39
|
const DEFAULT_ASSET_URL_EXPIRES_IN_SECONDS = 3600;
|
|
40
40
|
const ASSET_TTL = 5 * 60 * 1000;
|
|
41
|
+
/**
|
|
42
|
+
* Default bound on one `POST /assets/upload`, in ms. The client's per-request
|
|
43
|
+
* default (5s) is sized for JSON calls; a video sent over a phone connection
|
|
44
|
+
* needs minutes, and timing it out at 5s failed every upload past a few MB.
|
|
45
|
+
*/
|
|
46
|
+
const ASSET_UPLOAD_TIMEOUT_MS = 10 * 60 * 1000;
|
|
41
47
|
/**
|
|
42
48
|
* How long a resolved asset URL may stay in the SDK's GET cache, in ms: never
|
|
43
49
|
* longer than the media token's lifetime, and discounted below it.
|
|
@@ -65,7 +71,13 @@ class AssetsApi {
|
|
|
65
71
|
});
|
|
66
72
|
if (body.type && !headers.has('Content-Type'))
|
|
67
73
|
headers.set('Content-Type', body.type);
|
|
68
|
-
const result = await fetch(target.toString(), {
|
|
74
|
+
const result = await fetch(target.toString(), {
|
|
75
|
+
method: 'PUT',
|
|
76
|
+
body,
|
|
77
|
+
headers,
|
|
78
|
+
credentials: 'omit',
|
|
79
|
+
redirect: 'error',
|
|
80
|
+
});
|
|
69
81
|
if (!result.ok)
|
|
70
82
|
throw new Error(`Presigned upload failed (${result.status})`);
|
|
71
83
|
}
|
|
@@ -83,7 +95,8 @@ class AssetsApi {
|
|
|
83
95
|
const fileName = 'name' in file && file.name ? file.name : 'unknown';
|
|
84
96
|
const fileSize = 'size' in file && file.size ? file.size : 0;
|
|
85
97
|
const formData = new FormData();
|
|
86
|
-
if ((typeof File !== 'undefined' && file instanceof File) ||
|
|
98
|
+
if ((typeof File !== 'undefined' && file instanceof File) ||
|
|
99
|
+
(typeof Blob !== 'undefined' && file instanceof Blob)) {
|
|
87
100
|
formData.append('file', file, fileName);
|
|
88
101
|
}
|
|
89
102
|
else if ('uri' in file && typeof file.uri === 'string') {
|
|
@@ -99,7 +112,9 @@ class AssetsApi {
|
|
|
99
112
|
throw new Error(`Failed to read file from uri (status ${res.status})`);
|
|
100
113
|
}
|
|
101
114
|
const fetched = await res.blob();
|
|
102
|
-
const blob = fetched.type === '' && descriptor.type
|
|
115
|
+
const blob = fetched.type === '' && descriptor.type
|
|
116
|
+
? new Blob([fetched], { type: descriptor.type })
|
|
117
|
+
: fetched;
|
|
103
118
|
if (blob.size === 0) {
|
|
104
119
|
throw new Error('Cannot upload an empty file');
|
|
105
120
|
}
|
|
@@ -114,13 +129,19 @@ class AssetsApi {
|
|
|
114
129
|
if (options.metadata)
|
|
115
130
|
formData.append('metadata', JSON.stringify(options.metadata));
|
|
116
131
|
try {
|
|
117
|
-
const response = await this.ctx.request('POST', '/assets/upload', formData, {
|
|
132
|
+
const response = await this.ctx.request('POST', '/assets/upload', formData, {
|
|
133
|
+
cache: false,
|
|
134
|
+
timeout: options.timeout ?? ASSET_UPLOAD_TIMEOUT_MS,
|
|
135
|
+
});
|
|
118
136
|
options.onProgress?.(100);
|
|
119
137
|
return response;
|
|
120
138
|
}
|
|
121
139
|
catch (error) {
|
|
122
140
|
logger_1.logger.error('File upload error', error, { component: 'oxy.assets' });
|
|
123
|
-
error.fileContext = {
|
|
141
|
+
error.fileContext = {
|
|
142
|
+
fileName,
|
|
143
|
+
fileSize,
|
|
144
|
+
};
|
|
124
145
|
throw error;
|
|
125
146
|
}
|
|
126
147
|
}
|
|
@@ -136,7 +157,9 @@ class AssetsApi {
|
|
|
136
157
|
// ── Links ────────────────────────────────────────────────────────────────
|
|
137
158
|
/** Link an asset to an entity (what keeps it alive). */
|
|
138
159
|
async link(fileId, target, options = {}) {
|
|
139
|
-
const body = {
|
|
160
|
+
const body = {
|
|
161
|
+
...target,
|
|
162
|
+
};
|
|
140
163
|
if (options.visibility)
|
|
141
164
|
body.visibility = options.visibility;
|
|
142
165
|
if (options.webhookUrl)
|
|
@@ -156,7 +179,10 @@ class AssetsApi {
|
|
|
156
179
|
// ── Reads ────────────────────────────────────────────────────────────────
|
|
157
180
|
/** An asset's record: size, mime, visibility, links, variants. */
|
|
158
181
|
async get(fileId) {
|
|
159
|
-
return this.ctx.request('GET', `/assets/${enc(fileId)}`, undefined, {
|
|
182
|
+
return this.ctx.request('GET', `/assets/${enc(fileId)}`, undefined, {
|
|
183
|
+
cache: true,
|
|
184
|
+
cacheTTL: ASSET_TTL,
|
|
185
|
+
});
|
|
160
186
|
}
|
|
161
187
|
/** The signed-in user's files, newest first. */
|
|
162
188
|
async list(params = {}) {
|
|
@@ -169,7 +195,9 @@ class AssetsApi {
|
|
|
169
195
|
}
|
|
170
196
|
/** The account's storage usage, aggregated from its assets. */
|
|
171
197
|
async usage() {
|
|
172
|
-
return this.ctx.request('GET', '/storage/usage', undefined, {
|
|
198
|
+
return this.ctx.request('GET', '/storage/usage', undefined, {
|
|
199
|
+
cache: false,
|
|
200
|
+
});
|
|
173
201
|
}
|
|
174
202
|
// ── URLs ─────────────────────────────────────────────────────────────────
|
|
175
203
|
/**
|
|
@@ -251,7 +279,9 @@ class AssetsApi {
|
|
|
251
279
|
body.expiresIn = options.expiresIn;
|
|
252
280
|
if (typeof options?.context === 'string')
|
|
253
281
|
body.context = options.context;
|
|
254
|
-
return this.ctx.request('POST', '/assets/batch-access', body, {
|
|
282
|
+
return this.ctx.request('POST', '/assets/batch-access', body, {
|
|
283
|
+
cache: false,
|
|
284
|
+
});
|
|
255
285
|
}
|
|
256
286
|
// ── Content ──────────────────────────────────────────────────────────────
|
|
257
287
|
/** An asset's content as text. */
|
|
@@ -271,7 +301,9 @@ class AssetsApi {
|
|
|
271
301
|
*/
|
|
272
302
|
async delete(fileId, options = {}) {
|
|
273
303
|
const url = `/assets/${enc(fileId)}${options.force ? '?force=true' : ''}`;
|
|
274
|
-
const res = await this.ctx.request('DELETE', url, undefined, {
|
|
304
|
+
const res = await this.ctx.request('DELETE', url, undefined, {
|
|
305
|
+
cache: false,
|
|
306
|
+
});
|
|
275
307
|
this.evict(fileId);
|
|
276
308
|
return res;
|
|
277
309
|
}
|
|
@@ -313,7 +345,10 @@ class AssetsApi {
|
|
|
313
345
|
}
|
|
314
346
|
/** Drop the cached record and every cached URL variant of an asset, in one pass. */
|
|
315
347
|
evict(fileId) {
|
|
316
|
-
this.ctx.http.invalidateCache({
|
|
348
|
+
this.ctx.http.invalidateCache({
|
|
349
|
+
keys: [`GET:/assets/${enc(fileId)}`],
|
|
350
|
+
prefixes: [`GET:/assets/${enc(fileId)}/url`],
|
|
351
|
+
});
|
|
317
352
|
}
|
|
318
353
|
}
|
|
319
354
|
exports.AssetsApi = AssetsApi;
|
|
@@ -333,7 +368,9 @@ function dedupeFileAccessRequests(requests) {
|
|
|
333
368
|
if (seen.has(key))
|
|
334
369
|
continue;
|
|
335
370
|
seen.add(key);
|
|
336
|
-
out.push(req.variant === undefined
|
|
371
|
+
out.push(req.variant === undefined
|
|
372
|
+
? { fileId: req.fileId }
|
|
373
|
+
: { fileId: req.fileId, variant: req.variant });
|
|
337
374
|
}
|
|
338
375
|
return out;
|
|
339
376
|
}
|
package/dist/cjs/api/auth.js
CHANGED
|
@@ -233,7 +233,9 @@ class AuthPasswordApi {
|
|
|
233
233
|
return signInStep(this.ctx, res, 'auth/signin/password');
|
|
234
234
|
}
|
|
235
235
|
async set(request) {
|
|
236
|
-
return this.ctx.request('PUT', '/users/me/password', request, {
|
|
236
|
+
return this.ctx.request('PUT', '/users/me/password', request, {
|
|
237
|
+
cache: false,
|
|
238
|
+
});
|
|
237
239
|
}
|
|
238
240
|
}
|
|
239
241
|
exports.AuthPasswordApi = AuthPasswordApi;
|
|
@@ -243,7 +245,9 @@ class AuthTotpApi {
|
|
|
243
245
|
this.ctx = ctx;
|
|
244
246
|
}
|
|
245
247
|
async enroll() {
|
|
246
|
-
const res = await this.ctx.request('POST', '/users/me/totp/enroll', undefined, {
|
|
248
|
+
const res = await this.ctx.request('POST', '/users/me/totp/enroll', undefined, {
|
|
249
|
+
cache: false,
|
|
250
|
+
});
|
|
247
251
|
const parsed = (0, contracts_1.safeParseContract)(contracts_1.totpEnrollResponseSchema, res);
|
|
248
252
|
if (!parsed)
|
|
249
253
|
throw new Error('users/me/totp/enroll returned an unexpected response shape');
|
|
@@ -312,7 +316,10 @@ class AuthOAuthApi {
|
|
|
312
316
|
client_id: params.clientId,
|
|
313
317
|
code_verifier: params.codeVerifier,
|
|
314
318
|
});
|
|
315
|
-
const res = await this.ctx.request('POST', '/auth/oauth/token', form, {
|
|
319
|
+
const res = await this.ctx.request('POST', '/auth/oauth/token', form, {
|
|
320
|
+
cache: false,
|
|
321
|
+
skipAuth: true,
|
|
322
|
+
});
|
|
316
323
|
if (!res || typeof res !== 'object') {
|
|
317
324
|
throw new Error('auth/oauth/token returned an unexpected response shape');
|
|
318
325
|
}
|
|
@@ -363,7 +370,9 @@ class AuthOAuthApi {
|
|
|
363
370
|
* The response is a flat JSON document — no `{ data }` wrapper.
|
|
364
371
|
*/
|
|
365
372
|
async userInfo() {
|
|
366
|
-
const res = await this.ctx.request('GET', '/auth/oauth/userinfo', undefined, {
|
|
373
|
+
const res = await this.ctx.request('GET', '/auth/oauth/userinfo', undefined, {
|
|
374
|
+
cache: false,
|
|
375
|
+
});
|
|
367
376
|
if (!res || typeof res !== 'object') {
|
|
368
377
|
throw new Error('auth/oauth/userinfo returned an unexpected response shape');
|
|
369
378
|
}
|
|
@@ -693,12 +702,18 @@ class AuthAgentApi {
|
|
|
693
702
|
}
|
|
694
703
|
async requestChallenge(publicKey) {
|
|
695
704
|
const body = contracts_1.agentChallengeRequestSchema.parse({ publicKey });
|
|
696
|
-
const response = await this.ctx.request('POST', '/auth/agent/challenge', body, {
|
|
705
|
+
const response = await this.ctx.request('POST', '/auth/agent/challenge', body, {
|
|
706
|
+
cache: false,
|
|
707
|
+
skipAuth: true,
|
|
708
|
+
});
|
|
697
709
|
return contracts_1.agentProofClaimsSchema.parse(response);
|
|
698
710
|
}
|
|
699
711
|
async verify(publicKey, proof) {
|
|
700
712
|
const body = contracts_1.agentVerifyRequestSchema.parse({ publicKey, ...proof });
|
|
701
|
-
const response = await this.ctx.request('POST', '/auth/agent/verify', body, {
|
|
713
|
+
const response = await this.ctx.request('POST', '/auth/agent/verify', body, {
|
|
714
|
+
cache: false,
|
|
715
|
+
skipAuth: true,
|
|
716
|
+
});
|
|
702
717
|
return plantSession(this.ctx, response, 'auth/agent/verify');
|
|
703
718
|
}
|
|
704
719
|
}
|
|
@@ -714,14 +729,19 @@ class AuthApi {
|
|
|
714
729
|
this.agent = new AuthAgentApi(ctx);
|
|
715
730
|
}
|
|
716
731
|
/**
|
|
717
|
-
* Register a new
|
|
718
|
-
*
|
|
732
|
+
* Register a new account for a public key, together with its username.
|
|
733
|
+
*
|
|
734
|
+
* The username is required: the server writes it in the same insert as the
|
|
735
|
+
* key, so an account never exists without one. A taken username is a 409
|
|
736
|
+
* (`Username already taken`), as is a key that is already registered
|
|
737
|
+
* (`Identity already registered`).
|
|
719
738
|
*
|
|
720
739
|
* @param publicKey - The user's ECDSA public key (hex)
|
|
721
740
|
* @param signature - Signature of the registration request
|
|
722
741
|
* @param timestamp - Timestamp when the signature was created
|
|
742
|
+
* @param username - The account's username
|
|
723
743
|
*/
|
|
724
|
-
async registerKey(publicKey, signature, timestamp) {
|
|
744
|
+
async registerKey(publicKey, signature, timestamp, username) {
|
|
725
745
|
// Advisory for now (server soft-enforces — see
|
|
726
746
|
// `SessionController.register`), but solved unconditionally so every
|
|
727
747
|
// client is already sending it once the server starts requiring it.
|
|
@@ -731,6 +751,7 @@ class AuthApi {
|
|
|
731
751
|
publicKey,
|
|
732
752
|
signature,
|
|
733
753
|
timestamp,
|
|
754
|
+
username,
|
|
734
755
|
powNonce,
|
|
735
756
|
}, { cache: false, skipAuth: true });
|
|
736
757
|
if (!res || (typeof res === 'object' && Object.keys(res).length === 0)) {
|
|
@@ -895,7 +916,10 @@ class AuthApi {
|
|
|
895
916
|
*/
|
|
896
917
|
async checkUsername(username) {
|
|
897
918
|
// Public availability lookup (pre-session) — skip the bearer preflight.
|
|
898
|
-
return this.ctx.request('GET', `/auth/check-username/${username}`, undefined, {
|
|
919
|
+
return this.ctx.request('GET', `/auth/check-username/${username}`, undefined, {
|
|
920
|
+
cache: false,
|
|
921
|
+
skipAuth: true,
|
|
922
|
+
});
|
|
899
923
|
}
|
|
900
924
|
/**
|
|
901
925
|
* The authenticator's code (or a backup code) for a first factor's
|
|
@@ -913,7 +937,9 @@ class AuthApi {
|
|
|
913
937
|
return plantSession(this.ctx, res, 'auth/signup');
|
|
914
938
|
}
|
|
915
939
|
async methods() {
|
|
916
|
-
const res = await this.ctx.request('GET', '/users/me/sign-in-methods', undefined, {
|
|
940
|
+
const res = await this.ctx.request('GET', '/users/me/sign-in-methods', undefined, {
|
|
941
|
+
cache: false,
|
|
942
|
+
});
|
|
917
943
|
const parsed = (0, contracts_1.safeParseContract)(contracts_1.signInMethodsSchema, res);
|
|
918
944
|
if (!parsed)
|
|
919
945
|
throw new Error('users/me/sign-in-methods returned an unexpected response shape');
|
package/dist/cjs/api/billing.js
CHANGED
|
@@ -27,7 +27,9 @@ class BillingApi {
|
|
|
27
27
|
}
|
|
28
28
|
/** Public versioned personal plans. Discovery never proves customer access. */
|
|
29
29
|
async personalPlans() {
|
|
30
|
-
return contracts_2.personalPlanCatalogueSchema.parse(await this.ctx.request('GET', '/billing/personal-plans', undefined, {
|
|
30
|
+
return contracts_2.personalPlanCatalogueSchema.parse(await this.ctx.request('GET', '/billing/personal-plans', undefined, {
|
|
31
|
+
cache: false,
|
|
32
|
+
}));
|
|
31
33
|
}
|
|
32
34
|
/** Product rights only; requires a production application-bound user session. Never cached. */
|
|
33
35
|
async productAccess(query) {
|
|
@@ -37,19 +39,29 @@ class BillingApi {
|
|
|
37
39
|
}
|
|
38
40
|
/** Named commercial sources for the current subject; no inferred plan collapse. */
|
|
39
41
|
async productSubscriptions(expectedSubjectAccountId) {
|
|
40
|
-
return contracts_4.productSubscriptionsResponseSchema.parse(await this.ctx.request(
|
|
42
|
+
return contracts_4.productSubscriptionsResponseSchema.parse(await this.ctx.request('GET', expectedSubjectAccountId
|
|
43
|
+
? `/billing/product-subscriptions?expectedSubjectAccountId=${encodeURIComponent(expectedSubjectAccountId)}`
|
|
44
|
+
: '/billing/product-subscriptions', undefined, { cache: false })).subscriptions;
|
|
41
45
|
}
|
|
42
46
|
/** Per-grant credit provenance; no interpretation of the historical mixed balance. */
|
|
43
47
|
async creditGrants() {
|
|
44
|
-
return contracts_4.subscriptionCreditGrantsResponseSchema.parse(await this.ctx.request(
|
|
48
|
+
return contracts_4.subscriptionCreditGrantsResponseSchema.parse(await this.ctx.request('GET', '/billing/credit-grants', undefined, { cache: false })).grants;
|
|
45
49
|
}
|
|
46
50
|
/** Payer-only named-source cancellation. Resolves on provider acceptance, including pending local reconciliation. Use cancelProductSubscriptionWithStatus for detailed completion state. */
|
|
47
51
|
async cancelProductSubscription(sourceId, expectedSubjectAccountId, actionId) {
|
|
48
|
-
await this.ctx.request(
|
|
52
|
+
await this.ctx.request('POST', '/billing/product-subscriptions/cancel', contracts_4.cancelProductSubscriptionSchema.parse({
|
|
53
|
+
sourceId,
|
|
54
|
+
...(actionId ? { actionId } : {}),
|
|
55
|
+
...(expectedSubjectAccountId ? { expectedSubjectAccountId } : {}),
|
|
56
|
+
}), { cache: false });
|
|
49
57
|
}
|
|
50
58
|
/** Provider acceptance versus completed local cancellation, for user-facing flows. */
|
|
51
59
|
async cancelProductSubscriptionWithStatus(sourceId, expectedSubjectAccountId, actionId) {
|
|
52
|
-
return contracts_4.productSubscriptionCancellationResultSchema.parse(await this.ctx.request('POST', '/billing/product-subscriptions/cancel', contracts_4.cancelProductSubscriptionSchema.parse({
|
|
60
|
+
return contracts_4.productSubscriptionCancellationResultSchema.parse(await this.ctx.request('POST', '/billing/product-subscriptions/cancel', contracts_4.cancelProductSubscriptionSchema.parse({
|
|
61
|
+
sourceId,
|
|
62
|
+
...(actionId ? { actionId } : {}),
|
|
63
|
+
...(expectedSubjectAccountId ? { expectedSubjectAccountId } : {}),
|
|
64
|
+
}), { cache: false }));
|
|
53
65
|
}
|
|
54
66
|
/** The signed-in user's payment history. Never cached. */
|
|
55
67
|
async payments() {
|
|
@@ -66,7 +78,10 @@ class BillingApi {
|
|
|
66
78
|
/** A user's wallet (default: the signed-in user's). Cached briefly: the balance moves. */
|
|
67
79
|
async wallet(userId) {
|
|
68
80
|
const id = this.resolveUserId(userId);
|
|
69
|
-
return this.ctx.request('GET', `/wallet/${id}`, undefined, {
|
|
81
|
+
return this.ctx.request('GET', `/wallet/${id}`, undefined, {
|
|
82
|
+
cache: true,
|
|
83
|
+
cacheTTL: WALLET_TTL,
|
|
84
|
+
});
|
|
70
85
|
}
|
|
71
86
|
/** A page of a user's wallet transactions (default: the signed-in user's). Never cached. */
|
|
72
87
|
async walletTransactions(options = {}) {
|
|
@@ -76,7 +91,9 @@ class BillingApi {
|
|
|
76
91
|
params.limit = options.limit;
|
|
77
92
|
if (options.offset)
|
|
78
93
|
params.offset = options.offset;
|
|
79
|
-
return this.ctx.request('GET', `/wallet/transactions/${id}`, params, {
|
|
94
|
+
return this.ctx.request('GET', `/wallet/transactions/${id}`, params, {
|
|
95
|
+
cache: false,
|
|
96
|
+
});
|
|
80
97
|
}
|
|
81
98
|
resolveUserId(userId) {
|
|
82
99
|
const id = userId || this.ctx.oxy.session.userId;
|