@oxyhq/core 5.1.0 → 5.1.1
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/mixins/OxyServices.user.js +30 -11
- package/dist/esm/.tsbuildinfo +1 -1
- package/dist/esm/mixins/OxyServices.user.js +30 -11
- package/dist/types/.tsbuildinfo +1 -1
- package/dist/types/mixins/OxyServices.user.d.ts +33 -10
- package/package.json +1 -1
- package/src/mixins/OxyServices.user.ts +43 -11
- package/src/mixins/__tests__/getUsersByIds.test.ts +149 -0
|
@@ -230,16 +230,28 @@ export function OxyServicesUserMixin(Base) {
|
|
|
230
230
|
* by `id`); each is run through `normalizeUserIdentity`, matching
|
|
231
231
|
* `getUserById`.
|
|
232
232
|
*
|
|
233
|
-
* **
|
|
234
|
-
*
|
|
235
|
-
*
|
|
236
|
-
*
|
|
237
|
-
*
|
|
238
|
-
*
|
|
239
|
-
*
|
|
240
|
-
*
|
|
241
|
-
*
|
|
242
|
-
*
|
|
233
|
+
* **Dual-mode auth.** `/users/by-ids` is `optionalUserOrServiceAuth` on
|
|
234
|
+
* oxy-api: it accepts a service token, a user session, or an anonymous
|
|
235
|
+
* caller, and returns the SAME public `{ data: PublicUserProfile[] }`
|
|
236
|
+
* payload (canonical `name.displayName` + `_count`) in every case — no
|
|
237
|
+
* viewer-specific fields. This method picks the path automatically:
|
|
238
|
+
* - **Service-configured host (backend):** when `configureServiceAuth(apiKey,
|
|
239
|
+
* apiSecret)` has been called, the chunk is fetched via `makeServiceRequest`
|
|
240
|
+
* (attaches `Authorization: Bearer <serviceToken>`). This is the
|
|
241
|
+
* server-to-server feed/notification hydration path (e.g. Mention's
|
|
242
|
+
* `PostHydrationService`) and is unchanged.
|
|
243
|
+
* - **Plain client (browser / React Native with a user session):** when no
|
|
244
|
+
* service credentials are configured, the chunk is fetched via
|
|
245
|
+
* `makeRequest`, which attaches the configured user bearer. oxy-api's CSRF
|
|
246
|
+
* middleware skips bearer-authenticated writes, and `makeRequest` only
|
|
247
|
+
* fetches a CSRF token for cookie-only (no-bearer) state-changing requests,
|
|
248
|
+
* so the user-bearer POST is sent without CSRF and succeeds. Previously
|
|
249
|
+
* this method always used the service path, so every client-side caller
|
|
250
|
+
* silently received `[]` because `getServiceToken()` had no credentials.
|
|
251
|
+
*
|
|
252
|
+
* Both paths run results through `normalizeUserIdentity` and unwrap the
|
|
253
|
+
* API's `{ data }` envelope identically (`makeServiceRequest` is literally
|
|
254
|
+
* `makeRequest` plus a bearer service header).
|
|
243
255
|
*
|
|
244
256
|
* Resilience: chunks are independent. A failed chunk is logged and skipped
|
|
245
257
|
* — the method returns every user that resolved successfully rather than
|
|
@@ -258,15 +270,22 @@ export function OxyServicesUserMixin(Base) {
|
|
|
258
270
|
for (let i = 0; i < uniqueIds.length; i += USERS_BY_IDS_CHUNK_SIZE) {
|
|
259
271
|
chunks.push(uniqueIds.slice(i, i + USERS_BY_IDS_CHUNK_SIZE));
|
|
260
272
|
}
|
|
273
|
+
// A backend that called configureServiceAuth() uses the bearer-service
|
|
274
|
+
// path; any other caller (browser / RN with a user session) uses the
|
|
275
|
+
// user-bearer path. See the method doc for why the user path is CSRF-safe.
|
|
276
|
+
const useServiceAuth = Boolean(this._serviceApiKey && this._serviceApiSecret);
|
|
261
277
|
// Run chunks concurrently; a single chunk failure must not sink the rest.
|
|
262
278
|
const settled = await Promise.all(chunks.map(async (chunk) => {
|
|
263
279
|
try {
|
|
264
|
-
const users =
|
|
280
|
+
const users = useServiceAuth
|
|
281
|
+
? await this.makeServiceRequest('POST', '/users/by-ids', { ids: chunk })
|
|
282
|
+
: await this.makeRequest('POST', '/users/by-ids', { ids: chunk }, { cache: false });
|
|
265
283
|
return Array.isArray(users) ? users.map((user) => normalizeUserIdentity(user)) : [];
|
|
266
284
|
}
|
|
267
285
|
catch (error) {
|
|
268
286
|
logger.warn('getUsersByIds: chunk failed, continuing with remaining chunks', {
|
|
269
287
|
method: 'getUsersByIds',
|
|
288
|
+
mode: useServiceAuth ? 'service' : 'user',
|
|
270
289
|
chunkSize: chunk.length,
|
|
271
290
|
status: extractErrorStatus(error),
|
|
272
291
|
error: error instanceof Error ? error.message : String(error),
|