Skip to content

feat: Add Identity.search for IDSync Search#1255

Open
rmi22186 wants to merge 23 commits intodevelopmentfrom
feat/idsync-advertiser
Open

feat: Add Identity.search for IDSync Search#1255
rmi22186 wants to merge 23 commits intodevelopmentfrom
feat/idsync-advertiser

Conversation

@rmi22186
Copy link
Copy Markdown
Member

@rmi22186 rmi22186 commented Apr 28, 2026

Summary

  • New public API mParticle.Identity.search(workspaceApiKey, knownIdentities, callback) POSTs to mParticle's IDSync /v1/search and invokes the callback with { httpCode, body? }. Sits alongside identify/login/logout/modify/aliasUsers on the Identity surface. The caller supplies a workspace-scoped API key (sent as x-mp-key), held separately from the host SDK's _Store.devToken, so a single install can search against an arbitrary workspace without being reconfigured.
  • Outcomes: 200 → { httpCode: 200, body }; 404 → { httpCode: 404 }; missing key or invalid email → noHttpCoverage (no network); SDK opted out → loggingDisabledOrMissingAPIKey; network or JSON-parse failure → noHttpCoverage plus a structured ISDKError through _ErrorReportingDispatcher, mirroring identifyRequest in identityApiClient.ts.
  • Opt-out parity: gates on mpInstance._Helpers.canLog() before any network call, so setOptOut(true) short-circuits the request and no email is transmitted — matching identify/login/logout/modify/aliasUsers.
  • Pairs with the Rokt Web Kit PR — feat: Add Workspace IDSync search on user identification mparticle-integrations/mparticle-javascript-integration-rokt#92 — and depends on the Fastly edge allowlist for /v1/search being updated to include x-mp-key (curl already round-trips 200/404; the browser preflight is the only remaining blocker).
  • Test plan: npm run lint + npm run build clean; Karma on ChromeHeadless 1077 passing covering 200/404, validation, opt-out, and error-reporter paths in tests-search.ts. Live browser smoke test still blocked on the Fastly allowlist update.

🤖 Generated with Claude Code

rmi22186 and others added 3 commits April 28, 2026 15:28
Adds a new public API mParticle.Identity.searchAdvertiser(apiKey,
knownIdentities, callback) that POSTs to mParticle's IDSync /v1/search
endpoint so kits (initially the Rokt Web Kit) can look up an advertiser
identity (today, only email) without affecting the current user.

The advertiser API key is supplied explicitly by the caller rather than
read from the SDK's workspace token, so advertiser searches can be
authorised independently of the host SDK's workspace.

Missing apiKey, missing/invalid email, and a non-function callback all
return silently (no network call, no callback) so the path is inert
when the consumer hasn't opted in.

Note: a separate Fastly CORS configuration is required to permit the
x-mp-key header on /v1/search; this SDK code is built assuming that
allow-list will land separately.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The IDSync /v1/search endpoint requires Basic auth (or HMAC); key-only
auth via x-mp-key is not provisioned at the Fastly edge. Update the
public API to take an explicit `secret` argument and send
`Authorization: Basic <base64(apiKey:secret)>` instead of `x-mp-key`.

Public signature:
  Identity.searchAdvertiser(apiKey, secret, knownIdentities, callback)

Both apiKey and secret are required; either being missing/empty makes
the call silently inert (no network, no callback).

For Web workspaces the "secret" ships in the browser bundle and is not
actually a secret, but the Basic scheme still requires it as the
password component.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@rmi22186 rmi22186 requested a review from a team as a code owner April 28, 2026 20:08
@cursor
Copy link
Copy Markdown

cursor Bot commented Apr 28, 2026

PR Summary

Medium Risk
Adds a new identity-related network call (POST /v1/search) that transmits user identifiers (email) and introduces new callback/error-handling behavior; while gated by opt-out and well tested, it touches identity plumbing and request dispatch.

Overview
Adds a new public API mParticle.Identity.search(workspaceApiKey, knownIdentities, callback) that POSTs to the IDSync /v1/search endpoint to look up an identity without changing the current user, authenticating via caller-supplied x-mp-key.

Implements a typed request/envelope builder and network sender (sendSearchRequest) with opt-out gating, defensive validation (missing key/email/callback), best-effort JSON parsing, and structured error reporting via the SDK’s error-reporting dispatcher.

Updates preload snippets/stubs and instance-manager proxies to surface Identity.search, and adds comprehensive unit tests covering success/404, validation short-circuits, opt-out behavior, and error-reporting paths.

Reviewed by Cursor Bugbot for commit e47d52a. Bugbot is set up for automated code reviews on this repo. Configure here.

…cher

Match the pattern in identityApiClient.sendIdentityRequest: on a thrown
network error, log to console AND push a structured ISDKError through
the dispatcher so any registered listener (e.g. the Rokt Web Kit's
ErrorReportingService, registered via _registerErrorReportingService)
can observe the failure.

Adds an optional `errorReporter?: IErrorReportingService` parameter to
sendSearchAdvertiserRequest. The Identity.searchAdvertiser public
wrapper passes mpInstance._ErrorReportingDispatcher through.

Mirrors identifyRequest's error code and severity:
  code: ErrorCodes.IDENTITY_REQUEST
  severity: WSDKErrorSeverity.ERROR

Validation paths (missing apiKey, missing/invalid email, non-function
callback) remain silently inert — they're consumer-contract failures,
not infrastructure errors, and the existing identity routes don't
report on those either.

Tests:
  - reports a structured error through errorReporter on network failure
  - does not throw when errorReporter is omitted on network failure

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Comment thread src/identity/search.ts
Comment thread src/identity.js
Two findings from the automated review on PR #1255:

1. Validation paths now invoke the callback with `httpCode: noHttpCoverage`
   instead of returning silently. The earlier silent-return refactor
   contradicted the function's documented contract and broke parity with
   other identity methods. A consumer holding a loading state on the
   callback would have hung indefinitely on missing email or apiKey.

2. `Identity.searchAdvertiser` now gates on `_Helpers.canLog()` before
   making the network call, mirroring identify/login/logout/modify.
   Without this, an opted-out user (`setOptOut(true)`) would still POST
   their email to /v1/search. On guard fail the callback fires with
   `httpCode: loggingDisabledOrMissingAPIKey`, matching the existing
   identity-route precedent.

Tests updated to assert callback invocation on validation failures and
on the opt-out path (1077 passing on ChromeHeadless, +1 net).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Comment thread src/identity.js Outdated
rmi22186 and others added 2 commits April 29, 2026 15:36
The opt-out short-circuit in `Identity.searchAdvertiser` was using
`mpInstance._Helpers.invokeCallback`, which delivers the standard
Identity callback shape `{ httpCode, body, getUser, getPreviousUser }`.
That contradicts the `ISearchAdvertiserResult` contract
(`{ httpCode, body? }` with `body` typed as a parsed JSON object) and
would cause a consumer that did `if (result.body) result.body.mpid` to
crash on the abandon-log message string.

Invoke the callback directly with `{ httpCode: loggingDisabledOrMissingAPIKey }`
so all skipped-request paths in `searchAdvertiser` deliver a consistent,
typed result. Strengthens the opt-out test to assert `body`, `getUser`
and `getPreviousUser` are absent from the delivered result.

Addresses cursor-bot review on commit bb58f23.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The four locals introduced in `Identity.searchAdvertiser` (`serviceUrl`,
`searchUrl`, `environment`, `requestBuilder`) are never reassigned, so
declare them with `const`. The surrounding file uses `var` for legacy
reasons but new PR code should prefer `const` where possible.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Comment thread src/searchAdvertiser.ts Outdated
rmi22186 and others added 2 commits April 29, 2026 17:41
Cursor-bot review on PR #1255 (low severity) flagged that
`requestBuilder()`, `JSON.stringify(requestBody)`, and uploader
construction all executed outside the try/catch block. If any of those
threw, the async function rejected, but the caller in identity.js
discards the returned Promise (no await, no .catch) — turning it into
an unhandled rejection and leaving the consumer's callback unfired,
which could hang any loading state the consumer was holding open.

None of those operations are likely to throw in practice (request
shape is plain objects, no circular refs; uploaders only fail in
exotic environments), but the documented contract is "callback always
fires," so defense in depth is the right call. Move the existing try
opener up to wrap request setup as well — the existing catch already
calls safeInvoke({ httpCode: HTTPCodes.noHttpCoverage }) and reports
through the dispatcher, so the contract holds without any new code.

Test:
 - catches errors thrown during request setup (e.g. requestBuilder)
   and surfaces noHttpCoverage via the callback — passes a builder
   that throws and asserts the callback fires with noHttpCoverage,
   no exception propagates, and no network call happens.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three small changes to the IDSync searchAdvertiser API in identity.js
plus a related import cleanup:

1. JSDoc cleanup. Removed two misleading lines:
   - "Both 200 (match) and 404 (no match) are expected steady-state
     outcomes. Consumers should gate behaviour on httpCode === 200."
     The 200/404 enumeration was incomplete (the endpoint can also
     return 400/401/429/5xx), and the gate-on-200 advice is the
     consumer's call, not a contract this SDK enforces.
   - "v1 only supports email in knownIdentities." Misleading because
     /v1/search itself accepts the full IdentityTypeDto enum
     (customerid, ios_idfa, etc.). The single-email constraint is a
     self-imposed SDK type choice in ISearchAdvertiserKnownIdentities,
     not a server limitation.

2. Renamed parameter `apiKey` → `advertiserApiKey` to make it clear
   the caller passes the advertiser's workspace key — not the SDK's
   own _Store.devToken.

3. Appended a static cache-bust query parameter (`search?abc=123`) to
   the request URL. This is a workaround for Fastly's OPTIONS preflight
   cache poisoning on /v1/search: by giving this SDK's traffic a
   distinct URL, we get a separate cache slot at the edge, sidestepping
   the stale `Access-Control-Allow-Headers` body that's currently
   served for naked /v1/search. The proper fix is the
   `Vary: Access-Control-Request-Headers` header on origin (mpserver
   PR), at which point this query parameter can be removed.

Also drops the now-unused ISearchAdvertiserResult import from
identity.interfaces.ts.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Comment thread src/identity.js Outdated
rmi22186 and others added 3 commits April 29, 2026 18:40
- Drop `?abc=123` cache-buster from /v1/search URL (no longer needed).
- Propagate `apiKey` -> `advertiserApiKey` rename to the public TS
  surface (`identity.interfaces.ts`) and the instance-manager wrapper
  so IDE/IntelliSense matches the implementation.
- Sync test mock URL with the SDK's actual request URL.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Trim JSDoc on `searchAdvertiser` (interface + identity.js) and remove
  the internal callback-shape note from identity.js.
- Drop the Fastly/CORS NOTE from `searchAdvertiser.ts` — unblocked.
- Delete the redundant "does not throw when errorReporter is omitted"
  test; the case is already covered by the prior "catches network
  errors" test, which calls `sendSearchAdvertiserRequest` without an
  `errorReporter`. Removing it clears the SonarCloud duplicated-block
  in this test file.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The "advertiser" terminology was Rokt-internal context. mParticle
customers don't share that vocabulary — the underlying concept is a
workspace-scoped IDSync search. Rename the public API and all
supporting types/files to use "workspace" so the surface reads
naturally for any consumer.

Public surface changes (pre-release, no consumers yet):
- `mParticle.Identity.searchAdvertiser` -> `mParticle.Identity.searchWorkspace`
- `advertiserApiKey` parameter -> `workspaceApiKey`
- `ISearchAdvertiser*` types -> `ISearchWorkspace*`
- `SearchAdvertiserCallback` -> `SearchWorkspaceCallback`

File renames:
- `src/searchAdvertiser.ts` -> `src/searchWorkspace.ts`
- `test/src/tests-search-advertiser.ts` -> `test/src/tests-search-workspace.ts`

Paired with the Rokt kit rename in mparticle-javascript-integration-rokt.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@rmi22186 rmi22186 changed the title feat: Add Identity.searchAdvertiser for IDSync Search feat: Add Identity.searchWorkspace for IDSync Search Apr 30, 2026
@rmi22186
Copy link
Copy Markdown
Member Author

Note: Check to see if onIdentifyComplete is ever called when identify fails.

Aligns the new IDSync search primitive with the existing public
Identity API surface (`identify`/`login`/`logout`/`modify`/`aliasUsers`
/`search`). The "Workspace" qualifier on the method/types/file leaked
the kit-level feature name into the SDK primitive — the SDK doesn't
need to be told *what* the caller is searching, only *how*. The
caller's workspace API key is still surfaced via the
`workspaceApiKey` parameter, which keeps the auth contract explicit
without coloring the method name.

- `mParticle.Identity.searchWorkspace` -> `mParticle.Identity.search`
- `sendSearchWorkspaceRequest` -> `sendSearchRequest`
- `ISearchWorkspace*` types -> `ISearch*`; `SearchWorkspaceCallback` -> `SearchCallback`
- `src/searchWorkspace.ts` -> `src/search.ts`
- `test/src/tests-search-workspace.ts` -> `test/src/tests-search.ts`

Paired with the Rokt kit rename in mparticle-javascript-integration-rokt.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@rmi22186 rmi22186 changed the title feat: Add Identity.searchWorkspace for IDSync Search feat: Add Identity.search for IDSync Search Apr 30, 2026
The Identity.search wrapper body lived in identity.js — opt-out
gating, URL construction, request envelope building, and dispatch to
sendSearchRequest, all in plain JS. Move that glue into a typed
`executeSearchRequest(mpInstance, workspaceApiKey, knownIdentities,
callback)` helper in identity-utils.ts so the SDK wiring is
type-checked against `IMParticleWebSDKInstance`, `ISearchKnownIdentities`,
`ISearchRequestBody`, and `SearchCallback` instead of being implicit.
Behaviour is unchanged — identity.js's search method now delegates in
one line.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Comment thread src/identity.interfaces.ts Outdated
Comment on lines +16 to +17
ISearchKnownIdentities,
SearchCallback,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit:

Suggested change
ISearchKnownIdentities,
SearchCallback,
IIdentitySearchKnownIdentities,
IdentitySearchCallback,

Comment thread src/identity.js Outdated
mpInstance.Logger.verbose(
Messages.InformationMessages.AbandonLogEvent
);
if (mpInstance._Helpers.Validators.isFunction(callback)) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be pulled from utils.ts instead of Validators.

Suggested change
if (mpInstance._Helpers.Validators.isFunction(callback)) {
if (isFunction(callback)) {

Comment thread src/identity.js Outdated
} catch (e) {
mpInstance.Logger.error(
'Error invoking search callback: ' +
((e && e.message) || String(e))
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the robot's suggestion below.

Comment thread src/identity.js Outdated
sdk_version: Constants.sdkVersion,
},
environment: environment,
request_id: mpInstance._Helpers.generateUniqueId(),
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use utils.ts.

Suggested change
request_id: mpInstance._Helpers.generateUniqueId(),
request_id: generateUniqueId(),

Comment thread src/identity.js Outdated
// Build the same envelope that /v1/identify uses (client_sdk,
// request_id, request_timestamp_ms, environment) so the IDSync
// service can correlate requests across endpoints.
const requestBuilder = function() {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: can we extract this method outside of the function to make it more readable?

Comment thread src/identity.js Outdated
);
const searchUrl = serviceUrl + 'search?cb=1';

const environment = mpInstance._Store.SDKConfig.isDevelopmentMode
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can destructure a lot of these configvalues to make the code more readable.

Comment thread src/search.ts Outdated
@@ -0,0 +1,234 @@
import Constants, { HTTP_OK, HTTP_NOT_FOUND } from './constants';
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should put this in src/identity/search.ts so that we can eventually split out the other identity functions into their own space for cleaner organization.

rmi22186 and others added 2 commits April 30, 2026 12:54
Address PR review nit (alexs-mparticle on #1255): the `ISearch*` /
`SearchCallback` family is too generic for the public types surface
— scope them to `Identity` so they read clearly alongside the rest
of the IDSync types.

- ISearchKnownIdentities  -> IIdentitySearchKnownIdentities
- ISearchResponseBody     -> IIdentitySearchResponseBody
- ISearchResult           -> IIdentitySearchResult
- ISearchRequestBody      -> IIdentitySearchRequestBody
- ISearchPayload          -> IIdentitySearchPayload
- SearchCallback          -> IdentitySearchCallback

Function names (`sendSearchRequest`, `executeSearchRequest`) and the
public method (`Identity.search`) are unchanged — they're already
contextually scoped.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Use `isFunction` from utils.ts instead of `Validators.isFunction`
  (r3169167597).
- Use `generateUniqueId` from utils.ts instead of
  `mpInstance._Helpers.generateUniqueId()` (r3169189020).
- Destructure `_Helpers`/`_Store`/`Logger`/`_ErrorReportingDispatcher`
  and `identityUrl`/`isDevelopmentMode` from `mpInstance`/`SDKConfig`
  in `executeSearchRequest` for readability (r3169201394).
- Extract the IDSync envelope construction into a standalone
  `buildIdentitySearchEnvelope(environment)` helper so it can be
  unit-tested independently of the full request flow.
- Add four unit tests for `buildIdentitySearchEnvelope` (SDK
  identifiers + supplied environment, development branch, fresh
  request_id per call, no `known_identities` leakage).
- Move `src/search.ts` to `src/identity/search.ts` so future identity
  primitives can be grouped under one namespace (r3169209572); update
  all import paths and the relative imports inside the moved file.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Comment thread src/identity.js
Comment thread src/identity/search.ts Outdated
): Promise<void> => {
// Validate the callback up front. If it isn't a function we have nowhere
// to deliver a result to, so log and bail out without invoking anything.
if (typeof callback !== 'function') {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utils.ts.

Suggested change
if (typeof callback !== 'function') {
if (!isFunction(callback)) {

Comment thread src/identity/search.ts
Comment thread src/identity/search.ts Outdated

// FetchUploader returns a real Response with .json(); XHRUploader
// returns an XHR-shaped object with `responseText`. We tolerate both.
if (typeof (response as Response).json === 'function') {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isFunction

Comment thread src/identity/search.ts
Comment thread src/identity/search.ts
Comment thread src/identity.js
…arch

- Use `isFunction` from utils.ts at the two `typeof X === 'function'`
  call sites in `src/identity/search.ts` (lines 111 and 185), per
  Alex's nits on the latest review pass.
- Add `'search'` to the snippet pre-init `identityMethods` arrays in
  `snippet.js` and `snippet.rokt.js`, and add `search: voidFunction`
  to `src/stub/mparticle.stub.js` — without these, `Identity.search`
  doesn't get a queued stub, so a kit calling
  `mParticle.Identity.search(...)` before the SDK loads would throw
  `TypeError` instead of being replayed after init (cursor-bot bug
  flagged on identity.js:758).

Email validation (Alex's nit on line 131) is intentionally not added:
the IDSync backend accepts any string and validation belongs at the
client site.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Comment thread src/identity-utils.ts
rmi22186 and others added 3 commits April 30, 2026 14:57
Cursor-bot caught (PR #1255 r3170092708): the destructured local
`_ErrorReportingDispatcher` was unused — the call to `sendSearchRequest`
still went through `mpInstance._ErrorReportingDispatcher`. Use the
local now that it's been destructured, matching the pattern in
`identityApiClient.ts` (`_ErrorReportingDispatcher: errorReporter`).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two new tests exercising the pre-init queueing path and the offline
stub for the new `Identity.search` method:

- `test/snippet/tests-snippet.js`: extends the "mParticle object should
  proxy Identity methods" case to call `mParticle.Identity.search(...)`
  before init and assert the queued entry lands in `config.rq` as
  `Identity.search` with the workspace key, identities object, and
  callback function intact.
- `test/stub/tests-mParticle-stub.js`: extends the Identity stub case
  to call `Identity.identify`/`login`/`logout`/`modify`/`search` and
  verify they don't throw (matching the void-function pattern).

Also regenerates `snippet.min.js` and `snippet.rokt.min.js` so the
minified bundles include the new `'search'` entry in
`identityMethods`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Marginal cleanup — `Date.now()` is the idiomatic way to get the current
millisecond timestamp; `new Date().getTime()` allocates a Date object
just to immediately read its time. Same value, no allocation.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Comment thread src/identity/search.ts Outdated

// FetchUploader returns a real Response with .json(); XHRUploader
// returns an XHR-shaped object with `responseText`. We tolerate both.
if (isFunction((response as Response).json)) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the robot is right. You can probably remove as Response.

Comment thread src/identity/search.ts
Comment thread src/identity-utils.ts Outdated
rmi22186 and others added 2 commits April 30, 2026 15:46
Co-authored-by: Alex S <49695018+alexs-mparticle@users.noreply.github.com>
Two follow-ups from Alex's review pass on the latest commits:

- Fix the unresolved `Environment` reference in `executeSearchRequest`
  (suggestion 723e7e8 didn't add the import) and propagate the named
  type to `buildIdentitySearchEnvelope`'s parameter and to
  `IIdentitySearchRequestBody.environment`. `Environment` is the same
  `'development' | 'production'` union as before, just centralized
  through `Constants.Environment`.
- Drop redundant `(response as Response)` assertions in
  `identity/search.ts` — `response` is already typed `Response` from
  the awaited `api.upload(...)` return, so the cast is a no-op
  (Sonar S4325).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@sonarqubecloud
Copy link
Copy Markdown

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit e47d52a. Configure here.

Comment thread src/identity/search.ts
logger.verbose(
'search response had no parseable JSON body.',
);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JSON parse errors reported as success

Medium Severity

sendSearchRequest swallows response.json() failures and still returns the original HTTP status. A malformed or non-JSON 200 response is surfaced as success (httpCode: 200) instead of HTTPCodes.noHttpCoverage, and no structured error is reported. This can make callers treat failed IDSync responses as valid search hits.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit e47d52a. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants