@oxy.so/core 4.5.0-oxy-one.1 → 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 +39 -11
- package/dist/cjs/api/auth.js +28 -8
- 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 +39 -11
- package/dist/esm/api/auth.js +28 -8
- 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/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/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 +113 -43
- package/src/api/auth.ts +145 -77
- 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/src/api/follows.ts
CHANGED
|
@@ -128,7 +128,12 @@ export class FollowsApi {
|
|
|
128
128
|
|
|
129
129
|
/** Follow a user. */
|
|
130
130
|
async follow(userId: string): Promise<FollowMutationResult> {
|
|
131
|
-
const result = await this.ctx.request<FollowMutationResult>(
|
|
131
|
+
const result = await this.ctx.request<FollowMutationResult>(
|
|
132
|
+
'POST',
|
|
133
|
+
`/users/${userId}/follow`,
|
|
134
|
+
undefined,
|
|
135
|
+
{ cache: false },
|
|
136
|
+
);
|
|
132
137
|
this.invalidate([userId]);
|
|
133
138
|
return result;
|
|
134
139
|
}
|
|
@@ -136,14 +141,24 @@ export class FollowsApi {
|
|
|
136
141
|
/** Follow many users in one request (the server caps it at 200). */
|
|
137
142
|
async followMany(userIds: string[]): Promise<BulkFollowResult> {
|
|
138
143
|
if (userIds.length === 0) return { results: [], followedCount: 0 };
|
|
139
|
-
const result = await this.ctx.request<BulkFollowResult>(
|
|
144
|
+
const result = await this.ctx.request<BulkFollowResult>(
|
|
145
|
+
'POST',
|
|
146
|
+
'/users/follow/bulk',
|
|
147
|
+
{ userIds },
|
|
148
|
+
{ cache: false },
|
|
149
|
+
);
|
|
140
150
|
this.invalidate(userIds);
|
|
141
151
|
return result;
|
|
142
152
|
}
|
|
143
153
|
|
|
144
154
|
/** Unfollow a user. */
|
|
145
155
|
async unfollow(userId: string): Promise<FollowMutationResult> {
|
|
146
|
-
const result = await this.ctx.request<FollowMutationResult>(
|
|
156
|
+
const result = await this.ctx.request<FollowMutationResult>(
|
|
157
|
+
'DELETE',
|
|
158
|
+
`/users/${userId}/follow`,
|
|
159
|
+
undefined,
|
|
160
|
+
{ cache: false },
|
|
161
|
+
);
|
|
147
162
|
this.invalidate([userId]);
|
|
148
163
|
return result;
|
|
149
164
|
}
|
|
@@ -151,14 +166,22 @@ export class FollowsApi {
|
|
|
151
166
|
/** Unfollow many users in one request (the server caps it at 200). */
|
|
152
167
|
async unfollowMany(userIds: string[]): Promise<BulkUnfollowResult> {
|
|
153
168
|
if (userIds.length === 0) return { results: [], unfollowedCount: 0 };
|
|
154
|
-
const result = await this.ctx.request<BulkUnfollowResult>(
|
|
169
|
+
const result = await this.ctx.request<BulkUnfollowResult>(
|
|
170
|
+
'POST',
|
|
171
|
+
'/users/unfollow/bulk',
|
|
172
|
+
{ userIds },
|
|
173
|
+
{ cache: false },
|
|
174
|
+
);
|
|
155
175
|
this.invalidate(userIds);
|
|
156
176
|
return result;
|
|
157
177
|
}
|
|
158
178
|
|
|
159
179
|
/** Whether the signed-in user follows `userId`. Cached 1 minute, busted by every write. */
|
|
160
180
|
async status(userId: string): Promise<{ isFollowing: boolean }> {
|
|
161
|
-
return this.ctx.request('GET', `/users/${userId}/follow-status`, undefined, {
|
|
181
|
+
return this.ctx.request('GET', `/users/${userId}/follow-status`, undefined, {
|
|
182
|
+
cache: true,
|
|
183
|
+
cacheTTL: STATUS_TTL,
|
|
184
|
+
});
|
|
162
185
|
}
|
|
163
186
|
|
|
164
187
|
/**
|
|
@@ -222,10 +245,15 @@ export class FollowsApi {
|
|
|
222
245
|
* Signed out: `[]`. Cached 2 minutes.
|
|
223
246
|
*/
|
|
224
247
|
async mutualIds(params?: { limit?: number }): Promise<string[]> {
|
|
225
|
-
const response = await this.ctx.request<{ data: string[] }>(
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
248
|
+
const response = await this.ctx.request<{ data: string[] }>(
|
|
249
|
+
'GET',
|
|
250
|
+
'/users/mutual-ids',
|
|
251
|
+
buildPaginationParams(params ?? {}),
|
|
252
|
+
{
|
|
253
|
+
cache: true,
|
|
254
|
+
cacheTTL: GRAPH_TTL,
|
|
255
|
+
},
|
|
256
|
+
);
|
|
229
257
|
return response.data || [];
|
|
230
258
|
}
|
|
231
259
|
|
|
@@ -249,10 +277,15 @@ export class FollowsApi {
|
|
|
249
277
|
* Cached 2 minutes; follow, block and restrict writes bust it.
|
|
250
278
|
*/
|
|
251
279
|
async viewerGraph(): Promise<ViewerGraph> {
|
|
252
|
-
const response = await this.ctx.request<{ data: ViewerGraph }>(
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
280
|
+
const response = await this.ctx.request<{ data: ViewerGraph }>(
|
|
281
|
+
'GET',
|
|
282
|
+
'/users/me/graph',
|
|
283
|
+
undefined,
|
|
284
|
+
{
|
|
285
|
+
cache: true,
|
|
286
|
+
cacheTTL: GRAPH_TTL,
|
|
287
|
+
},
|
|
288
|
+
);
|
|
256
289
|
const graph = response.data;
|
|
257
290
|
return {
|
|
258
291
|
followingIds: graph?.followingIds || [],
|
|
@@ -284,9 +317,14 @@ export class FollowsApi {
|
|
|
284
317
|
* 'disabled')`.) Idempotent: `removed: false` when already gone.
|
|
285
318
|
*/
|
|
286
319
|
async unfollowTarget(relationshipId: string): Promise<UnfollowMutation> {
|
|
287
|
-
return this.ctx.request<UnfollowMutation>(
|
|
288
|
-
|
|
289
|
-
|
|
320
|
+
return this.ctx.request<UnfollowMutation>(
|
|
321
|
+
'DELETE',
|
|
322
|
+
`/v2/follows/${encodeURIComponent(relationshipId)}`,
|
|
323
|
+
undefined,
|
|
324
|
+
{
|
|
325
|
+
cache: false,
|
|
326
|
+
},
|
|
327
|
+
);
|
|
290
328
|
}
|
|
291
329
|
|
|
292
330
|
/**
|
|
@@ -294,9 +332,14 @@ export class FollowsApi {
|
|
|
294
332
|
* `effectiveState`; keep the other two for the explanation.
|
|
295
333
|
*/
|
|
296
334
|
async targetStatus(targetId: string): Promise<FollowStatus> {
|
|
297
|
-
return this.ctx.request<FollowStatus>(
|
|
298
|
-
|
|
299
|
-
|
|
335
|
+
return this.ctx.request<FollowStatus>(
|
|
336
|
+
'GET',
|
|
337
|
+
`/v2/follows/${encodeURIComponent(targetId)}/status`,
|
|
338
|
+
undefined,
|
|
339
|
+
{
|
|
340
|
+
cache: false,
|
|
341
|
+
},
|
|
342
|
+
);
|
|
300
343
|
}
|
|
301
344
|
|
|
302
345
|
/**
|
|
@@ -334,13 +377,20 @@ export class FollowsApi {
|
|
|
334
377
|
* on the URI, so two applications describing the same thing reach ONE row.
|
|
335
378
|
* `metadata` is a display snapshot refreshed only by the providing app.
|
|
336
379
|
*/
|
|
337
|
-
async ensureTarget(
|
|
380
|
+
async ensureTarget(
|
|
381
|
+
input: EnsureFollowTargetInput,
|
|
382
|
+
): Promise<{ id: string; uri: string; kind: string; created: boolean }> {
|
|
338
383
|
return this.ctx.request('POST', '/v2/follow-targets', input, { cache: false });
|
|
339
384
|
}
|
|
340
385
|
|
|
341
386
|
/** Claim a namespace for the calling application (first come; idempotent for the holder). */
|
|
342
387
|
async claimNamespace(namespace: string): Promise<{ namespace: string; created: boolean }> {
|
|
343
|
-
return this.ctx.request(
|
|
388
|
+
return this.ctx.request(
|
|
389
|
+
'POST',
|
|
390
|
+
'/v2/follow-targets/namespaces',
|
|
391
|
+
{ namespace },
|
|
392
|
+
{ cache: false },
|
|
393
|
+
);
|
|
344
394
|
}
|
|
345
395
|
|
|
346
396
|
/**
|
|
@@ -348,9 +398,14 @@ export class FollowsApi {
|
|
|
348
398
|
* registered in it. Idempotent (`released: false` when already unowned).
|
|
349
399
|
*/
|
|
350
400
|
async releaseNamespace(namespace: string): Promise<{ namespace: string; released: boolean }> {
|
|
351
|
-
return this.ctx.request(
|
|
352
|
-
|
|
353
|
-
|
|
401
|
+
return this.ctx.request(
|
|
402
|
+
'DELETE',
|
|
403
|
+
`/v2/follow-targets/namespaces/${encodeURIComponent(namespace)}`,
|
|
404
|
+
undefined,
|
|
405
|
+
{
|
|
406
|
+
cache: false,
|
|
407
|
+
},
|
|
408
|
+
);
|
|
354
409
|
}
|
|
355
410
|
|
|
356
411
|
/**
|
|
@@ -380,13 +435,15 @@ export class FollowsApi {
|
|
|
380
435
|
path: string,
|
|
381
436
|
params?: FollowGraphParams,
|
|
382
437
|
): Promise<{ data: User[]; total: number; hasMore: boolean }> {
|
|
383
|
-
const response = await this.ctx.request<{
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
438
|
+
const response = await this.ctx.request<{
|
|
439
|
+
data: User[];
|
|
440
|
+
pagination: { total: number; hasMore: boolean };
|
|
441
|
+
}>('GET', path, buildQueryParams(params ?? {}), { cache: true, cacheTTL: GRAPH_TTL });
|
|
442
|
+
return {
|
|
443
|
+
data: response.data || [],
|
|
444
|
+
total: response.pagination.total,
|
|
445
|
+
hasMore: response.pagination.hasMore,
|
|
446
|
+
};
|
|
390
447
|
}
|
|
391
448
|
|
|
392
449
|
/**
|
package/src/api/identity.ts
CHANGED
|
@@ -192,10 +192,15 @@ export class IdentityApi {
|
|
|
192
192
|
* document. Public (no auth required); short-TTL cached.
|
|
193
193
|
*/
|
|
194
194
|
async resolveDid(userId: string): Promise<DidDocument> {
|
|
195
|
-
return this.ctx.request<DidDocument>(
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
195
|
+
return this.ctx.request<DidDocument>(
|
|
196
|
+
'GET',
|
|
197
|
+
`/u/${encodeURIComponent(userId)}/did.json`,
|
|
198
|
+
undefined,
|
|
199
|
+
{
|
|
200
|
+
cache: true,
|
|
201
|
+
cacheTTL: SHORT_TTL,
|
|
202
|
+
},
|
|
203
|
+
);
|
|
199
204
|
}
|
|
200
205
|
|
|
201
206
|
/**
|
|
@@ -204,7 +209,10 @@ export class IdentityApi {
|
|
|
204
209
|
* verification-method fragment.
|
|
205
210
|
*/
|
|
206
211
|
async authMethods(): Promise<AuthMethodsResponse> {
|
|
207
|
-
return this.ctx.request<AuthMethodsResponse>('GET', '/auth/methods', undefined, {
|
|
212
|
+
return this.ctx.request<AuthMethodsResponse>('GET', '/auth/methods', undefined, {
|
|
213
|
+
cache: true,
|
|
214
|
+
cacheTTL: SHORT_TTL,
|
|
215
|
+
});
|
|
208
216
|
}
|
|
209
217
|
|
|
210
218
|
/**
|
|
@@ -212,7 +220,9 @@ export class IdentityApi {
|
|
|
212
220
|
* linked (self-custody), or the email of an account without a key.
|
|
213
221
|
*/
|
|
214
222
|
async rootStatus(): Promise<IdentityRootStatus> {
|
|
215
|
-
return this.ctx.request<IdentityRootStatus>('GET', '/identity/root-status', undefined, {
|
|
223
|
+
return this.ctx.request<IdentityRootStatus>('GET', '/identity/root-status', undefined, {
|
|
224
|
+
cache: false,
|
|
225
|
+
});
|
|
216
226
|
}
|
|
217
227
|
|
|
218
228
|
/**
|
|
@@ -250,11 +260,14 @@ export class IdentityApi {
|
|
|
250
260
|
throw new Error('No authenticated user — sign in before rotating your key.');
|
|
251
261
|
}
|
|
252
262
|
|
|
253
|
-
const { KeyManager, RecoveryPhraseService, SignatureService, signMessage } = await import(
|
|
263
|
+
const { KeyManager, RecoveryPhraseService, SignatureService, signMessage } = await import(
|
|
264
|
+
'../crypto/internal'
|
|
265
|
+
);
|
|
254
266
|
|
|
255
267
|
// 1. The NEW identity (in memory only). The UI may pre-derive + pre-show
|
|
256
268
|
// it and pass it back here so the phrase shown === the phrase committed.
|
|
257
|
-
const pending =
|
|
269
|
+
const pending =
|
|
270
|
+
options.pendingIdentity ?? (await RecoveryPhraseService.derivePendingIdentity());
|
|
258
271
|
const newPublicKey = pending.publicKey;
|
|
259
272
|
|
|
260
273
|
// 2. Resolve the OLD signing capability from the chosen proof mode.
|
|
@@ -271,16 +284,23 @@ export class IdentityApi {
|
|
|
271
284
|
} else {
|
|
272
285
|
const currentPublicKey = await KeyManager.getPublicKey();
|
|
273
286
|
if (!currentPublicKey) {
|
|
274
|
-
throw new Error(
|
|
287
|
+
throw new Error(
|
|
288
|
+
'No on-device identity found. Use the recovery-phrase option to rotate your key.',
|
|
289
|
+
);
|
|
275
290
|
}
|
|
276
291
|
oldPublicKey = currentPublicKey;
|
|
277
292
|
signWithOldKey = (message) => SignatureService.sign(message);
|
|
278
293
|
}
|
|
279
294
|
|
|
280
295
|
// 3. Request a single-use rotate_key challenge (bearer).
|
|
281
|
-
const { challenge } = await this.ctx.request<RotateKeyChallengeResponse>(
|
|
282
|
-
|
|
283
|
-
|
|
296
|
+
const { challenge } = await this.ctx.request<RotateKeyChallengeResponse>(
|
|
297
|
+
'POST',
|
|
298
|
+
'/auth/rotate/challenge',
|
|
299
|
+
undefined,
|
|
300
|
+
{
|
|
301
|
+
cache: false,
|
|
302
|
+
},
|
|
303
|
+
);
|
|
284
304
|
|
|
285
305
|
// 4. Sign the rotation proofs. The OLD key proves control of the key being
|
|
286
306
|
// replaced; the NEW key proves possession of the key being rotated in.
|
|
@@ -406,7 +426,9 @@ export class IdentityApi {
|
|
|
406
426
|
*/
|
|
407
427
|
private async rotationAlreadyApplied(userId: string, newPublicKey: string): Promise<boolean> {
|
|
408
428
|
return this.ctx
|
|
409
|
-
.request<DidDocument>('GET', `/u/${encodeURIComponent(userId)}/did.json`, undefined, {
|
|
429
|
+
.request<DidDocument>('GET', `/u/${encodeURIComponent(userId)}/did.json`, undefined, {
|
|
430
|
+
cache: false,
|
|
431
|
+
})
|
|
410
432
|
.then((doc) =>
|
|
411
433
|
doc.verificationMethod.some(
|
|
412
434
|
(vm) =>
|
|
@@ -442,7 +464,9 @@ export class IdentityLinksApi {
|
|
|
442
464
|
* The "Link Commons" panel shows its `qrPayload`; Commons scans it and signs with `sign`.
|
|
443
465
|
*/
|
|
444
466
|
async create(): Promise<IdentityLinkCreateResponse> {
|
|
445
|
-
const res = await this.ctx.request<unknown>('POST', '/identity/link', undefined, {
|
|
467
|
+
const res = await this.ctx.request<unknown>('POST', '/identity/link', undefined, {
|
|
468
|
+
cache: false,
|
|
469
|
+
});
|
|
446
470
|
const parsed = safeParseContract(identityLinkCreateResponseSchema, res);
|
|
447
471
|
if (!parsed) throw new Error('identity/link returned an unexpected response shape');
|
|
448
472
|
return parsed;
|
|
@@ -450,10 +474,15 @@ export class IdentityLinksApi {
|
|
|
450
474
|
|
|
451
475
|
/** Where a link request stands. Both devices poll it; it needs no session. */
|
|
452
476
|
async get(linkId: string): Promise<IdentityLinkState> {
|
|
453
|
-
const res = await this.ctx.request<unknown>(
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
477
|
+
const res = await this.ctx.request<unknown>(
|
|
478
|
+
'GET',
|
|
479
|
+
`/identity/link/${encodeURIComponent(linkId)}`,
|
|
480
|
+
undefined,
|
|
481
|
+
{
|
|
482
|
+
cache: false,
|
|
483
|
+
skipAuth: true,
|
|
484
|
+
},
|
|
485
|
+
);
|
|
457
486
|
const parsed = safeParseContract(identityLinkStateSchema, res);
|
|
458
487
|
if (!parsed) throw new Error('identity/link returned an unexpected response shape');
|
|
459
488
|
return parsed;
|
|
@@ -464,9 +493,17 @@ export class IdentityLinksApi {
|
|
|
464
493
|
* device's identity key and post it. NATIVE-ONLY. Resolves to the key and the
|
|
465
494
|
* 6-digit code the other screen will show for it, for the person to compare.
|
|
466
495
|
*/
|
|
467
|
-
async sign(
|
|
468
|
-
|
|
469
|
-
|
|
496
|
+
async sign(
|
|
497
|
+
linkId: string,
|
|
498
|
+
challenge: string,
|
|
499
|
+
): Promise<{ publicKey: string; code: string; username: string | null }> {
|
|
500
|
+
const { KeyManager, signIdentityProof, deriveIdentityLinkCode } = await import(
|
|
501
|
+
'../crypto/internal'
|
|
502
|
+
);
|
|
503
|
+
const [privateKey, publicKey] = await Promise.all([
|
|
504
|
+
KeyManager.getPrivateKey(),
|
|
505
|
+
KeyManager.getPublicKey(),
|
|
506
|
+
]);
|
|
470
507
|
if (!privateKey || !publicKey) {
|
|
471
508
|
throw new Error('No identity on this device to link');
|
|
472
509
|
}
|
|
@@ -492,7 +529,11 @@ export class IdentityLinksApi {
|
|
|
492
529
|
{ publicKey: root, proof },
|
|
493
530
|
{ cache: false, skipAuth: true },
|
|
494
531
|
);
|
|
495
|
-
return {
|
|
532
|
+
return {
|
|
533
|
+
publicKey: root,
|
|
534
|
+
code: deriveIdentityLinkCode(linkId, root),
|
|
535
|
+
username: state.username,
|
|
536
|
+
};
|
|
496
537
|
}
|
|
497
538
|
|
|
498
539
|
/**
|
|
@@ -517,7 +558,12 @@ export class IdentityLinksApi {
|
|
|
517
558
|
|
|
518
559
|
/** Withdraw a link request that has not completed. */
|
|
519
560
|
async cancel(linkId: string): Promise<void> {
|
|
520
|
-
await this.ctx.request<unknown>(
|
|
561
|
+
await this.ctx.request<unknown>(
|
|
562
|
+
'DELETE',
|
|
563
|
+
`/identity/link/${encodeURIComponent(linkId)}`,
|
|
564
|
+
undefined,
|
|
565
|
+
{ cache: false },
|
|
566
|
+
);
|
|
521
567
|
}
|
|
522
568
|
}
|
|
523
569
|
|
|
@@ -534,7 +580,12 @@ export class IdentityDomainsApi {
|
|
|
534
580
|
* `verify`.
|
|
535
581
|
*/
|
|
536
582
|
async requestVerification(domain: string): Promise<DomainVerificationInstructions> {
|
|
537
|
-
return this.ctx.request<DomainVerificationInstructions>(
|
|
583
|
+
return this.ctx.request<DomainVerificationInstructions>(
|
|
584
|
+
'POST',
|
|
585
|
+
'/identity/domains',
|
|
586
|
+
{ domain },
|
|
587
|
+
{ cache: false },
|
|
588
|
+
);
|
|
538
589
|
}
|
|
539
590
|
|
|
540
591
|
/**
|
|
@@ -555,10 +606,15 @@ export class IdentityDomainsApi {
|
|
|
555
606
|
|
|
556
607
|
/** The signed-in user's verified domains. */
|
|
557
608
|
async list(): Promise<VerifiedDomain[]> {
|
|
558
|
-
const res = await this.ctx.request<{ domains?: VerifiedDomain[] }>(
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
609
|
+
const res = await this.ctx.request<{ domains?: VerifiedDomain[] }>(
|
|
610
|
+
'GET',
|
|
611
|
+
'/identity/domains',
|
|
612
|
+
undefined,
|
|
613
|
+
{
|
|
614
|
+
cache: true,
|
|
615
|
+
cacheTTL: SHORT_TTL,
|
|
616
|
+
},
|
|
617
|
+
);
|
|
562
618
|
return res.domains ?? [];
|
|
563
619
|
}
|
|
564
620
|
|
|
@@ -649,7 +705,8 @@ export class IdentityBackupApi {
|
|
|
649
705
|
* from SecureStore.
|
|
650
706
|
*/
|
|
651
707
|
async create(phrase: string): Promise<BackupStatusResponse> {
|
|
652
|
-
const { KeyManager, RecoveryPhraseService, BACKUP_KDF_ENCRYPTION_INFO, encryptAead } =
|
|
708
|
+
const { KeyManager, RecoveryPhraseService, BACKUP_KDF_ENCRYPTION_INFO, encryptAead } =
|
|
709
|
+
await import('../crypto/internal');
|
|
653
710
|
const { backupKey, lookupId } = await RecoveryPhraseService.deriveBackupMaterial(phrase);
|
|
654
711
|
const privateKey = await RecoveryPhraseService.derivePrivateKeyFromPhrase(phrase);
|
|
655
712
|
const publicKey = KeyManager.derivePublicKey(privateKey);
|
|
@@ -672,7 +729,9 @@ export class IdentityBackupApi {
|
|
|
672
729
|
lookupId,
|
|
673
730
|
};
|
|
674
731
|
|
|
675
|
-
return this.ctx.request<BackupStatusResponse>('POST', '/identity/backup', body, {
|
|
732
|
+
return this.ctx.request<BackupStatusResponse>('POST', '/identity/backup', body, {
|
|
733
|
+
cache: false,
|
|
734
|
+
});
|
|
676
735
|
}
|
|
677
736
|
|
|
678
737
|
/**
|
|
@@ -680,12 +739,16 @@ export class IdentityBackupApi {
|
|
|
680
739
|
* and timestamp. Returns no ciphertext and no locator.
|
|
681
740
|
*/
|
|
682
741
|
async status(): Promise<BackupStatusResponse> {
|
|
683
|
-
return this.ctx.request<BackupStatusResponse>('GET', '/identity/backup/status', undefined, {
|
|
742
|
+
return this.ctx.request<BackupStatusResponse>('GET', '/identity/backup/status', undefined, {
|
|
743
|
+
cache: false,
|
|
744
|
+
});
|
|
684
745
|
}
|
|
685
746
|
|
|
686
747
|
/** Delete the signed-in user's stored backup. Idempotent. */
|
|
687
748
|
async delete(): Promise<{ success: boolean }> {
|
|
688
|
-
return this.ctx.request<{ success: boolean }>('DELETE', '/identity/backup', undefined, {
|
|
749
|
+
return this.ctx.request<{ success: boolean }>('DELETE', '/identity/backup', undefined, {
|
|
750
|
+
cache: false,
|
|
751
|
+
});
|
|
689
752
|
}
|
|
690
753
|
|
|
691
754
|
/**
|
|
@@ -718,7 +781,12 @@ export class IdentityBackupApi {
|
|
|
718
781
|
}
|
|
719
782
|
|
|
720
783
|
const aad = buildBackupAad(envelope.version, envelope.publicKeyHint);
|
|
721
|
-
const plaintext = decryptAead(
|
|
784
|
+
const plaintext = decryptAead(
|
|
785
|
+
backupKey,
|
|
786
|
+
fromHex(envelope.nonce),
|
|
787
|
+
fromHex(envelope.ciphertext),
|
|
788
|
+
aad,
|
|
789
|
+
);
|
|
722
790
|
const payload = JSON.parse(new TextDecoder().decode(plaintext)) as BackupPayload;
|
|
723
791
|
|
|
724
792
|
if (!payload.privateKey || !payload.publicKey) {
|
|
@@ -37,7 +37,10 @@ export class LinkedAccountsApi {
|
|
|
37
37
|
* to be sent back to your app afterwards.
|
|
38
38
|
* @returns The URL to open, and when the attempt expires (ten minutes).
|
|
39
39
|
*/
|
|
40
|
-
async start(
|
|
40
|
+
async start(
|
|
41
|
+
network: LinkedAccountNetwork,
|
|
42
|
+
options: StartLinkedAccountRequest,
|
|
43
|
+
): Promise<StartLinkedAccountResponse> {
|
|
41
44
|
return this.ctx.request<StartLinkedAccountResponse>(
|
|
42
45
|
'POST',
|
|
43
46
|
`/linked-accounts/${encodeURIComponent(network)}/start`,
|
|
@@ -53,15 +56,25 @@ export class LinkedAccountsApi {
|
|
|
53
56
|
* Repeating it within the code's five minutes returns the same link.
|
|
54
57
|
*/
|
|
55
58
|
async complete(code: string): Promise<LinkedAccount> {
|
|
56
|
-
const res = await this.ctx.request<CompleteLinkedAccountResponse>(
|
|
57
|
-
|
|
58
|
-
|
|
59
|
+
const res = await this.ctx.request<CompleteLinkedAccountResponse>(
|
|
60
|
+
'POST',
|
|
61
|
+
'/linked-accounts/complete',
|
|
62
|
+
{ code },
|
|
63
|
+
{
|
|
64
|
+
cache: false,
|
|
65
|
+
},
|
|
66
|
+
);
|
|
59
67
|
return res.linkedAccount;
|
|
60
68
|
}
|
|
61
69
|
|
|
62
70
|
/** The current user's live linked accounts, oldest first. */
|
|
63
71
|
async list(): Promise<LinkedAccount[]> {
|
|
64
|
-
const res = await this.ctx.request<LinkedAccountListResponse>(
|
|
72
|
+
const res = await this.ctx.request<LinkedAccountListResponse>(
|
|
73
|
+
'GET',
|
|
74
|
+
'/linked-accounts',
|
|
75
|
+
undefined,
|
|
76
|
+
{ cache: false },
|
|
77
|
+
);
|
|
65
78
|
return res.linkedAccounts;
|
|
66
79
|
}
|
|
67
80
|
|
|
@@ -71,8 +84,13 @@ export class LinkedAccountsApi {
|
|
|
71
84
|
* linked to another Oxy account.
|
|
72
85
|
*/
|
|
73
86
|
async revoke(linkedAccountId: string): Promise<void> {
|
|
74
|
-
await this.ctx.request<void>(
|
|
75
|
-
|
|
76
|
-
|
|
87
|
+
await this.ctx.request<void>(
|
|
88
|
+
'DELETE',
|
|
89
|
+
`/linked-accounts/${encodeURIComponent(linkedAccountId)}`,
|
|
90
|
+
undefined,
|
|
91
|
+
{
|
|
92
|
+
cache: false,
|
|
93
|
+
},
|
|
94
|
+
);
|
|
77
95
|
}
|
|
78
96
|
}
|
package/src/api/nodes.ts
CHANGED
|
@@ -126,16 +126,23 @@ export class NodesApi {
|
|
|
126
126
|
|
|
127
127
|
/** The signed-in user's node status, or `null` when they have none. Short-TTL cached. */
|
|
128
128
|
async mine(): Promise<UserNodeStatus | null> {
|
|
129
|
-
const res = await this.ctx.request<{ node: UserNodeStatus | null }>(
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
129
|
+
const res = await this.ctx.request<{ node: UserNodeStatus | null }>(
|
|
130
|
+
'GET',
|
|
131
|
+
'/nodes/me',
|
|
132
|
+
undefined,
|
|
133
|
+
{
|
|
134
|
+
cache: true,
|
|
135
|
+
cacheTTL: SHORT_TTL,
|
|
136
|
+
},
|
|
137
|
+
);
|
|
133
138
|
return res.node ?? null;
|
|
134
139
|
}
|
|
135
140
|
|
|
136
141
|
/** Revoke the signed-in user's node registration. */
|
|
137
142
|
async removeMine(): Promise<RemoveNodeResult> {
|
|
138
|
-
const res = await this.ctx.request<{ success: boolean }>('DELETE', '/nodes/me', undefined, {
|
|
143
|
+
const res = await this.ctx.request<{ success: boolean }>('DELETE', '/nodes/me', undefined, {
|
|
144
|
+
cache: false,
|
|
145
|
+
});
|
|
139
146
|
this.sweep();
|
|
140
147
|
return { revoked: res.success === true };
|
|
141
148
|
}
|
|
@@ -145,7 +152,12 @@ export class NodesApi {
|
|
|
145
152
|
* user. Idempotent server-side; the owner comes from the session.
|
|
146
153
|
*/
|
|
147
154
|
async provisionManagedVault(): Promise<UserNodeStatus> {
|
|
148
|
-
const res = await this.ctx.request<{ node: UserNodeStatus }>(
|
|
155
|
+
const res = await this.ctx.request<{ node: UserNodeStatus }>(
|
|
156
|
+
'POST',
|
|
157
|
+
'/nodes/managed',
|
|
158
|
+
undefined,
|
|
159
|
+
{ cache: false },
|
|
160
|
+
);
|
|
149
161
|
this.sweep();
|
|
150
162
|
return res.node;
|
|
151
163
|
}
|
package/src/api/notifications.ts
CHANGED
|
@@ -57,14 +57,24 @@ export class NotificationsApi {
|
|
|
57
57
|
|
|
58
58
|
/** One page of the inbox, newest first, with the unread count across all pages. */
|
|
59
59
|
async list(params: { page?: number; limit?: number } = {}): Promise<NotificationPage> {
|
|
60
|
-
return this.ctx.request<NotificationPage>(
|
|
61
|
-
|
|
62
|
-
|
|
60
|
+
return this.ctx.request<NotificationPage>(
|
|
61
|
+
'GET',
|
|
62
|
+
'/notifications',
|
|
63
|
+
buildQueryParams({ page: params.page, limit: params.limit }),
|
|
64
|
+
{
|
|
65
|
+
cache: false,
|
|
66
|
+
},
|
|
67
|
+
);
|
|
63
68
|
}
|
|
64
69
|
|
|
65
70
|
/** How many notifications are unread. */
|
|
66
71
|
async unreadCount(): Promise<number> {
|
|
67
|
-
const res = await this.ctx.request<{ unreadCount: number }>(
|
|
72
|
+
const res = await this.ctx.request<{ unreadCount: number }>(
|
|
73
|
+
'GET',
|
|
74
|
+
'/notifications/unread-count',
|
|
75
|
+
undefined,
|
|
76
|
+
{ cache: false },
|
|
77
|
+
);
|
|
68
78
|
return res.unreadCount;
|
|
69
79
|
}
|
|
70
80
|
|
|
@@ -90,7 +100,12 @@ export class NotificationsApi {
|
|
|
90
100
|
|
|
91
101
|
/** Delete one notification. */
|
|
92
102
|
async delete(notificationId: string): Promise<void> {
|
|
93
|
-
await this.ctx.request(
|
|
103
|
+
await this.ctx.request(
|
|
104
|
+
'DELETE',
|
|
105
|
+
`/notifications/${encodeURIComponent(notificationId)}`,
|
|
106
|
+
undefined,
|
|
107
|
+
{ cache: false },
|
|
108
|
+
);
|
|
94
109
|
}
|
|
95
110
|
|
|
96
111
|
// ── Push tokens ──────────────────────────────────────────────────────────
|
|
@@ -130,6 +145,11 @@ export class NotificationsApi {
|
|
|
130
145
|
* no longer holds.
|
|
131
146
|
*/
|
|
132
147
|
async unregisterPushToken(expoPushToken: string): Promise<void> {
|
|
133
|
-
await this.ctx.request(
|
|
148
|
+
await this.ctx.request(
|
|
149
|
+
'DELETE',
|
|
150
|
+
'/notifications/push-token',
|
|
151
|
+
{ token: expoPushToken },
|
|
152
|
+
{ cache: false },
|
|
153
|
+
);
|
|
134
154
|
}
|
|
135
155
|
}
|